pi-gauntlet 7.25.0 → 7.26.0

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 CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## v7.26.0 - 2026-10-22
4
+
5
+ ### Changed
6
+
7
+ - **The implement orchestrator honors standing amend grants and per-task fix-round funding.** With amend permission on the spec's `**Amend-grant:**` line, it applies each amend-class item's recommended edit in the same turn instead of presenting an option menu; a redraw still stops. A granting sentence may include `fund N fix rounds` or `N more fix rounds`, giving each task N funded fix rounds past the escalated round. Each funded dispatch prints `funded round <k> of <N> for task <n>`, and every stop note while funding exists carries `budget: <spent> of <N> spent`. A funded `STAGNANT`, error, or non-`DONE` status still stops; unrecoverable spend on resume counts as exhausted. (#74)
8
+
9
+ ## v7.25.1 - 2026-10-22
10
+
11
+ ### Changed
12
+
13
+ - **shape-ticket carries every Problem example's source into the ticket body.** A URL, attachment, or pasted screenshot the reporter supplied lands as a `source:` footer line under the Problem example it supports, in every ticket type. A non-discovery example with no source renders a named `source missing:` gap at the existing approval gate; the reply supplies the link, a reason, or "proceed without" (bug tickets list the gap first and re-ask on a plain `yes`), and the drafter never authors the reason. Repair prefills `source: none (not recorded at filing)` for a hand-filed body so a plain `yes` accepts it, and never reports "conforms" for a body missing the footer. Ticket-wording rules 7 and 8 exempt the footer from pointer demotion. The Roast's inline chair call names `cwd` = repo root like the member fan-out. (#76)
14
+
15
+ ### Added
16
+
17
+ - Eval samples `source-carried`, `source-missing`, `bug-source-ack`, and `repair-source` under `eval/shape-ticket/`; the target's SKILL.md slice now reaches `## Evidence gate`. (#76)
18
+
3
19
  ## v7.25.0 - 2026-10-21
4
20
 
5
21
  ### Changed
package/README.md CHANGED
@@ -122,7 +122,7 @@ Run by a human against pi-cohort >= 7.1.0, before a pi-gauntlet release claims t
122
122
  ## Requirements
123
123
 
124
124
  - [pi-coding-agent](https://github.com/earendil-works/pi) ≥ 0.85.1 - tested minimum for sequential `phase_tracker` tool execution, which persists a tracker update before a later tool call in the same model message.
125
- - [pi-cohort](https://github.com/jjuraszek/pi-cohort) >= 7.4.3 - required peer package, including binary-safe worktree patches. Skills that dispatch agents (`requesting-code-review`, `subagent-driven-development`, `dispatching-parallel-agents`, `writing-plans`, `forge-skill`, `shape-ticket`, `roasting-the-spec`) call `subagent({})`, which pi-cohort provides. pi-gauntlet does not vendor the dispatch tool; without pi-cohort those skills have nothing to call. Gauntlet execution dispatches explicitly use `async: false`; do not enable pi-cohort's incompatible `forceTopLevelAsync` setting. See pi-cohort's [dispatch configuration](https://github.com/jjuraszek/pi-cohort/blob/main/doc/configuration.md) for that setting's owner and semantics. A wave of N >= 1 tasks dispatches its implementers and first spec reviews as one chain call. `subagent-driven-development` stops before dispatch on unsupported installs; there is no older-runtime fallback.
125
+ - [pi-cohort](https://github.com/jjuraszek/pi-cohort) >= 7.4.4 - required peer package, including binary-safe worktree patches. Skills that dispatch agents (`requesting-code-review`, `subagent-driven-development`, `dispatching-parallel-agents`, `writing-plans`, `forge-skill`, `shape-ticket`, `roasting-the-spec`) call `subagent({})`, which pi-cohort provides. pi-gauntlet does not vendor the dispatch tool; without pi-cohort those skills have nothing to call. Gauntlet execution dispatches explicitly use `async: false`; do not enable pi-cohort's incompatible `forceTopLevelAsync` setting. See pi-cohort's [dispatch configuration](https://github.com/jjuraszek/pi-cohort/blob/main/doc/configuration.md) for that setting's owner and semantics. A wave of N >= 1 tasks dispatches its implementers and first spec reviews as one chain call. `subagent-driven-development` stops before dispatch on unsupported installs; there is no older-runtime fallback.
126
126
 
127
127
  Both packages must be listed in your `.pi/settings.json#packages` array (pi adds them automatically when you `pi install`). pi-gauntlet and pi-cohort are versioned independently but release together whenever dispatch semantics change - pin compatible versions of both. At each pi-gauntlet release, set the pi-cohort peer minimum and README floor together to the newest released pi-cohort version; `/skill:release` checks the registry before proceeding.
128
128
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-gauntlet",
3
- "version": "7.25.0",
3
+ "version": "7.26.0",
4
4
  "description": "Opinionated, gated workflow skills, subagent personas, and runtime extensions for the pi coding agent.",
5
5
  "author": "Jacek Juraszek",
6
6
  "type": "module",
@@ -62,7 +62,7 @@
62
62
  "test": "node scripts/ci.mjs"
63
63
  },
64
64
  "peerDependencies": {
65
- "pi-cohort": ">=7.4.3"
65
+ "pi-cohort": ">=7.4.4"
66
66
  },
67
67
  "dependencies": {
68
68
  "yaml": "^2.9.0"
@@ -19,6 +19,8 @@ A grant is the spec's `**Amend-grant:**` line read through the shared predicate;
19
19
  | exactly one line whose trimmed value is any other non-empty single-line text | grant active; the sentence is that value |
20
20
  | two or more lines, one line with an empty value, or a value continued onto the next physical line (any non-blank line directly below the field that is neither a `**Key:**` header line nor a `> **Superseded by:**` banner line) | malformed -> stop, print the offending line(s) |
21
21
 
22
+ **Value decoding**. Run the structural predicate first; missing or `none` gives neither capability, and malformed lines stop with the offending lines quoted. Decode every active value: section 1 at each batch boundary, SDD Fix-Loop Rounds at each funded dispatch, and `spec-finalization.md` before writing the value. Match exactly one `fund N fix rounds` or `N more fix rounds` anywhere on the line, with N matching `[1-9][0-9]*`; no match funds nothing. Stop and quote the line before any item applies or any round is funded on two or more matches or a token-shaped invalid phrase (`fund 0 fix rounds`, `fund three fix rounds`, `-2 more fix rounds`). Remove the matched token and its `; ` / `, ` separators for amend decoding: a non-empty remainder keeps wording-agnostic amend permission (`auto-apply amends`, `apply spec fixes without asking`, or equivalent); an empty remainder is budget-only, with no amend permission. Keep grants without a budget unchanged. Decode `auto-apply amends; fund 3 fix rounds` as both capabilities and `2 more fix rounds` as budget-only. The budget is non-retroactive: rounds spent before the line was written do not count against or toward it. Write `none` on revocation such as `revoke auto-apply amends`, clearing both capabilities; retain funding alone by writing the token alone.
23
+
22
24
  **Writers.** Spec-writing and the spec gate are owned by `spec-finalization.md`; this file owns the mid-flow changes:
23
25
 
24
26
  | Event | Edit |
@@ -54,7 +56,7 @@ Collect every amendment pending at this decision point (same spec-review round,
54
56
 
55
57
  The working tree stays at pre-batch HEAD until apply (section 5) - nothing is edited before the reviewer and, where needed, the human have answered. A redraw item stops alone first (`../SKILL.md` redraw path); amend items are held and re-batched after it resolves.
56
58
 
57
- **Standing grant active** ([boundaries](#standing-grants)): at every batch boundary re-read the spec's `**Amend-grant:**` line through the predicate; malformed stops the batch with the offending line(s). Active -> skip steps 2-4, apply every item, print one line each `amended the spec: <title> - <what>`, record `granted`, and quote the line's value in the commit body - the record kind `finishing-a-development-branch` Step 4's digest reads is unchanged.
59
+ **Standing grant active** ([boundaries](#standing-grants)): at every batch boundary re-read the spec's `**Amend-grant:**` line through the predicate and Value decoding; malformed stops the batch with the offending line(s). Active with amend permission -> skip steps 2-4, apply every item's `recommended` choice (`accept` or its named `alt-n`, never `accept` by default) through section 5, print one line each `amended the spec: <title> - <what>`, record `granted`, and quote the line's value in the commit body - the record kind `finishing-a-development-branch` Step 4's digest reads is unchanged. Budget-only takes ordinary steps 2-4; absent or `none` follows the ordinary path.
58
60
 
59
61
  ## 2. Prefilter - no model call
60
62
 
@@ -126,6 +126,7 @@ New predecessor candidates at spec-writing: <path> (<title>), ... - index rows a
126
126
  1 - approve: proceed to planning under the existing amendment review; a fresh reviewer applies evidence-backed factual corrections on its own, and every other spec amendment (scope, acceptance-criteria, or contract edits, and redraws) stops for your review.
127
127
  2 - approve, auto-apply amends: every later spec amendment in this flow (corrected facts, paths, verification lines, and scope, acceptance-criteria, or public-contract edits alike) applies without asking; only a redraw (changed problem statement, component added, removed, or re-bounded) still stops for you, and the grant never stands in for a spec approval.
128
128
  3 - show council dispositions: prints the council audit verbatim, then re-presents this gate. Not an approval.
129
+ Add "; fund N fix rounds" (or "N more fix rounds") to 1 or 2 to fund N implement fix rounds past the escalated round.
129
130
 
130
131
  Or tell me what to change in the spec, or say "revert applied council edit <X>" to undo a specific applied edit.
131
132
  ```
@@ -134,7 +135,20 @@ If you believe the summary needs correcting, do **not** silently rewrite it - re
134
135
 
135
136
  **Revert valve.** "Revert applied council edit X" is a normal change request: revise the spec to undo edit X, re-dispatch the summarizer with a **fresh** temp path (per the re-dispatch rule below), and re-present the gate. This is cheap here - the spec is not yet plan- or code-bearing.
136
137
 
137
- Wait for the user. On a change request (including a revert), revise the spec and re-present - mint a **fresh** temp path for the re-dispatched summarizer (never reuse a prior round's path, so stale content can never be mistaken for the new summary). On `3` or its label alone: print the audit verbatim from `git -C <abs worktree path> show -s --format=%b HEAD` (never from a held tool result; the body survives the grant's `--amend --no-edit`), then re-present the same gate - the briefing text of the gate message just rendered, reused verbatim (no summarizer re-dispatch, no read of the removed `$SUMMARY_PATH`; if that text is no longer in context, the one-line degrade note takes its place), the `Council:` line, the adjacent lines, the three rows; nothing in the spec or the commit changes. `3` plus a change request is a change request. `3` plus `1`/`2` prints and re-presents, and the approval is read only from a clean `1`/`2` on the re-presented gate - a reply carrying `3` never grants. A gate-round recommit (change request or revert) re-runs the same heredoc commit with the audit as its body, so HEAD always carries it; on a revert of edit X, move X's `Applied:` line to `Rejected:` with `-> reverted at gate` and recompute the `Council:` counts from the revised audit. On approval - `1`, `approve`, or equivalent prose approves without a grant; `2`, `approve, auto-apply amends`, or equivalent prose approves and grants - proceed immediately to `/skill:writing-plans` with no further prompt; first read [Standing grants](amendment-surface.md#standing-grants) (stop if unreadable). On a grant (`2`, `approve, auto-apply amends`, or equivalent prose), `edit` the spec's `**Amend-grant:**` value to the granting sentence (the digit `2` becomes the grant description after `2 - approve, auto-apply amends:` above), then `git -C <abs worktree path> add -- <spec path>` and `git -C <abs worktree path> commit --amend --no-edit -q`, so the spec commit carries the line and keeps its council-audit body; then confirm `git -C <abs worktree path> show HEAD:<spec path>` reads "grant active" through the predicate. On a plain approval (`1`, `approve`) the value stays `none` and the commit is untouched. A reply that mixes approval with a change request ("2 but rename the section") is a change request: revise, re-present, and read the grant only from the reply to the re-presented gate. If the amend or the HEAD check fails, stop and report; never proceed as granted. The plan and execution mode are mechanical derivatives, so the only human gate here is spec approval itself. Don't land the spec on `main`; it stays in the worktree and ships in the same squash commit as the implementation.
138
+ Wait for the user. Interpret funded replies with this table before routing change requests:
139
+
140
+ | Reply | Action / written value |
141
+ |---|---|
142
+ | bare `2` | approve; persist the option-2 description above |
143
+ | `2; fund 3 fix rounds` or `2, fund 3 fix rounds` | approve; persist that description plus `; fund 3 fix rounds`, not a change request |
144
+ | `1` with a budget token | approve; persist `fund 3 fix rounds` alone for that token (budget-only) |
145
+ | approval prose with a token | approve; preserve the prose collapsed to one physical line |
146
+ | budget token alone (`fund 3 fix rounds`) | re-present the gate asking for `1` or `2`; write nothing |
147
+ | token with malformed N | re-present the gate quoting the token; write nothing, never imply a change request |
148
+
149
+ For every value to persist, read [Standing grants](amendment-surface.md#standing-grants) and run Value decoding. Decode before `edit` or `--amend`; never persist a malformed token. Use the decoded table value in the approval persistence below, including budget-only approvals.
150
+
151
+ On a change request (including a revert), revise the spec and re-present - mint a **fresh** temp path for the re-dispatched summarizer (never reuse a prior round's path, so stale content can never be mistaken for the new summary). On `3` or its label alone: print the audit verbatim from `git -C <abs worktree path> show -s --format=%b HEAD` (never from a held tool result; the body survives the grant's `--amend --no-edit`), then re-present the same gate - the briefing text of the gate message just rendered, reused verbatim (no summarizer re-dispatch, no read of the removed `$SUMMARY_PATH`; if that text is no longer in context, the one-line degrade note takes its place), the `Council:` line, the adjacent lines, the three rows; nothing in the spec or the commit changes. `3` plus a change request is a change request. `3` plus `1`/`2` prints and re-presents, and the approval is read only from a clean `1`/`2` on the re-presented gate - a reply carrying `3` never grants. A gate-round recommit (change request or revert) re-runs the same heredoc commit with the audit as its body, so HEAD always carries it; on a revert of edit X, move X's `Applied:` line to `Rejected:` with `-> reverted at gate` and recompute the `Council:` counts from the revised audit. On approval - `1`, `approve`, or equivalent prose approves without a grant; `2`, `approve, auto-apply amends`, or equivalent prose approves and grants - proceed immediately to `/skill:writing-plans` with no further prompt; first read [Standing grants](amendment-surface.md#standing-grants) (stop if unreadable). On a grant or funded approval, `edit` the spec's `**Amend-grant:**` value to the table value for funded replies, otherwise the granting sentence (the digit `2` becomes the grant description after `2 - approve, auto-apply amends:` above), then `git -C <abs worktree path> add -- <spec path>` and `git -C <abs worktree path> commit --amend --no-edit -q`, so the spec commit carries the line and keeps its council-audit body; then confirm `git -C <abs worktree path> show HEAD:<spec path>` reads "grant active" through the predicate. On a plain approval (`1`, `approve`) the value stays `none` and the commit is untouched. A reply that mixes approval with a change request ("2 but rename the section") is a change request: revise, re-present, and read the grant only from the reply to the re-presented gate. If the amend or the HEAD check fails, stop and report; never proceed as granted. The plan and execution mode are mechanical derivatives, so the only human gate here is spec approval itself. Don't land the spec on `main`; it stays in the worktree and ships in the same squash commit as the implementation.
138
152
 
139
153
  Post-approval changes follow [Amending an approved spec](../SKILL.md#amending-an-approved-spec).
140
154
 
@@ -34,7 +34,7 @@ It is a tool, not a phase: no `plan_tracker`, no `phase_tracker`, no worktree re
34
34
 
35
35
  ## Hard constraint
36
36
 
37
- **Every tracker write sits behind exactly one confirmation gate, presented as an explicit old->new (or as-new) diff. No affirmative answer on that exact diff = no write.** This includes create, repair, split writes, and discovery-conversion writes - one gate covers the whole batch. A headless or unattended run (no interactive response available) stops at the gate. There is no timeout-approve, no "the user implied yes earlier," no partial write before the gate.
37
+ **Every tracker write sits behind exactly one confirmation gate, presented as an explicit old->new (or as-new) diff. No affirmative answer on that exact diff = no write.** Approve the exact presented diff plus only the `source:` footer substitutions resolved by that same approving reply under step 8; make no other post-approval edit and add no second gate. This includes create, repair, split writes, and discovery-conversion writes - one gate covers the whole batch. A headless or unattended run (no interactive response available) stops at the gate. There is no timeout-approve, no "the user implied yes earlier," no partial write before the gate.
38
38
 
39
39
  ## Mode routing
40
40
 
@@ -86,24 +86,24 @@ Accumulate step-4 demotion, step-5 moves, and roast-removed mechanism verbatim u
86
86
 
87
87
  ### 5 - Deterministic gates
88
88
 
89
- Before any subagent dispatch, inline and cheap: AC integrity gate, evidence gate, metadata audit, split detection (all below), and this displaced-detail check:
89
+ Before any subagent dispatch, inline and cheap: AC integrity gate, evidence gate, metadata audit, split detection (all below), and this displaced-detail check. After the evidence gate's existing checks, run its source-gap rule and carry gap rows to step 8:
90
90
 
91
91
  | Section | Move to accumulated Reporter note |
92
92
  |---|---|
93
93
  | Idea | Beyond the one attributed sketch line: a second paragraph, a list, or a code block |
94
94
  | Context, Problem | Implementer inventories: file paths; module/script/function/setting identifiers; sizes and line counts; lists of those; code blocks |
95
95
 
96
- Exempt one deletion-safe rule-7 pointer per failure, rule-5 one-sentence/one-number examples, requester-used dual-use terms, and plain-words failure/impact lists. Move the whole list/block or path/count-bearing sentence verbatim, never summarize or drop it; restore a unit when moving it breaks the plain-words lead or product cause/effect (rule 3). Leave a paragraph-long single Idea line to roast judgment; it does not match this closed list.
96
+ Exempt one deletion-safe rule-7 pointer per failure, rule-5 one-sentence/one-number examples, requester-used dual-use terms, plain-words failure/impact lists, and `source:` footers (Evidence gate). Move the whole list/block or path/count-bearing sentence verbatim, never summarize or drop it; restore a unit when moving it breaks the plain-words lead or product cause/effect (rule 3). Leave a paragraph-long single Idea line to roast judgment; it does not match this closed list.
97
97
 
98
98
  ### 6 - No-op check
99
99
 
100
100
  For ordinary repair only, if the body already conforms AND the metadata audit is clean AND no comment is proposed: report "conforms, no changes proposed" and stop. No write, no confirmation prompt, no roast. A conforming ticket never pays for a dispatch - a conforming body with pending overflow still reaches the gate.
101
101
 
102
- "Conforms" includes the ticket wording contract (`reference/ticket-wording.md`, resolved against this skill's own directory), applied inline as a short checklist over Context/Problem/Idea: strip test passes (rule 2)? plain-words lead per asserted failure (rule 4)? example or `none (<reason>)` per failure (rule 5)? repo-native terms defined or dropped and requester-used terms left undefined under rule 6's attribution test? Idea within one attributed sketch line? Context/Problem free of step-5 closed-list matches? references parenthetical and deletion-safe (rule 7)? links summarized, no spiderman hops (rule 8)? Any "no" makes the body non-conforming: repair proposes a rewrite through the normal draft -> gates -> roast -> gate path instead of reporting "conforms" - the contract-briefed roast backstops this inline judgment. Route each failure through draft -> step 5 -> roast -> old/new gate, with a new comment for newly displaced detail. The conformance-only rewrite touches Context/Problem/Idea prose only: copy the original bytes under the AC heading unchanged and compare bytes before presenting the gate; any mismatch fails the repair run.
102
+ "Conforms" includes the ticket wording contract (`reference/ticket-wording.md`, resolved against this skill's own directory), applied inline as a short checklist over Context/Problem/Idea: strip test passes (rule 2)? plain-words lead per asserted failure (rule 4)? example or `none (<reason>)` per failure (rule 5)? repo-native terms defined or dropped and requester-used terms left undefined under rule 6's attribution test? Idea within one attributed sketch line? Context/Problem free of step-5 closed-list matches? references parenthetical and deletion-safe (rule 7)? links summarized, no spiderman hops (rule 8, with the named example serving as a source footer's summary)? every gathered URL, attachment, or pasted screenshot is carried in a source: footer under its example (Evidence gate carry rule)? every non-discovery Problem example has a source: footer (Evidence gate gap rule)? Any "no" makes the body non-conforming: repair proposes a rewrite through the normal draft -> gates -> roast -> gate path instead of reporting "conforms" - the contract-briefed roast backstops this inline judgment. Route each failure through draft -> step 5 -> roast -> old/new gate, with a new comment for newly displaced detail. The conformance-only rewrite touches Context/Problem/Idea prose only: copy the original bytes under the AC heading unchanged and compare bytes before presenting the gate; any mismatch fails the repair run. Check source carrying for every title; check source gaps only for non-discovery bodies. Preserve existing `source:` lines verbatim. For missing-footer-only repair, add only the footer under step 8 and leave existing prose and AC bytes unchanged; never report "conforms, no changes proposed".
103
103
 
104
104
  ### 7 - Roast
105
105
 
106
- See Roast below. Unambiguous findings are applied to the draft (one re-pass max - never a third pass). Ambiguous findings are surfaced at the confirmation gate, never auto-applied. Any roast-applied edit re-runs step 5's deterministic gates before the draft reaches the gate - a fix must not reintroduce a failing AC.
106
+ See Roast below. Surface source-gap findings at step 8; never apply them by inventing a reason or inserting a `none` footer. Restore an actual dropped gathered URL or attachment as an ordinary concrete fix. Unambiguous findings are applied to the draft (one re-pass max - never a third pass). Ambiguous findings are surfaced at the confirmation gate, never auto-applied. Any roast-applied edit re-runs step 5's deterministic gates before the draft reaches the gate - a fix must not reintroduce a failing AC.
107
107
 
108
108
  ### 8 - Confirmation gate
109
109
 
@@ -113,18 +113,30 @@ Present, per proposed issue:
113
113
  - Body old->new (repair) or as-new (create).
114
114
  - Metadata changeset: `field: current -> proposed -- why` lines.
115
115
  - Evidence list.
116
+ - Source gaps: render the Evidence gate's rows as `source missing: <label>`, matching multi-example footer labels exactly; for one example use its sentence or opening words, e.g. `source missing: import run 42 finished with zero rows`. For bugs with repro steps, render these rows first in the gate message, before Title; otherwise render them after Evidence. Offer the write despite gaps.
116
117
  - Roast dispositions: applied / surfaced-ambiguous.
117
118
  - Split proposal, if any: per slice, the three-line justification block (see Split rule). A withdrawn split is reported with the `split-axis:` finding that killed it, so the user can re-request it (sticky; see Split rule).
118
119
  - Proposed comment and supported relations, verbatim, if any - one approval covers the exact title + body + metadata + comment + relation payload.
119
120
  - For overlap, show mutually exclusive supported enrichment/create-anyway/no-write alternatives and coverage under the gathered reference; show failing alternatives unavailable. Selecting an option approves that displayed payload without another authorization prompt.
120
121
 
122
+ At gate-open, leave create-mode gap footer slots absent. Render create-gap approval choices as "Approve with a link, attachment, or reason" and "Approve and proceed without"; request the reply without printing any hypothetical `source:` value in commentary or options. Print resolved footer values only after the approving reply. In repair, prefill each gap with `source: [<label> - ]none (not recorded at filing)` and show the addition in the old->new diff. Missing-footer-only repair changes no existing prose or AC bytes.
123
+
124
+ Resolve each named gap under the same gate:
125
+
126
+ | Mode | Approving reply supplies link/attachment or reason | Plain "yes" | Explicit "proceed without" |
127
+ |---|---|---|---|
128
+ | Create, bug or non-bug | Replace only that named footer slot with the supplied URL/attachment or `none (<human reason verbatim>)` | No write; re-ask every unresolved gap: `source missing: <label or example opening> - link, reason, or "proceed without"?`; repeat on another plain yes | Fill only the acknowledged slots with `none (proceed without - <YYYY-MM-DD>)` |
129
+ | Repair | Replace only that named prefilled footer with the supplied URL/attachment or `none (<human reason verbatim>)` | Accept the displayed `none (not recorded at filing)` constant without re-ask | Replace only the acknowledged slots with the dated form above |
130
+
131
+ Keep partially resolved create gates open with only unresolved rows; never fill unnamed create gaps with a constant. Keep the gate open on a non-approval reply. For proceed-without, use `date +%F` when a shell exists, else the session date. Discovery/Spike carries supplied sources but renders no gaps and needs no source re-ask.
132
+
121
133
  Read and apply [menu-layout](../brainstorming/reference/menu-layout.md) before presenting these options and before acting on a numeric reply.
122
134
 
123
- Number the options. A split offers per-issue subset selection, e.g. "approve 1,3; decline 2". **No affirmative answer on the exact presented diff = no write.**
135
+ Number the options. A split offers per-issue subset selection, e.g. "approve 1,3; decline 2". **No affirmative answer on the exact presented diff plus only the `source:` substitutions resolved by that same approving reply = no write; make no other post-approval edit and add no second gate.**
124
136
 
125
137
  ### 9 - Write
126
138
 
127
- Immediately before any mutation, including comments - after approval, not at gate-open - re-fetch the relevant body, discussion, and workflow of any existing ticket underlying the selected changeset (repair, enrichment, or override-create). Compare against the exact snapshot the user approved; only a change loops back to step 8 with the delta. Use tracker version/ETag preconditions where supported. Treat unrelated hits listed as rejected coverage as non-sources; a plain create with no underlying existing ticket has nothing to revalidate. For overlap, follow the gathered reference's selected-operation rules. Then one batched write per approved issue, body first, then the approved Reporter-note comment if any; a split is N gated writes under the one approval, honoring subset selection. Mid-batch failure: report exactly what landed; the remaining changeset is preserved for retry.
139
+ Immediately before any mutation, including comments - after approval, not at gate-open - re-fetch the relevant body, discussion, and workflow of any existing ticket underlying the selected changeset (repair, enrichment, or override-create). Write the resolved source footers in the approved payload. Compare against the original gathered ticket snapshot the user approved, not the pending footer-bearing replacement; only a change loops back to step 8 with the delta. Use tracker version/ETag preconditions where supported. Treat unrelated hits listed as rejected coverage as non-sources; a plain create with no underlying existing ticket has nothing to revalidate. For overlap, follow the gathered reference's selected-operation rules. Then one batched write per approved issue, body first, then the approved Reporter-note comment if any; a split is N gated writes under the one approval, honoring subset selection. Mid-batch failure: report exactly what landed; the remaining changeset is preserved for retry.
128
140
 
129
141
  ## AC integrity gate
130
142
 
@@ -188,7 +200,7 @@ No block, no split. A block failing the identity or outcome test, or naming a no
188
200
  Inline council dispatch, reusing spec-council config and personas - **not** `/skill:roasting-the-spec` (that skill's contract is spec-file apply mechanics; a tracker draft is not a spec file). No new agents.
189
201
 
190
202
  1. Resolve `gauntlet_setting({ key: "specCouncil" })` when the tool exists. Verdict `council` -> dispatch `spec-council-member`s in parallel plus a `spec-council-synthesizer` chair. Verdict `worker` (or empty members) -> one fresh `worker` critique with the four-axis brief of item 4, its task text carrying the absolute path to `reference/ticket-wording.md` (resolved against this skill's own directory). Malformed config -> one warning line, then branch on verdict.
191
- 2. **Dispatch shape**, mirroring `/skill:roasting-the-spec`: write the draft body and the source snapshot (original ticket + comments, or the create-mode inputs) to absolute temp files under `mktemp -d`; delimit untrusted snapshots as data. The raw ask (create mode) or the original ticket body (repair mode) is also passed as the `Human input (verbatim; off-limits for over-spec)` block. For overlap, include all available mutually exclusive alternatives and the fenced read-only source; do not treat alternatives as split slices. When a split is proposed, the draft artifact holds all N proposed bodies plus their three-line justification blocks (see Split rule) in one file, not a single body. Two separate calls - never fuse members and chair into one chain (a fused chain lets one member failure kill the roast before the chair runs). Call 1: one member fanout with `cwd` = repo root, absolute `output` paths and `outputMode: "file-only"` on every member task and targeted retry, run-level `control: { needsAttentionAfterMs: 60000, inFlightSilenceCeilingMs: 240000, inFlightSilenceKillMs: 300000 }` (sits beside `tasks`, not inside each task; effective silence-kill max(300s, 240+60) = 300s - record all three fields verbatim so a pi-cohort default change cannot stretch the kill). Then probe the member output files on disk with item 7's usable test. Call 2: the inline chair, with explicit usable member paths in its task text, the same control block (`:low` chair turns are short), and task text that (a) forbids repository access - member disagreement on a fact is reported in the synthesis, never verified against the repo - and (b) states coverage: `Coverage: N of M members reported; <slug>: <reason>` (pi-cohort's kill diagnostic when present, else "no output produced"; omit reasons at full coverage; singular wording when one member reported). Member task text: *the draft at `<path>` is the artifact under review; name the displaced text its trailing `## Proposed Reporter note` section already retains before naming anything missing; this ticket brief supersedes your spec-axis template - emit the same findings format against the draft; content-only review: the temp files plus the two referenced reference paths (split-axes, ticket-wording) are the entire permitted input - do not read, search, or scan the repository; do not edit any file.* Include the absolute paths to `reference/split-axes.md` and `reference/ticket-wording.md` (both resolved against this skill's own directory) in each member's task text - members run with `cwd` = the consumer repo, where a package-relative path does not resolve.
203
+ 2. **Dispatch shape**, mirroring `/skill:roasting-the-spec`: write the draft body and the source snapshot (original ticket + comments, or the create-mode inputs) to absolute temp files under `mktemp -d`; delimit untrusted snapshots as data. The raw ask (create mode) or the original ticket body (repair mode) is also passed as the `Human input (verbatim; off-limits for over-spec)` block. For overlap, include all available mutually exclusive alternatives and the fenced read-only source; do not treat alternatives as split slices. When a split is proposed, the draft artifact holds all N proposed bodies plus their three-line justification blocks (see Split rule) in one file, not a single body. Two separate calls - never fuse members and chair into one chain (a fused chain lets one member failure kill the roast before the chair runs). Call 1: one member fanout with `cwd` = repo root, absolute `output` paths and `outputMode: "file-only"` on every member task and targeted retry, run-level `control: { needsAttentionAfterMs: 60000, inFlightSilenceCeilingMs: 240000, inFlightSilenceKillMs: 300000 }` (sits beside `tasks`, not inside each task; effective silence-kill max(300s, 240+60) = 300s - record all three fields verbatim so a pi-cohort default change cannot stretch the kill). Then probe the member output files on disk with item 7's usable test. Call 2: the inline chair, with `cwd` = repo root, explicit usable member paths in its task text, the same control block (`:low` chair turns are short), and task text that (a) forbids repository access - member disagreement on a fact is reported in the synthesis, never verified against the repo - and (b) states coverage: `Coverage: N of M members reported; <slug>: <reason>` (pi-cohort's kill diagnostic when present, else "no output produced"; omit reasons at full coverage; singular wording when one member reported). Member task text: *the draft at `<path>` is the artifact under review; name the displaced text its trailing `## Proposed Reporter note` section already retains before naming anything missing; this ticket brief supersedes your spec-axis template - emit the same findings format against the draft; content-only review: the temp files plus the two referenced reference paths (split-axes, ticket-wording) are the entire permitted input - do not read, search, or scan the repository; do not edit any file.* Include the absolute paths to `reference/split-axes.md` and `reference/ticket-wording.md` (both resolved against this skill's own directory) in each member's task text - members run with `cwd` = the consumer repo, where a package-relative path does not resolve.
192
204
  3. **Effort: cheap by default.** Append a `:low` thinking suffix to each member's model string at dispatch (this beats the persona's frontmatter `xhigh` pin). Same for the chair: a configured chair string gets any existing suffix replaced with `:low`; an unconfigured chair is dispatched with the main loop's own string, read from `$PI_PROVIDER`/`$PI_MODEL` with the bash tool, plus `:low`. The `worker` fallback carries no thinking pin - it runs at the preset's default. **Full-roast escape:** the user may request a full roast, dispatching all model strings bare/as-configured, restoring the xhigh pins; a full roast reuses the spec-roast control blocks (members `{ needsAttentionAfterMs: 300000, inFlightSilenceCeilingMs: 300000, inFlightSilenceKillMs: 600000 }`, chair `{ needsAttentionAfterMs: 300000, inFlightSilenceCeilingMs: 600000, inFlightSilenceKillMs: 900000 }`) - the 5-minute figures in item 2 are `:low`-only.
193
205
  4. **Brief covers four axes**, absorbing the fidelity-review role without a new persona: *fidelity* - compare draft against source intent (original ticket + comments in repair; prompt + answers in create), flag `lost` / `added` / `gap` (unpacking existing claims to satisfy the ticket wording contract is not `added`; contract-conformance findings on Context/Problem/Idea outrank fidelity flags that only object to extra explanation of the same claims); and *quality* - problem framing, AC integrity beyond the deterministic gate, scope, wording, and conformance to the ticket wording contract (reference path provided in every roast brief). Flag quality findings for the product-aware repo-stranger reader, one-sentence/one-number examples, trigger/current-state Context without mechanism, and Idea overflow including a paragraph-long single line; apply rule 3's comprehension precedence: never remove a plain-words Problem lead or a product-level cause-and-effect sentence through a cut, compression, or redundancy finding. And *split soundness* - if the draft proposes a split, test each slice against the split-axes reference (path provided in the task text); an architecture-shaped boundary is reported as a finding line containing the marker `split-axis:` (members keep their existing spec-axis findings template; the marker is a substring flag within it, not a new findings kind), e.g. `- [major] split-axis: <slice> - <why> -> merge`. Members may argue toward one ticket, never propose or endorse a split. And *attribution* - when the Acceptance Criteria section carries `### <repo>` groups, every row sits under the repo that can observe it; a misplaced row is a finding naming the group it belongs to, applied like any other concrete fix; a repo group is never a `split-axis:` finding.
194
206
  5. Disposition: unambiguous concrete fixes applied to the draft (one re-pass max); ambiguous findings surfaced at the confirmation gate. Apply roast edits to the body draft pre-write and re-run step 5; append removed Context/Problem mechanism verbatim to the accumulated Reporter-note payload, never delete it. Roast findings themselves are never posted as a tracker comment. Additionally, the parent scans the **usable member output files (item 7's structural test) directly** for lines containing `split-axis:` (substring match), independent of the chair synthesis; any such finding on an actual split (never mutually exclusive overlap alternatives) auto-applies a merge - the split is withdrawn and the draft becomes one ticket with phased AC groups, inside the same one-re-pass budget, and the pre-merge N-body draft is kept alongside: a human re-request of the split at the gate re-presents those N bodies old->new as the approval diff (see the Split rule's sticky override). The chair keeps every other axis; clearing a `split-axis:` finding is not on its path. The same directional rule - toward one ticket, never toward a split - binds the `worker` fallback and the runtime conditional (item 6).
@@ -255,7 +267,15 @@ Runs every invocation, not just on request. Scope: every field the tracker expos
255
267
 
256
268
  ## Evidence gate
257
269
 
258
- Claims about user-visible/UI behavior need evidence: screenshots/artifacts via repo-documented capture tooling (resolved through the ladder), else ask the user to supply them. Label provenance (which env, when). `none (<reason>)` is a valid explicit outcome. Bug tickets require repro steps + observed-vs-expected. No project-specific mechanics (asset URL schemes, session tables) live in this skill body - they belong in the overrides file.
270
+ Claims about user-visible/UI behavior need evidence: screenshots/artifacts via repo-documented capture tooling (resolved through the ladder), else ask the user to supply them. Label provenance (which env, when). `none (<reason>)` is a valid explicit outcome. Require bug repro steps + observed-vs-expected in the gate's Evidence list and the AC rows' setup/action/result; keep each Problem example to rule 5's one sentence or one number, followed by its source footer. No project-specific mechanics (asset URL schemes, session tables) live in this skill body - they belong in the overrides file.
271
+
272
+ Gather provenance separately from example text: read the ask/session and, in repair, the existing body, comments and attachment list. Treat URLs (`http(s)://...`), named or uploaded attachment references, and pasted images (cite as `pasted screenshot`) as sources. Treat quoted log lines, errors and other pasted text as examples/evidence, never their own sources. Never invent a URL or attachment reference.
273
+
274
+ Carry every gathered source in Problem, including Discovery/Spike bodies. After the Problem prose, at the end of that section, emit one footer per example: `source: <label> - <value>`, using a short stable example label and a value of URL, `attachment: <name>`, `pasted screenshot`, or `none (<reason>)`. Omit the label for a single example. Two examples sharing a URL each get a footer. Carry unrelated URLs with label `other`; these create no gap. Keep footers deletion-safe and associate each with its example.
275
+
276
+ Collect a source gap for each actual rule-5 example without its footer only when the title lacks `Discovery:` / `Spike:`. A rule-5 `none (<reason>)` example slot needs no source. Carry gaps to step 8 without blocking its write offer. Keep the two `none`s distinct: rule 5 permits drafter-authored example explanations; source reasons are only human reply text verbatim, the fixed repair constant, or step 8's dated proceed-without form.
277
+
278
+ Route each footer with its example on a split. For overlap enrichment, carry sources only for added/changed Problem prose; preserve legacy bodies and evidence-only operations under the overlap reference's payload-local rules. A displaced pasted log block remains evidence in the Reporter note, never a source.
259
279
 
260
280
  ## Ticket wording
261
281
 
@@ -322,7 +342,7 @@ Read this when applying the AC integrity gate (drafting, repairing, or adjudicat
322
342
 
323
343
  ## Red flags - STOP
324
344
 
325
- - About to write to the tracker without the confirmation gate's explicit yes on the exact presented diff
345
+ - About to write without the gate's explicit approval of the exact displayed diff plus only the `source:` substitutions resolved by that same approving reply, or making another post-approval edit or adding a second gate
326
346
  - Inventing a number, list, label, assignee, or URL to pass a gate
327
347
  - An AC gated on a set this ticket itself will produce
328
348
  - A prod-only observation left in the AC list
@@ -17,8 +17,8 @@ Scope: Context/Problem/Idea prose only. ACs, split justification blocks, metadat
17
17
  4. **Plain-words lead.** Each independently asserted failure or impact in Problem opens with a plain-words sentence of what goes wrong and what it costs, before any mechanism. (The lead and example rules bind Problem; Context and Idea are bound by the general self-containment test.)
18
18
  5. **Example per failure.** Give each independently asserted failure a concrete example limited to one sentence or one number: real numbers, a before/after, or a short transcript. One example may serve multiple sentences describing the same failure. `none (<reason>)` is permitted only when no observable exists yet (pure rename/removal, or discovery work whose deliverable is the observable); the reason is part of the draft and thus roast-reviewable. A disputed reason is an ordinary roast finding handled by the existing disposition machinery (applied if unambiguous, surfaced at the gate if not) - no new disposition class.
19
19
  6. **Jargon.** Define repo-native terms (module, script, internal tool, extension, or setting names) at first use in plain words, or drop them. Leave product and domain terms the requester used undefined; requester usage wins for terms that are also internal names. Establish requester usage from the ask's own words, reporter-authored comments, a quoted ask, or explicit attribution ("the reporter calls this ..."), never from unattributed existing body prose. Keep an internal term's definition when its only usage evidence is the existing body. A link is not a definition when the term is load-bearing for triage.
20
- 7. **Pointer demotion.** Code/doc references in Context/Problem/Idea are demoted to parenthetical pointers whose deletion loses no meaning, e.g. "(Pointer for the implementer: detectChains, src/chain-detector.ts.)". Composition with the tracker-native-links rule in SKILL.md's `## Ticket wording`: that rule governs *how* a reference is written (native link/mention form, never bare identifiers); pointer demotion governs *where* it may sit (parenthetical, deletion-safe).
21
- 8. **Link-vs-inline (anti-spiderman).** Linking stays legitimate for targets impractical to inline - a whole design doc, a KB page, a long log - and for general-knowledge material; every such link carries a one-line plain-words statement of what the reader needs from it. What is forbidden is the spiderman shape: many small load-bearing hops, where the full picture must be assembled from N places even when each individual inline would be cheap. Discriminator: "is this definition load-bearing for triage?" - load-bearing small definitions get inlined; big chunks get linked with a summary line.
20
+ 7. **Pointer demotion.** Code/doc references in Context/Problem/Idea are demoted to parenthetical pointers whose deletion loses no meaning, e.g. "(Pointer for the implementer: detectChains, src/chain-detector.ts.)". Composition with the tracker-native-links rule in SKILL.md's `## Ticket wording`: that rule governs *how* a reference is written (native link/mention form, never bare identifiers); pointer demotion governs *where* it may sit (parenthetical, deletion-safe). Keep the Evidence gate's `source:` footer in Problem as the sanctioned deletion-safe parenthetical reference; step 5 never moves it to the Reporter note.
21
+ 8. **Link-vs-inline (anti-spiderman).** Linking stays legitimate for targets impractical to inline - a whole design doc, a KB page, a long log - and for general-knowledge material; every such link carries a one-line plain-words statement of what the reader needs from it. What is forbidden is the spiderman shape: many small load-bearing hops, where the full picture must be assembled from N places even when each individual inline would be cheap. Discriminator: "is this definition load-bearing for triage?" - load-bearing small definitions get inlined; big chunks get linked with a summary line. Treat the example a `source:` footer names as its summary; require no second plain-words sentence.
22
22
 
23
23
  ## Exemplar
24
24
 
@@ -30,7 +30,7 @@ You are the **orchestrator**. You read the plan, dispatch, review the review, de
30
30
  **Do not pause to check in with the user between tasks.** The plan is already approved. Pause only when:
31
31
 
32
32
  - A subagent returns `NEEDS_CONTEXT` or `BLOCKED` (see [Implementer Status](#implementer-status))
33
- - An escalated round fails (stop note per [Fix-Loop Rounds](#fix-loop-rounds))
33
+ - An escalated round fails with no funded round left (stop note per [Fix-Loop Rounds](#fix-loop-rounds))
34
34
  - A ⚠️ workflow warning fires
35
35
 
36
36
  Reaching the end of the plan is not a pause: continue through verification and invoke `/skill:finishing-a-development-branch <abs worktree path>` as defined in [After All Tasks](#after-all-tasks-complete).
@@ -45,7 +45,7 @@ Periodic "should I continue?" prompts add latency without adding safety. The pla
45
45
 
46
46
  Extract **`SCOPED_TEST_COMMANDS`** from the task's `**Tests:**` command bullets, backticks stripped, one per line; `- none:` -> `none`; a wave = the union of its tasks' commands. Treat `via:` and `baseline:` bullets and `- Test:` paths as contract, not commands: carry them with the task text, never in `SCOPED_TEST_COMMANDS`.
47
47
 
48
- Keep the orchestrator as the spec's only writer during execution. On implementer `BLOCKED` citing a spec defect, or a review finding showing the spec (not the code) is wrong, pause the fix loop, read and execute brainstorming's [amendment path](../brainstorming/SKILL.md#amending-an-approved-spec) in place (it reviews first, stops only on escalation or redraw), then resume. Keep code-vs-spec mismatch in the SR loop. Require an SR unable to read the spec at a cited anchor (missing file, unresolvable heading/range) to return a blocking finding - the contract is spec+task or stop, never a silent fallback to task-only review.
48
+ Keep the orchestrator as the spec's only writer during execution. On implementer `BLOCKED` citing a spec defect, or a review finding showing the spec (not the code) is wrong, pause the fix loop, read and execute brainstorming's [amendment path](../brainstorming/SKILL.md#amending-an-approved-spec) in place (it reviews first; with amend permission on the `**Amend-grant:**` line it applies amends without a stop and still stops on a redraw; without permission it stops on escalation or redraw), then resume. Keep code-vs-spec mismatch in the SR loop. Require an SR unable to read the spec at a cited anchor (missing file, unresolvable heading/range) to return a blocking finding - the contract is spec+task or stop, never a silent fallback to task-only review.
49
49
 
50
50
  ## Fix-Loop Rounds
51
51
 
@@ -68,7 +68,7 @@ Every fix re-dispatch (implementer) and code-review re-review carries the consum
68
68
 
69
69
  Every dispatched fix is verified by a re-review before escalation or task progression - the loop only ever exits on a clean review or an escalation.
70
70
 
71
- **Escalate** = one escalated round; stop only on failure. Call `gauntlet_setting({ key: "escalationLoop" })` (unavailable -> stop and report). `implModel` undefined -> stop note. Otherwise re-dispatch that fix - same payload and isolation knobs (`cwd`, `worktree`, `SCOPED_TEST_COMMANDS`, status protocol, prior patch, spec anchors) plus the prior report verbatim - overriding only `model: <implModel>`, `context: "fresh"`, `async: false`; one implementer, no fan-out. Run the normal fix-round review gate (SR then CR on `Behaviour-change: yes`, else the triggering reviewer with the re-review marker). All clean -> proceed; the escalated patch supersedes the prior one at integrate. Any review with issues, a non-`DONE` status, or a dispatch error -> stop note per `stop-note.md`; no second dispatch. Once per loop; independent of the convergence exception. No `plan_tracker` write during escalation - the task stays `in_progress` until the human decides.
71
+ Read [reference/fix-loop.md](./reference/fix-loop.md) now for escalation and funded-round dispatch rules.
72
72
 
73
73
  **Worked examples:**
74
74
 
@@ -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 | Resolve fact asks per [lookup handling](./stop-note.md). For decisions, answer and re-dispatch with answers in the task text, or escalate to the user. |
107
- | `BLOCKED` | Cannot proceed (missing dependency, spec contradicts code, environment broken) | Resolve fact asks per [lookup handling](./stop-note.md). For decisions, stop and diagnose: fix the orchestration-level issue and re-dispatch, or escalate to the user. |
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 with answers in the task text, 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, stop and diagnose: fix the orchestration-level issue and re-dispatch, or escalate to the user. |
108
108
 
109
- Classify each question: artifact location, value, or existence is a fact ask; scope choices, option choices, and another-round approval are decisions.
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 a redraw: changed problem statement; component added, removed, or re-bounded. 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
 
@@ -305,7 +305,7 @@ git -C "$SR_TREE" apply --index "$SR_PATCH" || exit 1
305
305
  printf 'snapshot: %s\n' "$SR_TREE"
306
306
  ```
307
307
 
308
- Record its review tree per [Fix delta](#fix-delta) before every parent-dispatched SR, keyed by task. Use the printed snapshot path as that spec-review task's `cwd` and whole-file read root. Keep the authoritative spec's absolute path in the implementation worktree. Pass the patch diff as before; the snapshot contains this task's changed and added files, with deleted files absent. Read deleted files from `WAVE_BASE_SHA` when the review needs their prior contents. Dispatch read-only, with no `worktree` flag. On snapshot setup or tree-capture failure, or a missing snapshot path, stop dispatch and retain the failed snapshot directory and shell output for diagnosis; dispatch no review and perform no snapshot cleanup. Save each snapshot-backed review's terminal report to its `output:` path, read it, then remove that review's snapshot with `git -C <implementation-worktree> worktree remove --force <snapshot-path>`. Keep every snapshot used as a reviewer `cwd` until that terminal report is saved; recording its tree never authorizes early cleanup. Remove a reconstruction used only to record tree-before after capturing its tree, since no reviewer runs there. Recreate from the replacement patch for each pre-integration re-review. Post-integration SR reviews the implementation worktree directly.
308
+ Record its review tree per [Fix delta](#fix-delta) before every parent-dispatched SR, keyed by task. Use the printed snapshot path as that spec-review task's `cwd` and whole-file read root. Keep the authoritative spec's absolute path in the implementation worktree. Pass the patch diff as before; the snapshot contains this task's changed and added files, with deleted files absent. Read deleted files from `WAVE_BASE_SHA` when the review needs their prior contents. Dispatch read-only, with no `worktree` flag. On snapshot setup or tree-capture failure, or a missing snapshot path, stop dispatch and retain the failed snapshot directory and shell output for diagnosis; dispatch no review and perform no snapshot cleanup. Save each snapshot-backed review's terminal report to its `output:` path, read it, then remove that review's snapshot with `git -C <implementation-worktree> worktree remove --force <snapshot-path>`. Keep every snapshot used as a reviewer `cwd` until that terminal report is saved; recording its tree never authorizes early cleanup. Remove a reconstruction used only to record tree-before after capturing its tree, since no reviewer runs there. Recreate from the replacement patch for each pre-integration re-review; on a failed recreate, stop dispatch and retain that snapshot directory and shell output, like any setup failure. Post-integration SR reviews the implementation worktree directly.
309
309
 
310
310
  ## When a Subagent Fails
311
311
 
@@ -338,13 +338,13 @@ Record its review tree per [Fix delta](#fix-delta) before every parent-dispatche
338
338
  ## Red Flags — STOP
339
339
 
340
340
  - Writing code yourself instead of dispatching.
341
- - Pausing between tasks for anything other than `NEEDS_CONTEXT`, `BLOCKED`, a fix-loop escalation, a workflow warning, or a spec amendment.
341
+ - Pausing between tasks for anything other than `NEEDS_CONTEXT`, `BLOCKED`, a fix-loop escalation, a workflow warning, a redraw, or an amend with no standing grant.
342
342
  - Dispatching parallel implementers on overlapping files, on a shared mutable runtime resource, or without `worktree: true`.
343
343
  - Making a subagent read the plan, inlining spec excerpts to the spec reviewer, or dispatching with a `SCOPED_TEST_COMMANDS` value missing or not copied from the plan's `Tests:` bullets.
344
344
  - Dispatching `code-reviewer` before every in-scope spec-review verdict is ✅, or per task inside a wave.
345
345
  - Moving to the next task with either review still showing issues, or skipping the `Implementer Status` parse.
346
346
  - Second chain call in the same wave after a stop or a chain error - the retained results are the fan-out result; continue on the snapshot path.
347
- - Dispatching fix 3 without a reviewer-emitted `CONVERGING` verdict, or continuing past `STAGNANT` instead of escalating.
347
+ - Dispatching fix 3 without a reviewer-emitted `CONVERGING` verdict, or continuing past `STAGNANT` instead of escalating (or, on a funded re-review, stopping).
348
348
  - Running the full verification entrypoint, or any test command outside `SCOPED_TEST_COMMANDS`, during the implement phase.
349
349
  - Dispatching a repair before reopening the plan-task indices that own its files, whole-diff CR before parent verification passes, or conformance before the CR result is accepted.
350
350
  - Polling, joining, or relaunching an unexpectedly asynchronous dispatch, or starting on main without explicit user consent.
@@ -0,0 +1,23 @@
1
+ # Escalated fix rounds
2
+
3
+ **Escalate** = one escalated round; stop only on failure. Call `gauntlet_setting({ key: "escalationLoop" })` (unavailable -> stop and report). `implModel` undefined -> stop note. Otherwise re-dispatch that fix - same payload and isolation knobs (`cwd`, `worktree`, `SCOPED_TEST_COMMANDS`, status protocol, prior patch, spec anchors) plus the prior report verbatim - overriding only `model: <implModel>`, `context: "fresh"`, `async: false`; one implementer, no fan-out. Run the normal fix-round review gate (SR then CR on `Behaviour-change: yes`, else the triggering reviewer with the re-review marker). All clean -> proceed; the escalated patch supersedes the prior one at integrate. A non-`DONE` status or a dispatch error -> stop note per `stop-note.md`. A review with issues -> a funded round while one remains for the task (below), otherwise stop note; no other second dispatch. Once per loop; independent of the convergence exception. No `plan_tracker` write during escalation - keep the task `in_progress` until the wave commit or, on a stop, the human decides.
4
+
5
+ ## Funded rounds
6
+
7
+ Decode the current `**Amend-grant:**` line using **Value decoding** in [Standing grants](../../brainstorming/reference/amendment-surface.md#standing-grants) before each funded dispatch. Funding is independent of ordinary fixes and the escalated round; it never supplies a missing `implModel`, another escalation grant, verify credits, or `grant_fix_rounds`. Keep the review-3 convergence exception once per loop; never re-arm it through funding.
8
+
9
+ Start one per-task ledger at zero when each task first enters Fix-Loop Rounds. Carry it across SR, behavior-change reroutes, the SR-to-CR transition, and wave repairs re-entering SR; use no wave-level allowance. Determine touched owners using the SR targeting rule (tasks whose files the fix touches). For a multi-task CR repair, spend once from every touched task; a touched exhausted owner stops the wave with that task's stop note before dispatch.
10
+
11
+ Before every funded dispatch, print `funded round <k> of <N> for task <n>` for each touched task. Apply mid-loop grants prospectively, with spent starting at zero: rounds before the token was written neither count against nor toward it. Repeat the escalated payload and isolation exactly: configured `model: <implModel>` from `escalationLoop`, `context: "fresh"`, `async: false`, one implementer, no fan-out, same `cwd`/`worktree`, task text, prior patch, spec anchors, status protocol, `SCOPED_TEST_COMMANDS`, and complete prior report verbatim. Run the same tests and same review gate: SR then CR on `Behaviour-change: yes`, otherwise the triggering reviewer with the re-review marker, trajectory block and Fix delta. Every dispatched round spends one, including failures.
12
+
13
+ | Funded outcome | Action |
14
+ |---|---|
15
+ | Errors and non-`DONE` | Count as spent and stop with the task's stop note. |
16
+ | Any funded re-review reports `STAGNANT` | Stop immediately regardless of funding remaining. |
17
+ | Issue-bearing re-review with rounds left | Dispatch the next funded round. |
18
+ | Issue-bearing re-review after N rounds | Stop with the exhausted task's stop note. |
19
+ | All reviews clean | Continue through the wave gate and commit before task completion. |
20
+
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
+
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.