🐛 What happens: PlayoutFeeder.ObserveAsync returns false whenever OnAirNewestAsync is null, meaning the engine's output has no metadata yet. RefillAsync then never runs. If the fallback scope is empty, the engine plays silence with no metadata, and the feeder never pushes a track. The result is permanent silence even when ready music exists.
🔎 Found by: the nightly fresh leg in #888. A seed render failed, the fallback scope stayed empty, and 4 ready tracks never aired. The api waiting on the engine used to hide this. #888's compose fix restores the start order, but not the invariant.
✅ Want: a cold start with an empty engine queue still refills (SPEC F1.3, never silent; F7.5 boot refill). Also consider having the boot seeder retry the fallback clip render instead of waiting for the next boot.
🐛 What happens:
PlayoutFeeder.ObserveAsyncreturns false wheneverOnAirNewestAsyncis null, meaning the engine's output has no metadata yet.RefillAsyncthen never runs. If the fallback scope is empty, the engine plays silence with no metadata, and the feeder never pushes a track. The result is permanent silence even when ready music exists.🔎 Found by: the nightly fresh leg in #888. A seed render failed, the fallback scope stayed empty, and 4 ready tracks never aired. The api waiting on the engine used to hide this. #888's compose fix restores the start order, but not the invariant.
✅ Want: a cold start with an empty engine queue still refills (SPEC F1.3, never silent; F7.5 boot refill). Also consider having the boot seeder retry the fallback clip render instead of waiting for the next boot.