The fix loop Shipped
Select findings, synthesize a contract from them, dispatch a grounded coder, and let a scoped re-review decide whether each one is actually gone.
How a pass runs
- Every finding carries a disposition — fix or defer — emitted whether or not you asked for the loop.
--fix recommendedtakes everything not marked defer;--fix alltakes everything; bare--fixresolves torecommendedrather than asking. The interactive picker belongs to the other case — plainreview codewith no fix flag at all, where the session offers the numbered table afterwards.- A fix contract is synthesized with one criterion per selected finding, pinning its location and anchor.
- A pinned coder subagent edits code only — Read, Grep, Write, Edit. No Bash, no Agent, so it cannot fan out.
- Every path:line the coder cites must resolve to a line it actually added or modified, or the increment goes back once and then blocks the commit.
- The session commits, never the coder. Each pass is its own commit, so the git history is the rollback trail.
- The gate is a re-review, not the contract: a finding is fixed only when its anchor no longer appears in the re-review.
- Capped at three passes. Leftovers are reported as fixed, re-deferred, or still-open — a re-deferred finding is never reported as fixed.
Why the contract is not the judge
The synthesized contract exists to brief the coder, and nothing else. If the criteria were also the gate, the loop would be marking its own work against a target it wrote for itself. The independent re-review is the judge, and any new recommended finding the fix introduces is folded into the next pass automatically.
It needs a driving session
From a bare terminal, --fix prints a redirect rather than running: the loop applies edits and makes commits, and that belongs to a session that can be interrupted, not to a fire-and-forget subprocess.