Goal
Implement an in-flight work index so the dispatcher refuses to dispatch an issue whose work is already underway on another branch. Prevents the dispatcher from launching duplicate work that a previous cron run already started.
Success Criteria
- New
runtime/state/in_flight_tasks.json updated atomically on every agent_launch and agent_exit event
- Records
{task_id, issue_number, repo, branch, started_at, status: launching|running|completed|failed}
- Dispatcher consults the index before dispatching: if target issue appears in
running state for any repo, dispatch is refused with "already in flight" reason logged
- Daily garbage collection: entries older than 48h marked stale and ignored (prevents crashed dispatcher from permanently blocking an issue)
- Integration tested: verify that dispatching same issue twice is blocked when first dispatch is in
running state; verify stale entries are ignored
Constraints
- In-flight index must use atomic-write pattern (tempfile + os.replace) to prevent corruption from mid-write crashes
- Must not depend on Phase 1 implementation details (semantic dedup) — runs independently
Part of #259
Goal
Implement an in-flight work index so the dispatcher refuses to dispatch an issue whose work is already underway on another branch. Prevents the dispatcher from launching duplicate work that a previous cron run already started.
Success Criteria
runtime/state/in_flight_tasks.jsonupdated atomically on everyagent_launchandagent_exitevent{task_id, issue_number, repo, branch, started_at, status: launching|running|completed|failed}runningstate for any repo, dispatch is refused with "already in flight" reason loggedrunningstate; verify stale entries are ignoredConstraints
Part of #259