In a large skillet over medium heat, melt butter with olive oil. Add onions and a pinch of salt. Cook, stirring occasionally, for 30–45 minutes until deeply caramelized and jammy. If onions begin to stick, add small splashes of water and scrape the pan.
In a separate pan, sear beef over medium-high heat until browned on all sides. Remove and set aside.
Add garlic and thyme to the onions and cook for 1 minute. Stir in flour and cook for 60–90 seconds.
Pour in wine and scrape the pan thoroughly. Cook for 2–3 minutes until slightly reduced and no longer smells strongly of alcohol.
Add 1½ cups beef broth, Worcestershire sauce, soy sauce (if using), bay leaf, and the seared beef. Cover and simmer for 10–12 minutes.
Uncover and simmer for another 10–12 minutes until the sauce thickens slightly. If needed, add more broth to loosen or simmer longer to reduce.
Remove bay leaf. Stir in Dijon mustard. Taste and adjust salt and pepper as needed.
Preheat oven to 400°F (200°C).
Transfer the filling to a baking dish or ramekins. Stir in about ¾ of the Gruyère cheese and sprinkle the remaining cheese lightly on top.
Lay puff pastry over the top, trim edges, and cut small vents.
Bake for 20–25 minutes until the crust is golden brown and the filling is bubbling.
Let rest for 5–10 minutes before serving.