pi-gauntlet 4.3.1 → 4.4.1

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.
@@ -0,0 +1,117 @@
1
+ # Context Gather (brainstorming supplementary)
2
+
3
+ Consumed only by `SKILL.md` in this directory. Runs unconditionally between worktree
4
+ setup and the questionary. **Foreground, no user interaction** — the first thing the
5
+ operator sees after gather is questionary question one. Do not announce, do not ask.
6
+
7
+ ## Dispatch
8
+
9
+ Mint a temp dir outside the worktree (never committed):
10
+
11
+ ```bash
12
+ GATHER_DIR=$(mktemp -d)
13
+ ```
14
+
15
+ Set the substep, then dispatch one parallel-tasks `subagent` call (foreground — no
16
+ `async:`; no `model:` — pi-cohort `agentOverrides` owns builder models):
17
+
18
+ ```
19
+ phase_tracker({ action: "substep", phase: "brainstorm", substep: "gather" })
20
+ subagent({
21
+ tasks: [
22
+ { agent: "scout", cwd: "<abs worktree path>", phase: "context-gather",
23
+ output: "<GATHER_DIR>/scout.md",
24
+ task: "<scout task, template below>" },
25
+ // include ONLY when the trigger rule below fires:
26
+ { agent: "context-builder", cwd: "<abs worktree path>", phase: "context-gather",
27
+ output: "<GATHER_DIR>/external.md",
28
+ task: "<context-builder task, template below>" }
29
+ ]
30
+ })
31
+ ```
32
+
33
+ Absolute `output:` paths are mandatory: relative paths in parallel mode resolve
34
+ against the worktree and would get committed.
35
+
36
+ ## Task templates
37
+
38
+ Scout (always dispatched):
39
+
40
+ > Recon for an upcoming design discussion. The request: `<initial prompt verbatim>`.
41
+ > Map the territory this change touches: relevant files with line ranges, existing
42
+ > patterns and conventions the change must match, test conventions, integration
43
+ > points, and whether the codebase or ecosystem already solves any of this. Cite
44
+ > exact paths and line ranges. End with an "Open questions that matter for the spec"
45
+ > section. Compact handoff, not a dump.
46
+
47
+ Context-builder (conditional):
48
+
49
+ > Extract external context for an upcoming design discussion. The request:
50
+ > `<initial prompt verbatim>`. Fetch and distill these references:
51
+ > `<detected refs, one per line>`. For each: acceptance criteria, hard constraints,
52
+ > linked discussion that changes scope, and contradictions with the request as
53
+ > stated. Write ONLY the context handoff to your output path; do NOT produce a
54
+ > meta-prompt file. End with an "Open questions that matter for the spec" section.
55
+ > If a ref is unreadable, say so explicitly and continue.
56
+
57
+ (The meta-prompt exclusion matters: in chain mode context-builder emits two files —
58
+ `context.md` + `meta-prompt.md`; this flow consumes only the context handoff.)
59
+
60
+ ## Context-builder trigger rule
61
+
62
+ Dispatch context-builder when the initial prompt (or a file it explicitly references)
63
+ contains any of:
64
+
65
+ - an `http(s)://` URL;
66
+ - a tracker-style ID matching `[A-Z][A-Z0-9]+-\d+` (Linear/Jira form) **when a fetch
67
+ path exists** (a tracker tool/MCP, or a URL pattern in `.pi/gauntlet-overrides.md`);
68
+ - a GitHub-style ref `owner/repo#N`, or a bare `#N` when the repo's tracker is
69
+ GitHub Issues.
70
+
71
+ Examples: "implement ABC-123" with a Linear tool available → trigger; "add rate
72
+ limiting like https://example.com/rfc" → trigger; "rename the settings resolver" →
73
+ scout only. An opaque ID with **no** fetch path → do not dispatch; list it in the
74
+ draft's `## External context` as an unfetched ref instead of guessing.
75
+
76
+ ## Failure and degradation
77
+
78
+ A builder **failed** when its task errored **or** its output file is missing or
79
+ empty (0 bytes). Degradation never blocks and never surfaces to the user at gather
80
+ time:
81
+
82
+ - scout failed → `## Codebase recon` reads: `Scout recon failed (<one-line reason>).
83
+ Draft is thin; exploration falls to the questionary.` followed by the initial prompt.
84
+ - context-builder failed → `## External context` reads: `External refs not fetched
85
+ (<one-line reason>):` followed by the ref list — the critique pass later surfaces
86
+ them as external-ref candidates.
87
+
88
+ ## Draft assembly
89
+
90
+ Read the temp files and write the draft **to the spec path** (normal filename
91
+ convention; slug minted from the initial prompt):
92
+
93
+ ```markdown
94
+ # CONTEXT DRAFT - NOT A SPEC - fully replaced at spec-writing
95
+
96
+ ## Codebase recon
97
+ <scout output, or the degraded text>
98
+
99
+ ## External context
100
+ <context-builder output, degraded text, or unfetched-ref list; omit this section
101
+ only when the trigger rule never fired>
102
+
103
+ ## Appended during questionary
104
+ <starts empty>
105
+ ```
106
+
107
+ The marker line is **line 1, verbatim**. Then clean up and clear the substep:
108
+
109
+ ```bash
110
+ rm -rf "$GATHER_DIR"
111
+ ```
112
+
113
+ ```
114
+ phase_tracker({ action: "substep", phase: "brainstorm", substep: null })
115
+ ```
116
+
117
+ The questionary runs under plain `brainstorm`.
@@ -70,24 +70,61 @@ git merge-base HEAD main 2>/dev/null || git merge-base HEAD master 2>/dev/null
70
70
 
71
71
  Or ask: "This branch split from main - is that correct?"
72
72
 
73
- ### Step 3.5: Surface Closure / Conformance Status
73
+ ### Step 3.5: Closure / Conformance Disposition Gate
74
74
 
75
- Before presenting finish options, surface the closing-loop conformance result as **its own section** — the user is about to choose how to ship, and they need to see whether the deliverable matches what was *asked*, not just whether tests pass. Tests prove the code runs; conformance proves it does what was requested. Different gates.
75
+ This is an **enforced per-gap disposition gate**, not a surface-only notice. The user is about to choose how to ship; every carried-open gap must get an explicit disposition here, before Step 4's menu. Tests prove the code runs; conformance proves it does what was requested — different gates.
76
76
 
77
- - **If the execution flow already closed the loop** (the `conformance-reviewer` ran in the `subagent-driven-development` verify gate), restate its verdict here: `CONFORMS`, or the `GAPS` and how each was dispositioned (fixed / accepted-and-recorded-in-spec / rescoped). If any gap is still open, drive it through the remediation loop in `verification-before-completion/reference/conformance-check.md` "When the check finds gaps"; on a normal-repo (`GIT_DIR == GIT_COMMON`) or detached-HEAD finish there is no worktree to dispatch fix waves into, so that menu offers accept / rescope / manual fix-in-place only.
78
- - **If no conformance check has run in this flow** (e.g., ad-hoc work that landed without an execution skill), say so plainly and offer to run it now — dispatch a fresh-context `conformance-reviewer` against the origin (spec + verbatim prompt + full diff vs base) per `verification-before-completion/reference/conformance-check.md`. Closing the loop is cheap relative to shipping unverified intent.
79
- - **Unreconciled gaps are a blocker, not a footnote.** Do not bury them inside the options menu. If any gap is still open, resolve it (or get explicit user acceptance recorded in the spec) before offering Option 1 (squash-merge) or Option 2 (PR).
77
+ **If no conformance check has run in this flow** (e.g., ad-hoc work that landed without an execution skill): say so, then dispatch a fresh-context `conformance-reviewer` against the origin (spec + verbatim prompt + full diff vs base) per `verification-before-completion/reference/conformance-check.md`. Closing the loop is cheap relative to shipping unverified intent. Then proceed below with its verdict.
80
78
 
81
- Present it as a distinct line the user reads before choosing:
79
+ **If verdict is `CONFORMS`** (no carried-open gaps): report `Closure / conformance: CONFORMS`. If the run auto-applied any fixes, also surface the flat `auto-applied fix commits: <Gn: SHA>, ...` index from the `## Closure / conformance` block with a one-line revert offer (see "Revert semantics") — a gap that auto-converged to `CONFORMS` mid-verify has no per-gap line above, so this index is the only place its fix commit stays revertable. No per-gap menu. Continue to Step 4.
80
+
81
+ **If gaps were carried open:** read the `## Closure / conformance` block from the verify completion summary (schema and field names defined once in `verification-before-completion/reference/conformance-check.md` — do not re-derive them here). For each `Gn` line, render it verbatim and offer this ordered menu — the human must pick one entry per gap before Step 4:
82
+
83
+ ```
84
+ G<n>: <verdict> — recommended: <fix|accept|rescope> — touched-files: <paths>
85
+ round history: R1 ..., R2 ...
86
+
87
+ D1. Apply now: accept-into-spec — fold a dated decision into the spec now (main session edits the spec directly, never a subagent)
88
+ D2. Apply now: rescope-into-spec — same, recorded as reduced/changed scope
89
+ D3. Apply now: fix-now — run the fix loop now (worktree finish paths only, see below)
90
+ D4. Custom disposition — e.g. capture as a follow-up ticket per this project's issue-tracker convention (see `.pi/gauntlet-overrides.md`)
91
+ D5. Revert an auto-applied change for this gap (see "Revert semantics" below)
92
+
93
+ Which option for G<n>?
94
+ ```
95
+
96
+ Also surface the flat `auto-applied fix commits: <Gn: SHA>, ...` index from the same block — this is the revert candidate list for D5, covering every `conformance fix Gn` commit this run (open and already-closed gaps alike).
97
+
98
+ **`fix-now` loop scope (worktree finish paths only):**
99
+
100
+ 1. Commit any `accept-into-spec` / `rescope-into-spec` edits picked in this gate **before** dispatching — a dirty tree rejects `worktree: true`, and the re-audit must read the amended spec.
101
+ 2. Run the **full** loop from `verification-before-completion/reference/conformance-check.md` "Fix loop" (implementer → integrate → test → `code-reviewer` → re-audit). Do not re-describe the loop steps here — that file is the single source.
102
+ 3. Re-run Step 1's test verification on the result.
103
+ 4. Re-enter this step (3.5) with the re-audited `## Closure / conformance` block before re-presenting ship options.
104
+
105
+ **Non-worktree precondition (unchanged):** on a normal-repo finish (`GIT_DIR == GIT_COMMON`) or detached HEAD there is no worktree to dispatch fix waves into — the menu above offers D1, D2, D4, and D5 (manual fix-in-place substitutes for D3) but never dispatches `fix-now`.
106
+
107
+ No auto-proceed: every carried-open gap needs an explicit answer from the list above before Step 4 renders. Once all gaps are dispositioned, report the final state as a distinct line:
82
108
 
83
109
  ```
84
110
  Closure / conformance: CONFORMS
85
- (or: GAPS — <n> open)
86
- - <gap> → proposed remediation: <one line> [if any open]
111
+ (or: GAPS — <n> dispositioned: G1 accept-into-spec, G2 fix-now → CONFORMS, ...)
87
112
  ```
88
113
 
89
114
  Then continue to Step 4.
90
115
 
116
+ ### Revert semantics
117
+
118
+ Three tiers, increasing cost — name the tier when a revert is requested:
119
+
120
+ | Tier | What's reverted | Cost | Mechanics |
121
+ |---|---|---|---|
122
+ | Cheap | Council edit, reverted at the `brainstorming` gate | Spec isn't yet plan- or code-bearing | Revise spec, re-present |
123
+ | Light | Conformance fix, reverted at finish | Gap re-opens for a fresh disposition | Revert the `conformance fix Gn` commit(s), re-audit |
124
+ | Heavy | Council edit, reverted at finish | Rewrites the already-ratified contract that drove the plan and code | Amend spec → re-approve → regenerate affected plan/code → re-run verify before ship |
125
+
126
+ A **heavy** revert is not a menu toggle — say so explicitly to the user before proceeding, and do not present it as equivalent-effort to the light tier. The council audit that lets the human identify revert candidates lives in the `brainstorming` spec commit message body (not a committed spec section).
127
+
91
128
  ### Step 4: Present Options
92
129
 
93
130
  **Normal repo and named-branch worktree — present exactly these 4 options:**
@@ -300,7 +337,7 @@ phase_tracker({ action: "complete", phase: "ship" })
300
337
  - Remove a worktree before confirming merge success
301
338
  - Clean up worktrees you didn't create (provenance check)
302
339
  - Run `git worktree remove` from inside the worktree
303
- - Present finish options while a conformance gap is open and undispositioned
340
+ - Auto-proceed past an undispositioned carried-open gap
304
341
  - Skip the guarded plan-doc removal before push on Option 2 when a plan doc was committed
305
342
 
306
343
  **Always:**
@@ -1,13 +1,13 @@
1
1
  ---
2
2
  name: roasting-the-spec
3
- description: Use after writing a spec, when a spec council is configured (the resolved piGauntlet.specCouncil council, via the gauntlet_setting tool, repo settings over the preset). Auto-dispatched by /skill:brainstorming as the critique pass when members is non-empty (no longer offered). N members on different models critique in parallel, a neutral chair consolidates and adjudicates, the parent proposes dispositions, the user approves.
3
+ description: Use after writing a spec, when a spec council is configured (the resolved piGauntlet.specCouncil council, via the gauntlet_setting tool, repo settings over the preset). Auto-dispatched by /skill:brainstorming as the critique pass when members is non-empty (no longer offered). N members on different models critique in parallel, a neutral chair consolidates and adjudicates, the parent applies its own dispositions and returns an audit for the user to ratify at brainstorming's gate.
4
4
  ---
5
5
 
6
6
  # Roasting the Spec (Spec Council)
7
7
 
8
8
  ## Overview
9
9
 
10
- A multi-model critique pass for a freshly written spec. Each council **member** runs on a different model and critiques the spec independently — different models surface different angles. A neutral **chair** consolidates the critiques and adjudicates disagreements. The parent proposes what to apply; the **user** approves. The council never decides on its own what changes land.
10
+ A multi-model critique pass for a freshly written spec. Each council **member** runs on a different model and critiques the spec independently — different models surface different angles. A neutral **chair** consolidates the critiques and adjudicates disagreements. The parent decides what to apply and applies it before returning; the **user** ratifies (or reverts) the result at brainstorming's single gate. The council never decides on its own what changes land.
11
11
 
12
12
  Auto-dispatched from `/skill:brainstorming` as the critique pass, after the inline lint and before the user review gate, **only when a council is configured** (`members` non-empty). brainstorming owns that gate; when no council is configured it runs a single fresh-`worker` critique instead and does not invoke this skill.
13
13
 
@@ -19,8 +19,8 @@ This skill may read anything and edit **only** the spec under `doc/specs/`. It d
19
19
 
20
20
  - **Members** — independent witnesses. One per configured model, fresh context, read-only.
21
21
  - **Chair** — judge of the testimony. Fresh context (never saw the spec authored); consolidates and resolves member-vs-member conflicts. Final say on conflicts; no say on what gets applied.
22
- - **Parent (you)** — advocate. Proposes apply / defer / reject per finding on scope grounds. Cannot suppress findings.
23
- - **User** — jury. Approves what actually lands, at the existing review gate.
22
+ - **Parent (you)** — advocate, and now also executor. You decide apply / defer / reject per finding on scope grounds, then apply the apply-set yourself (you hold the `edit`/`write` tools; this was always the main-loop model's job, just moved earlier). Cannot suppress findings — every finding lands in the audit as applied, deferred, or rejected.
23
+ - **User** — sole jury. Ratifies (or reverts) the finished spec at brainstorming's one gate — after the apply, not before.
24
24
 
25
25
  ## Configuration and gating
26
26
 
@@ -100,32 +100,41 @@ List the exact member paths in the task text. The `reads:` array injects their c
100
100
 
101
101
  If the configured `chair` model is unreachable, retry once with the inherited model.
102
102
 
103
- ### 3 — Propose dispositions
103
+ ### 3 — Decide and apply
104
104
 
105
- For each cluster in the chair's report, decide and state one of:
105
+ For each cluster in the chair's report, decide one of:
106
106
 
107
- - **apply** — with the concrete edit you will make.
108
- - **defer** — out of scope for this spec; name where it belongs.
109
- - **reject** — with a one-line reason.
107
+ - **apply** — make the concrete edit to the spec under `doc/specs/` now.
108
+ - **defer** — out of scope for this spec; name where it belongs. Do not edit the spec.
109
+ - **reject** — one-line reason. Do not edit the spec.
110
110
 
111
- You are the advocate here, not the judge — propose, do not unilaterally apply.
111
+ Also inline any `external-ref:` cluster you have context for (e.g. a ticket fetched during brainstorming) as part of the apply-set — this is your call, same as any other cluster.
112
112
 
113
- ### 4 — User gate
113
+ You are the advocate — decide on scope grounds — and, unlike a dispatched subagent, also the executor: you hold `edit`/`write` tools directly, so apply the edit yourself instead of proposing it for someone else to make. Do this **before** returning to brainstorming.
114
114
 
115
- Fold the chair's clusters, its `resolved` audit notes, and your proposed dispositions into brainstorming's user review gate. Let the user approve or adjust.
115
+ ### 4 — Emit the audit
116
116
 
117
- ### 5 — Apply and clean up
117
+ Return a structured audit, gate-only (not a committed spec section) — three labelled lists:
118
118
 
119
- Apply the approved edits to the spec under `doc/specs/`. Re-run brainstorming's placeholder scan. Remove the temp dir (`rm -rf` the `mktemp -d` path). Then continue with brainstorming's normal commit. Nothing council-related (member files) is ever staged.
119
+ - `Applied:` — cluster -> the concrete edit made.
120
+ - `Deferred:` — cluster -> where it belongs.
121
+ - `Rejected:` — cluster -> one-line reason.
120
122
 
121
- Single pass — no automatic re-roast loop. The user can invoke this skill again after edits for another round.
123
+ Hand this audit to brainstorming along with the now-final spec. brainstorming writes it into the **spec commit message body** (git-native, readable pre-squash) so it survives for finish-time revert visibility, then shows it to the user alongside the final spec at its one review gate. The user can revert any applied edit there — that gate, not this skill, is where ratification happens.
124
+
125
+ ### 5 — Clean up
126
+
127
+ Re-run brainstorming's placeholder scan over the applied result. Remove the temp dir (`rm -rf` the `mktemp -d` path). Nothing council-related (member files) is ever staged.
128
+
129
+ Single pass — no automatic re-roast loop. The user can invoke this skill again after the gate for another round.
122
130
 
123
131
  ## Red flags — STOP
124
132
 
125
133
  - Running the council when `piGauntlet.specCouncil.members` is absent or empty (brainstorming owns the gate and should have used the worker fallback).
126
134
  - Reading member critique files yourself instead of routing them through the chair.
127
135
  - Writing member files to a relative path (they land in the worktree).
128
- - Auto-applying findings without the user gate.
136
+ - Applying edits without surfacing the audit at brainstorming's gate — apply-before-the-gate is correct; apply-without-the-gate is not.
137
+ - Suppressing a finding instead of routing it to applied, deferred, or rejected in the audit.
129
138
  - Surfacing member-vs-member disagreements to the user instead of letting the chair adjudicate.
130
139
  - Editing anything other than the spec under `doc/specs/`.
131
140
 
@@ -190,9 +190,9 @@ For the fan-out + worktree + patch-integration + conflict mechanics, see `dispat
190
190
 
191
191
  0. Call `phase_tracker({ action: "start", phase: "verify" })`. (The `implement` phase was started at execution start and auto-completes from `plan_tracker` once all tasks are done; this flow runs its own verify gate instead of `/skill:verification-before-completion`, so it must mark verify itself.)
192
192
  1. **Run the whole-diff code review.** Dispatch `/skill:requesting-code-review` against the worktree's full diff vs `main` (already covered in [The Process](#the-process) step "After all tasks"). Address Critical and Moderate findings before handoff. (Consumers wanting an in-flow project-specific audit re-add it as an explicit step in `.pi/gauntlet-overrides.md`, or run `/self-audit` manually.)
193
- 2. **Close the loop — conformance check.** The review in step 1 is plan-vs-code (single-step); it inherits any requirement the plan already dropped. Before marking verify complete, dispatch a fresh-context **`conformance-reviewer`** — its **own** dispatch, never fused into the step-1 review — to confront the deliverable (code **and** docs) against the *origin* — the spec **and** the original prompt — per `verification-before-completion/reference/conformance-check.md`. Pass the spec path, the verbatim original prompt, and the full diff. On `GAPS`, do not auto-fix or auto-proceed: run the remediation loop in `verification-before-completion/reference/conformance-check.md` "When the check finds gaps" (disposition menu → isolated fix waves → bounded delta re-audit, capped by `gauntlet_setting({ key: "closureReview" }).maxFixRounds`). Only when the verdict is `CONFORMS` (or every gap is dispositioned) call `phase_tracker({ action: "complete", phase: "verify" })`.
194
- 3. Summarize what was implemented (tasks completed, files changed, test counts, code-review verdict). Give the closing loop its **own section** — `Closure / conformance: CONFORMS` (or `GAPS` with each gap and its disposition) — so the user sees intent-fidelity as a first-class line before any finishing decision, not buried in the review verdict.
195
- 4. **Proceed to finishing — no confirmation prompt.** When the verdict is `CONFORMS` (or every gap is dispositioned), invoke `/skill:finishing-a-development-branch` immediately. Its Step 4 menu (squash / PR / keep / discard) is the human gate; a separate "ready to finish?" prompt only stacks a second stop in front of it. Open gaps are already owned by step 2, so nothing is left to decide here. Manual testing is a follow-up after the finishing choice (on `<base-branch>` after a squash-merge, or on the PR branch), never a reason to hold this gate.
193
+ 2. **Close the loop — conformance check.** The review in step 1 is plan-vs-code (single-step); it inherits any requirement the plan already dropped. Before marking verify complete, dispatch a fresh-context **`conformance-reviewer`** — its **own** dispatch, never fused into the step-1 review — to confront the deliverable (code **and** docs) against the *origin* — the spec **and** the original prompt — per `verification-before-completion/reference/conformance-check.md`. Pass the spec path, the verbatim original prompt, and the full diff. On `GAPS`, this skill does not choose a disposition or stop for one: `conformance-check.md` "When the check finds gaps" auto-runs the fix loop for every `recommended: fix` gap (no menu, no stop) and carries any `accept`/`rescope`/`UNAUTHORIZED` gap OPEN to the finish gate — follow that file for the partition rule and the fix-loop mechanics; do not reimplement them here. The fix loop may drive `plan_tracker` to surface fix-wave progress (task name = `Gn: <short desc>`, lifecycle `pending → in_progress → complete` per gap); it never calls `phase_tracker`. Call `phase_tracker({ action: "complete", phase: "verify" })` once every gap is either fixed (`CONFORMS`) or carried OPEN as a deferred `accept`/`rescope`/`UNAUTHORIZED` gap — escalation (fix-round cap reached with an open `fix` gap) is the sole non-completing terminal state; on escalation, do not complete verify, stop and report.
194
+ 3. Summarize what was implemented (tasks completed, files changed, test counts, code-review verdict). Emit the `## Closure / conformance` block verbatim per the schema defined in `verification-before-completion/reference/conformance-check.md` (do not rename or reformat its fields); `finishing-a-development-branch` Step 3.5 consumes it by those exact field names.
195
+ 4. **Proceed to finishing — no confirmation prompt.** Once verify is complete per step 2's criterion, invoke `/skill:finishing-a-development-branch` immediately. Its Step 4 menu (squash / PR / keep / discard) is the human gate; a separate "ready to finish?" prompt only stacks a second stop in front of it. Carried-open gaps are resolved at Step 3.5 of that skill via the `## Closure / conformance` block from step 3 — nothing is left to decide here. Manual testing is a follow-up after the finishing choice (on `<base-branch>` after a squash-merge, or on the PR branch), never a reason to hold this gate.
196
196
 
197
197
  ## Red Flags — STOP
198
198
 
@@ -215,7 +215,7 @@ For the fan-out + worktree + patch-integration + conflict mechanics, see `dispat
215
215
  - `/skill:using-git-worktrees` — set up isolation first (small changes can branch in place with user approval)
216
216
  - `/skill:writing-plans` — creates the plan this skill executes
217
217
  - `/skill:requesting-code-review` — review template for reviewer subagents
218
- - `/skill:finishing-a-development-branch` — invoked automatically once the conformance verdict is `CONFORMS` (or all gaps dispositioned)
218
+ - `/skill:finishing-a-development-branch` — invoked automatically once every gap is fixed (`CONFORMS`) or carried open
219
219
 
220
220
  **Subagents follow by default:**
221
221
 
@@ -57,7 +57,7 @@ Skip any step = lying, not verifying
57
57
  | Regression test works | Red-green cycle verified | Test passes once |
58
58
  | Agent completed | VCS diff shows changes | Agent reports "success" |
59
59
  | Requirements met | Line-by-line checklist | Tests passing |
60
- | Intent delivered (loop closed) | Fresh reviewer audits code+doc vs origin spec + prompt (`reference/conformance-check.md`) | Plan-vs-code review, tests passing |
60
+ | Intent delivered (loop closed) | Fresh reviewer audits code+doc vs origin spec + prompt; verify completes when every gap is `CONFORMS` or carried-open as a deferred `accept`/`rescope`/`UNAUTHORIZED` gap - the sole non-completing terminal state is escalation (cap reached with an unresolved `fix` gap). Partition, fix loop, and `## Closure / conformance` schema: `reference/conformance-check.md` | Plan-vs-code review, tests passing |
61
61
 
62
62
  ## Rationalization Prevention
63
63
 
@@ -89,132 +89,145 @@ The reviewer **proposes, it does not dispose.** It emits structured gap blocks
89
89
  the verify gate) drives disposition, fixes, and re-audit. The reviewer never edits,
90
90
  dispatches, or re-audits itself.
91
91
 
92
- ### CONFORMS
93
-
94
- Record the verdict in the completion summary's closure section and proceed.
95
-
96
- ### GAPS — disposition menu
97
-
98
- Do **not** auto-proceed and do **not** auto-fix. Render the enumerated gap list —
99
- each as `Gn [VERDICT] origin — remediation (recommended: fix|accept|rescope)` — then
100
- a numbered prompt (a chat turn cannot express a bare keystroke):
92
+ ### Disposition — verdict-then-`recommended` partition, no menu
93
+
94
+ Render the enumerated gap list — each as `Gn [VERDICT] origin — remediation
95
+ (recommended: fix|accept|rescope)` — then partition and act, in this exact order.
96
+ No prompt, no menu: this partition is deterministic and exhaustive.
97
+
98
+ 1. **Verdict `CONFORMS`** (no gaps) → record the verdict in the completion
99
+ summary's closure section and proceed. No loop.
100
+ 2. **Any gap is `UNAUTHORIZED`** → that gap **always** defers to the finish gate,
101
+ regardless of its `recommended` value. Never auto-remove or auto-accept
102
+ unrequested code here.
103
+ 3. **Every remaining `PARTIAL`/`MISSING`/`DRIFTED` gap**:
104
+ - `recommended: fix` → auto-run the fix loop below — **unless `maxFixRounds:
105
+ 0`**, in which case carry the gap **OPEN** (see the fix loop's
106
+ `maxFixRounds: 0` note).
107
+ - `recommended: accept` or `recommended: rescope` → carry the gap **OPEN**,
108
+ deferred to the finish gate. Do not apply a spec edit here — the finish
109
+ gate owns disposition of deferred gaps.
110
+
111
+ So the fast path (all gaps `recommended: fix`, none `UNAUTHORIZED`, cap > 0)
112
+ therefore auto-runs the fix loop with no menu, stop, or confirmation; any other
113
+ mix carries the `accept`/`rescope`/`UNAUTHORIZED` gaps OPEN while the `fix` gaps
114
+ run. Record every gap's outcome (`CONFORMS`-closed or carried OPEN) in the
115
+ `## Closure / conformance` block (schema below).
116
+
117
+ **Re-partition after every re-audit.** A re-audit can introduce `Gn+1` or flip a
118
+ carried gap's `recommended`. Re-run steps 1-3 above over the **full current
119
+ open-gap set** each time the reviewer returns a report — never reuse a stale
120
+ partition from an earlier round.
121
+
122
+ ### Fix loop — SDD Parallel-Wave mirror, per round
123
+
124
+ Mirrors `subagent-driven-development` Parallel-Wave Mode and reuses its
125
+ `plan_tracker` progress surface. Runs entirely inside the gate — it invokes
126
+ **no** `phase_tracker` calls (`phase_tracker({ phase: "implement" })` errors
127
+ while verify is `in_progress`) and does **not** enter SDD's phase machinery.
128
+ Only the fan-out/integrate/review shape and `plan_tracker` are reused.
129
+
130
+ **Precondition — worktree required.** The loop needs a worktree HEAD to branch
131
+ fixes from. On the ad-hoc `finishing-a-development-branch` paths that run in a
132
+ normal repo (`GIT_DIR == GIT_COMMON`) or detached HEAD, there is no such HEAD:
133
+ skip this loop, carry every `fix` gap OPEN, and resolve manually at finish
134
+ (`accept`/`rescope`/manual fix-in-place only).
135
+
136
+ Per round:
137
+
138
+ 1. **`plan_tracker` init** with the round's gaps as tasks. Wave-prefix tasks
139
+ when the reviewer's `Parallel-safe:` line marks a `conflicts` pair (file OR
140
+ `touched-resources` overlap) — that pair runs in separate serial waves;
141
+ `disjoint` gaps share one wave. Lifecycle per gap: `pending` →
142
+ `in_progress` → `complete`. This re-init **replaces** the implement phase's
143
+ completed task list in the singleton widget — state-safe, since
144
+ `phase-tracker.ts` `applyPlanActivity` only auto-completes `implement`
145
+ while it is `in_progress`; the widget now shows fix-wave progress during
146
+ verify.
147
+ 2. **Per gap** (task → `in_progress`): dispatch `implementer` (fresh context,
148
+ `worktree: true`, `cwd` = the conformance worktree, `touched-files` from the
149
+ gap block as an explicit ownership boundary) → dispatch `spec-reviewer` on
150
+ the gap-block reference contract below → task → `complete`.
151
+ 3. **Integrate** serially via `git apply` onto the worktree HEAD, one gap's
152
+ patch at a time. Failure handling is inherited verbatim from
153
+ `dispatching-parallel-agents` "Review and Integrate": textual conflict →
154
+ re-run one agent sequentially with the other's integrated changes as
155
+ context; semantic conflict (applies clean, suite fails) → re-run the
156
+ offending task sequentially on integrated HEAD; a failed agent → integrate
157
+ the successes, then retry the failure with fresh context including the
158
+ integrated changes. A `BLOCKED`/`NEEDS_CONTEXT` return surfaces to the user.
159
+ 4. **Test gate** on the integrated tree, using the project's canonical test
160
+ command. A failure re-enters the failure-handling rules above.
161
+ 5. **`code-reviewer` once** on the round's cumulative fix delta (not per gap).
162
+ 6. **Re-audit**: re-dispatch `conformance-reviewer` over the fixes **plus** the
163
+ regression guard (any prior-`DELIVERED` requirement whose `evidence` file
164
+ the fix diff touched). Pass the full prior conformance report (every row,
165
+ including DELIVERED rows and their `evidence` `file:line`) and the round's
166
+ fix diff. Inject `model:` call-site per `gauntlet_setting({ key:
167
+ "closureReview" }).model` — same mechanism as the initial audit; omit
168
+ `model:` when it is `undefined` to inherit the parent's model. The
169
+ phase-tracker closure guard blocks a dispatch that omits `model:` when
170
+ `closureReview.model` is set, and warns (non-blocking) on one whose model
171
+ differs.
172
+ 7. **Converge or continue**: verdict `CONFORMS` → record it, done. Open gaps
173
+ within the cap → re-partition (per the rule above) and start the next
174
+ round. Cap (`gauntlet_setting({ key: "closureReview" }).maxFixRounds`,
175
+ default `2`, floors negatives at `0`, coerces non-integers to `2`) reached
176
+ with an open `fix` gap → **escalate to the human** with the per-gap
177
+ round-by-round verdict trail. Escalation is the sole non-completing
178
+ terminal state — no silent re-loop, no auto-ship.
179
+
180
+ Commit each per-gap fix with the message **`conformance fix Gn`** (durable,
181
+ `git log`-readable pre-squash) so the finish gate and any revert can identify
182
+ auto-applied fixes.
183
+
184
+ **`maxFixRounds: 0`**: skip this loop entirely. Every `recommended: fix` gap
185
+ becomes carried OPEN to the finish gate instead of auto-running — the user
186
+ opted out of auto-fix, so treat `fix` gaps like any other deferred gap. This
187
+ differs from a cap > 0 that is *exhausted*: that case escalates mid-verify
188
+ because the loop tried and could not converge.
189
+
190
+ ### `spec-reviewer` gap-block reference contract
191
+
192
+ Per-gap `spec-reviewer` in step 2 above is a **pre-integration mechanical
193
+ check**, distinct from the round-level re-audit in step 6 (which still
194
+ references the *origin* — spec + original prompt — unchanged). Frame the
195
+ per-gap dispatch against the **gap block**, not a plan task:
196
+
197
+ - **Requirement** = the gap's `origin` + `remediation` (what must be true
198
+ after the fix).
199
+ - **Closure proof** = the patch satisfies that requirement within the gap's
200
+ `touched-files` — nothing missing, nothing extra.
201
+ - **Output** = `spec-reviewer`'s normal MATCH/DRIFT verdict, referenced to the
202
+ gap block instead of a plan task.
203
+
204
+ This is a task-framing contract in the dispatch, not a new persona.
205
+
206
+ ## Closure / conformance
207
+
208
+ Emit this block in the verify completion summary. It is the durable handoff
209
+ `finishing-a-development-branch` Step 3.5 consumes — parseable even if session
210
+ context was pruned. Verify completes when every gap is either fixed
211
+ (`CONFORMS`) or carried OPEN as a deferred `accept`/`rescope`/`UNAUTHORIZED`
212
+ gap; escalation (cap reached with an open `fix` gap) is the one
213
+ non-completing terminal state.
214
+
215
+ For each carried-open gap:
101
216
 
102
217
  ```
103
- [1] apply all recommended dispositions
104
- [2] review per-gap (override fix/accept/rescope before applying)
218
+ Gn: <verdict> — recommended: <fix|accept|rescope> — touched-files: <paths>
219
+ round history: R1 <verdict/action>, R2 <verdict/action>, ...
105
220
  ```
106
221
 
107
- `[1]` applies each gap's `recommended` disposition, **except** any gap whose
108
- `recommended` is `accept` or `rescope`: list those and require an explicit confirming
109
- reply before their spec edits land (accept/rescope rewrite the origin — never on the
110
- unconfirmed fast path). `[2]` prompts a per-gap override, then applies.
111
-
112
- Disposition semantics:
113
-
114
- - `fix` — dispatch a remediation unit (below), then re-audit. For an `UNAUTHORIZED`
115
- gap, "fix" = **remove** the unrequested code.
116
- - `accept` — the **main session** (not a subagent) folds the deviation into the spec as
117
- a dated decision (template below). For `UNAUTHORIZED`, accept = keep the behavior,
118
- document it as intended.
119
- - `rescope` — the main session records the requirement in the spec as an explicit
120
- out-of-scope / deferred item, dated.
222
+ Then a single flat revert index of **every** `conformance fix Gn` commit the fix
223
+ loop produced this run — including gaps that later converged to `CONFORMS`
224
+ (a closed gap has no block above, so its commit lives only here) — since the
225
+ finish gate's revert option needs them all:
121
226
 
122
- Dated-decision template (append to the spec's decisions/deviations section):
123
-
124
- ```
125
- - YYYY-MM-DD accept|rescope Gn: <requirement/behavior> — <one-line rationale> (conformance gate)
126
227
  ```
127
-
128
- **Commit accept/rescope spec edits BEFORE any fix wave dispatches:** pi-cohort
129
- rejects a dirty tree on a `worktree: true` dispatch, and the re-audit must read the
130
- amended spec. If a round has only accept/rescope and no `fix`, the edits land, the
131
- verdict is recorded, and no re-audit runs.
132
-
133
- ### Fix dispatch — reuse dispatching-parallel-agents mechanics
134
-
135
- Fixes reuse the `dispatching-parallel-agents` fan-out primitive. Invoke **no**
136
- `phase_tracker` / `plan_tracker` calls and do **not** enter `subagent-driven-development`
137
- Parallel-Wave Mode (that mode opens with `phase_tracker({ phase: "implement" })`, which
138
- errors while the verify phase is `in_progress`, and needs a plan the fix loop lacks).
139
-
140
- **Precondition — worktree required.** Fix-via-dispatch needs a worktree HEAD to branch
141
- from. On the ad-hoc `finishing-a-development-branch` paths that run in a normal repo
142
- (`GIT_DIR == GIT_COMMON`) or detached HEAD, there is no such HEAD: the menu offers
143
- `accept` / `rescope` and **manual fix-in-place** only; unresolved gaps route to escalation.
144
- The loop below applies only when the gate already runs inside a worktree.
145
-
146
- **Wave grouping** comes from the reviewer's `Parallel-safe:` line: `disjoint` gaps form
147
- one parallel wave; any `conflicts` pair splits into separate serial waves. A pair conflicts
148
- on **file OR runtime-resource** overlap - two gaps whose fixes touch disjoint files but whose
149
- verification shares a `touched-resources` entry (DB/schema, port, fixture, external service,
150
- shared temp path) are **not** parallel-safe and run in separate serial waves, identical to
151
- planned-execution wave grouping. This is why the reviewer certifies both axes.
152
-
153
- **Dispatch shape** (mirrors `dispatching-parallel-agents`):
154
-
155
- ```ts
156
- subagent({
157
- context: "fresh",
158
- worktree: true,
159
- cwd: "<abs worktree path, from git rev-parse --show-toplevel>",
160
- tasks: [
161
- { agent: "implementer",
162
- task: "Close conformance gap G1. Origin requirement: <origin>. What's missing: " +
163
- "<remediation>. Satisfy the requirement; do not expand scope. " +
164
- "Ownership boundary — modify only: <touched-files>." },
165
- // one task per disjoint gap in this wave
166
- ],
167
- })
228
+ auto-applied fix commits: <Gn: SHA>, <Gm: SHA>, ... (revertable)
168
229
  ```
169
230
 
170
- - Unit = `implementer`, fresh context, `worktree: true`, `cwd` = the conformance
171
- worktree. Pass `touched-files` as an explicit ownership boundary.
172
- - **Integrate** serially via `git apply` back onto the worktree HEAD — the fix ships in
173
- the same worktree and rides `finishing-a-development-branch`'s squash. No new merge machinery.
174
- - **Failure handling is inherited verbatim** from `dispatching-parallel-agents`
175
- "Review and Integrate": textual conflict → re-run one agent sequentially with the
176
- other's integrated changes as context; semantic conflict (applies clean, suite fails)
177
- → re-run the offending task sequentially on integrated HEAD; a failed agent → integrate
178
- the successes, then retry the failure with fresh context including the integrated changes.
179
- A `BLOCKED` / `NEEDS_CONTEXT` return surfaces to the user.
180
- - **`code-reviewer` over the integrated fix delta, once per round** (not per gap) — gap
181
- fixes land after the branch's final code review, so review the round's cumulative diff.
182
- - **`spec-reviewer` is excluded** — plan-vs-code is the wrong reference point; the re-audit
183
- checks fixes against the origin.
184
- - **Test gate** on the integrated tree after the round's waves apply, using the project's
185
- canonical test command. A failure re-enters the failure-handling rules above.
186
-
187
- One round = dispatch waves → serial integrate → `code-reviewer` on round delta → test
188
- gate → re-audit.
189
-
190
- ### Delta re-audit + cap
191
-
192
- Re-dispatch `conformance-reviewer` for a delta-scoped re-audit. Pass:
193
-
194
- - the **full prior conformance report** — every row including DELIVERED rows and their
195
- `evidence` `file:line` (needed for the regression guard), not just gap IDs;
196
- - the **fix diff** for the round.
197
-
198
- The reviewer (not the orchestrator) computes the regression intersection: it re-verifies
199
- the gaps marked `fix` this round **plus** any previously-DELIVERED requirement whose
200
- `evidence` file appears in the fix diff. It reuses `G1..Gn`, marking each `DELIVERED`,
201
- still-open with its prior verdict, or introducing `Gn+1`.
202
-
203
- - The re-audit dispatch carries the **same call-site `model:` injection** as the initial
204
- audit (when `piGauntlet.closureReview.model` is set, the phase-tracker closure guard
205
- blocks a `conformance-reviewer` dispatch that omits `model:`, and warns — non-blocking —
206
- on one whose model differs from the configured value).
207
- - New or still-open gaps within the cap re-enter the menu above.
208
- - **Cap: `gauntlet_setting({ key: "closureReview" }).maxFixRounds`** (the tool applies the
209
- default `2`, floors negatives at `0`, and coerces non-integers to `2`). `0` = audit-only:
210
- `GAPS` renders an accept/rescope-only menu and any unresolved gap escalates instead of
211
- dispatching a fix.
212
- - **On non-convergence** (cap reached with open gaps): **escalate to human** with the
213
- per-gap round-by-round verdict trail. No silent re-loop, no auto-ship.
214
-
215
- No completion claim stands over a gap that is neither fixed, accepted, nor rescoped.
216
- "Surface, don't auto-fix": the orchestrator presents options, the user decides.
217
-
218
231
  ## Checklist
219
232
 
220
233
  - [ ] Located canonical requirements (spec → prompt → ticket fallback)