feat(implement-loop): standard end-verify gains an independent suite gate
Standard mode was the only execution path without an end-of-iteration suite gate: tree-check only counted files, so suite-green rode on the per-task implementers' self-reports while mini-verify and compiler-driven-edit both re-run the suite as a hard gate (pipeline-audit finding). The tree-check stage becomes end-verify with two independently-gating legs: files_touched (untracked-aware no-op gate, unchanged semantics) and suite_green (full independent suite run; red -> BLOCKED, route back to debug RED-first). Costs ~+51k real tokens per standard DONE iteration vs. the old count-only stage; the deterministic backstop is what makes the quality-review tiering in #30 defensible. Known trade-off, by design: a flaky or environment-red suite now blocks a standard iteration — the same exposure mini-verify has. closes #29
This commit is contained in:
+13
-9
@@ -114,6 +114,7 @@ NEVER PUSH PAST `BLOCKED` BY HAND.
|
||||
ON `PARTIAL` OR `BLOCKED`, THE END-REPORT CARRIES THE `BLOCKED.md` CONTENT (`artifacts.blocked_md`); THE ORCHESTRATOR'S FIRST ACTION ON READING SUCH A REPORT IS WRITING IT VERBATIM TO `BLOCKED.md` AT THE REPO ROOT — UNCOMMITTED BY CONVENTION. ON `DONE`, `artifacts.blocked_md` IS NULL. (EXCEPTIONS WHERE IT IS ALSO NULL: A NO-OP ITERATION — ITS TREE IS ALREADY CLEAN — AND ANY PRE-LOOP EARLY EXIT (MALFORMED CARRIER, DIRTY-TREE PREFLIGHT, PLAN-EXTRACT GUARD): NOTHING RAN AND NOTHING WAS WRITTEN, SO THE STATUS + `infra:`-PREFIXED REASON RIDE THE END-REPORT AND THERE IS NOTHING TO CLEAN UP OR EXPLAIN.)
|
||||
`DONE` REQUIRES POSITIVE EVIDENCE THAT AN EDIT LANDED — A NO-OP ITERATION (`git status --porcelain` EMPTY, untracked files INCLUDED) IS NEVER `DONE`, IT IS `BLOCKED` (the issue #11 vacuous-green shape, guarded on the main path). THE VERDICT IS THE GIT TREE COUNT, NEVER A SELF-REPORT.
|
||||
IN MINI MODE THE RED->GREEN IS OBSERVED, NOT ASSERTED: AN INDEPENDENT VERIFY RE-RUNS THE HANDED-OFF RED TEST AND THE SUITE; A STILL-RED TEST OR A REGRESSION IS `BLOCKED` (route back to debug, RED-first).
|
||||
IN STANDARD MODE THE END-VERIFY RE-RUNS THE FULL SUITE INDEPENDENTLY: SUITE RED IS `BLOCKED` (route back to debug, RED-first) — GREEN IS OBSERVED, NEVER TAKEN FROM PER-TASK SELF-REPORTS.
|
||||
THE COMPILER-DRIVEN ARM COMMITS ONLY ON CLEAN BUILD + SUITE GREEN UNCHANGED; ELSE IT BOUNCES (specify for a design hole, tdd for discovered new behaviour, debug for a regression).
|
||||
```
|
||||
|
||||
@@ -141,15 +142,18 @@ positive evidence that an edit landed. The verdict is taken from **git
|
||||
ground truth, never a self-report** — a self-report must never be able to
|
||||
*fail* a run that actually did the work:
|
||||
|
||||
- **Iteration gate (standard mode)** — a dedicated `tree-check` agent runs
|
||||
`git status --porcelain | wc -l` after the per-task loop but **before**
|
||||
E2E and finalize. A `DONE` outcome with a zero count is a no-op iteration
|
||||
→ `BLOCKED`. `git status --porcelain` (not `git diff HEAD`) is used so a
|
||||
brand-new **untracked** file — the implementer leaves edits unstaged —
|
||||
still counts; running before E2E/finalize keeps fixtures and the
|
||||
stats/`BLOCKED.md` artefacts from inflating it; and a non-returning agent
|
||||
is treated as `BLOCKED` (infra), never waved through. A clean-tree no-op
|
||||
writes no `BLOCKED.md` (nothing to clean up — see Step 4).
|
||||
- **Iteration gate (standard mode)** — a dedicated end-`verify` agent runs
|
||||
after the per-task loop but **before** E2E, with two independently-gating
|
||||
legs: `git status --porcelain | wc -l` (a `DONE` outcome with a zero count
|
||||
is a no-op iteration → `BLOCKED`) and a full **independent suite run**
|
||||
(suite red → `BLOCKED`, route back to `debug` RED-first — standard mode
|
||||
previously had no end-of-iteration suite gate while mini and
|
||||
compiler-driven both re-run the suite; the asymmetry is closed).
|
||||
`git status --porcelain` (not `git diff HEAD`) is used so a brand-new
|
||||
**untracked** file — the implementer leaves edits unstaged — still counts;
|
||||
running before E2E keeps fixtures from inflating it; and a non-returning
|
||||
agent is treated as `BLOCKED` (infra), never waved through. A clean-tree
|
||||
no-op carries no `BLOCKED.md` content (nothing to clean up — see Step 4).
|
||||
- **Mini mode gate** — an independent `mini-verify` agent re-runs the
|
||||
handed-off RED test and the suite and checks the tree is dirty
|
||||
(`git status --porcelain`); a still-red test, a regression, or a clean
|
||||
|
||||
Reference in New Issue
Block a user