Spawn candidate selection happens before budget checks.
Current flow in runCycle:
1. chooseSpawnCandidates slots ... domainTasks picks up to max-active tasks
2. spawnForTask then checks budget per picked task
3. If picked tasks fail budget, scheduler does not refill from the rest of ready queue
This means affordable tasks later in the ready list can starve indefinitely.
With max-active=8, if the first 8 domain-unique tasks are unaffordable, all 8 are skipped and the cycle ends with spawned=0 even if task #9+ could run.