Symptom
templates/fix-swarm/checks/fix-swarm.py writes <key>.patch on every check run. If attempt 1 produced a correct patch but the check failed for an unrelated reason (e.g. a buggy verify assertion), the retry — steered by that misleading failure context — can mangle the tree, and attempt 2's check run then overwrites the good patch.
Evidence
Near-miss on 2026-07-14 (protocol-spec-fixes, specs-registry lane): attempt 1's patch was the exactly-correct 8-line change; attempt 2 burned ~70k tokens trying to satisfy a verify assertion that could not pass on a pristine repo, and only by luck did not alter the file before its check run re-exported the patch.
Proposed fix
In the template's check script: export <key>.attempt<N>.patch per attempt and copy the final one to <key>.patch (preserving the current interface for orchestrators). The orchestrator can then recover attempt 1's work after diagnosing a check bug.
Size: S, template-only — no ringer.py change.
🤖 Generated with Claude Code
Symptom
templates/fix-swarm/checks/fix-swarm.pywrites<key>.patchon every check run. If attempt 1 produced a correct patch but the check failed for an unrelated reason (e.g. a buggy verify assertion), the retry — steered by that misleading failure context — can mangle the tree, and attempt 2's check run then overwrites the good patch.Evidence
Near-miss on 2026-07-14 (
protocol-spec-fixes, specs-registry lane): attempt 1's patch was the exactly-correct 8-line change; attempt 2 burned ~70k tokens trying to satisfy a verify assertion that could not pass on a pristine repo, and only by luck did not alter the file before its check run re-exported the patch.Proposed fix
In the template's check script: export
<key>.attempt<N>.patchper attempt and copy the final one to<key>.patch(preserving the current interface for orchestrators). The orchestrator can then recover attempt 1's work after diagnosing a check bug.Size: S, template-only — no ringer.py change.
🤖 Generated with Claude Code