pi-gauntlet 5.16.2 → 5.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## v5.17.0 - 2026-09-22
4
+
5
+ - `finishing-a-development-branch` runs the plan header's `**Verification:**` set once at ship: Step 1 skips when that set passed in this session's verify phase and `git -C "$WORKTREE" diff --quiet <verified commit> HEAD -- . ':!<telemetry.dir>'` is clean, so the gated flow verifies once before a PR and twice before a squash (the post-squash run stays). The landing menu is renumbered - 1 Push + PR, 2 Push + draft PR (`gh pr create --draft`), 3 Squash-merge, 4 Keep, 5 Discard (detached HEAD: PR, draft PR, Keep, Discard); overrides files that pin finishing option numbers need updating. `writing-plans` defines the header set for multi-service repos as the affected services' commands. `scripts/ci.mjs` pins the three landing headings.
6
+
7
+ ## v5.16.3 - 2026-09-22
8
+
9
+ - The amendment human batch card carries what the reviewer funnel already knows: the header names the step that raised the batch and the plan consequence of applying as recommended (`from <trigger>; applying as recommended reopens <ids>; <phase consequence>`), each item quotes the reviewer's verdict verbatim on a `Reviewer:` line (`not reviewed - <rule>` for prefiltered items, `reviewer unavailable: <reason>` on a failed dispatch), and `Impact:` states the approved-contract shift per spec section instead of listing plan tasks. The finish-gate disposition bullet mirrors `Reviewer:` and `Impact:`. Supersedes the card fields of `doc/specs/2026-09-19-readable-amendment-gates.md`.
10
+
3
11
  ## v5.16.2 - 2026-09-22
4
12
 
5
13
  - gatekeep-pr: `SKILL.md` is a flow-ordered body under 250 lines; the assessment phases, finding IDs and dispositions, consent table and courses, and the post-selection loop move to `skills/gatekeep-pr/reference/{assessment,findings,decision-menu,post-selection-loop}.md`, each rule owned once. The CI telemetry-salvage probe reads `reference/post-selection-loop.md`. (#43)
package/README.md CHANGED
@@ -40,7 +40,7 @@ Concretely, one change through the gauntlet:
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
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. 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.
43
- 5. **`finishing-a-development-branch`**: squash, PR, keep, or discard. Once a PR exists, run `/skill:gatekeep-pr <pr>` to verify it against its issue before merging. **Human gate 2** - the only other decision you make.
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 against its issue before merging. **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 invocation only, no auto-chain: deploys commonly lag merges by minutes to hours, so an auto-run would routinely check too early.
45
45
 
46
46
  Only the machine-owned `plan -> implement` and `verify -> ship` handoffs receive a branch-local one-shot nudge after an unexpected settled stop; it is fire-and-forget, does not bypass either human gate, and older Pi hosts without `agent_settled` retain existing behavior.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-gauntlet",
3
- "version": "5.16.2",
3
+ "version": "5.17.0",
4
4
  "description": "Opinionated, gated workflow skills, subagent personas, and runtime extensions for the pi coding agent.",
5
5
  "author": "Jacek Juraszek",
6
6
  "type": "module",
@@ -62,18 +62,19 @@ Expected reply - one line per item, nothing else:
62
62
  <handle>: auto-apply | escalate - <one-line reason> - probed: <check> - <result>
63
63
  ```
64
64
 
65
- Fail closed: a dispatch error, an async handle, a silence-kill, or a missing or malformed line -> that item (every item when the dispatch failed) is `escalate`, and the batch menu carries `reviewer unavailable: <reason>`.
65
+ Fail closed: a dispatch error, an async handle, a silence-kill, or a missing or malformed line -> that item (every item when the dispatch failed) is `escalate`, its `Reviewer:` line `reviewer unavailable: <reason>`.
66
66
 
67
67
  ## 4. Human batch - one menu
68
68
 
69
- Render only escalated and prefiltered items. Nothing symbol-dense above the fold; each item's `old -> new` sits under `Details`, after the footer.
69
+ 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.
70
70
 
71
71
  ```
72
- Spec amendments: <N> need your call.
72
+ Spec amendments: <N> need your call - from <trigger>; applying as recommended <reopens | adds | removes> <task ids | no tasks>; <phase consequence | no phase change>.
73
73
 
74
74
  * <handle> - <title>: <what>. <why>.
75
75
  Example: <before -> after>
76
- Impact: <plan tasks/waves affected, or: no plan yet>
76
+ Reviewer: <one-line reason verbatim | not reviewed - <prefilter rule> | reviewer unavailable: <reason>>
77
+ Impact: <spec section>: <approved contract> -> <new contract>; ...
77
78
  Recommended: <accept | alt-n> (<one-clause why>).
78
79
  Alternatives: alt-1 <one line>; alt-2 <one line>
79
80
 
@@ -84,6 +85,10 @@ Details
84
85
  <handle>: <location> - old: <text> -> new: <text>
85
86
  ```
86
87
 
88
+ `<trigger>` is the step the main loop is running when the batch forms: `the spec review`, `planning Task <n>`, `Task <n> BLOCKED`, `the verify-phase code review (FIX_FIRST <ids>)`, `the finish-gate council-edit revert`, else `the <phase> phase`; `your request` only for an amend the user raised in prose. The plan clause is the section 5 aftermath as `recommended` would land, over reviewer-cleared plus rendered items, read from the plan file and tracker state - call no `plan_tracker`/`phase_tracker` before the reply: any of `reopens <ids>`, `adds <n> task(s)`, `removes <ids>`, comma-joined (`reopens no tasks` when the plan is untouched), then `; restarts implement, then verify` when a reopen lands in `verify`/`ship`, else `; no phase change`.
89
+
90
+ `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`.
91
+
87
92
  `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. Take no action before the reply.
88
93
 
89
94
  ## 5. Apply, aftermath, commit
@@ -110,7 +115,7 @@ Called from `finishing-a-development-branch` Step 3.5, before the carried-open m
110
115
  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.
111
116
  2. Review (step 3), apply and commit (step 5).
112
117
  3. Re-audit against the amended spec; regenerate the inventory. Only concerns the re-audit closed drop out; sibling concerns keep their rows.
113
- 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:`) 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)`.
118
+ 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)`.
114
119
 
115
120
  ## Worked example
116
121
 
@@ -130,19 +135,22 @@ Eight synthetic items modelled on one real run. Items 1-5 and 8 reach the review
130
135
  The reviewer clears items 1-5; nothing is applied yet. The batch renders items 6-8 (items 1-5 apply together with the accepted ones after the reply):
131
136
 
132
137
  ```
133
- Spec amendments: 3 need your call.
138
+ Spec amendments: 3 need your call - from Task 7 BLOCKED; applying as recommended reopens Tasks 4, 6; no phase change.
134
139
 
135
140
  * scope - ROP feed out of scope: adds an out-of-scope line for the ROP feed to Non-goals. Drops a deliverable you approved.
136
141
  Example: regulator feed = NERC filings + ROP announcements -> NERC filings only
137
- Impact: Task 4, Wave 2
142
+ Reviewer: not reviewed - removes approved scope
143
+ Impact: Non-goals: the ROP feed ships this release -> (removed)
138
144
  Recommended: accept (the ROP source has no stable page this release).
139
145
  * count - Fewer announcements per fetch: the acceptance criterion drops from at least 3 to at least 1. Lowers the bar you set.
140
146
  Example: 3 items per fetch -> 1
141
- Impact: Task 6
147
+ Reviewer: not reviewed - acceptance-criteria location
148
+ Impact: Acceptance criteria: a fetch yields three or more announcements -> one or more
142
149
  Recommended: accept (the captured fixture has one item; the criterion assumed three).
143
- * bytes - Fixture byte count: the verification line changes from 41,208 to 43,117 bytes. No measurement was cited, so the reviewer could not confirm it.
150
+ * bytes - Fixture byte count: the verification line changes from 41,208 to 43,117 bytes. The verification line would assert a size nobody measured.
144
151
  Example: 41,208 bytes -> 43,117 bytes
145
- Impact: no plan yet
152
+ Reviewer: rubric (a) fails - no measurement cited for the new byte count
153
+ Impact: Verification: the fixture measures 41,208 bytes -> 43,117 bytes
146
154
  Recommended: alt-1 (measure first; apply whatever `wc -c` reports).
147
155
  Alternatives: alt-1 replace the number with the `wc -c` result
148
156
 
@@ -32,9 +32,11 @@ Then call `phase_tracker({ action: "start", phase: "ship" })`.
32
32
 
33
33
  ### Step 1: Verify Tests
34
34
 
35
- **Hard verification gate.** Tests/format/lint must pass before presenting any options — including Discard. The user's stated intent to throw the branch away does not change whether the diff is in a verifiable state; verifying first surfaces accidental damage to unrelated code before the branch is gone forever. No exceptions.
35
+ **Hard verification gate.** Tests/format/lint must pass before presenting any options — including Discard. The user's stated intent to throw the branch away does not change whether the diff is in a verifiable state; verifying first surfaces accidental damage to unrelated code before the branch is gone forever. The skip rule below is the only exception.
36
36
 
37
- Run the project's canonical verification target in the worktree: `(cd "$WORKTREE" && <verification command>)`. The exact command lives in the repo's `AGENTS.md` or service-level docs (look for "verification", "CI", or "test" sections). Typical patterns: `make ci`, `npm test`, `pytest`, `cargo test`, `bundle exec rspec`. Cross-cutting changes: run each affected service's target; don't skip any.
37
+ Run the plan header's `**Verification:**` set in the worktree: `(cd "$WORKTREE" && <command>)`. With no plan in this session, run the verification command(s) of the affected services from the gauntlet overrides file or `AGENTS.md` (look for "verification", "CI", or "test" sections).
38
+
39
+ **Skip rule.** Skip the run when this set passed in the verify phase of this session and the tree is unchanged since apart from the telemetry record: `git -C "$WORKTREE" diff --quiet <commit the run passed on> HEAD -- . ':!<telemetry.dir>'` (`<telemetry.dir>` defaults to `.pi/gauntlet/telemetry`) exits 0 and no edit or write landed outside `<telemetry.dir>` since. Otherwise run it once. Unsure means run.
38
40
 
39
41
  **Scoping caveat — pre-existing findings.** Some services carry lint findings unrelated to the diff. If verification fails on lines you didn't touch:
40
42
 
@@ -48,7 +50,7 @@ Tests failing (<N> failures). Must fix before completing:
48
50
 
49
51
  [Show failures]
50
52
 
51
- Cannot proceed with Options 1–3 until tests pass.
53
+ Cannot proceed until tests pass.
52
54
  ```
53
55
 
54
56
  Stop. Don't proceed to Step 2.
@@ -59,7 +61,7 @@ No documentation prompt here: Documentation impact is decided at spec time (`/sk
59
61
 
60
62
  ### Step 2: Detect Environment
61
63
 
62
- Detached HEAD (`git -C "$WORKTREE" symbolic-ref -q HEAD` prints nothing) -> reduced 3-option menu (no merge), no cleanup. Otherwise the standard 4 options.
64
+ Detached HEAD (`git -C "$WORKTREE" symbolic-ref -q HEAD` prints nothing) -> reduced 4-option menu (no merge), no cleanup. Otherwise the standard 5 options.
63
65
 
64
66
  ### Step 3: Determine Base Branch
65
67
 
@@ -144,38 +146,42 @@ Amendments auto-applied (N):
144
146
 
145
147
  Omit the block when N = 0.
146
148
 
147
- **Normal repo and named-branch worktree — present exactly these 4 options:**
149
+ **Normal repo and named-branch worktree — present exactly these 5 options:**
148
150
 
149
151
  ```
150
152
  Implementation complete. What would you like to do?
151
153
 
152
- 1. Squash-merge to <base-branch> (no PR, no surviving branch)
153
- 2. Push and create a Pull Request
154
- 3. Keep the branch as-is (I'll handle it later)
155
- 4. Discard this work
154
+ 1. Push and create a Pull Request
155
+ 2. Push and create a draft Pull Request
156
+ 3. Squash-merge to <base-branch> (no PR, no surviving branch)
157
+ 4. Keep the branch as-is (I'll handle it later)
158
+ 5. Discard this work
156
159
 
157
160
  Which option?
158
161
  ```
159
162
 
160
- **Detached HEAD — present exactly these 3 options:**
163
+ **Detached HEAD — present exactly these 4 options:**
161
164
 
162
165
  ```
163
166
  Implementation complete. You're on a detached HEAD (externally managed workspace).
164
167
 
165
168
  1. Push as new branch and create a Pull Request
166
- 2. Keep as-is (I'll handle it later)
167
- 3. Discard this work
169
+ 2. Push as new branch and create a draft Pull Request
170
+ 3. Keep as-is (I'll handle it later)
171
+ 4. Discard this work
168
172
 
169
173
  Which option?
170
174
  ```
171
175
 
176
+ Rows 1-2 run the Option 1/2 blocks; row 3 runs the Keep block and row 4 the Discard block.
177
+
172
178
  **Don't add explanation** - keep options concise.
173
179
 
174
180
  ### Step 5: Execute Choice
175
181
 
176
- #### Strip the plan, keep the record (Options 1 and 2)
182
+ #### Strip the plan, keep the record (Options 1-3)
177
183
 
178
- Run this on the feature branch before either landing path. The spec and its telemetry record (`<telemetry.dir>/<spec path with .md -> .yaml>`, default `.pi/gauntlet/telemetry/doc/specs/<spec>.yaml`) are deliverables and ship in the squash; only the plan is stripped. `<bin>` is `<directory of this skill's SKILL.md>/../../bin`, resolved from the skill's `<location>` in the system prompt.
184
+ Run this on the feature branch before any landing path. The spec and its telemetry record (`<telemetry.dir>/<spec path with .md -> .yaml>`, default `.pi/gauntlet/telemetry/doc/specs/<spec>.yaml`) are deliverables and ship in the squash; only the plan is stripped. `<bin>` is `<directory of this skill's SKILL.md>/../../bin`, resolved from the skill's `<location>` in the system prompt.
179
185
 
180
186
  ```bash
181
187
  # Plans are ephemeral - if one was committed on this branch, remove it before landing.
@@ -190,27 +196,7 @@ node <bin>/gauntlet-telemetry-salvage.mjs --worktree "$WORKTREE" --base <base-br
190
196
 
191
197
  The salvage prints one line per spec on the branch (`present`, `present <path> (marked shipped)`, `restored <path> from <sha>`, `restored <path> from <sha> (marked shipped)`, `no telemetry run`, `never written`, `restore failed <path>: <reason>`) and always exits 0. `(marked shipped)` means the record was still `in_progress` with no ship phase (the recorder lost its binding) and the salvage committed `status: shipped` + `shipped_at` as one `telemetry:` commit; it rides the squash or push like any branch commit. Print its stdout verbatim in the ship completion message. A `restore failed` line is reported, never retried, and never blocks the ship - the record stays recoverable from the branch ref.
192
198
 
193
- #### Option 1: Squash-merge to base
194
-
195
- Run the strip-and-salvage block above first (plan stripped, telemetry record kept), then:
196
-
197
- ```bash
198
- git -C "$PRIMARY" checkout <base-branch>
199
- git -C "$PRIMARY" pull
200
- git -C "$PRIMARY" merge --squash "$FEATURE"
201
- git -C "$PRIMARY" commit -m "<imperative summary> (ref <ticket-id>)"
202
- (cd "$PRIMARY" && <Step 1 command for the service(s) touched>)
203
- ```
204
-
205
- The plan was already removed on the branch, so the staged squash tree carries the spec, the telemetry record, and the implementation - never the plan.
206
-
207
- The post-squash re-verify is not optional - `git merge --squash` can surface conflict-resolution mistakes the worktree-side run couldn't catch.
208
-
209
- Cleanup worktree (Step 6), then, if Step 6 removed the worktree, `git -C "$PRIMARY" branch -D "$FEATURE"`.
210
-
211
- **No push. No PR.** The squashed commit stays local on `<base-branch>` unless the user explicitly asks to push.
212
-
213
- #### Option 2: Push and Create PR
199
+ #### Option 1: Push and Create PR
214
200
 
215
201
  Run the strip-and-salvage block above first (plan stripped, telemetry record kept), then:
216
202
 
@@ -231,7 +217,7 @@ EOF
231
217
  )")
232
218
  ```
233
219
 
234
- When the spec's `## Acceptance criteria` has at least one `venue:` or `deferred:` row, append this block after `## Test Plan`, listing those rows verbatim with their disposition, so the reader knows what `/skill:check-delivery` verifies after deploy and what a follow-up owns. With no such rows the body ends at `## Test Plan`, byte-identical to today. Option 1's squash commit message is unchanged.
220
+ When the spec's `## Acceptance criteria` has at least one `venue:` or `deferred:` row, append this block after `## Test Plan`, listing those rows verbatim with their disposition, so the reader knows what `/skill:check-delivery` verifies after deploy and what a follow-up owns. With no such rows the body ends at `## Test Plan`, byte-identical to today. Option 3's squash commit message is unchanged.
235
221
 
236
222
  ```markdown
237
223
  ## Acceptance criteria
@@ -241,13 +227,37 @@ When the spec's `## Acceptance criteria` has at least one `venue:` or `deferred:
241
227
 
242
228
  **Do NOT clean up worktree** — user needs it alive to iterate on PR feedback.
243
229
 
244
- #### Option 3: Keep As-Is
230
+ #### Option 2: Push and Create Draft PR
231
+
232
+ Run the strip-and-salvage block above first (plan stripped, telemetry record kept), then Option 1's push and `gh pr create` commands with `--draft` added. The PR body is unchanged. Do not clean up the worktree.
233
+
234
+ #### Option 3: Squash-merge to base
235
+
236
+ Run the strip-and-salvage block above first (plan stripped, telemetry record kept), then:
237
+
238
+ ```bash
239
+ git -C "$PRIMARY" checkout <base-branch>
240
+ git -C "$PRIMARY" pull
241
+ git -C "$PRIMARY" merge --squash "$FEATURE"
242
+ git -C "$PRIMARY" commit -m "<imperative summary> (ref <ticket-id>)"
243
+ (cd "$PRIMARY" && <the Step 1 set>)
244
+ ```
245
+
246
+ The plan was already removed on the branch, so the staged squash tree carries the spec, the telemetry record, and the implementation - never the plan.
247
+
248
+ The post-squash re-verify is not optional - `git merge --squash` can surface conflict-resolution mistakes the worktree-side run couldn't catch.
249
+
250
+ Cleanup worktree (Step 6), then, if Step 6 removed the worktree, `git -C "$PRIMARY" branch -D "$FEATURE"`.
251
+
252
+ **No push. No PR.** The squashed commit stays local on `<base-branch>` unless the user explicitly asks to push.
253
+
254
+ #### Option 4: Keep As-Is
245
255
 
246
256
  Report: "Keeping branch <name>. Worktree preserved at <path>."
247
257
 
248
258
  **Don't cleanup worktree.**
249
259
 
250
- #### Option 4: Discard
260
+ #### Option 5: Discard
251
261
 
252
262
  **Confirm first:**
253
263
  ```
@@ -265,7 +275,7 @@ If confirmed: Cleanup worktree (Step 6), then, if Step 6 removed the worktree, `
265
275
 
266
276
  ### Step 6: Cleanup Workspace
267
277
 
268
- **Only runs for Options 1 and 4.** Options 2 and 3 always preserve the worktree.
278
+ **Only runs for the Squash-merge and Discard options (3 and 5).** The PR, draft PR, and Keep options always preserve the worktree.
269
279
 
270
280
  **If the worktree was created by a project-native script** (e.g. `script/worktree create`, `bin/worktree`): defer to its destroy command, run against the primary: `"$PRIMARY/script/worktree" destroy "${WORKTREE##*/}"`.
271
281
 
@@ -284,10 +294,11 @@ Removal precedes branch deletion in both options; `git branch -d`/`-D` fails whi
284
294
 
285
295
  | Option | Merge | Push | Keep Worktree | Cleanup Branch | Plan strip + record salvage |
286
296
  |---|---|---|---|---|---|
287
- | 1. Squash-merge locally | yes (squash) | - | - | yes (after Step 6 removal) | yes (guarded, on the branch before squash) |
288
- | 2. Create PR | - | yes | yes | - | yes (guarded, on the branch before push) |
289
- | 3. Keep as-is | - | - | yes | - | - |
290
- | 4. Discard | - | - | - | yes (force, after Step 6 removal) | - |
297
+ | 1. Create PR | - | yes | yes | - | yes (guarded, on the branch before push) |
298
+ | 2. Create draft PR | - | yes | yes | - | yes (guarded, on the branch before push) |
299
+ | 3. Squash-merge locally | yes (squash) | - | - | yes (after Step 6 removal) | yes (guarded, on the branch before squash) |
300
+ | 4. Keep as-is | - | - | yes | - | - |
301
+ | 5. Discard | - | - | - | yes (force, after Step 6 removal) | - |
291
302
 
292
303
  A host-owned worktree (Step 6 "Otherwise") keeps both the worktree and the branch.
293
304
 
@@ -295,15 +306,15 @@ A host-owned worktree (Step 6 "Otherwise") keeps both the worktree and the branc
295
306
 
296
307
  **Skipping test verification**
297
308
  - **Problem:** Merge broken code, create failing PR
298
- - **Fix:** Always verify tests before offering options
309
+ - **Fix:** Verify, or apply the Step 1 skip rule, before offering options
299
310
 
300
311
  **Open-ended questions**
301
312
  - **Problem:** "What should I do next?" is ambiguous
302
- - **Fix:** Present exactly 4 structured options (or 3 for detached HEAD)
313
+ - **Fix:** Present exactly 5 structured options (or 4 for detached HEAD)
303
314
 
304
- **Cleaning up worktree for Option 2**
315
+ **Cleaning up worktree for a PR option (1 or 2)**
305
316
  - **Problem:** Remove worktree user needs for PR iteration
306
- - **Fix:** Only cleanup for Options 1 and 4
317
+ - **Fix:** Only cleanup for the Squash-merge and Discard options (3 and 5)
307
318
 
308
319
  **Deleting branch before removing worktree**
309
320
  - **Problem:** `git branch -d` fails because worktree still references the branch
@@ -321,7 +332,7 @@ A host-owned worktree (Step 6 "Otherwise") keeps both the worktree and the branc
321
332
  - **Problem:** Accidentally delete work
322
333
  - **Fix:** Require typed "discard" confirmation
323
334
 
324
- **Skipping the strip-and-salvage block in Options 1 and 2 (any path that lands on base)**
335
+ **Skipping the strip-and-salvage block in Options 1-3 (any path that lands on base)**
325
336
  - **Problem:** Plan docs are ephemeral and shouldn't land on `<base-branch>`; the telemetry record is a deliverable and must. Skipping the block ships the plan, or drops the record the spec index reads.
326
337
  - **Fix:** Run the block on `$WORKTREE` before the squash or the push. The plan stays in the branch's git history (`git -C "$PRIMARY" log --all -- doc/plans/...`). Spec and telemetry record stay on `<base-branch>`; plan does not.
327
338
 
@@ -331,7 +342,7 @@ A host-owned worktree (Step 6 "Otherwise") keeps both the worktree and the branc
331
342
 
332
343
  ## Completion
333
344
 
334
- Once the chosen option (Options 1, 2, or 3 — not Discard) is executed successfully, mark the ship phase complete:
345
+ Once the chosen option (Options 1-4 — not Discard) is executed successfully, mark the ship phase complete:
335
346
 
336
347
  ```
337
348
  phase_tracker({ action: "complete", phase: "ship" })
@@ -350,16 +361,16 @@ Once the merge (and any deploy) has landed, `/skill:check-delivery <ticket-ref>`
350
361
  - Clean up worktrees you didn't create (provenance check)
351
362
  - Run any step without the `<worktree-path>` argument
352
363
  - Auto-proceed past an undispositioned carried-open gap
353
- - Skip the strip-and-salvage block before the Option 1 squash or the Option 2 push
364
+ - Skip the strip-and-salvage block before the Option 3 squash or the Option 1/2 push
354
365
  - Delete the telemetry record (`.pi/gauntlet/telemetry/**` or the configured `telemetry.dir`) on any path
355
366
 
356
367
  **Always:**
357
- - Verify tests before offering options
368
+ - Verify, or apply the Step 1 skip rule, before offering options
358
369
  - Print the `gauntlet-telemetry-salvage.mjs` output verbatim in the ship completion message
359
370
  - Derive `$PRIMARY` and `$FEATURE` from `<worktree-path>` before presenting the menu
360
- - Present exactly 4 options (or 3 for detached HEAD)
361
- - Get typed confirmation for Option 4
362
- - Clean up worktree for Options 1 & 4 only
371
+ - Present exactly 5 options (or 4 for detached HEAD)
372
+ - Get typed confirmation for Option 5 (Discard)
373
+ - Clean up worktree for Options 3 & 5 (Squash-merge, Discard) only
363
374
  - Target `$PRIMARY` with `git -C` for merge, worktree removal, and branch deletion
364
375
  - Run `git -C "$PRIMARY" worktree prune` after removal
365
376
  - Surface the closure / conformance verdict as its own section before the options menu
@@ -11,7 +11,7 @@ Each bullet:
11
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
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
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 and `Example: <before -> after>` - the readable card from `../../brainstorming/reference/amendment-surface.md`, adapted to this bullet. Escalated items are ordinary rows here; no second amendment menu renders.
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
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
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").
17
17
 
@@ -224,7 +224,7 @@ For the fan-out + worktree + patch-integration + conflict mechanics, see `dispat
224
224
  2. **Whole-diff code review.** Only after passing full verification, dispatch one foreground whole-diff `code-reviewer` per `/skill:requesting-code-review` against that committed HEAD, with `SCOPED_TEST_COMMANDS: none`; the reviewer does not repeat the full suite. Address Critical and Moderate findings. Before dispatching a review repair, reopen (`in_progress`) every existing plan-task index whose `Files:` ownership includes its touched files; leave unowned cross-cutting repair work in the review report. Mark each reopened index `complete` only once the repair is re-verified and the re-review accepts it — this is the same completion point step 1's reopened indices wait for, not an extra gate, and the gate order stays full verification -> whole-diff CR -> conformance. Any repair invalidates prior full verification, so rerun the full set successfully before the next gate.
225
225
  3. **Close the loop — conformance check.** The review in step 2 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-2 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. Follow that reference for the partition rule, concern decomposition, and fix-loop mechanics; do not reimplement them here. The fix loop reuses durable `Gn` gap indices as defined in conformance-check.md; it never calls `phase_tracker`. Call `phase_tracker({ action: "complete", phase: "verify" })` only when the reference says the handoff is durably complete: either a current `CONFORMS` result, or a current `## Closure / conformance` inventory whose carried-open concerns all come from valid deferred gaps, including `recommended: fix` gaps carried open because a declared precondition made the fix loop unavailable (`maxFixRounds: 0`, or no eligible named-branch worktree). A started positive-cap fix loop that blocks, fails, or exhausts its rounds with an open `fix` gap is escalation, not completion; on escalation, do not complete verify, stop and report.
226
226
  4. Summarize what was implemented (tasks completed, files changed, test counts, code-review verdict). Emit the `## Closure / conformance` block exactly as defined in `verification-before-completion/reference/conformance-check.md`: it must open with the two-line sentinel (`status: CONFORMS (0 open)` or `status: GAPS (N open)`, then `audited-base: <full HEAD SHA>`), then carry the exact durable concern schema by reference with no renamed or reformatted fields. `finishing-a-development-branch` Step 3.5 consumes that block verbatim.
227
- 5. **Proceed to finishing — no confirmation prompt.** Once verify is complete per step 3's criterion, invoke `/skill:finishing-a-development-branch <abs worktree path>` immediately - the same absolute path every dispatch in this flow carried as `cwd`; finishing stops without it. 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 concerns are resolved there per concern via the `## Closure / conformance` block from step 4. 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.
227
+ 5. **Proceed to finishing — no confirmation prompt.** Once verify is complete per step 3's criterion, invoke `/skill:finishing-a-development-branch <abs worktree path>` immediately - the same absolute path every dispatch in this flow carried as `cwd`; finishing stops without it. Its Step 4 menu (PR / draft PR / squash / keep / discard) is the human gate; a separate "ready to finish?" prompt only stacks a second stop in front of it. Carried-open concerns are resolved there per concern via the `## Closure / conformance` block from step 4. 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.
228
228
 
229
229
  ## Red Flags — STOP
230
230
 
@@ -154,7 +154,7 @@ Each step is **one action, 2-5 minutes**:
154
154
 
155
155
  **Spec:** `<project>/doc/specs/<same-filename-as-this-plan>.md`
156
156
 
157
- **Verification:** `<full verification command set — tests + style + format; a single bundling entrypoint, or the listed individual commands; from the recon report / project overrides>`
157
+ **Verification:** `<full verification command set — tests + style + format; a single bundling entrypoint, or the listed individual commands; from the recon report / project overrides>` - in a repo with per-service verification commands, list the command of every service the change affects (its own files or code it depends on; a repo-wide shared path such as root config, a lockfile, or a shared library affects every dependent service), taking the per-service commands from the overrides file or AGENTS.md when recon reports a single entrypoint
158
158
 
159
159
  **Ticket:** `<ticket-id>` (omit if none)
160
160