try_submit() returned after a single submission and was only called at
startup and once per completion, capping real concurrency at 1 task
regardless of the parallel setting — the ThreadPoolExecutor pool was
sized but never filled. Loop until every free slot is filled or no
eligible candidate remains, per spec §10 (wording sharpened to make the
whole-pool semantics explicit). No stub-claude harness exists yet to
test dispatch concurrency end-to-end; verified live against the real
queue (36 candidates, parallel=20).
Claude-Session: https://claude.ai/code/session_01Lgv4Qn82boNFC1jn8QXSNw