pi-gauntlet 7.41.1 → 7.41.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +2 -2
- package/package.json +1 -1
- package/skills/brainstorming/SKILL.md +1 -1
- package/skills/brainstorming/reference/amendment-surface.md +4 -4
- package/skills/gatekeep-pr/reference/batch.md +1 -1
- package/skills/loop-implementation/SKILL.md +18 -6
- package/skills/subagent-driven-development/SKILL.md +4 -4
- package/skills/subagent-driven-development/reference/fix-loop.md +20 -0
- package/skills/subagent-driven-development/stop-note.md +3 -0
- package/skills/writing-plans/SKILL.md +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v7.41.3 - 2026-10-30
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- `/skill:gatekeep-pr` on a set of PRs renders one PR's report and menu per turn: the summary turn carries only the first PR's report and menu, each later PR renders only after the previous pick is collected, and no message asks for all picks at once. (#103)
|
|
8
|
+
|
|
9
|
+
## v7.41.2 - 2026-10-30
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- Under an active amend grant, an implementer-execution failure in either implement engine (the waves third attempt, a loop row at its allowance, the loop exit-verification repair) spends one escalated round on `escalationLoop.implModel` before stopping. A stop whose `Recommendation:` names work the grant already authorizes (an amend, a narrower test filter, a fix-first ticket) is taken; `Recommendation: none`, budget- or consent-spending recommendations, a third human-facing aftermath outcome, and repeated evidence still stop for the human, and every implement-phase stop note ends with a `Recommendation:` line. An approved drafted AC-row correction backed by implementer evidence is an amend item under the grant; cap, stagnation, and boundary stops are unchanged. (#101)
|
|
14
|
+
|
|
3
15
|
## v7.41.1 - 2026-10-29
|
|
4
16
|
|
|
5
17
|
### Changed
|
package/README.md
CHANGED
|
@@ -39,7 +39,7 @@ Concretely, one change through the gauntlet:
|
|
|
39
39
|
1. Opt in with `/skill:brainstorming` and describe the change. The command is the reliable discovery-and-entry path; explicit prose requesting brainstorming/the gauntlet also supplies consent when the skill is already loaded or an available instruction or route identifies it. An ordinary implementation request or an agent recommendation is not consent. A leading run of GitHub references (`#N`, `owner/repo#N`, or a `/pull/N` or `/issues/N` URL), separated by whitespace or commas, resolves each reference as a PR first: related open, same-repository, non-fork PRs on one base form one rework subject, including drafts. Admission runs in listed order and relatedness is checked before provisioning; the first retained PR is home, whose existing branch rebases onto the fetched PR base by default, then member commits replay onto it in listed order. The first intent word `merge-forward` opts out and keeps the merge path. An unresolved conflict after its scoped helper aborts that step and continues to the spec with the repair as Task 1. A single non-PR reference follows the ticket path. The first non-reference token starts intent text; mid-sentence references and other ticket/free-text subjects keep their existing paths. The combined code, PR-carried specs, claims, and review threads are the brainstorm input, with each PR's provenance retained; only home's bound ticket supplies acceptance criteria, while member tickets supply context. A single PR retains the same rework path without member replays or a close offer. The combined state is judged against constraints from the fetched current base HEAD, not the fork point or the PRs' proposed policy edits; see the [PR-subject contract](skills/brainstorming/reference/pr-subject.md) and [PR-head worktree owner](skills/using-git-worktrees/reference/pr-head.md). **`brainstorming`** sets up an isolated worktree (on the existing branch for PR rework), explores the codebase, and turns the subject into a written spec - when its recon finds a cited case that the ask is the wrong change (misdiagnosed, wrong-sized, already solved, a band-aid, or cutting across a sound pattern - including a repo convention that is itself debt) and can name the alternative, question one is a framing question (`as framed`, `pivot: <alternative>`, or `smaller or none`); otherwise it opens with one sentence naming what it checked, and every approach it proposes ends with a `Pattern:` line naming what it follows or cuts across; when the run starts from a ticket, the spec carries the ticket's acceptance criteria verbatim, each with a disposition (`in-scope`, `deviates:`, `deferred:`, `venue:`, `elsewhere:` for a row another repo's part delivers), scope cuts come only from your answer to a cut question and are listed at the gate, the conformance gate checks the in-scope ones, and `/skill:check-delivery` verifies `venue:` rows before the prod deploy. A multi-model critique runs on it automatically. If the spec replaces a known prior spec, brainstorming marks the predecessor with a `> **Superseded by:**` banner under its title (default format, syntax overridable via `.pi/gauntlet-overrides.md`; candidates come from brainstorming's scout recon, never a mechanical sweep). **You read and approve the spec - human gate 1.** Options 1/2/4/5 approve and pick an engine; option 6 approves the content only: it writes `**Engine:** deferred` under `**Amend-grant:** none`, pushes the branch, opens a draft PR carrying just the spec, prints the URL, and ends the flow - no plan, no loop, no handoff brief. For a coordinated spec, it first pushes every companion branch to origin, then opens one home draft PR; it creates no companion PRs. A later `brainstorming #N` reconstructs the recorded companions from their origin branches before re-presenting the implementation gate; the [publication and re-gate owner](skills/brainstorming/reference/spec-pr.md) defines all-member preflight, recovery, and cleanup. The branch stays; a gauntlet-owned worktree is removed, a host-owned checkout is reported and left. Option 6 is withheld on a PR subject (`Withheld: draft PR - #N already exists`) and when the branch's diff against the default branch is not spec-only. A later `brainstorming #N` on that PR classifies it from the diff alone: one added spec carrying the marker plus banner-only predecessor edits re-presents the gate with 1/2/4/5 (3 only when the spec commit carries a council audit) and skips gather, questionary, council, and scout; a spec-only diff without the marker prints `spec-only PR without the gate marker - running lint and council` and takes the normal brainstorm path with the carried spec as the draft; any other diff takes the rework path. Approval at that re-gate writes `**Engine:**`, `**Amend-grant:**`, and `**PR:** <owner/repo#N>` as a new commit on the PR branch and chains into planning or the loop as usual. Before approval, PR rework's sole write/run exception outside the spec directories permits only the base sync (rebase or merge), each member replay or merge, their conflict helpers' edits to the conflicted files, and their scoped conflict tests; other subjects have no implementation code yet.
|
|
40
40
|
2. By default, **`writing-plans`** decomposes the approved spec into atomic, independently-verifiable tasks, grouped into parallel waves where they don't touch the same files. Experimental approval options 4/5 instead select **`loop-implementation`**: the plan phase is skipped and a stamped acceptance-criteria ledger replaces the task plan. Option 4 retains amendment review; option 5 grants auto-apply amends, with redraws still stopping. See [Loop engine operations](doc/configuration.md#loop-engine-operations).
|
|
41
41
|
3. **`subagent-driven-development`** executes the plan one task at a time, each in a fresh subagent, behind spec-compliance review then code-quality review. TDD-locked: red, green, refactor. Independent implementation, review, and council batches remain parallel, but their dispatches are foreground: the orchestrator waits for terminal results before accepting work or advancing a phase.
|
|
42
|
-
The loop alternative to step 3 runs one fresh `loop-implementer` per seed or row iteration, without implement-phase reviewers.
|
|
42
|
+
The loop alternative to step 3 runs one fresh `loop-implementer` per seed or row iteration, without implement-phase reviewers. Stagnation stops for a human decision. Under amend permission, row-allowance exhaustion and failed exit verification each get one bounded escalated-model round within the existing cap; passing full verification with every row closed enters the same verify gates.
|
|
43
43
|
|
|
44
44
|
4. **verify**: the parent first runs the plan's full verification command set (the ledger's `verification:` command for loop); only a passing result permits whole-diff code review, then the **conformance gate**. A review fix invalidates that result, so the parent reruns full verification before the next review or conformance gate. When the overrides file declares a happy path for the touched paths (see [Project-specific overrides](#project-specific-overrides)), the parent runs it once here, between code review and the conformance gate, and the reviewer reads its transcript as runtime evidence - a hang or a failed request shows up in the audit with the transcript quoted - as a gap when an origin clause ties to it, otherwise as a `happy-path: failed - unattributable` line - never as a silent green. The conformance subagent reads the finished code and docs against your *original words* from step 1, not the plan, and reports per-requirement: delivered, partial, missing, drifted, or unauthorized. Unauthorized rows - shipped surface no human input asked for, whether it crept in or was laundered through the spec - follow their recommendation like every other row: a contained removal auto-runs, anything another requirement leans on is deferred with a plain-language "I'd cut it / I'd keep it" recommendation. Inside a brainstorming-entered flow this gate is machine-blocked from being skipped. Compatible executable recommendations auto-run through an isolated fix-and-re-audit loop with no prompt; anything still open surfaces as a numbered decision brief - one item per decision, the problem in plain words first, lettered options each with a one-line consequence, and `Recommended: <letter> - <reason>` or `No recommendation - pick one`. Reply with one line per item (`1. B`), or bare `1` to take every recommendation (no-recommendation items are re-asked by number); a current `CONFORMS` / no-concerns result goes straight to the branch options with no extra conformance sign-off.
|
|
45
45
|
5. **`finishing-a-development-branch`**: PR, draft PR, squash, keep, or discard; PR rework's row 1 offers a lease push of the rebased home branch to the existing PR (`Base:` records in `merge:` form push non-force). A spec whose header carries `**PR:**` (approved at a spec-PR re-gate) and no `## Rework record` replaces the two create rows with `Push to PR #N and mark it ready for review` and `Push to PR #N, keep it a draft` (`Push to PR #N (already ready for review)` when the PR is already ready): both push without force after strip-and-seal, the first then runs `gh pr ready`, neither rewrites the PR body, and both are withheld when origin's branch head is no longer an ancestor of local HEAD. For coordinated specs, these [header-linked rows 1/2](skills/finishing-a-development-branch/reference/spec-pr.md#push-rows-12) deliver companions in recorded order before one home seal carrying every companion PR URL, then push home and apply its readiness choice. Row 1 makes companion drafts ready too; row 2 creates drafts but never converts an already-ready PR back to draft. Companion URLs appear in the shipped summary, companions first and home last, not in the unchanged home PR body; keep that summary for cross-repo review because successful home delivery removes receipts. A spec still carrying `**Engine:** deferred` stops finishing (and `gauntlet-resume`) with `spec approved for handoff only - run brainstorming #N` before any phase change, verification, or push. The PR-rework push appends a `## Rework` block naming absorbed PRs while retaining the original description bytes; the header-linked `**PR:**` push leaves the body untouched. Only after a successful rework push and home-description edit does one gated confirmation show the exact close comments and eligible member targets, linking home; declining or any other finish option leaves members open. Closing never deletes member branches, and finish posts no review-thread replies. Its `Before:` handle includes the full portable pre-rework SHA and the local `refs/gauntlet/pre-rework/pr-<N>` ref in the rework checkout. The [finishing owner](skills/finishing-a-development-branch/SKILL.md#pr-subject-row-1-push-to-the-pr-branch) defines the landing and body-update contract. Once a PR exists, run `/skill:gatekeep-pr <pr>` to verify it before merging - it judges the diff against the spec at the PR's head (the acceptance-criteria dispositions and Design you approved; the PR description when no spec applies) - rows the spec defers or deviates are settled, every other row needs its mechanism (code, tests, docs) - and against the rubric; whatever can be seen only after merge is left to step 6. **Human gate 2** - the only other decision you make.
|
|
@@ -71,7 +71,7 @@ In create mode, `shape-ticket` runs one bounded overlap check after clarificatio
|
|
|
71
71
|
|
|
72
72
|
Use `/skill:shape-ticket --skip-overlap <ask>` to bypass discovery explicitly. Repair mode never discovers candidates. Bypass still retains source reads, known conflicts, integrity checks, roast, approval, and source revalidation. Incomplete search coverage is disclosed, not treated as proof of no overlap; independent sessions can still race, so this is not a uniqueness guarantee.
|
|
73
73
|
|
|
74
|
-
|
|
74
|
+
Between gate 1 and gate 2, both engines take named authorized recommendations under the spec's amend grant and run one bounded escalated execution round before eligible stops; budgets, cap, stagnation, boundary failures and redraws still stop, and budget-only grants supply no amend permission. Planning takes concrete baseline `narrow` or `amend` recommendations under that permission; `fix-first` enters ticket shaping's own gate. An implementer-evidenced text correction to a drafted AC is an amendment, not a redraw; ticket rows, row add/remove and problem or component boundary changes still require redraw approval. See [execution continuation](doc/implement-engines.md#stops-models-and-telemetry). Once gate 1 picks an engine, task breakdown, implementation and reviews proceed within those limits; option 6 parks the approved spec in a draft PR and planning starts only when someone runs `brainstorming #N` on it and approves at the re-gate. Changing an approved spec later goes through brainstorming's `Amending an approved spec`: a fresh-context reviewer clears evidence-backed factual corrections on its own, escalations reach you as one readable batch, and only a redraw is a full stop - not a third numbered gate. That's the mechanism. What follows is the machinery behind it.
|
|
75
75
|
|
|
76
76
|
### Multi-repo runs
|
|
77
77
|
|
package/package.json
CHANGED
|
@@ -193,7 +193,7 @@ Execute in place from any later phase; never invoke `/skill:brainstorming` for i
|
|
|
193
193
|
|
|
194
194
|
Every skill resource in this flow (a `SKILL.md` or a `reference/*.md`) is loaded with the `read` tool at its absolute path under `skills/`, never with a shell command - pruning protection keys on `read`'s `path`.
|
|
195
195
|
|
|
196
|
-
Classify a
|
|
196
|
+
Classify a text correction to an approved drafted acceptance-criteria row backed by implementer evidence (a quoted test, assertion, or code line in a `BLOCKED`/`NEEDS_CONTEXT` return) as an amend item. Keep ticket rows, row add/remove, reviewer-only or taste objections, problem statement changes, and component boundary changes as redraws at batch preparation, before any standing grant: re-draft from the new design and ratify at the full gate. Keep a disposition-only change to such a row in the amendment grammar so it keeps the cut question. Apply an item the human has answered by letter or custom text as recorded. Redraw test: the change alters the problem statement, adds or removes a component, or moves a component boundary -> redraw. A change inside one component (a persistence mechanism, a worker's HTTP client, dropping a fallback and its task) -> amend. State the call; the user overrides either way.
|
|
197
197
|
|
|
198
198
|
Amend -> `read` `reference/amendment-surface.md` and follow it (unreadable -> stop with a blocking error; never improvise the grammar). Apply its [Standing grants](reference/amendment-surface.md#standing-grants) boundaries.
|
|
199
199
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Amendment surface
|
|
2
2
|
|
|
3
|
-
`read` this file (the `read` tool at its absolute path, never a shell command) from `skills/brainstorming/SKILL.md` section Amending an approved spec, from any phase, for amend-class changes; at approval, load only [Standing grants](#standing-grants), not the batch procedure. Keep redraws outside this procedure. Classify a
|
|
3
|
+
`read` this file (the `read` tool at its absolute path, never a shell command) from `skills/brainstorming/SKILL.md` section Amending an approved spec, from any phase, for amend-class changes; at approval, load only [Standing grants](#standing-grants), not the batch procedure. Keep redraws outside this procedure. Classify a text correction to an approved drafted acceptance-criteria row backed by implementer evidence (a quoted test, assertion, or code line in a `BLOCKED`/`NEEDS_CONTEXT` return) as an amend item. Keep ticket rows, row add/remove, reviewer-only or taste objections, problem statement changes, and component boundary changes as redraws at batch preparation, before any standing grant: re-draft from the new design and ratify at the full gate. Keep a disposition-only change to such a row in this grammar so it keeps the cut question. Apply an item the human has answered by letter or custom text as recorded. Only the main loop holding `edit`/`write` authors amendments and human-facing amendment text. Use the human last: a fresh reviewer clears evidence-backed factual corrections; present the rest to the human once per batch plainly.
|
|
4
4
|
|
|
5
5
|
## Standing grants
|
|
6
6
|
|
|
@@ -157,7 +157,7 @@ reread rule; amend the block before using a changed contract. Legacy specs
|
|
|
157
157
|
without that section retain finish-time rereading. A one-member run has no
|
|
158
158
|
companion artifact or companion aftermath.
|
|
159
159
|
|
|
160
|
-
Aftermath, once per batch, only when at least one item applied (nothing applied -> skip to the commit below). Ledger exists (line 1 `# Ledger - loop engine` in the resolved plan dir) -> skip `plan-writer`, `plan_check`, and `plan_tracker`. Reconcile the ledger against the approved spec dispositions: `deviates:`, `deferred:`, or `elsewhere:` -> `cut`, evidence = the disposition; factual or requirement-preserving amendment -> preserve rows; re-bounded `done` row -> `open`, evidence = `reopened by amendment`. Preserve every row's attempts and the ledger's iterations.
|
|
160
|
+
Aftermath, once per batch, only when at least one item applied (nothing applied -> skip to the commit below). Ledger exists (line 1 `# Ledger - loop engine` in the resolved plan dir) -> skip `plan-writer`, `plan_check`, and `plan_tracker`. Reconcile the ledger against the approved spec dispositions: `deviates:`, `deferred:`, or `elsewhere:` -> `cut`, evidence = the disposition; factual or requirement-preserving amendment -> preserve rows; re-bounded `done` row -> `open`, evidence = `reopened by amendment`. Preserve every row's attempts and the ledger's iterations and cap. Apply evidenced drafted-row text corrections as amend items while preserving row identity; retain the cut/reopen rules above. Ticket text and row add/remove changes remain redraws. Commit spec + ledger together with subject `loop: cut row <n>` for a batch containing only one cut, otherwise `loop: amend` (including mixed batches), carrying the amendment audit body below (including each `granted` record and granting sentence); continue without task-plan aftermath. No plan yet -> commit the spec; continue. Plan exists -> read `git -C "<abs worktree path>" status --porcelain` (plain jj: `jj -R "<abs worktree path>" diff --summary`); collect the parent's in-flight workflow edits as worktree-relative paths, including the amended spec and staged in-place wave-repair deliverables. Dispatch `plan-writer` per `writing-plans` `## Author the plan` step 3 with an `Amend:` block naming the amended spec sections, an `In-flight:` list of those paths (the parent supplies the set; the child never infers it), and the rule "preserve every task title and wave position the amendment does not touch; edit only affected anchors and tasks", then run that section's steps 5-6 (the parent `plan_check` and its branches).
|
|
161
161
|
|
|
162
162
|
At that return point, classify human-facing outcomes with this table; let writing-plans' first `Findings:` repair run as written.
|
|
163
163
|
|
|
@@ -166,9 +166,9 @@ At that return point, classify human-facing outcomes with this table; let writin
|
|
|
166
166
|
| Second identical `plan_check` FAIL | compare the FAIL lines and their quoted plan text |
|
|
167
167
|
| First `- Task N: ... fails on <sha>` or `dirtied tracked source` row | compare the row's baseline command |
|
|
168
168
|
|
|
169
|
-
Compare the quoted FAIL plan text or baseline command with this batch's edits: use the owning task's `Spec:` anchors to an amended section or its changed `Tests:` text against `git -C "<abs worktree path>" show HEAD:<plan path>`. Require text this batch added or changed; neither a plan line number, task membership, nor retained baseline evidence proves attribution. For unchanged text and writer-only defects (such as missing `baseline:` without spec text behind it), render the writing-plans step-6 branch in full from the outcome already in hand: quote the FAIL lines verbatim as the open question; state the task, command, SHA, exit, and summary with `fix-first`, `narrow`, and `amend` options on their own lines and `Recommendation: <option> - <reason
|
|
169
|
+
Compare the quoted FAIL plan text or baseline command with this batch's edits: use the owning task's `Spec:` anchors to an amended section or its changed `Tests:` text against `git -C "<abs worktree path>" show HEAD:<plan path>`. Require text this batch added or changed; neither a plan line number, task membership, nor retained baseline evidence proves attribution. For unchanged text and writer-only defects (such as missing `baseline:` without spec text behind it), render the writing-plans step-6 branch in full from the outcome already in hand: quote the FAIL lines verbatim as the open question; state the task, command, SHA, exit, and summary with `fix-first`, `narrow`, and `amend` options on their own lines and `Recommendation: <option>[ <filter>] - <reason>`; use the same grant-aware step-6 path before waiting (including unchanged-command and writer-only failures), never treating the grant as consent for redraw or restoration; name dirty paths and cause; clear the parent's own wave/amendment source work through its own commit step and list doc-only work under `In-flight:` before re-dispatch; take every other path, including every test-dirtied path, to the human to commit, discard, or move, without restoration - never name step 6 and defer the exit. Partition mixed output: form items only from attributable lines and render the unrelated lines' step-6 branches in full by the same rule. Classify attributable outcomes as amendment items independent of candidate answers and grant state. Keep findings from this batch's own aftermath in this batch until commit; apply section 1's later-finding rule after commit.
|
|
170
170
|
|
|
171
|
-
Apply at most two aftermath items per batch. Send a third human-facing outcome, or evidence repeating an already-applied item's evidence, to step 6
|
|
171
|
+
Apply at most two aftermath items per batch. Send a third human-facing outcome, or evidence repeating an already-applied item's evidence, to step 6 without restoration: render the exit in full, end it with `Recommendation: none - <two-item limit reached | evidence repeats item <n>>` so it waits under any grant, and list the batch's retry items and evidence. Before restoring any path, handle a redraw-class finding by committing the batch as-is, handing dirty paths to step 6 without restoration, then taking `../SKILL.md`'s redraw path. Treat the spec/plan commit as batch preservation, not cleanup. For an amend-class `dirtied tracked source` row, check every named path with `git -C "<abs worktree path>" ls-files -- "<path>"` and against the spec, plan, and `In-flight:` list. Require every path to print as tracked and to be outside those protected paths before restoring any. Route an entire row with any untracked or protected path through step 6, without partial restoration; a new `??` at a `Create:`/`Test:` path is ineligible. Preserve `artifacts:` and `In-flight:` paths. Restore exactly the eligible row's paths, one quoted path per command, in the explicit worktree; for example:
|
|
172
172
|
|
|
173
173
|
```bash
|
|
174
174
|
git -C /tmp/report-worktree ls-files -- "eval/report-runner/report.md"
|
|
@@ -80,7 +80,7 @@ The parent alone renders menus, gathers answers, and runs cleanup/stop consequen
|
|
|
80
80
|
|
|
81
81
|
Use the child's supplied Verdict text unchanged, `conflicting - <sync record>`, `failed - <reason>`, or `stopped - <ask>`. Express a pending binding check only in that PR's queued menu: describe watching the check in its deliver row and print `Not offered: merge (<check> pending)`; leave the supplied verdict unchanged. Evidence is the record's resolved source; use unknown before Verify. Count open P# findings; use unknown without review. Follow with `Shared files:` and every changed path shared by two or more PRs, `<path> - #<N>, #<M>`. Include `#<N> - files unknown` for missing gathered files; print `none` when no path overlaps. Never schedule merges or choose landing order.
|
|
82
82
|
|
|
83
|
-
Print each supplied child report file verbatim in roster order, each under its own `#<N>` heading and directly above that PR's queued menu from `menus.md`; add no synthetic `Verdict:` restatement at the menu turn. Render each child's template from `menus.md`: reports with their template rows, conflicts through `menus.md` `## batch summary`'s recovered CONFLICTING template, failures with retry/evidence/stop, STOPPED with the recorded ask and stop last. For retry use exactly `retry - re-dispatch this PR's assessment with the same record`, recommended only after clean recovery and no rebase. Resolve the actual gitdir with git (a worktree .git can be a file); require empty `git -C <worktree> status --porcelain` and neither rebase-merge nor rebase-apply there. Otherwise omit the row and print `Not offered: retry (worktree dirty or mid-rebase: <state>)`. Substitute `<observed state>` with the concrete observation - the porcelain line(s) or the rebase directory name - one line per snapshot, never the placeholder text.
|
|
83
|
+
Print each supplied child report file verbatim in roster order, each under its own `#<N>` heading and directly above that PR's queued menu from `menus.md`; add no synthetic `Verdict:` restatement at the menu turn. Render only the first PR's report and menu in the summary turn; collect each PR's pick before rendering the next PR's report and menu in a new turn. Never put two PRs' menus in one message or ask for all picks in one combined reply. Render each child's template from `menus.md`: reports with their template rows, conflicts through `menus.md` `## batch summary`'s recovered CONFLICTING template, failures with retry/evidence/stop, STOPPED with the recorded ask and stop last. For retry use exactly `retry - re-dispatch this PR's assessment with the same record`, recommended only after clean recovery and no rebase. Resolve the actual gitdir with git (a worktree .git can be a file); require empty `git -C <worktree> status --porcelain` and neither rebase-merge nor rebase-apply there. Otherwise omit the row and print `Not offered: retry (worktree dirty or mid-rebase: <state>)`. Substitute `<observed state>` with the concrete observation - the porcelain line(s) or the rebase directory name - one line per snapshot, never the placeholder text.
|
|
84
84
|
|
|
85
85
|
Queue every parent-owned terminal pick (post coverage to PR or ticket, merge, cleanup, wait, stop) until every roster entry's pick for the round is collected. Print `Queued until all picks are collected (<roster summary>)` before the execution block for each queued pick, including a single-entry roster. Summarize each roster entry's collected pick or pending status inside `<roster summary>`.
|
|
86
86
|
|
|
@@ -62,12 +62,18 @@ Read the ledger and require its `cap:` header before the ordered table, includin
|
|
|
62
62
|
| Order | Observed state | Action |
|
|
63
63
|
|---|---|---|
|
|
64
64
|
| 1 | No `open` or `failed` row | Exit verification. All-cut and baseline-complete ledgers exit normally. |
|
|
65
|
-
| 2 | Unresolved row attempts
|
|
65
|
+
| 2 | Unresolved row attempts >= allowance | Apply row escalation below, otherwise human stop. Exempt `done` and `cut`, including third-attempt success. |
|
|
66
66
|
| 3 | Last two child row commits both changed no file outside the ledger and no row status | Human stop, regardless of funding. Count child `loop: row ...` commits only, excluding seed and parent repair/retry/cut commits. A decision alone is not progress. |
|
|
67
67
|
| 4 | `iterations` >= `cap` | Human stop naming the header cap value and every open/failed row with its attempts, before dispatch and before verification. Seed and interrupted dispatches count. |
|
|
68
68
|
| 5 | Dispatch allowed | Select target by the priority below. |
|
|
69
69
|
|
|
70
|
-
Set row allowance to 3 + funded N, increased to the latest `row <n> retry` decision's `allowed attempts <m>` when larger. Recover spent funding per row as `max(0, attempts - 3)`; a mid-loop grant applies prospectively. Before dispatch on a funded row with attempts >= 3 and spent < N print `funded round <k> of <N> for row <n>`, with k = attempts - 3 + 1. Funding buys neither cap bypass nor empty-commit bypass nor an escalated model. Include `budget: <spent> of <N> spent` in funded stops.
|
|
70
|
+
Set row allowance to 3 + funded N, increased to the latest `row <n> retry` decision's `allowed attempts <m>` when larger. Recover spent funding per row as `max(0, min(attempts, 3 + N) - 3)`; a mid-loop grant applies prospectively. Before dispatch on a funded row with attempts >= 3 and spent < N print `funded round <k> of <N> for row <n>`, with k = attempts - 3 + 1. Funding buys neither cap bypass nor empty-commit bypass nor an escalated model. Include `budget: <spent> of <N> spent` in funded stops.
|
|
71
|
+
|
|
72
|
+
Decode the current `**Amend-grant:**` through [amendment-surface Value decoding](../brainstorming/reference/amendment-surface.md). A budget-only grant gives no amend permission or escalation. At rule 2, hard boundaries and rules 3-4 win before escalation: cap or child-only stagnation stops without dispatch. Preserve `STAGNANT`, `REJECT`, closureReview and grant_fix_rounds boundaries; this is implement permission, not verify credit.
|
|
73
|
+
|
|
74
|
+
With amend permission and no existing durable `row <n> escalated` decision, resolve `gauntlet_setting({ key: "escalationLoop" })` and require `implModel`; unavailable tool or undefined model stops with the missing capability in Problem. Append `row <n> escalated | implModel round | allowed attempts <attempts + 1>`, commit parent `loop: escalate row <n>`, print `escalated round for row <n>`, and dispatch exactly once through the normal loop-implementer target, bump and validation path. This decision grants only this round, not a repeatedly matching old allowance. Exclude the parent escalation commit from child-only stagnation; it starts no new window. Recover identity from the ledger on resume; unrecoverable means spent. Retry, funding and amendments never erase or rearm it. Dispatch errors, non-DONE and validation failures consume it before any recommendation decision.
|
|
75
|
+
|
|
76
|
+
For attempts 5 with fund 2, append `row 2 escalated | implModel round | allowed attempts 6`, commit `loop: escalate row 2`, print `escalated round for row 2`, then attempt 6; attempts 4 and 5 paid the two funded rounds, spent remains 2. Clamp funding as above even beyond allowance, retaining prospective grants. The amend-permission escalated round is the only `implModel` dispatch.
|
|
71
77
|
|
|
72
78
|
Select `seed` until a validated `loop: seed evidence` commit with its `row 0 done` decision and evidence on every non-cut row survives on the branch, independently of `iterations`; otherwise select the still-unresolved human retry target, then the still-failed row named by the previous decision, then first failed row, then first open row. Use the latest operational `row <n> ...` decision for targeting and the child's `previous decision:` input, skipping cap grant history while retaining the entire Decisions section. Durable status beats a decision's suggestion. Keep the retry hint only for its target.
|
|
73
79
|
|
|
@@ -89,7 +95,7 @@ subagent({ agent: "loop-implementer", context: "fresh", async: false,
|
|
|
89
95
|
|
|
90
96
|
For `target: seed`, explicitly instruct the child to apply its seed contract even when iteration is greater than 0; carry that instruction in the existing `hint` field. Keep the actual consumed count in `iteration`.
|
|
91
97
|
|
|
92
|
-
Omit the model override; let the persona override or parent inheritance resolve it. Carry effects only: one file-reference return, one ledger read, git boundary checks. Never read a child transcript or carry reasoning history. Stop on dispatch error or an async handle; never poll, join or relaunch.
|
|
98
|
+
Omit the model override except on an escalated round (`model: <implModel>`); let the persona override or parent inheritance resolve it. Carry effects only: one file-reference return, one ledger read, git boundary checks. Never read a child transcript or carry reasoning history. Stop on dispatch error or an async handle; never poll, join or relaunch.
|
|
93
99
|
|
|
94
100
|
## Validate the return
|
|
95
101
|
|
|
@@ -172,13 +178,17 @@ NODE
|
|
|
172
178
|
|
|
173
179
|
## Exit verification
|
|
174
180
|
|
|
175
|
-
For coordinated exit, read each leg's verification from the home spec's `## Legs` `contract:` `- verification:` line and run it once foreground in its owning checkout
|
|
181
|
+
For coordinated exit, read each leg's verification from the home spec's `## Legs` `contract:` `- verification:` line and run it once foreground in its owning checkout. Require every leg to pass before completing implement. For legacy/single-member exit, run the ledger's `verification:` command once foreground in the worktree. Failure uses `Stopped: verification failed with every row closed`, Problem quoting failing output.
|
|
182
|
+
|
|
183
|
+
Apply hard boundaries first; at cap use the cap stop without repair. With amend permission, `iterations < cap`, resolved `escalationLoop.implModel` and no spent `loop: repair verification` identity, bump home iterations once and record `HEAD_BEFORE` in the failing leg. Dispatch exactly one `implementer` with `model: <implModel>`, `context: "fresh"`, `async: false`, that leg's cwd/Rules, failing output, absolute home spec path and exact leg verification command. Require a clean tree and exactly one commit after HEAD_BEFORE; dirty/zero/multiple commits use existing boundary stops preserving count and state. Require all ledger rows unchanged, preserving mapping, cap and prior decisions. The home child's sole commit includes the already-bumped home ledger; after validation parent commits `loop: repair verification`, using an empty parent marker when no dirt remains. A companion child commits its leg only; parent commits the bumped home ledger as `loop: repair verification`, preserving rows and mapping. This marker is once per flow, not per failing leg.
|
|
184
|
+
|
|
185
|
+
Rerun that command once in the failing leg only. Never spend another leg's verification or verify-phase credits. A second failure retains the original header plus `escalated round spent`, then goes through Human stop. Dispatch error or non-DONE consumes the round before a decision; preserve the consumed count and stop. Recover spent identity from the parent commit on resume; interrupted or unrecoverable identity is spent, never add a carrier or fabricate success. With no permission or spent identity: no reopening and no automatic rerun. Missing settings/model stops with the capability in Problem. Success only after every leg passes: record verified HEAD and clean status; call `phase_tracker({ action: "complete", phase: "implement" })`, then continue immediately below.
|
|
176
186
|
|
|
177
187
|
## Human stop
|
|
178
188
|
|
|
179
189
|
Read and apply [menu-layout](../brainstorming/reference/menu-layout.md). Start the message with `gauntlet: question` at every human stop, including the discard/reset authorization ask for a dirty or commit-boundary return. Put it alone on the first output line, followed by a newline before the stop text, without a driver-state preamble, wrapper or code fence. These decisions are neither done nor stuck outcomes.
|
|
180
190
|
|
|
181
|
-
Leave implement active. Use one screen of plain words: `Stopped on row <n> (<row text>)` for row failures, or the concrete boundary/cap/verification header above. `Problem:` quotes the evidence cell verbatim, identifying the actual spec/code contradiction, failing assertion/output or missing capability, and quotes the last decision line. Include funding budget only when funded. At every stop print `Preserve every row's attempts and the total iteration cap.`
|
|
191
|
+
Leave implement active. Use one screen of plain words: `Stopped on row <n> (<row text>)` for row failures, or the concrete boundary/cap/verification header above. `Problem:` quotes the evidence cell verbatim, identifying the actual spec/code contradiction, failing assertion/output or missing capability, and quotes the last decision line. Include funding budget only when funded. At every stop print `Preserve every row's attempts and the total iteration cap.` Name `escalated round spent` when applicable; omit round history and reasoning traces.
|
|
182
192
|
|
|
183
193
|
Offer these concrete actions. Offer `cap +N` only at a clean cap or legacy missing-cap stop; dirty-tree and commit-boundary stops keep discard authorization and never offer `cap +N`. When both the row allowance and total cap are exhausted, list independent funding and cap offers despite rule 2 priority. Take separate replies: funding follows the spec's `**Amend-grant:**` contract, cap follows the row below; define no combined syntax.
|
|
184
194
|
|
|
@@ -195,7 +205,9 @@ For dirty/commit-boundary retry, ask the human to authorize discarding uncommitt
|
|
|
195
205
|
|
|
196
206
|
For coordinated amendments, reconcile by original AC/leg mapping without resetting attempts, iterations or cap. Re-read explicit scope lists after approved ownership amendments and reconcile expanded entries; a disposition-only cut changes neither original indices nor ownership. Preserve unchanged mapped entries and their histories.
|
|
197
207
|
|
|
198
|
-
For ledger amendments use its line-1 discriminant: no plan writer, plan_check or task-tracker lifecycle. Approved deviates/deferred/elsewhere becomes `cut` with disposition evidence; requirement-preserving amendments leave rows unchanged; a re-bounded done row becomes `open` with `reopened by amendment`. Preserve attempts, iterations and cap. Commit spec + ledger as `loop: cut row <n>` or `loop: amend`. Option 4 stops for amendments, option 5 auto-applies amends, redraw always stops and deletes the ledger with the plan.
|
|
208
|
+
For ledger amendments use its line-1 discriminant: no plan writer, plan_check or task-tracker lifecycle. Approved deviates/deferred/elsewhere becomes `cut` with disposition evidence; requirement-preserving amendments leave rows unchanged; a re-bounded done row becomes `open` with `reopened by amendment`. Preserve attempts, iterations and cap. Commit spec + ledger as `loop: cut row <n>` or `loop: amend`. Option 4 stops for amendments, option 5 auto-applies amends, redraw always stops and deletes the ledger with the plan. Cut only through the amendment surface, including its standing-grant section 5.
|
|
209
|
+
|
|
210
|
+
End every stop with `Recommendation: <option> - <why>` or `Recommendation: none - <why>`. An unnamed repair is none. Under amend permission take only a named authorized amend: print `took recommendation: amend for row <n>`, apply amendment-surface section 5 (including its audit), commit `loop: amend` / `loop: cut row <n>`, then return to the ordered table. Whitespace-normalize the row evidence cell and compare with evidence already auto-resolved on that row; repetition renders `Recommendation: none - evidence repeats row <n>`. Recover this evidence from amendment/ledger history; missing history never authorizes a repeated action. A cut leaves the stop; an unresolved row at allowance stops again, not a free retry. Retry, more attempts, cap +N and redraw wait for the human. Fix-first enters `/skill:shape-ticket`'s own gate, never an automatic separate repair. Hard boundaries never auto-take recommendations.
|
|
199
211
|
|
|
200
212
|
## After the loop
|
|
201
213
|
|
|
@@ -103,10 +103,10 @@ Every implementer dispatch returns one of:
|
|
|
103
103
|
|---|---|---|
|
|
104
104
|
| `DONE` | Implemented + tests pass + self-reviewed; work present in the worker's tree; the wave commit is step 7 | Proceed to spec review |
|
|
105
105
|
| `DONE_WITH_CONCERNS` | Implemented + tests pass, but flagged a deviation or risk | Read concerns. If acceptable, proceed. If not, dispatch fix subagent. |
|
|
106
|
-
| `NEEDS_CONTEXT` | Implementer needs information you have | For a spec-defect citation, take the amendment route below first. Resolve fact asks per [lookup handling](./stop-note.md). For decisions, answer and re-dispatch
|
|
107
|
-
| `BLOCKED` | Cannot proceed (missing dependency, spec contradicts code, environment broken) | For a spec-defect citation, take the amendment route below first. Resolve fact asks per [lookup handling](./stop-note.md). For decisions
|
|
106
|
+
| `NEEDS_CONTEXT` | Implementer needs information you have | For a spec-defect citation, take the amendment route below first. Resolve fact asks per [lookup handling](./stop-note.md). For decisions under amend permission, follow [Implementer-failure stops](reference/fix-loop.md#implementer-failure-stops); otherwise answer and re-dispatch or escalate to the user. |
|
|
107
|
+
| `BLOCKED` | Cannot proceed (missing dependency, spec contradicts code, environment broken) | For a spec-defect citation, take the amendment route below first. Resolve fact asks per [lookup handling](./stop-note.md). For decisions under amend permission, follow [Implementer-failure stops](reference/fix-loop.md#implementer-failure-stops); otherwise diagnose and re-dispatch or escalate to the user. |
|
|
108
108
|
|
|
109
|
-
Classify each question: treat a question whose candidate answers are each edits to the spec, plan, or an approved rule as an amendment batch per [amendment-surface.md](../brainstorming/reference/amendment-surface.md), never a decision. Stop for
|
|
109
|
+
Classify each question: treat a question whose candidate answers are each edits to the spec, plan, or an approved rule as an amendment batch per [amendment-surface.md](../brainstorming/reference/amendment-surface.md), never a decision. Treat a drafted AC row text correction backed by quoted implementer evidence (test, assertion, or code line) as an amend; record it in the granted `amend:` audit body. Stop for redraws: ticket rows, row add/remove, reviewer-only or taste objections, problem changes, or component boundary changes. Decode the `**Amend-grant:**` value through that surface's Standing grants. With amend permission, apply each item's `recommended` (`accept` or named `alt-n`), print `amended the spec: <title> - <what>`, and complete section 5's plan-writer amend dispatch, `plan_check`, tracker update, and one `amend:` commit in the same turn; skip reviewer, menu, and confirmation turns. Without permission (including absent or `none`), retain the surface's menu and escalation/redraw routing. For remaining questions, classify artifact location, value, or existence as a fact ask; scope and option choices as decisions; another-round approval as a decision only with no funded round left.
|
|
110
110
|
|
|
111
111
|
Implementer prompt templates must instruct subagents to return one of these statuses explicitly.
|
|
112
112
|
|
|
@@ -323,7 +323,7 @@ Record its review tree per [Fix delta](#fix-delta) before every parent-dispatche
|
|
|
323
323
|
|
|
324
324
|
1. **Attempt 1:** dispatch a NEW fix subagent with the error output, the original task, and specific instructions about what went wrong.
|
|
325
325
|
2. **Attempt 2:** if attempt 1 also fails, dispatch one more with a simplified scope or different approach.
|
|
326
|
-
3. **After 2 failed attempts:**
|
|
326
|
+
3. **After 2 failed attempts:** under amend permission follow [Implementer-failure stops](reference/fix-loop.md#implementer-failure-stops) for one escalated attempt; otherwise STOP and report. Keep `in_progress` pending the human decision; completion requires the wave commit.
|
|
327
327
|
|
|
328
328
|
**NEVER:**
|
|
329
329
|
|
|
@@ -21,3 +21,23 @@ Before every funded dispatch, print `funded round <k> of <N> for task <n>` for e
|
|
|
21
21
|
Emit the task's stop note for the funded-stop outcomes above (including `STAGNANT`) and an escalated-round failure with no funded round left. While a budget token exists, include `budget: <spent> of <N> spent` in every stop note after `Problem:` and any `Searched:` lines and before the file finding, including pre-escalation stops, missing `implModel`, and exhausted fact lookups at spent zero; use the `(not recovered on resume)` suffix below when recovery fails, and omit the line without a token. Treat this line as the only round-history exception to `stop-note.md`'s no-round-history rule.
|
|
22
22
|
|
|
23
23
|
On resume, keep header restoration unchanged; recover each task's spent count only from its `funded round <k> of <N>` transcript lines. Without recoverable lines, treat funding as exhausted; stop the next issue-bearing re-review with `budget: <N> of <N> spent (not recovered on resume)`. Treat a newly written budget token as the human refund, never a resume reset. Use no new spent carrier or handoff/resume grammar.
|
|
24
|
+
|
|
25
|
+
## Implementer-failure stops
|
|
26
|
+
|
|
27
|
+
Decode grants through [Value decoding](../../brainstorming/reference/amendment-surface.md#standing-grants); absent/`none`/budget-only: retain the ordinary two-attempt stop. Follow [stop-note.md](../stop-note.md) for lookups/status; preserve review/funding rules above.
|
|
28
|
+
|
|
29
|
+
1. **Hard stops**: stop first for malformed grants, missing `implModel`, unavailable settings tools, dirty-tree/commit-boundary returns, empty-commit stagnation, cap, funded re-review `STAGNANT`, `REJECT`, and [redraws](../SKILL.md#implementer-status).
|
|
30
|
+
2. **Takeable decision**: route only `BLOCKED`/`NEEDS_CONTEXT` decisions with attempts remaining below. Compare whitespace-normalized `file:line` finding or failing command plus assertion already auto-resolved on this task -> `Recommendation: none - evidence repeats task <n>`; stop.
|
|
31
|
+
3. **Execution escalation**: after two failed attempts, escalate before routing `Recommendation:`; call `gauntlet_setting({ key: "escalationLoop" })`; `implModel` undefined stops with the existing note. Print `escalated round for task <n> after 2 failed attempts`. Dispatch one implementer: `model: <implModel>`, `context: "fresh"`, `async: false`, same payload and isolation as above (`SCOPED_TEST_COMMANDS`, complete prior report verbatim); retain siblings; no fan-out/re-chain. Spend once/task/site, independently of review escalation/funding.
|
|
32
|
+
4. **Resulting decision**: dispatch error or non-`DONE` spends escalation; use step 2's table; no fourth unnamed repair. Success still runs the ordinary scoped tests and SR/CR gates before wave commit/completion.
|
|
33
|
+
|
|
34
|
+
When taken, print `took recommendation: <option> for task <n>`.
|
|
35
|
+
|
|
36
|
+
| Recommendation | Action |
|
|
37
|
+
|---|---|
|
|
38
|
+
| In-task repair | Preserve payload/isolation; count every re-dispatch as an ordinary attempt; enforce two-attempt limit. |
|
|
39
|
+
| Spec/plan rule edit, including drafted-AC-row text correction backed by quoted implementer test/assertion/code evidence | Follow [amendment-surface section 5](../../brainstorming/reference/amendment-surface.md#5-apply-aftermath-commit) under grant. |
|
|
40
|
+
| `fix-first` | Enter `/skill:shape-ticket` at its gate. |
|
|
41
|
+
| `none`/budget/consent/redraw/separate change | Emit stop note ending in `Recommendation: <option> - <why>`; wait. |
|
|
42
|
+
|
|
43
|
+
Recover only that line in matching task's transcript, not a review escalation or sibling line; unrecoverable means spent. A mid-loop grant or explicit retry never re-arms.
|
|
@@ -23,10 +23,12 @@ Fix options:
|
|
|
23
23
|
c) <optional third>
|
|
24
24
|
|
|
25
25
|
Pick one, or give another fix.
|
|
26
|
+
Recommendation: <option> - <why>
|
|
26
27
|
```
|
|
27
28
|
|
|
28
29
|
## Rules
|
|
29
30
|
|
|
31
|
+
- End every note with `Recommendation: <option> - <why>`, or `Recommendation: none - <why>` when no named change is recommended. Apply [Implementer-failure stops](reference/fix-loop.md#implementer-failure-stops) before emitting an execution decision note.
|
|
30
32
|
- Bracketed header clause only when an escalated round actually ran; omit it when no model was resolvable or the dispatch errored.
|
|
31
33
|
- For review stalls, quote only residual issues from the final review report; do not summarize history.
|
|
32
34
|
- For fact asks, put one `Searched: <where> - <result>` line per lookup directly under `Problem:`, in lookup order. For an unavailable named tool, write `Searched: <tool> - not available`. Omit `Searched:` for decisions, including extra-round approval.
|
|
@@ -54,4 +56,5 @@ Fix options:
|
|
|
54
56
|
b) amend plan task 4 so the client retries on any non-negative delay, and keep the policy as is
|
|
55
57
|
|
|
56
58
|
Pick one, or give another fix.
|
|
59
|
+
Recommendation: a - retries the first failure without changing the approved policy.
|
|
57
60
|
```
|
|
@@ -76,7 +76,7 @@ The main loop never writes the plan. One fresh `plan-writer` child does the reco
|
|
|
76
76
|
|
|
77
77
|
| Row form | Parent handling |
|
|
78
78
|
|---|---|
|
|
79
|
-
| `- Task N: ... fails on <sha>` | Name task, original command, SHA, exit and summary. Present three options, one per line: `fix-first` - run `/skill:shape-ticket` for the base failure (its own gate applies), then report the plan paused and end the turn; `narrow
|
|
79
|
+
| `- Task N: ... fails on <sha>` | Name task, original command, SHA, exit and summary. Present three options, one per line: `fix-first` - run `/skill:shape-ticket` for the base failure (its own gate applies), then report the plan paused and end the turn; `narrow <filter>` - name a concrete filter or path when evidence supports one, otherwise request it; `amend` - use brainstorming's `reference/amendment-surface.md` section 5. Follow with `Recommendation: <option>[ <filter>] - <reason>`. Resolve permission before waiting: read the approved spec header grant through amendment-surface.md's structural predicate and Value decoding. Under amend permission print `took recommendation: <option>` and take the named recommendation: `narrow <filter>` re-dispatches per step 3 with the exact filter in Findings (for example `narrow hook-config` sends `Task N Tests: narrow to hook-config`); `amend` runs section 5; `fix-first` enters `/skill:shape-ticket`, whose own gate is the only remaining stop. `none` or `narrow` without a concrete filter waits. With no amend permission (budget-only, `none`, or absent), retain the menu and wait for the human. Never infer consent for a redraw or restoration. After fix-first lands, bring the advanced base into the worktree through `/skill:using-git-worktrees`' existing advanced-base procedure (rebase, or merge for a shared branch), re-dispatch per step 3 with `Findings: rerun baseline`, then step 5; after a session break use `/skill:gauntlet-resume`'s baseline continuation. For narrow, re-dispatch with a Findings row `Task N Tests: narrow to `<text>``; for amend, use section 5. Both run Baseline's rerun rule before step 5. |
|
|
80
80
|
| `- Baseline: worktree dirty`, `- Baseline: in-flight source edits`, `dirtied tracked source`, `moved HEAD` | Restore-and-rerun, not the menu: name paths and cause. Clear the parent's own wave/amendment source work through its own commit step; list doc-only work under `In-flight:` before re-dispatch. Take every other path, including every test-dirtied path, to the human to commit, discard, or move; never clean automatically. Once restored, re-dispatch per step 3 with `Findings: rerun baseline`, then step 5. Bullet `artifacts:` need no action. |
|
|
81
81
|
| Other substantive rows (contract questions) | Present the rows, wait for answers, re-dispatch per step 3 with the answers as the `Findings:` block, then step 5. |
|
|
82
82
|
- `PLAN WRITTEN` + `FAIL` -> re-dispatch per step 3 with the verbatim `FAIL (...)` output as the `Findings:` block, then step 5. Once per verbatim FAIL output: the same FAIL a second time goes to the user as an open question (the FAIL lines, verbatim), as an exhausted finding does.
|