pi-gauntlet 7.11.3 → 7.12.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## v7.12.1 - 2026-10-16
4
+
5
+ ### Added
6
+
7
+ - One-sample noninteractive judgment recovery with `node eval/run.mjs <target> <sample> --refresh-judgments`: reuses current saved replies, refreshes LLM judgments and preserves a bounded previous/refreshed audit without accepting variance or replacing primary replies. Documents admission, interruption and failure handling in the [eval process](eval/README.md#recover-a-disputed-saved-judgment). (#64)
8
+
9
+ ## v7.12.0 - 2026-10-16
10
+
11
+ ### Changed
12
+
13
+ - The carried-open conformance menu and the spec-amendment batch menu render as numbered decision briefs - the problem in plain words first, lettered options with one-line consequences, `Recommended: <letter> - <reason>` or `No recommendation - pick one` - and accept one reply line per item (`1. B`); bare `1` applies every recommendation and re-asks no-recommendation items by number, so the old `recommended: none` withholding is gone. (#63)
14
+
3
15
  ## v7.11.3 - 2026-10-16
4
16
 
5
17
  ### Added
package/README.md CHANGED
@@ -39,7 +39,7 @@ Concretely, one change through the gauntlet:
39
39
  1. Opt in with `/skill:brainstorming` and describe the change. The command is the reliable discovery-and-entry path; explicit prose requesting brainstorming/the gauntlet also supplies consent when the skill is already loaded or an available instruction or route identifies it. An ordinary implementation request or an agent recommendation is not consent. **`brainstorming`** sets up an isolated worktree, explores the codebase, and turns your description 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.** No implementation code exists yet.
40
40
  2. **`writing-plans`** decomposes the approved spec into atomic, independently-verifiable tasks, grouped into parallel waves where they don't touch the same files.
41
41
  3. **`subagent-driven-development`** executes the plan one task at a time, each in a fresh subagent, behind spec-compliance review then code-quality review. TDD-locked: red, green, refactor. Independent implementation, review, and council batches remain parallel, but their dispatches are foreground: the orchestrator waits for terminal results before accepting work or advancing a phase.
42
- 4. **verify**: the parent first runs the plan's full verification command set; only a passing result permits whole-diff code review, then the **conformance gate**. A review fix invalidates that result, so the parent reruns full verification before the next review or conformance gate. When the overrides file declares a happy path for the touched paths (see [Project-specific overrides](#project-specific-overrides)), the parent runs it once here, between code review and the conformance gate, and the reviewer reads its transcript as runtime evidence - a hang or a failed request shows up in the audit with the transcript quoted - as a gap when an origin clause ties to it, otherwise as a `happy-path: failed - unattributable` line - never as a silent green. The conformance subagent reads the finished code and docs against your *original words* from step 1, not the plan, and reports per-requirement: delivered, partial, missing, drifted, or unauthorized. Unauthorized rows - shipped surface no human input asked for, whether it crept in or was laundered through the spec - follow their recommendation like every other row: a contained removal auto-runs, anything another requirement leans on is deferred with a plain-language "I'd cut it / I'd keep it" recommendation. Inside a brainstorming-entered flow this gate is machine-blocked from being skipped. Compatible executable recommendations auto-run through an isolated fix-and-re-audit loop with no prompt; anything still open surfaces as a dense list - one line per decision, plain-language, with its recommended choice inline. Reply `1` to take every recommendation, or `2:` with per-item overrides; a current `CONFORMS` / no-concerns result goes straight to the branch options with no extra conformance sign-off.
42
+ 4. **verify**: the parent first runs the plan's full verification command set; only a passing result permits whole-diff code review, then the **conformance gate**. A review fix invalidates that result, so the parent reruns full verification before the next review or conformance gate. When the overrides file declares a happy path for the touched paths (see [Project-specific overrides](#project-specific-overrides)), the parent runs it once here, between code review and the conformance gate, and the reviewer reads its transcript as runtime evidence - a hang or a failed request shows up in the audit with the transcript quoted - as a gap when an origin clause ties to it, otherwise as a `happy-path: failed - unattributable` line - never as a silent green. The conformance subagent reads the finished code and docs against your *original words* from step 1, not the plan, and reports per-requirement: delivered, partial, missing, drifted, or unauthorized. Unauthorized rows - shipped surface no human input asked for, whether it crept in or was laundered through the spec - follow their recommendation like every other row: a contained removal auto-runs, anything another requirement leans on is deferred with a plain-language "I'd cut it / I'd keep it" recommendation. Inside a brainstorming-entered flow this gate is machine-blocked from being skipped. Compatible executable recommendations auto-run through an isolated fix-and-re-audit loop with no prompt; anything still open surfaces as a numbered decision brief - one item per decision, the problem in plain words first, lettered options each with a one-line consequence, and `Recommended: <letter> - <reason>` or `No recommendation - pick one`. Reply with one line per item (`1. B`), or bare `1` to take every recommendation (no-recommendation items are re-asked by number); a current `CONFORMS` / no-concerns result goes straight to the branch options with no extra conformance sign-off.
43
43
  5. **`finishing-a-development-branch`**: PR, draft PR, squash, keep, or discard. 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.
44
44
  6. *(Optional)* Once the merge lands, `/skill:check-delivery <ref>` can prove delivery - default-branch landing, delivery target, per-AC evidence - before the tracker status advances. Explicit ask only, no auto-chain: deploys commonly lag merges by minutes to hours, so an auto-run would routinely check too early.
45
45
 
@@ -109,7 +109,7 @@ Run by a human against pi-cohort >= 7.1.0, before a pi-gauntlet release claims t
109
109
  | --- | --- |
110
110
  | Gate | A machine-enforced checkpoint between phases (e.g. within a brainstorming-entered flow, `complete verify` is blocked until conformance review has run). Not a suggestion. |
111
111
  | Spec council | Multi-model critique of the spec before you see it (`roasting-the-spec`); members also flag unrelated extras or sufficient in-scope simplifications (`over-spec`) for cuts or replacements before planning, every member closes with a `lean:` line - "nothing to cut" is a first-class answer - and the chair tallies them (`lean: <k> of <n> members found nothing to cut`). Falls back to a single-model critique if no council is configured. |
112
- | Conformance gate | The closing check: does the delivered code + docs match your *original prompt*, not the derived plan? Compatible executable recommendations auto-fix first; anything still open renders as a dense one-line-per-decision list with each recommended choice inline. Reply `1` to accept all recommendations or `2:` with per-item overrides; a current `CONFORMS` / no-concerns handoff goes straight to branch options with no extra sign-off. |
112
+ | Conformance gate | The closing check: does the delivered code + docs match your *original prompt*, not the derived plan? Compatible executable recommendations auto-fix first; anything still open renders 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 handoff goes straight to branch options with no extra sign-off. |
113
113
  | Wave | A batch of plan tasks that don't touch the same files, dispatched to implementers in parallel. |
114
114
  | Overrides file | `.pi/gauntlet-overrides.md` - where you put project-specific detail the generic skills don't know (CI command, worktree wrapper, routing rules). |
115
115
 
@@ -163,7 +163,7 @@ pi install -l ~/repos/pi-gauntlet
163
163
 
164
164
  ## Evals
165
165
 
166
- Run `node eval/run.mjs <target>` to check a wording change on fixed inputs: two frozen replay models produce before/after outputs, and one frozen judge checks must-hold facts against a committed `intent.md`. The [eval process](eval/README.md) explains the single driver, target and sample layout, newest-only records, and anonymization rule. Model calls run manually, never in CI; CI runs deterministic library tests, structural lint, and hygiene checks. `eval/` is checkout-only and excluded from the npm tarball.
166
+ Run `node eval/run.mjs <target>` to check a wording change on fixed inputs: two frozen replay models produce before/after outputs, and one frozen judge checks must-hold facts against a committed `intent.md`. The [eval process](eval/README.md) explains the single driver, target and sample layout, newest-only primary replies with a bounded judgment-refresh audit, and anonymization rule. Model calls run manually, never in CI; CI runs deterministic library tests, structural lint, and hygiene checks. `eval/` is checkout-only and excluded from the npm tarball.
167
167
 
168
168
  ## Use from Claude Code
169
169
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-gauntlet",
3
- "version": "7.11.3",
3
+ "version": "7.12.1",
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",
@@ -102,19 +102,24 @@ Fail closed: a dispatch error, an async handle, a silence-kill, or a missing or
102
102
 
103
103
  ## 4. Human batch - one menu
104
104
 
105
- Render only escalated and prefiltered items; `<N>` counts them. Nothing symbol-dense above the fold; each item's `old -> new` sits under `Details`, after the footer.
105
+ Decide every recommendation and its reason before writing the menu text: the menu text is written after the recommendation is decided, never while deciding it. Never leak deliberation: `recommended: custom? Hmm. Dispositions: fix-now ... Actually, the amended spec makes G2 ...`.
106
+
107
+ Render only escalated and prefiltered items; `<N>` counts them. Build the opening sentence from the prepared item's `what` and `why`; take the human-call sentence from the prefilter rule or reviewer's escalate reason in plain words, with `Reviewer:` verbatim beneath it. Nothing symbol-dense above the fold; each item's `old -> new` sits under `Details`, after the footer. This menu's grammar governs the amendment batch only; brainstorming's questionary formats (the labeled recommendation question and the ticket cut question) keep their own rules - including the cut question's re-ask after a cancelled repair, re-rendered in full with the row unchanged.
106
108
 
107
109
  ```
108
110
  Spec amendments: <N> need your call - from <trigger>; applying as recommended <reopens | adds | removes> <task ids | no tasks>; no phase change.
109
111
 
110
- * <handle> - <title>: <what>. <why>.
111
- Example: <before -> after>
112
- Reviewer: <one-line reason verbatim | not reviewed - <prefilter rule> | reviewer unavailable: <reason>>
113
- Impact: <spec section>: <approved contract> -> <new contract>; ...
114
- Recommended: <accept | alt-n> (<one-clause why>).
115
- Alternatives: alt-1 <one line>; alt-2 <one line>
116
-
117
- Reply: 1 (apply all recommendations) | 2: <handle>=<accept|alt-n|custom(<effect>)>, ...
112
+ 1. <title> - <what>. <why>
113
+ <why this is a human call: the prefilter rule or the reviewer's escalate reason in plain words>
114
+ Example: <before -> after>
115
+ Reviewer: <one-line reason verbatim | not reviewed - <prefilter rule> | reviewer unavailable: <reason>>
116
+ Impact: <spec section>: <approved contract> -> <new contract>; ...
117
+ A) accept - the spec reads the new text
118
+ B) alt-1 - <the alternative's effect, one line>
119
+ Custom: <your own answer> - executed as given; may redirect away from the spec
120
+ Recommended: A - <one-clause why>
121
+
122
+ Reply with one line per item: `1. A`, `2. <your own text>`. Bare `1` takes every recommendation.
118
123
  Standing grant: reply "auto-apply amends" - every later spec amendment in this flow (corrected facts, paths, verification lines, and scope, acceptance-criteria, or public-contract edits alike) applies without asking; only a redraw (changed problem statement, component added, removed, or re-bounded) still stops for you, and the grant never stands in for a spec approval.
119
124
 
120
125
  Details
@@ -125,7 +130,9 @@ Details
125
130
 
126
131
  `Reviewer:` quotes the `<one-line reason>` of the section 3 reply verbatim; the `probed:` half stays in the commit body; a prefiltered item carries `not reviewed - <the rule that prefiltered it>`. `Impact:` restates the design-contract shift from `location` in the reader's words, never quoted spec text, one clause per touched decision, `;`-joined; `(none) -> <new>` for a contract added, `<old> -> (removed)` for a contract removed. `Details` keeps the verbatim `old -> new`.
127
132
 
128
- `Alternatives:` appears only when genuine ones exist; otherwise the item's choices are exactly `accept` and `custom(...)`. Reply grammar: `1` applies every recommendation; `2:` overrides the named handles, omitted handles keep theirs, a handle at most once; `custom(<effect>)` is free text and may redirect anywhere ("keep the spec, fix the parser"). A redirect away from the spec drops the item (still recorded in the batch commit body as `custom(<effect>)`) and returns the finding to its calling loop. Invalid handle or choice -> reprompt for that item only, keep every valid pick, never reopen the gate; a bare `2` without a colon is an invalid tier-2 reply (reprompt the same way) and never a grant. Take no action before the reply.
133
+ Letter options in fixed order: `A) accept`, then `B) alt-1`, `C) alt-2` in index order, only for genuine alternatives. Give each option its one-line effect; tie the recommendation's reason to the end goal or a development practice. Record a letter as its shown option's token. Keep custom unlettered as shown. Keep an unavailable option visible and unlettered: `Not available: <option> - <missing prerequisite>`. Use exactly `Recommended: <letter> - <reason>` or `No recommendation - pick one`; the prepared-item schema requires a recommendation, so this amendment menu never renders the second form.
134
+
135
+ Reply grammar: one line per item, `<n>. <letter or free text>`; bare `1` applies every recommendation and re-asks any item without one by number, never re-rendering the menu (vacuous here: the prepared-item schema always supplies a recommendation); an omitted item keeps its recommendation; free text is `custom(<text>)` and may redirect anywhere ("keep the spec, fix the parser") - a redirect drops the item (still recorded in the batch commit body as `custom(<effect>)`) and returns the finding to its calling loop; a letter always picks its shown option, even when free text would spell its name. A legacy `2: <handle>=<choice>` reply is accepted silently as the same picks; the form is never rendered in a prompt. Invalid number or letter -> reprompt for that item only, keep every valid pick, never reopen the gate; a bare digit other than `1` is an invalid reply and never a grant (reprompt the same way). A bare letter or bare `1` mixed with numbered lines is invalid; free text matching an option's name remains `custom(<text>)`. Resolve every item before applying; retain original numbers during reprompts. Take no action before the reply. After the reply lands and the batch applies, print one confirmation line `Recorded: <handle>=<choice>, ...` covering the batch's decided items (a custom choice keeps the reply's free text verbatim; grant-applied items record their recommended choice); this is the only place `<handle>=<choice>` appears to the human.
129
136
 
130
137
  ## 5. Apply, aftermath, commit
131
138
 
@@ -153,7 +160,7 @@ Called from `finishing-a-development-branch` Step 3.5, before the carried-open m
153
160
  1. Draft an item (step 1) for each gap with `recommended: accept`, verdict `DRIFTED` or `PARTIAL`, not `UNAUTHORIZED`, whose `origin` is not an acceptance criterion - the `accept-into-spec` edit built from its `origin` + `evidence`. Every other gap skips the funnel and stays a menu row.
154
161
  2. Review (step 3), apply and commit (step 5).
155
162
  3. Re-audit against the amended spec; regenerate the inventory. Only concerns the re-audit closed drop out; sibling concerns keep their rows.
156
- 4. Render the disposition menu for what remains - escalated items are ordinary rows there, never a second menu. Rows whose recommended disposition edits the spec carry the readable card fields (`what`, `why`, `Example:`, `Reviewer:`, `Impact:`) on the bullet, adapted to the disposition bullet grammar. A human-selected spec-changing disposition (`accept-into-spec`, `rescope-into-spec`, state-changing `custom`) is already approved: it applies at the protocol's execute-order step 2, bypasses steps 2-4 of this surface, and is recorded as today (`Gn - <title>: <disposition>`); an auto-applied item is recorded `Gn - <title>: accept-into-spec (auto-applied)`.
163
+ 4. Render the disposition menu for what remains - escalated items are ordinary rows there, never a second menu. Rows whose recommended disposition edits the spec carry the readable card fields (`what`, `why`, `Example:`, `Reviewer:`, `Impact:`) on the item, adapted to the numbered item render. A human-selected spec-changing disposition (`accept-into-spec`, `rescope-into-spec`, state-changing `custom`) is already approved: it applies at the protocol's execute-order step 2, bypasses steps 2-4 of this surface, and is recorded as today (`Gn - <title>: <disposition>`); an auto-applied item is recorded `Gn - <title>: accept-into-spec (auto-applied)`.
157
164
 
158
165
  ## Worked example
159
166
 
@@ -175,24 +182,33 @@ The reviewer clears items 1-5; nothing is applied yet. The batch renders items 6
175
182
  ```
176
183
  Spec amendments: 3 need your call - from Task 7 BLOCKED; applying as recommended reopens Tasks 4, 6; no phase change.
177
184
 
178
- * scope - ROP feed out of scope: adds an out-of-scope line for the ROP feed to Non-goals. Drops a deliverable you approved.
179
- Example: regulator feed = NERC filings + ROP announcements -> NERC filings only
180
- Reviewer: not reviewed - removes approved scope
181
- Impact: Non-goals: the ROP feed ships this release -> (removed)
182
- Recommended: accept (the ROP source has no stable page this release).
183
- * count - Fewer announcements per fetch: the acceptance criterion drops from at least 3 to at least 1. Lowers the bar you set.
184
- Example: 3 items per fetch -> 1
185
- Reviewer: not reviewed - acceptance-criteria location
186
- Impact: Acceptance criteria: a fetch yields three or more announcements -> one or more
187
- Recommended: accept (the captured fixture has one item; the criterion assumed three).
188
- * bytes - Fixture byte count: the verification line changes from 41,208 to 43,117 bytes. The verification line would assert a size nobody measured.
189
- Example: 41,208 bytes -> 43,117 bytes
190
- Reviewer: rubric (a) fails - no measurement cited for the new byte count
191
- Impact: Verification: the fixture measures 41,208 bytes -> 43,117 bytes
192
- Recommended: alt-1 (measure first; apply whatever `wc -c` reports).
193
- Alternatives: alt-1 replace the number with the `wc -c` result
194
-
195
- Reply: 1 (apply all recommendations) | 2: <handle>=<accept|alt-n|custom(<effect>)>, ...
185
+ 1. Fewer announcements per fetch - the acceptance criterion drops from at least 3 to at least 1. Lowers the bar you set.
186
+ Only you can change the acceptance criterion.
187
+ Example: 3 items per fetch -> 1
188
+ Reviewer: not reviewed - acceptance-criteria location
189
+ Impact: Acceptance criteria: a fetch yields three or more announcements -> one or more
190
+ A) accept - the spec reads the new text
191
+ Custom: <your own answer> - executed as given; may redirect away from the spec
192
+ Recommended: A - the captured fixture has one item; the criterion assumed three
193
+ 2. Fixture byte count - the verification line changes from 41,208 to 43,117 bytes. The verification line would assert a size nobody measured.
194
+ The reviewer cannot clear a correction without a cited measurement.
195
+ Example: 41,208 bytes -> 43,117 bytes
196
+ Reviewer: rubric (a) fails - no measurement cited for the new byte count
197
+ Impact: Verification: the fixture measures 41,208 bytes -> 43,117 bytes
198
+ A) accept - the spec reads the new text
199
+ B) alt-1 - replace the number with the `wc -c` result
200
+ Custom: <your own answer> - executed as given; may redirect away from the spec
201
+ Recommended: B - measure first so the verification line matches the fixture
202
+ 3. ROP feed out of scope - adds an out-of-scope line for the ROP feed to Non-goals. Drops a deliverable you approved.
203
+ Only you can remove approved scope.
204
+ Example: regulator feed = NERC filings + ROP announcements -> NERC filings only
205
+ Reviewer: not reviewed - removes approved scope
206
+ Impact: Non-goals: the ROP feed ships this release -> (removed)
207
+ A) accept - the spec reads the new text
208
+ Custom: <your own answer> - executed as given; may redirect away from the spec
209
+ Recommended: A - the ROP source has no stable page this release
210
+
211
+ Reply with one line per item: `1. A`, `2. <your own text>`. Bare `1` takes every recommendation.
196
212
  Standing grant: reply "auto-apply amends" - every later spec amendment in this flow (corrected facts, paths, verification lines, and scope, acceptance-criteria, or public-contract edits alike) applies without asking; only a redraw (changed problem statement, component added, removed, or re-bounded) still stops for you, and the grant never stands in for a spec approval.
197
213
 
198
214
  Details
@@ -201,4 +217,4 @@ count: Acceptance criteria - old: at least 3 announcements per fetch -> new: at
201
217
  bytes: Verification - old: fixture is 41,208 bytes -> new: fixture is 43,117 bytes
202
218
  ```
203
219
 
204
- Reply `2: scope=custom(keep scope; fix the parser instead)` drops `scope`, returns it to the fix loop, and applies `count` and `bytes` as recommended.
220
+ Reply `3. keep scope; fix the parser instead` drops item 3 (recorded `scope=custom(keep scope; fix the parser instead)`), returns it to the fix loop, and applies items 1 and 2 as recommended, recorded `count=accept`, `bytes=alt-1`.
@@ -90,32 +90,60 @@ This is an **enforced disposition gate**, not a surface-only notice. The user is
90
90
  Closure / conformance: CONFORMS
91
91
  ```
92
92
 
93
- then continue directly to Step 4. No approval prompt, no menu, no shared options line, no sign-off. If the run auto-applied fixes, surface the flat `auto-applied fix commits: <Gn: SHA>, ...` index from the durable block as **one informational, non-blocking line** with a one-line revert offer (see "Revert semantics") - a gap that auto-converged mid-verify has no bullet, so this index is the only place its fix commit stays revertable. Do not wait for acknowledgment.
93
+ then continue directly to Step 4 and render its menu in full, options included. Place no approval prompt, conformance menu, or sign-off between the CONFORMS line and that menu. The render never stops at Step 4's question line; the numbered options are part of the same message. If the run auto-applied fixes, surface the flat `auto-applied fix commits: <Gn: SHA>, ...` index from the durable block as **one informational, non-blocking line** with a one-line revert offer (see "Revert semantics") - a gap that auto-converged mid-verify has no bullet, so this index is the only place its fix commit stays revertable. Do not wait for acknowledgment.
94
94
 
95
95
  When the sentinel carries a `happy-path:` line, print it directly under `Closure / conformance: CONFORMS` as one informational, non-blocking line in the same shape as the `auto-applied fix commits` line: `happy-path: passed`, `happy-path: failed - unattributable`, or `happy-path: not run - <reason>` (a `failed - attributed to G<n>` value cannot reach this branch: its gaps are open). When the sentinel carries a `Deferred/deviates per spec:` line, print it verbatim as one informational line directly under the `happy-path:` line when present, else directly under `Closure / conformance: CONFORMS` or the `Conformance: N decisions needed before shipping.` header, and above the `whole-diff minors` line (both paths).
96
96
 
97
97
  **Pre-menu amendment funnel (GAPS only).** Before rendering the carried-open menu, `read` and run [`amendment-surface.md` § Conformance entry](../brainstorming/reference/amendment-surface.md) over the inventory once: gaps with `recommended: accept`, verdict `DRIFTED` or `PARTIAL`, not `UNAUTHORIZED`, whose `origin` is not an acceptance criterion are drafted as `accept-into-spec` items (the edit built from `origin` + `evidence`) and sent to the reviewer in one call; cleared items apply and land as one batch commit, the spec is re-audited, the inventory regenerated. Only concerns the re-audit actually closed drop out; sibling concerns in the same gap keep their rows and dispositions. Survivors and every other gap render as ordinary rows below - one menu, never two.
98
98
 
99
- **Carried-open (`status: GAPS (N open)`).** Read `reference/disposition-protocol.md` and follow it for the carried-open render (dense) grammar, the response grammar, and the 9-step execute order. Render the human decision menu in the shape below, with the sentinel's `happy-path:` line (when present) printed as one informational line directly under the `Conformance: N decisions needed before shipping.` header - a `failed - attributed to G<n>,...` value names the rows whose evidence is the transcript, a `rescope` recommendation on such a row means the failure lies in code the change never owned - drive the dispositions per that reference, then print the summary render and continue to Step 4. If that reference file cannot be read, stop and surface a blocking error — do **not** improvise the grammar from memory.
99
+ **Carried-open (`status: GAPS (N open)`).** Read `reference/disposition-protocol.md` and follow it for the carried-open render grammar, the response grammar, and the 9-step execute order. Render the human decision menu in the shape below; print the `Conformance: N decisions needed before shipping.` header below the item list, followed by the sentinel's informational lines (`happy-path:`, `Deferred/deviates per spec:`, `whole-diff minors:`) when present, in that order, above the reply instruction - a `failed - attributed to G<n>,...` value names the rows whose evidence is the transcript, a `rescope` recommendation on such a row means the failure lies in code the change never owned - drive the dispositions per that reference, then print the summary render and continue to Step 4. If that reference file cannot be read, stop and surface a blocking error — do **not** improvise the grammar from memory.
100
100
 
101
101
  Representative carried-open render (multi-concern gap split to `e2e`; single-concern gap `cache`; `UNAUTHORIZED` gap `auth`):
102
102
 
103
103
  ```
104
- Conformance: 3 decisions needed before shipping.
105
-
106
- * e2e - Source-image E2E validation: not run; blocked (HYDRA1.png, HTTP 401).
107
- Still in scope for this branch? Recommended: rescope (defer until image available) (fix-now N/A: needs HYDRA1.png).
108
- * cache - Cache coverage: implemented but the spec is silent on it.
109
- In scope? Recommended: accept into spec (behavior is intentional).
110
- * auth - Unrequested admin bypass: adds an unlisted route. Should this unrequested behavior become part of the current workflow? Recommended: fix-now = remove it (rescope N/A: scope creep).
104
+ 1. Source-image E2E validation - not run; blocked (HYDRA1.png, HTTP 401), so the branch ships without its end-to-end evidence.
105
+ The spec requires this validation, but HYDRA1.png is unavailable; decide whether it stays in scope for this branch.
106
+ what: The spec's Verification section gains a line deferring the source-image E2E run until the image is available.
107
+ why: The branch cannot produce that evidence without the image.
108
+ Example: Run the packed-image E2E before merge -> deferred until HYDRA1.png is available
109
+ Reviewer: not reviewed - the pre-menu funnel drafts only recommended-accept items
110
+ Impact: Verification: E2E evidence required before merge -> deferred until the image lands
111
+ A) accept - Ratify shipping without the end-to-end evidence in the spec.
112
+ B) rescope - Defer the validation requirement in the spec until the image is available.
113
+ C) follow-up - Transfer validation to separately owned work with a tracked ticket.
114
+ Custom: <your own answer> - Execute your disposition after clarifying its effect.
115
+ Recommended: B - Defer until the image is available.
116
+ Not available: fix-now - needs HYDRA1.png
117
+
118
+ 2. Cache coverage - implemented but the spec is silent on it, leaving the intended contract unclear.
119
+ Spec and code disagree; decide whether the implemented behavior is in scope.
120
+ what: The spec's Design section gains a clause ratifying the implemented cache coverage.
121
+ why: The behavior is intentional and the spec is silent.
122
+ Example: spec silent on cache coverage -> Design states the cache covers the rendered menu path
123
+ Reviewer: not reviewed - origin quotes an acceptance criterion
124
+ Impact: Design: no cache-coverage contract -> cache coverage is ratified as specified behavior
125
+ A) fix-now - Align the implementation with the current spec.
126
+ B) accept - Ratify the implemented cache behavior in the spec.
127
+ C) rescope - Explicitly remove or defer the origin requirement in the spec.
128
+ D) follow-up - Transfer the concern to separately owned work with a tracked ticket.
129
+ Custom: <your own answer> - Execute your disposition after clarifying its effect.
130
+ Recommended: B - The behavior is intentional.
131
+
132
+ 3. Unrequested admin bypass - adds an unlisted route, expanding the workflow beyond approved scope.
133
+ Should this unrequested behavior become part of the current workflow?
134
+ A) fix-now - Remove the unrequested admin bypass.
135
+ B) accept - Ratify the bypass as approved scope in the spec.
136
+ C) follow-up - Transfer the decision or removal task to separately owned work with a tracked ticket.
137
+ Custom: <your own answer> - Execute your disposition after clarifying its effect.
138
+ Recommended: A - Remove the unrequested behavior.
139
+ Not available: rescope - scope creep
111
140
 
112
- Other options per item: fix-now / accept / rescope / follow-up / custom.
141
+ Conformance: 3 decisions needed before shipping.
113
142
 
114
- 1. Go with recommended
115
- 2. Recommended except <handle>=<choice> e.g. "2: cache=follow-up"
143
+ Reply with one line per item: `1. C`, `2. A`. Bare `1` takes every recommendation and re-asks items without one by number.
116
144
  ```
117
145
 
118
- A single-concern render is identical minus the split: one bullet whose handle is the gap ID or word, no sibling.
146
+ A single-concern render is identical minus the split: one numbered item, no siblings.
119
147
 
120
148
  Execute the chosen dispositions per `reference/disposition-protocol.md` (Execute order), then print the closure summary and continue to Step 4:
121
149
 
@@ -1,34 +1,39 @@
1
1
  # Carried-open disposition protocol
2
2
 
3
- Consumed by `finishing-a-development-branch` Step 3.5 on the **GAPS branch only** — the CONFORMS fast path never reads this file. Antecedent map for the relocated grammar below: "the reference" = `../../verification-before-completion/reference/conformance-check.md` (canonical for the availability table, the `UNAUTHORIZED` question, the `recommended: none` preflight, the freshness rule, and the concern-scoped fix projection); "Revert semantics", "the zero-gap path", and every `Step N` (`Step 1`, `Step 3.5`, `Step 4`) reference = `../SKILL.md`.
3
+ Consumed by `finishing-a-development-branch` Step 3.5 on the **GAPS branch only** — the CONFORMS fast path never reads this file. Antecedent map for the relocated grammar below: "the reference" = `../../verification-before-completion/reference/conformance-check.md` (canonical for the availability table, the `UNAUTHORIZED` question, the `recommended: none` rule, the freshness rule, and the concern-scoped fix projection); "Revert semantics", "the zero-gap path", and every `Step N` (`Step 1`, `Step 3.5`, `Step 4`) reference = `../SKILL.md`.
4
4
 
5
- **Carried-open render (dense).** Read the `## Closure / conformance` block. Render a header with the decision count, one bullet per decision unit (a gap by default; a `Gn/Cn` concern only where the reference split it), then the shared options line, then the recommended-set reply. Never show durable-card internals (ownership, evidence tokens, identity, hashes) in the render.
5
+ **Carried-open render (numbered brief).** Read the `## Closure / conformance` block. The menu text is written after the recommendation is decided, never while deciding it. Negative example: `recommended: custom? Hmm. Dispositions: fix-now ... Actually, the amended spec makes G2 ...`.
6
6
 
7
- Each bullet:
7
+ Open with item 1's plain-words problem sentence, never metadata. Render one numbered item per decision unit (a gap by default; a `Gn/Cn` concern only where the reference split it):
8
8
 
9
- `* <handle> - <plain title>: <what's unresolved, one clause>. <short question> Recommended: <choice> (<one-clause why>).`
9
+ ```text
10
+ <n>. <plain title> - <what is unresolved and what it costs, one sentence>.
11
+ <why this is a human call, one sentence>.
12
+ A) <option> - <one-line consequence>
13
+ B) <option> - <one-line consequence>
14
+ Custom: <your own answer> - <the availability table's custom effect, one line>
15
+ Recommended: <letter> - <reason>
16
+ Not available: <option> - <missing prerequisite>
17
+ ```
10
18
 
11
- - `<handle>` leads the bullet and is a short unique human word derived from the title (`Cache coverage` -> `cache`); on collision append a digit. It is the token option 2 targets. When a gap split and no clean word fits, use the bare `Gn/Cn`; a single-concern gap uses its gap ID `Gn`.
12
- - The shared options line sits below the bullets: `Other options per item: fix-now / accept / rescope / follow-up / custom`, listing the options **generally available across items**. When a specific item's availability deviates - an option unavailable for it, or an `UNAUTHORIZED` item whose `rescope` is unavailable and whose `fix-now` means removal - note that deviation as a short parenthetical on **that item's bullet** (one clause, not a block), e.g. `(rescope N/A: scope creep)`. The shared line appears **only in the carried-open render**, never in the zero-gap path. Full per-option effects only on request, or when option 2 targets an unclear choice.
13
- - Group items under one recommended line only when they share a disposition and rationale; each grouped handle repeats its title.
14
- - A bullet whose recommendation edits the spec (`accept-into-spec`, `rescope-into-spec`, or an item the pre-menu funnel escalated) carries, indented under it, `what` and `why` as one sentence each, `Example: <before -> after>`, `Reviewer: <one-line reason verbatim | not reviewed - <the Conformance entry step 1 exclusion that kept it out> | reviewer unavailable: <reason>>`, and `Impact: <spec section>: <approved contract> -> <new contract>; ...` - the readable card from `../../brainstorming/reference/amendment-surface.md`, adapted to this bullet. Escalated items are ordinary rows here; no second amendment menu renders.
15
- - Availability per concern comes from the reference's single availability table - apply it against current context (worktree state, `maxFixRounds`, ownership, resource accessibility), do not restate it. `UNAUTHORIZED` bullets ask the reference's question verbatim (`Should this unrequested behavior become part of the current workflow?`); `rescope-into-spec` is shown **unavailable** (not dropped) and `fix-now` means **removal** of the unrequested code.
16
- - `revert conformance fix Gn`, when the gap has an auto-applied fix, renders on the shared options line as a **separate one-off action** - never inside a bullet's recommendation and never in the option-2 list. Name the parent gap and warn that revert undoes the entire gap-level commit (see "Revert semantics").
19
+ - Build the problem sentence from the concern card's existing `unresolved` and `impact`; invent no sentence sources at render time. Derive the human-call sentence from the verdict: `UNAUTHORIZED` asks `Should this unrequested behavior become part of the current workflow?` verbatim; `MISSING`/`PARTIAL` says the spec requires it and implementation is incomplete or blocked, naming the missing prerequisite; `DRIFTED` says spec and code disagree and only the human can say which is the contract. For a fix gap carried open because the fix loop cannot run (`maxFixRounds: 0`, no named-branch worktree, unknown ownership), say so and name the prerequisite.
20
+ - For a spec-editing recommendation (`accept-into-spec`, `rescope-into-spec`) or a pre-menu escalated item, indent the readable card between the problem sentence and lettered options: `what` and `why` as one sentence each, `Example: <before -> after>`, `Reviewer: <one-line reason verbatim | not reviewed - <the Conformance entry step 1 exclusion that kept it out> | reviewer unavailable: <reason>>`, and `Impact: <spec section>: <approved contract> -> <new contract>; ...`. Adapt the card from `../../brainstorming/reference/amendment-surface.md`; keep escalated items here, not in a second menu.
21
+ - Apply the reference's single availability table against current context (worktree state, `maxFixRounds`, ownership, resource accessibility); do not restate it. Letter available named options in table row order (`fix-now`, `accept`, `rescope`, `follow-up`), skipping unavailable ones. Lettering follows availability only - a `No recommendation - pick one` item letters its available options like any other. Give every lettered option the table's one-line effect for this verdict. Keep letters stable for the shown menu; map each pick to its shown disposition token. Use the menu's short forms `accept` and `rescope` for the canonical `accept-into-spec` and `rescope-into-spec`.
22
+ - Keep one unlettered `Custom:` line per item as shown. Keep unavailable options visible and unlettered as `Not available: <option> - <missing prerequisite>`; render `UNAUTHORIZED` rescope as `Not available: rescope - scope creep`, and its `fix-now` consequence as removal of the unrequested code. Show no bare option tokens.
23
+ - Use exactly `Recommended: <letter> - <reason>`, with a one-sentence reason tied to the end goal or a development practice, or `No recommendation - pick one` when no named choice is executable. Never recommend custom.
24
+ - Below the item list, render `Conformance: N decisions needed before shipping.` (when the count is 1, write `Conformance: 1 decision needed before shipping.`), then the informational `happy-path:`, `Deferred/deviates per spec:`, and `whole-diff minors:` lines in their current relative order, above the reply instruction: `Reply: one line per item: <n>. <letter or free text>; bare "1" takes every recommendation and re-asks items without one by number.` Keep handles and durable-card internals (ownership, evidence tokens, identity, hashes) out of the prompt.
25
+ - Render `revert conformance fix Gn` for an indexed auto-applied fix on its own line outside the items, never lettered. Name the parent gap and warn that revert undoes the entire gap-level commit (see "Revert semantics").
17
26
 
18
27
  #### Response grammar
19
28
 
20
- ```
21
- 1 -> apply every recommendation
22
- 2: cache=follow-up
23
- 2: e2e=custom(open ticket after image lands), cache=follow-up
24
- ```
29
+ One reply line per item: `<n>. <letter or free text>`. Free text is always the custom path (`custom(<text>)`), even when it matches a shown option's name - letters pick options, text instructs. No other forms: no bare letters, no mixing bare `1` with item lines.
25
30
 
26
- - `1` (or `apply recommended`) applies all recommendations.
27
- - `2:` takes a comma-separated override list, each `<handle>=<choice>`; omitted items keep their recommendation. A handle may appear at most once (repeat = invalid).
28
- - `custom(<concrete effect>)` supplies an inline effect. Manual fix-in-place is expressed only as `custom(...)` where isolated `fix-now` is unavailable.
29
- - `recommended: none` items follow the reference's preflight (linked, not restated): the item needs a `<handle>=custom(...)` decision, and option 1 is withheld until every open item has an executable recommendation; after the custom decision the menu re-renders for the remainder.
30
- - `revert conformance fix Gn` is a valid standalone reply, mutually exclusive with `1` and `2:`; it never appears inside a `2:` override list.
31
- - Invalid handle or choice -> focused reprompt naming only that item, retaining every valid pick and never reopening the gate. Unknown token: list the valid titled handles. Known item, bad choice: repeat its title + its available choices.
31
+ - Bare `1` (or `apply recommended`, accepted, never advertised) applies every item that has a recommendation and re-asks only the items without one, by number, never re-rendering the whole menu.
32
+ - An omitted item keeps its recommendation; an omitted no-recommendation item is re-asked by number, same as after a bare `1`.
33
+ - A legacy `2: <handle>=<choice>` reply is accepted silently as the same picks and recorded normally; the form is never rendered in a prompt.
34
+ - An invalid number or letter gets a focused reprompt naming only that item, retaining every valid pick, never reopening the gate. A bare digit other than `1` is an invalid reply and reprompts the same way.
35
+ - `revert conformance fix Gn` is a standalone reply, mutually exclusive with numbered lines and bare `1`; it never takes a letter and never waits on undecided items - the decide-everything-first barrier binds disposition batches only. Run execute-order step 8 without applying any recommendation.
36
+ - Nothing in a disposition batch executes until every item has a decision; then the execute order below runs once. Keep original item numbers through re-asks; no re-audit runs before the batch is decided.
32
37
 
33
38
  #### Execute order
34
39
 
@@ -44,4 +49,4 @@ Take **no** disposition action before the reply. Then, once, in order:
44
49
  8. **revert** (`revert conformance fix Gn`): light-revert the indexed commit, re-run Step 1's canonical tests; on failure stop; on pass re-audit and regenerate.
45
50
  9. Re-enter Step 3.5 with the re-audited block if any concern remains open.
46
51
 
47
- Record every final disposition with its **stable ID** as `Gn/Cn - <title>: <disposition>` (or `Gn - <title>: <disposition>` for a single-concern gap) - ticket ID/URL for `follow-up`, result for `custom`; never relabel a `custom` result as a recommendation. This durable record is the machine/audit surface; the interactive render stays handle-based. Then continue to Step 4:
52
+ Record every final disposition with its **stable ID** as `Gn/Cn - <title>: <disposition>` (or `Gn - <title>: <disposition>` for a single-concern gap) - ticket ID/URL for `follow-up`, result for `custom`; never relabel a `custom` result as a recommendation. This durable record is the machine/audit surface; keep canonical disposition tokens. After the reply, print each decided item's short-form choice in `Recorded: <handle>=<choice>, ...` (e.g. `Recorded: cache=accept, e2e=rescope`); keep custom choices as `custom(<text>)` with the reply's free text verbatim. Derive handles internally from a short unique word in the title; append a digit on collision. When no clean word fits, use `Gn/Cn` for a split concern or `Gn` for a single-concern gap. Use `<handle>=<choice>` only in this record line and silently accepted legacy replies, never in a prompt. Then continue to Step 4:
@@ -312,21 +312,7 @@ executable choice exists" - and its `rationale` must name the exact missing
312
312
  prerequisites plus the concrete custom effect still required. `custom` is never
313
313
  auto-recommended, so `none` never silently resolves to `custom`.
314
314
 
315
- A concern with `recommended: none` is excluded from the recommended set. Before
316
- any exhaustive `Apply recommended set`, the finish gate asks for a targeted
317
- custom approval that supplies a concrete effect for that one concern (finishing
318
- owns the exact reply syntax - a per-item `custom(...)` decision - not an `apply
319
- recommended` variant). That reply approves only that concrete custom effect for
320
- that concern. Validate and normalize it immediately: if the effect is ambiguous or
321
- unexecutable, clarify and keep the concern open; if executable, record it as a
322
- **pending approved custom decision** and remove that concern from the still-open
323
- inventory used to build the recommended set. If other open concerns remain,
324
- render the exhaustive recommended set for them and visibly carry the pending
325
- approved custom decision through the existing action-order and freshness
326
- barriers; `apply recommended` approves only the remaining recommendations. If no
327
- other concerns remain, execute the approved custom directly through the existing
328
- mechanics. The final disposition record keeps this concern as a `custom` result;
329
- never relabel it as a model recommendation.
315
+ A concern with `recommended: none` is excluded from the recommended set. It renders as `No recommendation - pick one` with its lettered options (finishing owns the render and the exact reply syntax). When the human's reply decides every recommended item (a bare `1`, or numbered lines covering them) but leaves a `recommended: none` item unanswered, the item is re-asked by its number, alone, never re-rendering the whole menu. Use the same one-line reply form as any item: a letter picks the shown option and records that option's disposition token (`accept` -> `accept-into-spec`, `rescope` -> `rescope-into-spec`, `follow-up` stays `follow-up`); free text is `custom(<text>)` and requires a concrete effect. Validate and normalize the custom effect immediately: ambiguous or unexecutable -> clarify and keep the concern open; never relabel a lettered pick as `custom`, and never relabel a `custom` result as a model recommendation.
330
316
 
331
317
  **Never recommend an unavailable disposition or an unexecutable `custom`
332
318
  placeholder.**
@@ -399,8 +385,9 @@ For each carried-open gap, emit a durable gap header plus one card per concern
399
385
  lists, clarification lists, and final disposition records, every user-facing
400
386
  identifier carries both its ID **and** title; bare `Gn`/`Cn` or grouped
401
387
  identifier lists without titles are prohibited. The only exceptions are the
402
- machine/interaction tokens the grammar requires: bare `Gn/Cn` inside typed
403
- response tokens, the literal `conformance fix Gn` commit/action identifiers, and
388
+ machine/interaction tokens the grammar requires: bare handles inside the
389
+ `Recorded:` disposition line and accepted legacy replies, the literal
390
+ `conformance fix Gn` commit/action identifiers, and
404
391
  the flat `auto-applied fix commits` index below. The surrounding prompt or list
405
392
  must map each token to its titled concern or gap before asking for input.
406
393