Stale reactive-execute state files are never cleaned, causing permanent dispatch stalls
Summary
When a session crashes or exhausts context during reactive-execute, the per-unit reactive state file ({mid}-{sid}-reactive.json) persists indefinitely. Nothing in the current codebase ever cleans these files (grep clearStaleReactiveStates → no hits at 33c00aaff), and the idempotent guard then blocks all future dispatch of that unit — a permanent stall that needs manual file deletion to clear.
Four call sites miss the cleanup, which is why this is one consolidated issue rather than four:
- Crash recovery (
crash-recovery.ts):clearStaleWorkerLockcleans worker locks but not reactive state files left by the same crash. - Bootstrap (
auto.ts): on session start, stale worker locks are handled but reactive state from a prior crashed session survives. - Reactive dispatch (
auto-dispatch.ts): the reactive-execute rule derives the task graph without evicting stale state first, so a stale file created within the current session blocks re-dispatch even after a clean bootstrap. - Orchestrator (
auto/orchestrator.ts): the blocked paths returnaction: "pause"with no stale-state eviction attempt, so the pause is permanent for the stale-state case. (The stuck-loop detector added when #5787 closed lives here now, but it also stops without attempting eviction.)
Proposed fix
Add a clearStaleReactiveStates() helper to reactive-graph.ts with two staleness signals:
- TTL: state file older than 30 minutes, and
- no-summary detection: none of the dispatched tasks has produced a
SUMMARY.md.
Call it from the four sites above; in the orchestrator, attempt eviction before the hard block and return a retry rather than a permanent pause when stale state was evicted. I have this running locally (patched .js in a production install) and will submit a TypeScript PR with tests referencing this issue.
Prior art (both closed): #5698, #5787 — the stuck-loop detection half landed via those; this issue covers the missing stale-state eviction half. #5898 (closed) addressed stale DB worker rows, which is a different artifact class than these .json state files.
Source: gsd-build/gsd-2