pi-gauntlet 8.5.0 → 8.6.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,17 @@
1
1
  # Changelog
2
2
 
3
+ ## v8.6.0 - 2026-11-15
4
+
5
+ - Replace the spec approval gate with four rows: `1` plan engine, `2` loop engine, `3` council explanation, and `4` draft-PR handoff. Mark exactly one row `[recommended]`: context reading above 25% recommends row `4` when available; otherwise zero acceptance rows or a bundled row recommends row `1`, and the default is row `2`. Bare `approve` takes the recommended row. The loop engine is no longer labeled experimental.
6
+ - Plain `1` or `2` now grants automatic application of later amendments within the original problem statement; add `--amends-stop` to require human approval instead. Redraws still stop for approval. Use `--fund-rounds=N` on row `1` to fund up to N extra fix rounds per task after its escalated round on the plan engine and `--allowance=N` on row `2` for the loop run allowance.
7
+ - Breaking reply grammar: old `2` changes from plan-with-grant to loop-with-grant, old `4` changes from loop-without-grant to draft-PR handoff, and old `5` and `6` leave the valid range. Gate suffixes `; fund N fix rounds` and `; allowance N` are replaced by `--fund-rounds=N` and `--allowance=N`, with no aliases for the old digits or suffixes.
8
+ - Add a model-visible `Context: <p>% of window` line to `phase_tracker` status (`Context: unknown` when unavailable), without adding it to the TUI.
9
+
10
+ ## v8.5.1 - 2026-11-13
11
+
12
+ - Housekeeping excludes spec and plan folders from content checks, keeps specs outside the file budget, and checks specs-only selections instead of ending empty. Fully superseded specs get a Delete-or-Keep card in every run, without a Ticket pick or hotfix-bounds gate; outside references recommend Keep. With no argument, checkout changes select uncommitted files and disclose commits ahead of the unfetched local ref; a clean checkout selects unpushed changes after fetching, with stops for divergent history, remote containment and squash receipts.
13
+ - pi-cohort peer floor raised to 8.1.0.
14
+
3
15
  ## v8.5.0 - 2026-11-13
4
16
 
5
17
  - Add human-only `housekeeping` on pi and Claude Code: check a directory, uncommitted files, or a PR against repo rules, then choose fixes, directory-only tickets, or ignored classes before any work runs. Directory fixes open one PR per class, uncommitted fixes stay in place, and PR fixes are pushed to the existing branch. Extend checks through `## housekeeping` in the overrides file.
package/README.md CHANGED
@@ -36,16 +36,16 @@ pi-gauntlet's only hard dependency is pi-cohort - every gate that dispatches a r
36
36
  Concretely, one change through the gauntlet:
37
37
 
38
38
  0. *(Optional)* Before there's even a spec, `/skill:shape-ticket` can create one tracker issue or repair a comma/whitespace list of issue refs - shaping each into a Context/Problem/Idea/Acceptance Criteria ticket, grounded by a repository audit, an AC integrity check, and a cheap council roast. Repair finishes preparation for all tickets before presenting exact-diff confirmations sequentially in ref order; each approval writes that ticket before the next gate, and may include one optional gated comment for a Reporter note or overlap evidence. The audit checks factual claims, Idea fit, AC mechanisms against cited repo guidance, and already-stated observable legs in configured sibling checkouts. It reports in-motion work and attempts a best-effort scenario through authorized current-system reads, without promising reproduction or a fix; missing access or nothing to observe is reported, not a new approval gate. Implementer detail moves into the gated Reporter note; brainstorming reads that note with the ticket so the spec retains the detail. A failed roast is retried once, then surfaced inline at the gate if it fails again. It's a tool, not a phase: no worktree, no plan/phase tracker, runs from any repo state. The agent may start it on its own when the ask is "file a ticket" or another skill routes there; the write still waits for your yes on the presented diff. Similarly, `/skill:chase-bug` triages a raw bug report into an evidenced verdict - and can hand off to shape-ticket, brainstorming, or a bounded hotfix - before any spec exists.
39
- 1. Opt in with `/skill:brainstorming` and describe the change. The command is the reliable discovery-and-entry path; explicit prose requesting brainstorming/the gauntlet also supplies consent when the skill is already loaded or an available instruction or route identifies it. An ordinary implementation request or an agent recommendation is not consent. A leading run of GitHub references (`#N`, `owner/repo#N`, or a `/pull/N` or `/issues/N` URL), separated by whitespace or commas, resolves each reference as a PR first: related open, same-repository, non-fork PRs on one base form one rework subject, including drafts. Admission runs in listed order and relatedness is checked before provisioning; the first retained PR is home, whose existing branch rebases onto the fetched PR base by default, then member commits replay onto it in listed order. The first intent word `merge-forward` opts out and keeps the merge path. An unresolved conflict after its scoped helper aborts that step and continues to the spec with the repair as Task 1. A single non-PR reference follows the ticket path. The first non-reference token starts intent text; mid-sentence references and other ticket/free-text subjects keep their existing paths. The combined code, PR-carried specs, claims, and review threads are the brainstorm input, with each PR's provenance retained; only home's bound ticket supplies acceptance criteria, while member tickets supply context. A single PR retains the same rework path without member replays or a close offer. The combined state is judged against constraints from the fetched current base HEAD, not the fork point or the PRs' proposed policy edits; see the [PR-subject contract](skills/brainstorming/reference/pr-subject.md) and [PR-head worktree owner](skills/using-git-worktrees/reference/pr-head.md). **`brainstorming`** sets up an isolated worktree (on the existing branch for PR rework), explores the codebase, and turns the subject into a written spec - when its recon finds a cited case that the ask is the wrong change (misdiagnosed, wrong-sized, already solved, a band-aid, or cutting across a sound pattern - including a repo convention that is itself debt) and can name the alternative, question one is a framing question (`as framed`, `pivot: <alternative>`, or `smaller or none`); otherwise it opens with one sentence naming what it checked, and every approach it proposes ends with a `Pattern:` line naming what it follows or cuts across; when the run starts from a ticket, the spec carries the ticket's acceptance criteria verbatim, each with a disposition (`in-scope`, `deviates:`, `deferred:`, `venue:`, `elsewhere:` for a row another repo's part delivers), scope cuts come only from your answer to a cut question and are listed at the gate, the conformance gate checks the in-scope ones, and `/skill:check-delivery` verifies `venue:` rows before the prod deploy. A multi-model critique runs on it automatically. If the spec replaces a known prior spec, brainstorming marks the predecessor with a `> **Superseded by:**` banner under its title (default format, syntax overridable via `.pi/gauntlet-overrides.md`; candidates come from brainstorming's scout recon, never a mechanical sweep). **You read and approve the spec - human gate 1.** Options 1/2/4/5 approve and pick an engine; option 6 approves the content only: it writes `**Engine:** deferred` under `**Amend-grant:** none`, pushes the branch, opens a draft PR carrying just the spec, prints the URL, and ends the flow - no plan, no loop, no handoff brief. For a coordinated spec, it first pushes every companion branch to origin, then opens one home draft PR; it creates no companion PRs. A later `brainstorming #N` reconstructs the recorded companions from their origin branches before re-presenting the implementation gate; the [publication and re-gate owner](skills/brainstorming/reference/spec-pr.md) defines all-member preflight, recovery, and cleanup. After confirming the live remote and local branch match the worktree commit, cleanup removes an owned tree and conditionally deletes the local branch at that pinned commit. A host-owned checkout or failed remote check keeps tree and branch, with a per-repo reason. Option 6 is withheld on a PR subject (`Withheld: draft PR - #N already exists`) and when the branch's diff against the default branch is not spec-only. A later `brainstorming #N` on that PR classifies it from the diff alone: one added spec carrying the marker plus banner-only predecessor edits re-presents the gate with 1/2/4/5 (3 only when the spec commit carries a council audit) and skips gather, questionary, council, and scout; a spec-only diff without the marker prints `spec-only PR without the gate marker - running lint and council` and takes the normal brainstorm path with the carried spec as the draft; any other diff takes the rework path. Approval at that re-gate writes `**Engine:**`, `**Amend-grant:**`, and `**PR:** <owner/repo#N>` as a new commit on the PR branch and chains into planning or the loop as usual. Before approval, PR rework's sole write/run exception outside the spec directories permits only the base sync (rebase or merge), each member replay or merge, their conflict helpers' edits to the conflicted files, and their scoped conflict tests; other subjects have no implementation code yet.
40
- 2. By default, **`writing-plans`** decomposes the approved spec into atomic, independently-verifiable tasks, grouped into parallel waves where they don't touch the same files. Experimental approval options 4/5 instead select **`loop-implementation`**: the plan phase is skipped and a stamped acceptance-criteria ledger replaces the task plan. Option 4 retains amendment review; option 5 auto-applies amends, including unreachable-row cuts, and funds conformance rounds up to the allowance when the cap blocks. Redraws and exhausted attempt or repair allowances still stop; an interrupted return recovers without a human turn under either option. See [Loop engine operations](doc/configuration.md#loop-engine-operations).
39
+ 1. Opt in with `/skill:brainstorming` and describe the change. The command is the reliable discovery-and-entry path; explicit prose requesting brainstorming/the gauntlet also supplies consent when the skill is already loaded or an available instruction or route identifies it. An ordinary implementation request or an agent recommendation is not consent. A leading run of GitHub references (`#N`, `owner/repo#N`, or a `/pull/N` or `/issues/N` URL), separated by whitespace or commas, resolves each reference as a PR first: related open, same-repository, non-fork PRs on one base form one rework subject, including drafts. Admission runs in listed order and relatedness is checked before provisioning; the first retained PR is home, whose existing branch rebases onto the fetched PR base by default, then member commits replay onto it in listed order. The first intent word `merge-forward` opts out and keeps the merge path. An unresolved conflict after its scoped helper aborts that step and continues to the spec with the repair as Task 1. A single non-PR reference follows the ticket path. The first non-reference token starts intent text; mid-sentence references and other ticket/free-text subjects keep their existing paths. The combined code, PR-carried specs, claims, and review threads are the brainstorm input, with each PR's provenance retained; only home's bound ticket supplies acceptance criteria, while member tickets supply context. A single PR retains the same rework path without member replays or a close offer. The combined state is judged against constraints from the fetched current base HEAD, not the fork point or the PRs' proposed policy edits; see the [PR-subject contract](skills/brainstorming/reference/pr-subject.md) and [PR-head worktree owner](skills/using-git-worktrees/reference/pr-head.md). **`brainstorming`** sets up an isolated worktree (on the existing branch for PR rework), explores the codebase, and turns the subject into a written spec - when its recon finds a cited case that the ask is the wrong change (misdiagnosed, wrong-sized, already solved, a band-aid, or cutting across a sound pattern - including a repo convention that is itself debt) and can name the alternative, question one is a framing question (`as framed`, `pivot: <alternative>`, or `smaller or none`); otherwise it opens with one sentence naming what it checked, and every approach it proposes ends with a `Pattern:` line naming what it follows or cuts across; when the run starts from a ticket, the spec carries the ticket's acceptance criteria verbatim, each with a disposition (`in-scope`, `deviates:`, `deferred:`, `venue:`, `elsewhere:` for a row another repo's part delivers), scope cuts come only from your answer to a cut question and are listed at the gate, the conformance gate checks the in-scope ones, and `/skill:check-delivery` verifies `venue:` rows before the prod deploy. A multi-model critique runs on it automatically. If the spec replaces a known prior spec, brainstorming marks the predecessor with a `> **Superseded by:**` banner under its title (default format, syntax overridable via `.pi/gauntlet-overrides.md`; candidates come from brainstorming's scout recon, never a mechanical sweep). **You read and approve the spec - human gate 1.** Rows 1/2 approve and pick the plan/loop engine respectively; row 3 explains the council audit; row 4 approves the content only: it writes `**Engine:** deferred` under `**Amend-grant:** none`, pushes the branch, opens a draft PR carrying just the spec, prints the URL, and ends the flow - no plan, no loop, no handoff brief. For a coordinated spec, it first pushes every companion branch to origin, then opens one home draft PR; it creates no companion PRs. A later `brainstorming #N` reconstructs the recorded companions from their origin branches before re-presenting the implementation gate; the [publication and re-gate owner](skills/brainstorming/reference/spec-pr.md) defines all-member preflight, recovery, and cleanup. After confirming the live remote and local branch match the worktree commit, cleanup removes an owned tree and conditionally deletes the local branch at that pinned commit. A host-owned checkout or failed remote check keeps tree and branch, with a per-repo reason. Row 4 is withheld on a PR subject (`Withheld: draft PR - #N already exists`) and when the branch's diff against the default branch is not spec-only. A later `brainstorming #N` on that PR classifies it from the diff alone: one added spec carrying the marker plus banner-only predecessor edits re-presents the gate with 1/2 (3 only when the spec commit carries a council audit) and skips gather, questionary, council, and scout; a spec-only diff without the marker prints `spec-only PR without the gate marker - running lint and council` and takes the normal brainstorm path with the carried spec as the draft; any other diff takes the rework path. Approval at that re-gate writes `**Engine:**`, `**Amend-grant:**`, and `**PR:** <owner/repo#N>` as a new commit on the PR branch and chains into planning or the loop as usual. Before approval, PR rework's sole write/run exception outside the spec directories permits only the base sync (rebase or merge), each member replay or merge, their conflict helpers' edits to the conflicted files, and their scoped conflict tests; other subjects have no implementation code yet.
40
+ 2. Choosing the plan engine (row 1) runs **`writing-plans`**, which decomposes the approved spec into atomic, independently-verifiable tasks, grouped into parallel waves where they don't touch the same files. Choosing the loop engine (row 2) runs **`loop-implementation`**: the plan phase is skipped and a stamped acceptance-criteria ledger replaces the task plan. Both engine rows auto-apply amends by default; `--amends-stop` retains amendment review. With amend permission, the loop auto-applies unreachable-row cuts and funds conformance rounds up to the allowance when the cap blocks. Redraws and exhausted attempt or repair allowances still stop; an interrupted return recovers without a human turn with or without amend permission. See [Loop engine operations](doc/configuration.md#loop-engine-operations).
41
41
  3. **`subagent-driven-development`** executes the plan in waves, with task implementers followed by one integrated `wave-reviewer` after the scoped test gate passes. The reviewer checks anchored spec clauses and code quality together; repairs stay on the current tree and pass the same gate before re-review. TDD-locked: red, green, refactor. Independent implementation, review, and council batches remain parallel, but their dispatches are foreground: the orchestrator waits for terminal results before accepting work or advancing a phase.
42
- The loop alternative to step 3 runs one fresh `loop-implementer` per seed or row iteration, without implement-phase reviewers. Each row starts with the shared allowance (default 4); approval replies such as `4; allowance 6` override it for one run. Under either loop approval option, attempt `escalateAfter + 1` (default 4), clamped to the last allowed attempt, escalates once per row on `escalationLoop.implModel` (the main-loop model when unset); later attempts use the ordinary worker model. The allowance also bounds seed and exit-verification repair counts; verification repairs use the same escalation model and count home repair commits plus an unmatched `pending: verify` reservation. Stagnation supplies a row-local hint, not an early stop. An interrupted return is one failed attempt: recovery is unconditional under either option, before checking allowance. The driver signals only identity-matching jobs, skips absent or mismatched jobs, deletes the jobs file, resets to the saved pre-dispatch HEAD and runs `clean -fd`, then restores the saved ledger and commits the failed attempt. Continue recovery even with a surviving job or remaining dirt. Wrong HEAD or an unwritten repair repeats reset and repair, counting each pass against the same allowance until the repair lands on the saved HEAD or the existing exhaustion stop fires. With no pending dispatch, a dirty entry or restored tree instead lists paths and asks for typed `discard` or Stop only; discard resets to HEAD, cleans and resumes the suspended entry or restore sequence before dispatch or verification. An admitted `unreachable:` target failure becomes an audited scope cut under amend permission, never a passing row. At a row stop, `retry <n> | <hint>` adds one attempt to that row, while `rows +N` raises every row's allowance. Attempts never reset and there is no total iteration cap. Ledger refresh completes implement when every row is closed; verify step 1 runs the gate set: deduplicated (owning checkout, command) pairs from done rows' recorded checks, with ownership from the ledger. Gate output goes to logs; the driver keeps exit codes and paths, not test output. CI on push owns the full run.
42
+ The loop alternative to step 3 runs one fresh `loop-implementer` per seed or row iteration, without implement-phase reviewers. Each row starts with the shared allowance (default 4); approval replies such as `2 --allowance=6` override it for one run. With or without amend permission, attempt `escalateAfter + 1` (default 4), clamped to the last allowed attempt, escalates once per row on `escalationLoop.implModel` (the main-loop model when unset); later attempts use the ordinary worker model. The allowance also bounds seed and exit-verification repair counts; verification repairs use the same escalation model and count home repair commits plus an unmatched `pending: verify` reservation. Stagnation supplies a row-local hint, not an early stop. An interrupted return is one failed attempt: recovery is unconditional with or without amend permission, before checking allowance. The driver signals only identity-matching jobs, skips absent or mismatched jobs, deletes the jobs file, resets to the saved pre-dispatch HEAD and runs `clean -fd`, then restores the saved ledger and commits the failed attempt. Continue recovery even with a surviving job or remaining dirt. Wrong HEAD or an unwritten repair repeats reset and repair, counting each pass against the same allowance until the repair lands on the saved HEAD or the existing exhaustion stop fires. With no pending dispatch, a dirty entry or restored tree instead lists paths and asks for typed `discard` or Stop only; discard resets to HEAD, cleans and resumes the suspended entry or restore sequence before dispatch or verification. An admitted `unreachable:` target failure becomes an audited scope cut under amend permission, never a passing row. At a row stop, `retry <n> | <hint>` adds one attempt to that row, while `rows +N` raises every row's allowance. Attempts never reset and there is no total iteration cap. Ledger refresh completes implement when every row is closed; verify step 1 runs the gate set: deduplicated (owning checkout, command) pairs from done rows' recorded checks, with ownership from the ledger. Gate output goes to logs; the driver keeps exit codes and paths, not test output. CI on push owns the full run.
43
43
 
44
44
  Approval authorizes every paid or external action named in an AC or Design, with its runner and inputs, for the whole flow. A count or wording deferring it to later approval does not withhold authorization. The worker runs it whenever an attempt needs it without asking and reuses its output for local rechecks; evidence commands name local replay or fixtures. Missing prerequisites and unnamed actions still fail as `unreachable:`.
45
45
 
46
46
  These are the loop stops this recovery and authorization contract keeps or touches, not the driver's whole stop set. Missing capabilities or references, malformed grants, unresolved verification entrypoints, repeated-evidence amendment handling and failed refresh guards retain their own text. The driver renders only stops named in its skill and references; another failed dispatch consumes an attempt, not an invented menu or approval.
47
47
 
48
- | Stop | Option 4 | Option 5 |
48
+ | Stop | Without amend permission (`2 --amends-stop`) | With amend permission (default `2`) |
49
49
  |---|---|---|
50
50
  | Row attempts reach effective allowance; seed repairs reach allowance; escalation model unavailable for a row's escalated round | Retry, `rows +N`, amend, stop | Same |
51
51
  | Verification repairs reach allowance; escalation model unavailable for a verification repair | Amend, stop | Same |
@@ -57,7 +57,7 @@ These are the loop stops this recovery and authorization contract keeps or touch
57
57
  | Dirty tree with no dispatch pending; on resume, admission question or missing-history stops (unrecoverable pre-dispatch ledger/tuple, or unreadable child attribution with no tuple) | Stops | Stops |
58
58
  | Dispatch returns an async handle despite `async: false` | Stops | Stops |
59
59
 
60
- A budget reply does not supply a missing escalation model. A reopened row already at allowance takes the row stop under either option; option 5 keeps verify active without a phase reset. Resume's admission question lists commits and dirt and explains that answering `interrupted` discards them through reset to the pre-dispatch HEAD and `clean -fd`. See [loop stop boundaries](doc/configuration.md#loop-stop-boundaries) for the reply and continuation details.
60
+ A budget reply does not supply a missing escalation model. A reopened row already at allowance takes the row stop with or without amend permission; with amend permission, verify stays active without a phase reset. Resume's admission question lists commits and dirt and explains that answering `interrupted` discards them through reset to the pre-dispatch HEAD and `clean -fd`. See [loop stop boundaries](doc/configuration.md#loop-stop-boundaries) for the reply and continuation details.
61
61
 
62
62
  4. **verify**: the parent first runs the plan's full verification command set for waves, or the ledger gate set for loop; only a passing result permits whole-diff code review, then the **conformance gate**. A review fix invalidates that result, so the parent reruns the same set before the next review or conformance gate. Loop conformance repairs and finish also use the gate set, never the ledger's full `verification:` command. When the overrides file declares a happy path for the touched paths (see [Project-specific overrides](#project-specific-overrides)), the parent runs it once here, between code review and the conformance gate, and the reviewer reads its transcript as runtime evidence - a hang or a failed request shows up in the audit with the transcript quoted - as a gap when an origin clause ties to it, otherwise as a `happy-path: failed - unattributable` line - never as a silent green. The conformance subagent reads the finished code and docs against your *original words* from step 1, not the plan, and reports per-requirement: delivered, partial, missing, drifted, or unauthorized. Unauthorized rows - shipped surface no human input asked for, whether it crept in or was laundered through the spec - follow their recommendation like every other row: a contained removal auto-runs, anything another requirement leans on is deferred with a plain-language "I'd cut it / I'd keep it" recommendation. Inside a brainstorming-entered flow this gate is machine-blocked from being skipped. Compatible executable recommendations auto-run through an isolated fix-and-re-audit loop with no prompt; anything still open surfaces as a numbered decision brief - one item per decision, the problem in plain words first, lettered options each with a one-line consequence, and `Recommended: <letter> - <reason>` or `No recommendation - pick one`. Reply with one line per item (`1. B`), or bare `1` to take every recommendation (no-recommendation items are re-asked by number); a current `CONFORMS` / no-concerns result goes straight to the branch options with no extra conformance sign-off.
63
63
  5. **`finishing-a-development-branch`**: PR, draft PR, squash, keep, or discard; PR rework's row 1 offers a lease push of the rebased home branch to the existing PR (`Base:` records in `merge:` form push non-force). A spec whose header carries `**PR:**` (approved at a spec-PR re-gate) and no `## Rework record` replaces the two create rows with `Push to PR #N and mark it ready for review` and `Push to PR #N, keep it a draft` (`Push to PR #N (already ready for review)` when the PR is already ready): both push without force after strip-and-seal, the first then runs `gh pr ready`, neither rewrites the PR body, and both are withheld when origin's branch head is no longer an ancestor of local HEAD. For coordinated specs, these [header-linked rows 1/2](skills/finishing-a-development-branch/reference/spec-pr.md#push-rows-12) deliver companions in recorded order before one home seal carrying every companion PR URL, then push home and apply its readiness choice. Row 1 makes companion drafts ready too; row 2 creates drafts but never converts an already-ready PR back to draft. Companion URLs appear in the shipped summary, companions first and home last, not in the unchanged home PR body; keep that summary for cross-repo review because successful home delivery removes receipts. A spec still carrying `**Engine:** deferred` stops finishing (and `gauntlet-resume`) with `spec approved for handoff only - run brainstorming #N` before any phase change, verification, or push. The PR-rework push appends a `## Rework` block naming absorbed PRs while retaining the original description bytes; the header-linked `**PR:**` push leaves the body untouched. Only after a successful rework push and home-description edit does one gated confirmation show the exact close comments and eligible member targets, linking home; declining or any other finish option leaves members open. Closing never deletes member branches, and finish posts no review-thread replies. Its `Before:` handle includes the full portable pre-rework SHA and the local `refs/gauntlet/pre-rework/pr-<N>` ref in the rework checkout. The [finishing owner](skills/finishing-a-development-branch/SKILL.md#pr-subject-row-1-push-to-the-pr-branch) defines the landing and body-update contract. Once a PR exists, run `/skill:gatekeep-pr <pr>` to verify it before merging - it judges the diff against the spec at the PR's head (the acceptance-criteria dispositions and Design you approved; the PR description when no spec applies) - rows the spec defers or deviates are settled, every other row needs its mechanism (code, tests, docs) - and against the rubric; whatever can be seen only after merge is left to step 6. **Human gate 2** - the only other decision you make.
@@ -72,7 +72,7 @@ flowchart LR
72
72
  T -.-> R
73
73
  B --> G1{{human gate 1:<br/>approve spec}}
74
74
  G1 --> P[plan]
75
- G1 -.option 6.-> H[draft spec PR]
75
+ G1 -.row 4.-> H[draft spec PR]
76
76
  H -.brainstorming re-entry.-> G1
77
77
  P --> I[implement<br/>waves + reviews]
78
78
  I --> V[verify]
@@ -89,7 +89,7 @@ In create mode, `shape-ticket` runs one bounded overlap check after clarificatio
89
89
 
90
90
  Use `/skill:shape-ticket --skip-overlap <ask>` to bypass discovery explicitly. Repair mode never discovers candidates. Bypass still retains source reads, known conflicts, integrity checks, roast, approval, and source revalidation. Incomplete search coverage is disclosed, not treated as proof of no overlap; independent sessions can still race, so this is not a uniqueness guarantee.
91
91
 
92
- Between gate 1 and gate 2, both engines take named authorized recommendations under the spec's amend grant and run one bounded escalated execution round before eligible stops; exhausted allowances, cap and admission failures, waves stagnation and redraws still stop, and budget-only grants supply no amend permission. Planning takes concrete baseline `narrow` or `amend` recommendations under that permission; `fix-first` enters ticket shaping's own gate. An implementer-evidenced text correction to a drafted AC is an amendment, not a redraw; ticket rows, row add/remove and problem or component boundary changes still require redraw approval. See [execution continuation](doc/implement-engines.md#stops-models-and-telemetry). Once gate 1 picks an engine, task breakdown, implementation and reviews proceed within those limits; option 6 parks the approved spec in a draft PR and planning starts only when someone runs `brainstorming #N` on it and approves at the re-gate. Changing an approved spec later goes through brainstorming's `Amending an approved spec`: a fresh-context reviewer clears evidence-backed factual corrections on its own, escalations reach you as one readable batch, and only a redraw is a full stop - not a third numbered gate. That's the mechanism. What follows is the machinery behind it.
92
+ Between gate 1 and gate 2, both engines take named authorized recommendations under the spec's amend grant and run one bounded escalated execution round before eligible stops; exhausted allowances, cap and admission failures, waves stagnation and redraws still stop, and budget-only grants supply no amend permission. Planning takes concrete baseline `narrow` or `amend` recommendations under that permission; `fix-first` enters ticket shaping's own gate. An implementer-evidenced text correction to a drafted AC is an amendment, not a redraw; ticket rows, row add/remove and problem or component boundary changes still require redraw approval. See [execution continuation](doc/implement-engines.md#stops-models-and-telemetry). Once gate 1 picks an engine, task breakdown, implementation and reviews proceed within those limits; row 4 parks the approved spec in a draft PR and planning starts only when someone runs `brainstorming #N` on it and approves at the re-gate. Changing an approved spec later goes through brainstorming's `Amending an approved spec`: a fresh-context reviewer clears evidence-backed factual corrections on its own, escalations reach you as one readable batch, and only a redraw is a full stop - not a third numbered gate. That's the mechanism. What follows is the machinery behind it.
93
93
 
94
94
  ### Multi-repo runs
95
95
 
@@ -99,7 +99,7 @@ The approved home spec records `## Legs`, including each leg's scope, rules and
99
99
 
100
100
  Home overrides and settings govern flow policy. Each leg's own overrides and settings govern checkout operations, directories and verification; absent configuration uses defaults. Recorded `contract:` lines are authoritative for every spec with `## Legs`, including one-member runs: amend the home block and affected companion file before using a changed contract. Finish does not replace them by rereading overrides. Legacy specs without `## Legs` are home-only and retain the finish-time reread.
101
101
 
102
- Option 6's draft-PR handle is one home draft PR plus companion branches on origin, with no brief, companion PRs or receipts. `brainstorming #N` preflights every recorded companion before provisioning them from origin and re-gating under the [publication and re-gate contract](skills/brainstorming/reference/spec-pr.md). Cleanup runs companions first, then home, removing owned trees and deleting local branches only after a live remote equality check and confirmed removal; each leg reports its read-back state even when another cleanup fails. This supersedes the kept-local-branch cleanup in the [spec-only draft-PR design](doc/specs/2026-10-28-spec-only-draft-pr.md); a remote branch deleted after handoff now needs restoration from a clone that still has it, not the cleaned-up machine. PR lists still take the rework path. The separate `gauntlet-handoff` / `gauntlet-resume` route carries every member in the brief's `legs:` block. Resume starts only from the home primary, validates companion repository, branch and home pointer, and announces per-leg HEAD and dirty drift. On that route a missing companion worktree requires a live-validated completion receipt; draft-PR re-entry instead uses the published origin branch. The [brief contract](skills/gauntlet-resume/reference/brief-contract.md#coordinated-brief-grammar) owns the brief grammar and admission rules.
102
+ Row 4's draft-PR handle is one home draft PR plus companion branches on origin, with no brief, companion PRs or receipts. `brainstorming #N` preflights every recorded companion before provisioning them from origin and re-gating under the [publication and re-gate contract](skills/brainstorming/reference/spec-pr.md). Cleanup runs companions first, then home, removing owned trees and deleting local branches only after a live remote equality check and confirmed removal; each leg reports its read-back state even when another cleanup fails. This supersedes the kept-local-branch cleanup in the [spec-only draft-PR design](doc/specs/2026-10-28-spec-only-draft-pr.md); a remote branch deleted after handoff now needs restoration from a clone that still has it, not the cleaned-up machine. PR lists still take the rework path. The separate `gauntlet-handoff` / `gauntlet-resume` route carries every member in the brief's `legs:` block. Resume starts only from the home primary, validates companion repository, branch and home pointer, and announces per-leg HEAD and dirty drift. On that route a missing companion worktree requires a live-validated completion receipt; draft-PR re-entry instead uses the published origin branch. The [brief contract](skills/gauntlet-resume/reference/brief-contract.md#coordinated-brief-grammar) owns the brief grammar and admission rules.
103
103
 
104
104
  One finish choice spans all legs. PR, draft PR and squash deliver companions in declaration order, then seal and deliver home; keep preserves all legs, and discard lists all legs before one confirmation. Verification and conformance run per leg; home's passing tests do not credit companions. Delivery failure stops without rollback and reports shipped and unshipped legs. A retry from the brief validates home-owned receipts and skips only proven deliveries; stale PR heads are updated, and failed post-squash verification reruns without another squash. See the [delivery and recovery contract](skills/finishing-a-development-branch/reference/legs.md).
105
105
 
@@ -121,7 +121,7 @@ Non-final `stop` removes an eligible tracked-clean, non-primary worktree, create
121
121
 
122
122
  pi-gauntlet ships three kinds of pieces, layered on top of pi-cohort's dispatch:
123
123
 
124
- - **22 skills** - the workflow logic. Sixteen activate automatically when pi sees the matching kind of task, and the workflow skills chain through their gates: `shape-ticket` (creates one tracker issue or repairs a comma/whitespace list of refs against a Context/Problem/Idea/Acceptance-Criteria template, with a grounded repo audit, an AC integrity check, a cheap council roast, and sequential per-ticket exact-diff write confirmations; model-invocable so other skills and commands can route "file a ticket" to it, the gate still needs your yes), `gatekeep-pr` (model-invocable on an explicit ask that names the PR and the verb; the gates still need your selection - is consent-gated pre-merge verification of a PR against the scope contract at its head - the approved spec's acceptance-criteria dispositions and Design when the PR carries one, else the PR's stated intent; the ticket is cross-checked, never judged here (`check-delivery` owns it) - read-only gathering, verification evidence resolved CI-first (green checks on the exact assessed head count as evidence; a pending commit status that GitHub does not report as blocking the gating actor (`mergeStateStatus` not `BLOCKED`) is not waited for - external-CI commit statuses included - while a running Actions check and an unknown merge state still withhold; a viewer GitHub reports as a ruleset bypass actor merges a `BLOCKED` PR on the ordinary `merge` row with CI evidence still binding and all other merge preconditions unchanged; false or unreadable bypass eligibility keeps `BLOCKED` withheld, and live non-admin bypass behavior remains unverified; the project's verification command runs only as fallback), a rubric-based review, a three-part plain-language report (change and scope, standing and problems, then recommendation) and action, final and post menus whose rows derive from the actor's permissions on the PR; nothing mutates (repairs, pushes, reviews, merges, tracker comments) until you pick a course or terminal row, except the opt-in `--rebase [base]` sync that rebases, reviews, and lease-pushes the head before verification, or holds the rebased head locally when a conflict stop's scoped tests fail, so a selected delivery course resolves it before the lease push; after your own merge one post menu offers drafted replies, ticket and PR copies of `AC coverage`, guarded checkout cleanup and separate `## cleanup` items; row 1 combines the runnable steps except duplicate PR coverage when ticket coverage is included, each step keeps its own row, and the run ends after the selected set finishes; approved and closed-PR states use the same post menu with their eligible steps - run it with `/skill:gatekeep-pr [<pr>] [--rebase [base]]` (no argument: your open PRs)), `check-delivery` (model-invocable on an explicit ask that names the ticket and the verb; the gates still need your selection - is a post-merge detective control: proves an issue actually shipped (default-branch landing, delivery target, per-AC evidence) before its tracker status advances; it never writes a terminal status - run it with `/skill:check-delivery <ref>` or, in pi, `/skill:check-delivery #12 #15` for fresh parallel verification and one gate and write per ticket in turn), `writing-plans`, `roasting-the-spec`, `test-driven-development`, `subagent-driven-development`, `loop-implementation` (the plan-free implement driver that iterates a fresh `loop-implementer` over the spec's acceptance-criteria ledger when approval picks the loop engine), `dispatching-parallel-agents`, `verification-before-completion`, `requesting-code-review`, `receiving-code-review`, `using-git-worktrees`, `finishing-a-development-branch`, `forge-skill`, `linear` (reads/searches/comments on/manages Linear tickets via the `linearis` CLI; owns all linearis mechanics and the `## Issue tracker` overrides schema; tracker-facing skills route to it). Six more require explicit entry (`disable-model-invocation: true`): `brainstorming` starts the gated workflow on explicit consent - use `/skill:brainstorming` for reliable discovery, or opt in through reachable explicit prose or a human-selected handoff; after spec approval, downstream planning and implementation still chain automatically. `chase-bug` is human-only bug triage: read-only root-cause discovery to an evidenced verdict menu (real bug -> ticket/brainstorm/hotfix/respond; five negative verdicts), then a gated response to the reporter for addressable origins (GitHub issue / tracker ticket) and a rendered verdict summary otherwise - it never fixes during triage; the hotfix row hands off to `skills/chase-bug/hotfix.md` after the menu - run it with `/skill:chase-bug`. `housekeeping` checks a directory, uncommitted files, or a PR against repository rules, then waits through one card per issue class before acting: directory fixes open separate PRs, uncommitted fixes stay in place, and PR fixes are committed and pushed to that PR; tickets are offered only for directories - run `/skill:housekeeping [<directory> | <pr>]` in the primary checkout on the default branch with no gauntlet flow active. `gauntlet-performance` reads the committed run telemetry (current repo by default, `--dir <path>` adds others) through the parse-only `gauntlet-performance` CLI and answers with one example-led recommendation, 3-5 cornerstone numbers, a council assessment when available, and a menu of at most three actions (render a report file, open the recommendation as a ticket via `shape-ticket`, drill into one run); it writes nothing unless you pick render - run it with `/skill:gauntlet-performance [--dir <path>]... [--since <version>]`. `gauntlet-handoff` ends a session whose flow a fresh session will continue: it invokes pi-cohort's `handoff` skill (`--out <path>` or `--key <name>`, default key = the run worktree's branch with `/` flattened to `-`, default file `<tmpdir>/pi-handoff/<key>.md`), then appends the gauntlet process-state section (phase/plan tracker status) per the shared contract `skills/gauntlet-resume/reference/brief-contract.md` - run it with `/skill:gauntlet-handoff [--out <path> | --key <name>]`. `gauntlet-resume` is the only way back into an interrupted flow from a fresh session: it takes a `gauntlet-handoff` brief (a file path, pasted text, or - with no arguments - a pick from the briefs under `<tmpdir>/pi-handoff/`), a bare worktree that already holds a spec, or a spec tracked on main under a configured spec dir (a spec seed: it creates or reuses the worktree through `using-git-worktrees` and pins the spec), restores phase/plan tracker state through the legal arming sequence (`start brainstorm`, `skip` with `resume:` reasons, `plan_check` before implement-or-later), and never infers approval from artifacts - run it with `/skill:gauntlet-resume [<brief-file> | <spec>.md | <worktree-name-or-path>]`.
124
+ - **22 skills** - the workflow logic. Sixteen activate automatically when pi sees the matching kind of task, and the workflow skills chain through their gates: `shape-ticket` (creates one tracker issue or repairs a comma/whitespace list of refs against a Context/Problem/Idea/Acceptance-Criteria template, with a grounded repo audit, an AC integrity check, a cheap council roast, and sequential per-ticket exact-diff write confirmations; model-invocable so other skills and commands can route "file a ticket" to it, the gate still needs your yes), `gatekeep-pr` (model-invocable on an explicit ask that names the PR and the verb; the gates still need your selection - is consent-gated pre-merge verification of a PR against the scope contract at its head - the approved spec's acceptance-criteria dispositions and Design when the PR carries one, else the PR's stated intent; the ticket is cross-checked, never judged here (`check-delivery` owns it) - read-only gathering, verification evidence resolved CI-first (green checks on the exact assessed head count as evidence; a pending commit status that GitHub does not report as blocking the gating actor (`mergeStateStatus` not `BLOCKED`) is not waited for - external-CI commit statuses included - while a running Actions check and an unknown merge state still withhold; a viewer GitHub reports as a ruleset bypass actor merges a `BLOCKED` PR on the ordinary `merge` row with CI evidence still binding and all other merge preconditions unchanged; false or unreadable bypass eligibility keeps `BLOCKED` withheld, and live non-admin bypass behavior remains unverified; the project's verification command runs only as fallback), a rubric-based review, a three-part plain-language report (change and scope, standing and problems, then recommendation) and action, final and post menus whose rows derive from the actor's permissions on the PR; nothing mutates (repairs, pushes, reviews, merges, tracker comments) until you pick a course or terminal row, except the opt-in `--rebase [base]` sync that rebases, reviews, and lease-pushes the head before verification, or holds the rebased head locally when a conflict stop's scoped tests fail, so a selected delivery course resolves it before the lease push; after your own merge one post menu offers drafted replies, ticket and PR copies of `AC coverage`, guarded checkout cleanup and separate `## cleanup` items; row 1 combines the runnable steps except duplicate PR coverage when ticket coverage is included, each step keeps its own row, and the run ends after the selected set finishes; approved and closed-PR states use the same post menu with their eligible steps - run it with `/skill:gatekeep-pr [<pr>] [--rebase [base]]` (no argument: your open PRs)), `check-delivery` (model-invocable on an explicit ask that names the ticket and the verb; the gates still need your selection - is a post-merge detective control: proves an issue actually shipped (default-branch landing, delivery target, per-AC evidence) before its tracker status advances; it never writes a terminal status - run it with `/skill:check-delivery <ref>` or, in pi, `/skill:check-delivery #12 #15` for fresh parallel verification and one gate and write per ticket in turn), `writing-plans`, `roasting-the-spec`, `test-driven-development`, `subagent-driven-development`, `loop-implementation` (the plan-free implement driver that iterates a fresh `loop-implementer` over the spec's acceptance-criteria ledger when approval picks the loop engine), `dispatching-parallel-agents`, `verification-before-completion`, `requesting-code-review`, `receiving-code-review`, `using-git-worktrees`, `finishing-a-development-branch`, `forge-skill`, `linear` (reads/searches/comments on/manages Linear tickets via the `linearis` CLI; owns all linearis mechanics and the `## Issue tracker` overrides schema; tracker-facing skills route to it). Six more require explicit entry (`disable-model-invocation: true`): `brainstorming` starts the gated workflow on explicit consent - use `/skill:brainstorming` for reliable discovery, or opt in through reachable explicit prose or a human-selected handoff; after spec approval, downstream planning and implementation still chain automatically. `chase-bug` is human-only bug triage: read-only root-cause discovery to an evidenced verdict menu (real bug -> ticket/brainstorm/hotfix/respond; five negative verdicts), then a gated response to the reporter for addressable origins (GitHub issue / tracker ticket) and a rendered verdict summary otherwise - it never fixes during triage; the hotfix row hands off to `skills/chase-bug/hotfix.md` after the menu - run it with `/skill:chase-bug`. `housekeeping` checks a directory, uncommitted files, unpushed commits, or a PR against repository rules. With no argument, it checks uncommitted files when the checkout has changes (including untracked files), otherwise files changed across commits ahead of `origin/<default>`. A dirty run reports commits ahead of the unfetched local ref as not checked. A clean run fetches first and refuses divergent history, HEAD held by a remote-tracking ref, or a delivery receipt naming HEAD as its squash. It waits through one card per issue class before acting: directory fixes open separate PRs, uncommitted fixes stay in place, and PR fixes are committed and pushed to that PR; tickets are offered only for directory content findings. An unpushed run on a clean checkout folds accepted fixes into the last unpushed commit in the primary checkout, keeps its message unchanged, and pushes nothing. Spec and plan folders skip content checks; fully superseded specs get one Delete-or-Keep card, never Ticket - run `/skill:housekeeping [<directory> | <pr>]` in the primary checkout on the default branch with no gauntlet flow active. `gauntlet-performance` reads the committed run telemetry (current repo by default, `--dir <path>` adds others) through the parse-only `gauntlet-performance` CLI and answers with one example-led recommendation, 3-5 cornerstone numbers, a council assessment when available, and a menu of at most three actions (render a report file, open the recommendation as a ticket via `shape-ticket`, drill into one run); it writes nothing unless you pick render - run it with `/skill:gauntlet-performance [--dir <path>]... [--since <version>]`. `gauntlet-handoff` ends a session whose flow a fresh session will continue: it invokes pi-cohort's `handoff` skill (`--out <path>` or `--key <name>`, default key = the run worktree's branch with `/` flattened to `-`, default file `<tmpdir>/pi-handoff/<key>.md`), then appends the gauntlet process-state section (phase/plan tracker status) per the shared contract `skills/gauntlet-resume/reference/brief-contract.md` - run it with `/skill:gauntlet-handoff [--out <path> | --key <name>]`. `gauntlet-resume` is the only way back into an interrupted flow from a fresh session: it takes a `gauntlet-handoff` brief (a file path, pasted text, or - with no arguments - a pick from the briefs under `<tmpdir>/pi-handoff/`), a bare worktree that already holds a spec, or a spec tracked on main under a configured spec dir (a spec seed: it creates or reuses the worktree through `using-git-worktrees` and pins the spec), restores phase/plan tracker state through the legal arming sequence (`start brainstorm`, `skip` with `resume:` reasons, `plan_check` before implement-or-later), and never infers approval from artifacts - run it with `/skill:gauntlet-resume [<brief-file> | <spec>.md | <worktree-name-or-path>]`.
125
125
  - **11 subagent personas** - the specialized child agents the skills dispatch via pi-cohort: `implementer`, `loop-implementer`, `wave-reviewer`, `conformance-reviewer`, `spec-summarizer`, `plan-writer`, `spec-council-member`, `spec-council-synthesizer`, `spec-council-applier`, `pr-gatekeeper`, `delivery-checker`. See [doc/personas.md](./doc/personas.md) for what each one does and why its permissions are scoped the way they are.
126
126
  - **4 runtime extensions** - the enforcement layer. `plan-tracker` and `phase-tracker` are tools skills call to track progress (with a TUI widget); `verify-before-ship` is a hook that warns if you push or open a PR without a passing test run since your last edit (expected when a loop gate set does not match its patterns; the scoped `Verification:` line answers it, not a full local run); a phase-tracker flow guard reminds on implement-phase commits missing spec/code review. Both engines use the tracker: waves manages plan tasks, while loop calls `plan_tracker refresh` to project ledger rows and preserve conformance tasks. Loop implement completes when every row is closed, then verify step 1 runs the ledger's gate set in the owning checkouts. In a brainstorming-entered flow, phase-tracker rejects `implement` or `verify` completion while tracker tasks remain pending or in progress; see [its configuration reference](./doc/configuration.md#phase-tracker). phase-tracker also registers `plan_check`, which verifies a plan against its spec and against the grammar in [skills/writing-plans/reference/plan-contract.md](./skills/writing-plans/reference/plan-contract.md), including that each task's `Tests:` commands are selective and never the full suite, and that every test command carries a passing base-commit result; a pass stamps the plan and spec content hashes for implementation and returns a bounded task manifest; see the [manifest contract and size limit](./doc/configuration.md#phase-tracker). `telemetry` publishes YAML records on the `refs/telemetry/records` ref, outside the product diff: one sealed brainstorming run plus one session leg per settled `shape-ticket`, `gatekeep-pr` or `check-delivery` invocation. In-progress runs live in Git common-dir metadata; `gauntlet-telemetry-seal` publishes before landing without changing checkout HEAD or index. Publication failure warns without blocking ship; plain jj keeps local metadata and reports no Git remote. A fetched shipped record blocks a brainstorm `write` into that spec. See [the record layout, settings and migration guide](./doc/configuration.md#telemetry). See [doc/configuration.md](./doc/configuration.md) for the settings each one reads. `phase_tracker`, `plan_check`, and `plan_tracker` are model-only (not callable from codemode scripts) because their state is rebuilt from transcript tool results, which nested calls do not persist.
127
127
 
@@ -145,7 +145,7 @@ Run by a human against pi-cohort >= 7.1.0, before a pi-gauntlet release claims t
145
145
  6. Primary session, idle trackers, spec tracked on main: `/skill:gauntlet-resume doc/specs/<x>.md` creates the worktree and asks the approval question; approval leaves `phase_tracker` at plan in_progress with brainstorm `⊘ (resume: ...)`.
146
146
  7. Fresh idle session, same seed: the registered worktree is reused (no creation) and the question repeats. Run once on a consumer whose `## using-git-worktrees` override lays worktrees out as sibling dirs, once on `.worktrees/`.
147
147
  8. After writing-plans commits the plan beside the seeded spec: `/skill:gauntlet-handoff` then a fresh `/skill:gauntlet-resume <brief>` restores plan phase; a fresh `/skill:gauntlet-resume <worktree>` reaches "Spec with plan" with task evidence from the plan commit.
148
- 9. Spec approved with `2`, then `/skill:gauntlet-handoff` and a fresh `/skill:gauntlet-resume <brief>`: the closing line is followed by `Standing grant active: <sentence>` and the next amend batch applies without a menu. A spec approved with `1` prints `No standing grant.`; a spec with two `**Amend-grant:**` lines stops before any tracker call, naming both lines.
148
+ 9. Spec approved with `2`, then `/skill:gauntlet-handoff` and a fresh `/skill:gauntlet-resume <brief>`: the closing line is followed by `Standing grant active: <sentence>` and the next amend batch applies without a menu. A spec approved with `1 --amends-stop` prints `No standing grant.`; a spec with two `**Amend-grant:**` lines stops before any tracker call, naming both lines.
149
149
 
150
150
  ## Key concepts
151
151
 
@@ -166,7 +166,7 @@ Run by a human against pi-cohort >= 7.1.0, before a pi-gauntlet release claims t
166
166
  ## Requirements
167
167
 
168
168
  - [pi-coding-agent](https://github.com/earendil-works/pi) >= 1.5.0 - supports model-only tracker exposure and sequential tracker execution, so updates persist as transcript tool results rather than nested calls.
169
- - [pi-cohort](https://github.com/jjuraszek/pi-cohort) >= 8.0.0 - required peer package, including binary-safe worktree patches; it also lets a persona with `subagent` in `tools:` start with inherited extensions ([pi-cohort #26](https://github.com/jjuraszek/pi-cohort/issues/26)), which multi-PR `gatekeep-pr` needs. 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.
169
+ - [pi-cohort](https://github.com/jjuraszek/pi-cohort) >= 8.1.0 - required peer package, including binary-safe worktree patches; it also lets a persona with `subagent` in `tools:` start with inherited extensions ([pi-cohort #26](https://github.com/jjuraszek/pi-cohort/issues/26)), which multi-PR `gatekeep-pr` needs. 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.
170
170
 
171
171
  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.
172
172
 
@@ -379,7 +379,7 @@ The gauntlet overrides file is the one place a repo tunes gauntlet's Markdown su
379
379
  | `## Capabilities` | shape-ticket | tool discovery | extends | tools, commands, env hosts available to ticket authoring |
380
380
  | `## Ticket wording` | shape-ticket | the shipped wording contract | overrides | ticket self-containment rules |
381
381
  | `## Response channels` | chase-bug | ask the user | overrides | where bug responses are posted |
382
- | `## housekeeping` | housekeeping | shipped base rules and steps | extends | prose adding rules, path scopes/skips, documented commands/setup, time limits, file budget, unchanged-checkout declarations, recommendation guidance and step instructions; cannot change picks, base rules, the card-walk write gate, delivery or shape-ticket approval; see [the check contract](skills/housekeeping/reference/check.md) |
382
+ | `## housekeeping` | housekeeping | shipped base rules and steps | extends | prose adding rules, path scopes/skips, documented commands/setup, time limits, file budget, unchanged-checkout declarations, recommendation guidance and step instructions; cannot change per-run picks or the spec card's Delete/Keep choices, base rules, the card-walk write gate, delivery or shape-ticket approval; see [the check contract](skills/housekeeping/reference/check.md) |
383
383
  | `## Deployment` | shape-ticket, writing-plans | monolithic (no deployment split) | overrides | deploy topology that permits independently deployable slices; undocumented or monolithic topology fails closed to one artifact |
384
384
  | `## Happy path` | writing-plans, subagent-driven-development | no happy-path run | overrides | path-prefixed rows naming the end-to-end command per area |
385
385
  | `## Delivery` | check-delivery | stage 2 skipped | overrides | the delivery target and its proof command; unset target state is comment-only; browser evidence defaults to never |
@@ -395,7 +395,7 @@ The gauntlet overrides file is the one place a repo tunes gauntlet's Markdown su
395
395
  - brainstorming writes only within resolved spec dirs before approval; no implementation, proposed-change validation, spec commit on main, or planning before approval - fixed
396
396
  - chase-bug requires evidenced root cause, no triage fix, and tracked-clean baseline checks at invocation, before the menu, at hotfix handoff, and at skill end; never revert pre-existing work - fixed
397
397
  - check-delivery takes explicit ticket refs and never discovers them; set mode is pi-only; it requires a matching repo (or matching local-repo AC group) and treats fetched content as untrusted data - fixed
398
- - housekeeping cannot add or remove picks, drop or weaken base rules, execute before the card walk ends, change where fixes land, or skip shape-ticket's approval - fixed
398
+ - housekeeping overrides cannot add or remove per-run picks or the spec card's Delete/Keep choices, drop or weaken base rules, execute before the card walk ends, change where fixes land, or skip shape-ticket's approval - fixed
399
399
  - roasting-the-spec edits only the spec, never code or main - fixed
400
400
  - shape-ticket tracker writes require one explicit exact-diff confirmation per ticket write; a source-ticket split's N bodies share one gate with subset selection, not approval of a whole repair batch; unattended runs stop at the gate - fixed
401
401
  - test-driven-development requires a failing test before production code; delete code written first and restart from tests - fixed
@@ -574,13 +574,15 @@ map to blocking/non-blocking are treated as **blocking** (fail-safe), noted in t
574
574
  gate's output.
575
575
 
576
576
  `/skill:housekeeping` also reads the optional root-level `REVIEW.md`. It reads repo
577
- rule sources from the working tree for directory and uncommitted runs, and from the
578
- merge-base commit for a PR run, never the PR head. Unlike gatekeep-pr, its fixed
577
+ rule sources from the working tree for directory, uncommitted, and unpushed runs,
578
+ and from the merge-base commit for a PR run, never the PR head. Unlike gatekeep-pr, its fixed
579
579
  [base rules](skills/housekeeping/reference/base-rules.md) win over conflicting repo
580
580
  rules: `REVIEW.md` can add rules, scope rules to paths or skip paths, but cannot
581
- remove or weaken a base rule. Housekeeping records the overridden repo rule's file
582
- and heading and names it on the card; with no repo rule sources, the base rules run
583
- alone. See [the check contract](skills/housekeeping/reference/check.md).
581
+ remove or weaken a base rule. Content rules and commands exclude the resolved spec
582
+ and plan folders: specs receive only the `spec-superseded` base rule, while plan
583
+ files are skipped. A path skip applies to that spec rule too. Housekeeping records
584
+ the overridden repo rule's file and heading and names it on the card; with no repo
585
+ rule sources, the base rules run alone. See [the check contract](skills/housekeeping/reference/check.md).
584
586
 
585
587
  For gatekeep-pr, `REVIEW.md` is a diff over the baseline, not a full rewrite. Starter template:
586
588
 
@@ -635,7 +637,7 @@ Anything a wrapper skill contains beyond trigger phrases is misplaced - move it
635
637
 
636
638
  Settled skill-owned turns carry a machine-readable first line identifying a gate, question, or terminal outcome. Programs answering these turns use the [gate inventory and reply contract](doc/gate-contract.md); the rendered row bodies define valid replies.
637
639
 
638
- Choose experimental loop options 4/5, configure the per-row allowance and worker model, and operate the planless ledger through [Loop engine operations](doc/configuration.md#loop-engine-operations). The menu shows the resolved allowance; `; allowance N` overrides it for one run. Resume preserves an existing allowance or migrates a legacy cap after pending recovery. Waves remains the default.
640
+ Choose the loop engine with row 2, configure the per-row allowance and worker model, and operate the planless ledger through [Loop engine operations](doc/configuration.md#loop-engine-operations). Its `--allowance=N` flag shows the resolved default; `2 --allowance=6` sets six attempts per row for one run. Auto-apply amends is the default; add `--amends-stop` to retain amendment review. Resume preserves an existing allowance or migrates a legacy cap after pending recovery. Specs without an Engine header use waves.
639
641
 
640
642
  | Want to ... | Read |
641
643
  |---|---|
@@ -650,12 +652,12 @@ The conformance gate's model, the spec council's roster, and the phase-tracker's
650
652
  | `closureReview.enforce` | phase-tracker | `true` | conformance gate on/off - [detail](./doc/configuration.md#conformance-gate-model) |
651
653
  | `closureReview.model` | phase-tracker | unset (inherits) | conformance reviewer model - [detail](./doc/configuration.md#conformance-gate-model) |
652
654
  | `closureReview.maxFixRounds` | phase-tracker | `5` | fix rounds before escalation - [detail](./doc/configuration.md#conformance-gate-model) |
653
- | `escalationLoop.implModel` | phase-tracker | unset (main loop) | execution escalation under either loop option; review escalation remains separate - [detail](./doc/configuration.md#escalation-loop) |
654
- | `loopEngine.maxIterationsPerRow` | phase-tracker | `4` (floor `1`) | fresh-ledger per-row allowance; run override on approval 4/5 - [detail](./doc/configuration.md#setting-and-command-resolution) |
655
+ | `escalationLoop.implModel` | phase-tracker | unset (main loop) | execution escalation with or without amend permission; review escalation remains separate - [detail](./doc/configuration.md#escalation-loop) |
656
+ | `loopEngine.maxIterationsPerRow` | phase-tracker | `4` (floor `1`) | fresh-ledger per-row allowance; run override with `2 --allowance=N` - [detail](./doc/configuration.md#setting-and-command-resolution) |
655
657
  | `loopEngine.escalateAfter` | phase-tracker | `3` (floor `1`) | pre-dispatch threshold; escalated attempt index is value + 1, clamped to the last allowed attempt - [detail](./doc/configuration.md#setting-and-command-resolution) |
656
658
  | `phaseModels.plan` / `.implement` / `.verify` / `.ship` | phase-tracker | unset (no switch) | `provider/id[:level]` applied persistently at that phase's start - [detail](./doc/configuration.md#phase-models) |
657
659
  | `flowGuards.enforce` | phase-tracker | `true` | phase gates on/off - [detail](./doc/configuration.md#phase-tracker) |
658
- | `flowGuards.specDirs` | phase-tracker, plan-tracker; telemetry and spec-index consumers | `["doc/specs", "docs/specs"]` | where specs and sibling plans live - [detail](./doc/configuration.md#phase-tracker) |
660
+ | `flowGuards.specDirs` | phase-tracker, plan-tracker; telemetry, spec-index and housekeeping consumers | `["doc/specs", "docs/specs"]` | where specs and sibling plans live - [detail](./doc/configuration.md#phase-tracker) |
659
661
  | `verifyBeforeShip.testCommands` | verify-before-ship | the `DEFAULT_TEST_COMMANDS` patterns in `extensions/lib/gauntlet-settings.ts` (make, npm, pnpm, yarn, pytest, rspec, cargo, go) | patterns that count as a test run - [detail](./doc/configuration.md#verify-before-ship) |
660
662
  | `verifyBeforeShip.warningReference` | verify-before-ship | unset | pointer shown with the warning - [detail](./doc/configuration.md#verify-before-ship) |
661
663
  | `telemetry.enabled` | telemetry | `true` | record each flow - [detail](./doc/configuration.md#telemetry) |
@@ -586,6 +586,53 @@ test("tracker registration is model-only and phase_tracker requests sequential e
586
586
  }
587
587
  });
588
588
 
589
+ for (const row of [
590
+ { name: "exactly 25 percent", read: () => ({ tokens: 250000, contextWindow: 1000000, percent: 0 }), expected: "25.0% of window" },
591
+ { name: "just above 25 percent", read: () => ({ tokens: 250001, contextWindow: 1000000, percent: 25 }), expected: "25.1% of window" },
592
+ { name: "exactly 26 percent", read: () => ({ tokens: 260000, contextWindow: 1000000, percent: null }), expected: "26.0% of window" },
593
+ { name: "zero tokens", read: () => ({ tokens: 0, contextWindow: 1000000, percent: 99 }), expected: "0.0% of window" },
594
+ { name: "fractional percentage", read: () => ({ tokens: 1, contextWindow: 3, percent: 33 }), expected: "33.4% of window" },
595
+ { name: "missing reader", read: undefined, expected: "unknown" },
596
+ { name: "no usage", read: () => undefined, expected: "unknown" },
597
+ { name: "null tokens", read: () => ({ tokens: null, contextWindow: 1000000, percent: null }), expected: "unknown" },
598
+ { name: "zero window", read: () => ({ tokens: 250000, contextWindow: 0, percent: 25 }), expected: "unknown" },
599
+ { name: "negative window", read: () => ({ tokens: 250000, contextWindow: -1, percent: 25 }), expected: "unknown" },
600
+ ]) {
601
+ test(`status context: ${row.name}`, async () => {
602
+ const h = harness();
603
+ const tool = h.tools.find(t => t.name === "phase_tracker")!;
604
+ const ctx = { ...h.ctx, getContextUsage: row.read };
605
+ const result = await tool.execute("status", { action: "status" }, undefined, undefined, ctx) as {
606
+ content: { text: string }[];
607
+ };
608
+ assert.equal(result.content.map(c => c.text).join("\n").split("\n").at(-1), `Context: ${row.expected}`);
609
+ });
610
+ }
611
+
612
+ for (const row of [
613
+ { name: "known", usage: { tokens: 1, contextWindow: 3, percent: 33 }, expected: "33.4% of window" },
614
+ { name: "unknown", usage: undefined, expected: "unknown" },
615
+ ]) {
616
+ test(`status context stays out of details, TUI and widget: ${row.name}`, async () => {
617
+ const state = phases({ brainstorm: "in_progress" });
618
+ const h = harness({ hasUI: true, branch: enteredBranch(state) });
619
+ Object.assign(h.ctx, { getContextUsage: () => row.usage });
620
+ await h.emit("session_start");
621
+ const widgetBefore = h.widgets.at(-1);
622
+ assert.match(widgetBefore!, /brainstorm/);
623
+ const tool = h.tools.find(t => t.name === "phase_tracker")! as any;
624
+ const result = await tool.execute("status", { action: "status" }, undefined, undefined, h.ctx);
625
+ assert.equal(result.content[0].text.split("\n").at(-1), `Context: ${row.expected}`);
626
+ assert.deepEqual(result.details, { action: "status", phases: state });
627
+ const rendered = tool.renderResult(result, {}, { fg: (_color: string, text: string) => text });
628
+ assert.match(rendered.text, /Phases:[\s\S]*brainstorm/);
629
+ assert.doesNotMatch(rendered.text, /Context:|of window/);
630
+ await h.emit("session_switch");
631
+ assert.equal(h.widgets.at(-1), widgetBefore);
632
+ for (const widget of h.widgets) assert.doesNotMatch(widget!, /Context:|of window/);
633
+ });
634
+ }
635
+
589
636
  test("all-complete plan activity auto-completes an active implement phase", async () => {
590
637
  const h = harness({ branch: implementBranch() });
591
638
  await h.emit("session_start");
@@ -1312,8 +1312,12 @@ export default function (pi: ExtensionAPI) {
1312
1312
  }
1313
1313
 
1314
1314
  case "status": {
1315
+ const usage = ctx.getContextUsage?.();
1316
+ const context = usage && usage.tokens !== null && usage.contextWindow > 0
1317
+ ? `${(Math.ceil(usage.tokens * 1000 / usage.contextWindow) / 10).toFixed(1)}% of window`
1318
+ : "unknown";
1315
1319
  return {
1316
- content: [{ type: "text", text: formatStatus(phases) }],
1320
+ content: [{ type: "text", text: `${formatStatus(phases)}\nContext: ${context}` }],
1317
1321
  details: { action: "status", phases: { ...phases } } as PhaseTrackerDetails,
1318
1322
  };
1319
1323
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-gauntlet",
3
- "version": "8.5.0",
3
+ "version": "8.6.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": ">=8.0.0"
65
+ "pi-cohort": ">=8.1.0"
66
66
  },
67
67
  "dependencies": {
68
68
  "yaml": "^2.9.0"
@@ -34,7 +34,7 @@ Treat the flag as discovery control, not harness authorization. The command reli
34
34
 
35
35
  ## Checklist
36
36
 
37
- Work through the items below **in order**. After a user answer or completed side task, resume the current checklist step and perform the next authorized action in the same turn, advancing once that step's required decisions and approvals are satisfied. Continue until a required question is unanswered, an existing approval is pending, the user explicitly pauses, or a failed required tool or unavailable required resource blocks progress. This is your own checklist to follow, not a `plan_tracker` plan - brainstorming is open-ended exploration, and `plan_tracker` is execution-only (the implement phase). The terminal state is the user review gate; after approval route 1/2 to `/skill:writing-plans` and 4/5 to `/skill:loop-implementation` per the gate; 6 ends the flow after publishing. Do not jump ahead of approval, and do not silently drop the critique pass.
37
+ Work through the items below **in order**. After a user answer or completed side task, resume the current checklist step and perform the next authorized action in the same turn, advancing once that step's required decisions and approvals are satisfied. Continue until a required question is unanswered, an existing approval is pending, the user explicitly pauses, or a failed required tool or unavailable required resource blocks progress. This is your own checklist to follow, not a `plan_tracker` plan - brainstorming is open-ended exploration, and `plan_tracker` is execution-only (the implement phase). The terminal state is the user review gate; after approval route 1 to `/skill:writing-plans` and 2 to `/skill:loop-implementation` per the gate; 4 ends the flow after publishing. Do not jump ahead of approval, and do not silently drop the critique pass.
38
38
 
39
39
  1. **Start brainstorm tracking (fresh epoch)** - as the first action on authorized fresh entry, before reading code, the worktree, or answering the user, reset both trackers and start the phase. A new brainstorm owns a clean slate, so stale phases and tasks from earlier work are cleared; re-entering mid-brainstorm is safe (nothing to lose, same clean slate):
40
40
 
@@ -55,7 +55,7 @@ Work through the items below **in order**. After a user answer or completed side
55
55
  10. **Re-run placeholder scan** - follow [Spec Self-Review](#spec-self-review-before-user-review-gate).
56
56
  11. **Generate spec summary** - follow [User Review Gate](#user-review-gate).
57
57
  12. **User review gate** - follow [User Review Gate](#user-review-gate).
58
- 13. **Transition** - after approval, invoke `/skill:writing-plans` on 1/2 or `/skill:loop-implementation` on 4/5 per [User Review Gate](#user-review-gate); 6 ends the flow after publishing.
58
+ 13. **Transition** - after approval, invoke `/skill:writing-plans` on 1 or `/skill:loop-implementation` on 2 per [User Review Gate](#user-review-gate); 4 ends the flow after publishing.
59
59
 
60
60
  ## Project Routing
61
61
 
@@ -168,7 +168,7 @@ Follow [Spec Council](reference/spec-finalization.md#spec-council) for the manda
168
168
 
169
169
  ## User Review Gate
170
170
 
171
- Follow [User Review Gate](reference/spec-finalization.md#user-review-gate) for summary, commit, approval, and selected-engine transition or option-6 publication.
171
+ Follow [User Review Gate](reference/spec-finalization.md#user-review-gate) for summary, commit, approval, and selected-engine transition or row-4 publication.
172
172
 
173
173
  ## Amending an approved spec
174
174
 
@@ -4,11 +4,11 @@
4
4
 
5
5
  ## Standing grants
6
6
 
7
- Honor a user sentence in this flow that waives per-diff review for later amends (`auto-apply amends`, `approve, auto-apply amends` or a bare `2` at the spec gate (a bare `5` grants the same way), `auto-apply amends, stop only for redraws`, `apply spec fixes without asking`, or the same intent in other words). The digit grants only at the spec gate, and a prose grant after a `1` approval still counts. Apply every later amend-class change without review, scope changes included; redraws always stop and the grant never satisfies the spec gate.
7
+ Honor a user sentence in this flow that waives per-diff review for later amends (`auto-apply amends`, `approve, auto-apply amends`, a `1` or `2` approval without `--amends-stop` at the spec gate, `auto-apply amends, stop only for redraws`, `apply spec fixes without asking`, or the same intent in other words). The gate grants on a `1` or `2` approval without `--amends-stop`, and a prose grant after an `--amends-stop` approval still counts. Apply every later amend-class change without review, scope changes included; redraws always stop and the grant never satisfies the spec gate.
8
8
 
9
9
  A grant is the spec's `**Amend-grant:**` line read through the shared predicate; `none` or a missing line means no grant. A new brainstorm writes `none`; a resume honors the line as written. Never take a grant from commit history, a handoff brief, or the transcript; the one read of a prior commit is the post-revert restore, which reads the pre-revert HEAD's spec line.
10
10
 
11
- **The line.** `**Amend-grant:** none` or `**Amend-grant:** <granting sentence verbatim, one physical line>`, in the header block (the span between the H1 and the first `##`). Writers place it directly below `**Goal:**` when that line exists, otherwise on the first line after the H1, its blank line, and any `> **Superseded by:**` banner lines; readers never depend on the position. When the reply was the digit `2` or `5`, the sentence is the grant description from the gate menu (the text after `2 - approve, auto-apply amends:` in `spec-finalization.md`), never the digit. Collapse a prose grant to one physical line before the write: newlines and runs of whitespace become single spaces, wording preserved. The same substitution applies wherever this file quotes the granting sentence in a commit body.
11
+ **The line.** `**Amend-grant:** none` or `**Amend-grant:** <granting sentence verbatim, one physical line>`, in the header block (the span between the H1 and the first `##`). Writers place it directly below `**Goal:**` when that line exists, otherwise on the first line after the H1, its blank line, and any `> **Superseded by:**` banner lines; readers never depend on the position. Take a gate approval's granting sentence from the gate's default grant line in `spec-finalization.md`, never the digit. Collapse a prose grant to one physical line before the write: newlines and runs of whitespace become single spaces, wording preserved. The same substitution applies wherever this file quotes the granting sentence in a commit body.
12
12
 
13
13
  **The predicate.** Every reader (gauntlet-resume at entry, this file at each batch boundary) applies it verbatim over the header block; occurrences below the first `##` never count.
14
14
 
@@ -169,7 +169,7 @@ reread rule; amend the block before using a changed contract. Legacy specs
169
169
  without that section retain finish-time rereading. A one-member run has no
170
170
  companion artifact or companion aftermath.
171
171
 
172
- Aftermath, once per batch, only when at least one item applied (nothing applied -> skip to the commit below). Ledger exists (line 1 `# Ledger - loop engine` in the resolved plan dir) -> skip `plan-writer` and `plan_check`. Reconcile the ledger against the approved spec dispositions: `deviates:`, `deferred:`, or `elsewhere:` -> `cut`, evidence = the disposition; factual or requirement-preserving amendment -> preserve rows; re-bounded `done` row -> `open`, evidence = `reopened by amendment`. Preserve every row's attempts and the ledger's iterations and allowance. Apply evidenced drafted-row text corrections as amend items while preserving row identity; retain the cut/reopen rules above. Ticket text and row add/remove changes remain redraws. Commit spec + ledger together with subject `loop: cut row <n>` for a batch containing only one cut, otherwise `loop: amend` (including mixed batches), carrying the amendment audit body below (including each `granted` record and granting sentence); after the commit, use the driver's next ledger-path refresh to project the new statuses and continue without task-plan aftermath. Keep task-plan `add`/`update`/`init` out of this route. Project `done -> cut` as `complete -> skipped` and a re-bound `done -> open` as `complete -> pending`; count neither as a reopen. During verify without amend permission, stop on a re-bound row with `Stopped: row <n> reopened by amendment during verify`; keep verify active and offer authorization to return that row to ledger implementation or stop. Under amend permission, continue without a second authorization. For the granted continuation or the option-4 authorization, apply the driver's `## Before each dispatch` boundaries, including exhausted-row rule 2, then apply `## Dispatch` through the driver's `## After the loop` step 3 one-task `tasks` continuation and `## Validate the return` (tuple, refresh, admission, refresh), keeping verify active with no phase reset; close the row on disk, then rerun the step 1 gate before verify continues. Never close it with `plan_tracker update`. No plan yet -> commit the spec; continue. Plan exists -> read `git -C "<abs worktree path>" status --porcelain` (plain jj: `jj -R "<abs worktree path>" diff --summary`); collect the parent's in-flight workflow edits as worktree-relative paths, including the amended spec and staged in-place wave-repair deliverables. Dispatch `plan-writer` per `writing-plans` `## Author the plan` step 3 with an `Amend:` block naming the amended spec sections, an `In-flight:` list of those paths (the parent supplies the set; the child never infers it), and the rule "preserve every task title and wave position the amendment does not touch; edit only affected anchors and tasks", then run that section's steps 5-6 (the parent `plan_check` and its branches).
172
+ Aftermath, once per batch, only when at least one item applied (nothing applied -> skip to the commit below). Ledger exists (line 1 `# Ledger - loop engine` in the resolved plan dir) -> skip `plan-writer` and `plan_check`. Reconcile the ledger against the approved spec dispositions: `deviates:`, `deferred:`, or `elsewhere:` -> `cut`, evidence = the disposition; factual or requirement-preserving amendment -> preserve rows; re-bounded `done` row -> `open`, evidence = `reopened by amendment`. Preserve every row's attempts and the ledger's iterations and allowance. Apply evidenced drafted-row text corrections as amend items while preserving row identity; retain the cut/reopen rules above. Ticket text and row add/remove changes remain redraws. Commit spec + ledger together with subject `loop: cut row <n>` for a batch containing only one cut, otherwise `loop: amend` (including mixed batches), carrying the amendment audit body below (including each `granted` record and granting sentence); after the commit, use the driver's next ledger-path refresh to project the new statuses and continue without task-plan aftermath. Keep task-plan `add`/`update`/`init` out of this route. Project `done -> cut` as `complete -> skipped` and a re-bound `done -> open` as `complete -> pending`; count neither as a reopen. During verify without amend permission, stop on a re-bound row with `Stopped: row <n> reopened by amendment during verify`; keep verify active and offer authorization to return that row to ledger implementation or stop. Under amend permission, continue without a second authorization. For the granted continuation or the human-authorized return, apply the driver's `## Before each dispatch` boundaries, including exhausted-row rule 2, then apply `## Dispatch` through the driver's `## After the loop` step 3 one-task `tasks` continuation and `## Validate the return` (tuple, refresh, admission, refresh), keeping verify active with no phase reset; close the row on disk, then rerun the step 1 gate before verify continues. Never close it with `plan_tracker update`. No plan yet -> commit the spec; continue. Plan exists -> read `git -C "<abs worktree path>" status --porcelain` (plain jj: `jj -R "<abs worktree path>" diff --summary`); collect the parent's in-flight workflow edits as worktree-relative paths, including the amended spec and staged in-place wave-repair deliverables. Dispatch `plan-writer` per `writing-plans` `## Author the plan` step 3 with an `Amend:` block naming the amended spec sections, an `In-flight:` list of those paths (the parent supplies the set; the child never infers it), and the rule "preserve every task title and wave position the amendment does not touch; edit only affected anchors and tasks", then run that section's steps 5-6 (the parent `plan_check` and its branches).
173
173
 
174
174
  At that return point, classify human-facing outcomes with this table; let writing-plans' first `Findings:` repair run as written.
175
175
 
@@ -32,7 +32,7 @@ Immediately after ordered admission and before binding, classify N=1 read-only.
32
32
  | Observation | Route |
33
33
  |---|---|
34
34
  | Shape fails | Pass the selected SYNC to provisioning. Continue unchanged through bind, gather, scout, and Rework record. |
35
- | Shape passes, marker absent | Force `SYNC=merge` for provisioning. Print `spec-only PR without the gate marker - running lint and council`. Provision the one-element admitted PR array through pr-head's checkout, base merge, and Step 4 report with no thread fetch (bypass its `## Fetch unresolved review threads` as on the marked route). Skip ticket binding, context-builder, the PR scout block, and gather; never write a `## Rework record`. Resume at checklist step 4 with the carried spec file at `<worktree>/<path>` as the draft, as a redraw does (recon falls to the questionary); spec-writing overwrites that file at its carried path. Run lint, council, and the gate as for any spec, with 6 withheld (`Withheld: draft PR - #N already exists`). On approval 1/2/4/5 persist `**Engine:**`, `**Amend-grant:**`, and `**PR:** <owner/repo#N>` as a new commit per spec-pr.md's re-gate persistence. |
35
+ | Shape passes, marker absent | Force `SYNC=merge` for provisioning. Print `spec-only PR without the gate marker - running lint and council`. Provision the one-element admitted PR array through pr-head's checkout, base merge, and Step 4 report with no thread fetch (bypass its `## Fetch unresolved review threads` as on the marked route). Skip ticket binding, context-builder, the PR scout block, and gather; never write a `## Rework record`. Resume at checklist step 4 with the carried spec file at `<worktree>/<path>` as the draft, as a redraw does (recon falls to the questionary); spec-writing overwrites that file at its carried path. Run lint, council, and the gate as for any spec, with 4 withheld (`Withheld: draft PR - #N already exists`). On approval 1/2 persist `**Engine:**`, `**Amend-grant:**`, and `**PR:** <owner/repo#N>` as a new commit per spec-pr.md's re-gate persistence. |
36
36
  | Shape and marker pass | Count carried `### Leg:` blocks under `## Legs` from the same `git show <headRefOid>:<path>` used for the marker, before home provisioning. Force `SYNC=merge`. Zero/one block keeps home-only pr-head checkout/base merge/Step 4. For observed N>1 blocks pass that coordinated marked context to pr-head's home base-sync recovery; malformed blocks missing repo, branch or contract stop naming the block and preserve home. Provision only the one-element admitted PR array, then follow spec-pr.md's re-gate and its coordinated settlement after home's Step 4. Skip binding and all before-gather thread queries. Treat draft and ready PRs equally. |
37
37
 
38
38
  ## Relatedness before provisioning