fix(implement-loop): guard against a task discarding sibling tasks' uncommitted work
During a multi-task run nothing commits between tasks, so one task's file-level `git checkout -- <file>` / `git restore <file>` silently destroys an earlier task's uncommitted DONE work in a shared file. The loss was structurally invisible: spec- and quality-reviewers are scoped to the current task's footprint, diff_fingerprint only detects same-task repair cycles, and the end-of-iteration tree gate counts files (the surviving changes keep it nonzero). Observed in the wild as a PARTIAL run whose DONE reports did not match the tree. Two layers, both plugin-side (harness-level prevention is ruled out — decision log on the issue): Prose guard — implementer.md Step 8 no longer sanctions file checkout for scope curation: over-reach is undone by editing back, a broken intermediate state is repaired forward or reported BLOCKED (new fourth BLOCKED bucket in the status protocol). A matching Iron Law line in implement/SKILL.md covers all in-loop agents, whole-file and --patch; docs/conventions.md now marks the checkout discard idiom as the orchestrator's, between iterations. Mechanical guard — after every task of a multi-task run a snapshot agent records `git stash create` (a dangling commit; HEAD, index, and tree untouched — semantics verified empirically in a scratch repo) plus the `git diff HEAD --name-only --no-renames` path set. A path that was HEAD-modified at one boundary and gone at the next trips a hard BLOCKED naming the lost paths, the boundary, and the recovery snapshot sha (`git show <sha>:<path>`); the discard verdict outranks per-task outcomes in blocked_detail since the reports and the tree have diverged. Coarse by design, in both directions, and documented as such: a checkout-then-re-edit or a --patch hunk restore escapes the comparison (the snapshot keeps it diagnosable); a legitimate back-to-HEAD edit trips it (the verdict says adjudicate against the snapshot). --no-renames keeps a staged rename from reading as a loss; untracked files are outside the threat model (checkout cannot discard them). Cost: one sonnet/medium call per task, multi-task runs only; single-task and mini runs are unchanged. Verified: node --check on the async-wrapped script and a stub-agent harness — discard trips the hard BLOCKED and stops the loop; an accumulating happy path, a plan-intended deletion, a single-task run, and a dead snapshot agent all pass without a false positive. closes #23
This commit is contained in:
@@ -162,8 +162,17 @@ substitute.
|
||||
Law from `tester.md` applies to your tests too.
|
||||
8. Self-review: re-read `git diff HEAD`. Did it match the
|
||||
task text? Did you do anything not in the task text?
|
||||
If yes, undo that part with `git checkout -- <path>` or
|
||||
by editing back — controller curates scope, not you.
|
||||
If yes, undo that part BY EDITING BACK — never with
|
||||
`git checkout` / `git restore`, whole-file or
|
||||
`-p`/`--patch`; the same holds for recovering from a
|
||||
broken intermediate state: repair forward by editing,
|
||||
or report `BLOCKED`.
|
||||
Nothing commits between the tasks of an iteration, so a
|
||||
file you touched may also carry EARLIER tasks'
|
||||
uncommitted, already-reviewed work — `git diff HEAD`
|
||||
shows those sibling chunks, and a file-level checkout
|
||||
silently destroys them along with yours. Controller
|
||||
curates scope, not you.
|
||||
Did the test you wrote actually fail before the GREEN
|
||||
code, or did you write it after? If after, delete the
|
||||
production code and start over. (TDD is letter-and-
|
||||
@@ -196,6 +205,10 @@ End every report with exactly one of:
|
||||
design ledger forbids)
|
||||
- hypothesis-space exhaustion (≥ 3 implementation
|
||||
strategies failed — architecture is wrong, escalate)
|
||||
- unrecoverable intermediate state (the tree broke
|
||||
mid-task and forward repair by editing failed —
|
||||
checkout/restore is not an option: it destroys
|
||||
sibling tasks' uncommitted work, Step 8)
|
||||
Never push past BLOCKED by hand.
|
||||
|
||||
## Output format
|
||||
|
||||
Reference in New Issue
Block a user