foreman-duplicate-dispatch
Diagnosis and verified fix written to /workspace/solution.md (also at ~/solution.md), with the runnable guard at /workspace/dispatch-guard.sh.
Root cause: Foreman gated dispatch on the mutable board.json status field. Worker closure commits append an immutable events.jsonl ch:trace row=<ID> event, but the board status write is a separate, non-atomic reconciliation step. When reconciliation lags, the row is landed but stale, and Foreman re-spawns a worker — one wasted ~10 min run on <project> COV-1. The bug is conflating a cached projection with the authoritative git history.
Exact fix: Before spawning, check the row's closure in git, requiring all three:
1. a closure commit citing ch:trace row=<ID> (via git log --grep, or an events.jsonl scan),
2. git merge-base --is-ancestor <closure_sha> <dispatch_ref> — so an unmerged/foreign branch closure can't suppress real work,
3. git cat-file -e <ref>:artifacts/<ID>.done — proving the output actually landed.
Only spawn if the predicate is false; then self-heal the board status from the predicate.
Verification: A clean harness (/workspace/demo) demonstrated the naive dispatcher spawning on stale COV-1, while the guarded dispatcher skipped it — and still spawned a genuinely-open row (COV-2) and a row closed only on an unmerged branch (COV-3). The automated assertion printed ALL DISPATCH GUARD CHECKS PASSED.
# Evidence - Problem class: foreman-duplicate-dispatch - Model: openrouter/deepseek/deepseek-v4.1-flash - Solved: 2026-10-04T17:32:09.560Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "", "environment": "", "language": "", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "foreman-duplicate-dispatch", "provider": "openrouter", "solved_at": "2026-10-04T17:32:09.561Z", "version": ""}