pi-gauntlet 7.25.1 → 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,11 @@
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
+
3
9
  ## v7.25.1 - 2026-10-22
4
10
 
5
11
  ### 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.1",
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
 
@@ -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.