pi-gauntlet 7.38.0 → 7.39.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,19 @@
1
1
  # Changelog
2
2
 
3
+ ## v7.39.0 - 2026-10-28
4
+
5
+ ### Added
6
+
7
+ - Spec gate option 6 `approve, hand off as draft PR`: approves the spec's content only, writes `**Engine:** deferred` under `**Amend-grant:** none`, pushes the branch, opens a draft PR carrying just the spec, and ends the flow without planning. The local branch is kept; a gauntlet-owned worktree is removed, a host-owned checkout is reported. Row 6 is withheld on PR subjects and when the diff against the default branch is not spec-only.
8
+ - `brainstorming #N` on an open PR whose diff is one added spec carrying `**Engine:** deferred` plus banner-only predecessor edits re-presents the gate with options 1/2/4/5 (3 only with a pinned council audit), skipping gather, questionary, scout, and council; approval writes `**Engine:**`, `**Amend-grant:**`, and `**PR:** <owner/repo#N>` as a new commit and chains as today. A spec-only diff without the marker runs the normal brainstorm path with the carried spec as the draft; every other PR keeps the rework path.
9
+ - Finishing a spec with `**PR:**` and no `## Rework record` offers `Push to PR #N and mark it ready for review` and `Push to PR #N, keep it a draft` in place of the create rows (non-force push, no body rewrite; row 1 runs `gh pr ready`), withheld when origin's branch head moved. A spec still marked `**Engine:** deferred` stops finishing and `gauntlet-resume` with `spec approved for handoff only - run brainstorming #N`.
10
+
11
+ ## v7.38.1 - 2026-10-28
12
+
13
+ ### Changed
14
+
15
+ - Amendment-aftermath `plan_check` and baseline failures attributable to the batch's edits become at most two retry items in that same batch, with the spec's amend grant controlling automatic apply; unrelated failures, protected paths, exhausted retries, and repeated evidence retain their existing stops, and only eligible tracked paths named by an attributable dirtied-source row receive a narrow orchestrator restore, not general implement-phase cleanup.
16
+
3
17
  ## v7.38.0 - 2026-10-28
4
18
 
5
19
  ### Changed
package/README.md CHANGED
@@ -36,13 +36,13 @@ pi-gauntlet's only hard dependency is pi-cohort - every gate that dispatches a r
36
36
  Concretely, one change through the gauntlet:
37
37
 
38
38
  0. *(Optional)* Before there's even a spec, `/skill:shape-ticket` can create one tracker issue or repair a comma/whitespace list of issue refs - shaping each into a Context/Problem/Idea/Acceptance Criteria ticket, grounded by a repository audit, an AC integrity check, and a cheap council roast. Repair finishes preparation for all tickets before presenting exact-diff confirmations sequentially in ref order; each approval writes that ticket before the next gate, and may include one optional gated comment for a Reporter note or overlap evidence. The audit checks factual claims, Idea fit, AC mechanisms against cited repo guidance, and already-stated observable legs in configured sibling checkouts. It reports in-motion work and attempts a best-effort scenario through authorized current-system reads, without promising reproduction or a fix; missing access or nothing to observe is reported, not a new approval gate. Implementer detail moves into the gated Reporter note; brainstorming reads that note with the ticket so the spec retains the detail. A failed roast is retried once, then surfaced inline at the gate if it fails again. It's a tool, not a phase: no worktree, no plan/phase tracker, runs from any repo state. The agent may start it on its own when the ask is "file a ticket" or another skill routes there; the write still waits for your yes on the presented diff. Similarly, `/skill:chase-bug` triages a raw bug report into an evidenced verdict - and can hand off to shape-ticket, brainstorming, or a bounded hotfix - before any spec exists.
39
- 1. Opt in with `/skill:brainstorming` and describe the change. The command is the reliable discovery-and-entry path; explicit prose requesting brainstorming/the gauntlet also supplies consent when the skill is already loaded or an available instruction or route identifies it. An ordinary implementation request or an agent recommendation is not consent. A leading run of GitHub references (`#N`, `owner/repo#N`, or a `/pull/N` or `/issues/N` URL), separated by whitespace or commas, resolves each reference as a PR first: related open, same-repository, non-fork PRs on one base form one rework subject, including drafts. Admission runs in listed order and relatedness is checked before provisioning; the first retained PR is home, and member heads merge into its existing branch in listed order before the fetched base merges. An unresolved member conflict after its scoped helper aborts that merge and stops the run before any spec, later merge, push, or close. A single non-PR reference follows the ticket path. The first non-reference token starts intent text; mid-sentence references and other ticket/free-text subjects keep their existing paths. The combined code, PR-carried specs, claims, and review threads are the brainstorm input, with each PR's provenance retained; only home's bound ticket supplies acceptance criteria, while member tickets supply context. A single PR retains the same rework path without member merges or a close offer. The combined state is judged against constraints from the fetched current base HEAD, not the fork point or the PRs' proposed policy edits; see the [PR-subject contract](skills/brainstorming/reference/pr-subject.md) and [PR-head worktree owner](skills/using-git-worktrees/reference/pr-head.md). **`brainstorming`** sets up an isolated worktree (on the existing branch for PR rework), explores the codebase, and turns the subject into a written spec - when its recon finds a cited case that the ask is the wrong change (misdiagnosed, wrong-sized, already solved, a band-aid, or cutting across a sound pattern - including a repo convention that is itself debt) and can name the alternative, question one is a framing question (`as framed`, `pivot: <alternative>`, or `smaller or none`); otherwise it opens with one sentence naming what it checked, and every approach it proposes ends with a `Pattern:` line naming what it follows or cuts across; when the run starts from a ticket, the spec carries the ticket's acceptance criteria verbatim, each with a disposition (`in-scope`, `deviates:`, `deferred:`, `venue:`, `elsewhere:` for a row another repo's part delivers), scope cuts come only from your answer to a cut question and are listed at the gate, the conformance gate checks the in-scope ones, and `/skill:check-delivery` verifies `venue:` rows before the prod deploy. A multi-model critique runs on it automatically. If the spec replaces a known prior spec, brainstorming marks the predecessor with a `> **Superseded by:**` banner under its title (default format, syntax overridable via `.pi/gauntlet-overrides.md`; candidates come from brainstorming's scout recon, never a mechanical sweep). **You read and approve the spec - human gate 1.** Before approval, PR rework's sole write/run exception outside the spec directories permits only the base merge, each admitted member-head merge, their conflict helpers' edits to the conflicted files, and their scoped conflict tests; other subjects have no implementation code yet.
39
+ 1. Opt in with `/skill:brainstorming` and describe the change. The command is the reliable discovery-and-entry path; explicit prose requesting brainstorming/the gauntlet also supplies consent when the skill is already loaded or an available instruction or route identifies it. An ordinary implementation request or an agent recommendation is not consent. A leading run of GitHub references (`#N`, `owner/repo#N`, or a `/pull/N` or `/issues/N` URL), separated by whitespace or commas, resolves each reference as a PR first: related open, same-repository, non-fork PRs on one base form one rework subject, including drafts. Admission runs in listed order and relatedness is checked before provisioning; the first retained PR is home, and member heads merge into its existing branch in listed order before the fetched base merges. An unresolved member conflict after its scoped helper aborts that merge and stops the run before any spec, later merge, push, or close. A single non-PR reference follows the ticket path. The first non-reference token starts intent text; mid-sentence references and other ticket/free-text subjects keep their existing paths. The combined code, PR-carried specs, claims, and review threads are the brainstorm input, with each PR's provenance retained; only home's bound ticket supplies acceptance criteria, while member tickets supply context. A single PR retains the same rework path without member merges or a close offer. The combined state is judged against constraints from the fetched current base HEAD, not the fork point or the PRs' proposed policy edits; see the [PR-subject contract](skills/brainstorming/reference/pr-subject.md) and [PR-head worktree owner](skills/using-git-worktrees/reference/pr-head.md). **`brainstorming`** sets up an isolated worktree (on the existing branch for PR rework), explores the codebase, and turns the subject into a written spec - when its recon finds a cited case that the ask is the wrong change (misdiagnosed, wrong-sized, already solved, a band-aid, or cutting across a sound pattern - including a repo convention that is itself debt) and can name the alternative, question one is a framing question (`as framed`, `pivot: <alternative>`, or `smaller or none`); otherwise it opens with one sentence naming what it checked, and every approach it proposes ends with a `Pattern:` line naming what it follows or cuts across; when the run starts from a ticket, the spec carries the ticket's acceptance criteria verbatim, each with a disposition (`in-scope`, `deviates:`, `deferred:`, `venue:`, `elsewhere:` for a row another repo's part delivers), scope cuts come only from your answer to a cut question and are listed at the gate, the conformance gate checks the in-scope ones, and `/skill:check-delivery` verifies `venue:` rows before the prod deploy. A multi-model critique runs on it automatically. If the spec replaces a known prior spec, brainstorming marks the predecessor with a `> **Superseded by:**` banner under its title (default format, syntax overridable via `.pi/gauntlet-overrides.md`; candidates come from brainstorming's scout recon, never a mechanical sweep). **You read and approve the spec - human gate 1.** Options 1/2/4/5 approve and pick an engine; option 6 approves the content only: it writes `**Engine:** deferred` under `**Amend-grant:** none`, pushes the branch, opens a draft PR carrying just the spec, prints the URL, and ends the flow - no plan, no loop, no handoff brief. The branch stays; a gauntlet-owned worktree is removed, a host-owned checkout is reported and left. Option 6 is withheld on a PR subject (`Withheld: draft PR - #N already exists`) and when the branch's diff against the default branch is not spec-only. A later `brainstorming #N` on that PR classifies it from the diff alone: one added spec carrying the marker plus banner-only predecessor edits re-presents the gate with 1/2/4/5 (3 only when the spec commit carries a council audit) and skips gather, questionary, council, and scout; a spec-only diff without the marker prints `spec-only PR without the gate marker - running lint and council` and takes the normal brainstorm path with the carried spec as the draft; any other diff takes the rework path. Approval at that re-gate writes `**Engine:**`, `**Amend-grant:**`, and `**PR:** <owner/repo#N>` as a new commit on the PR branch and chains into planning or the loop as usual. Before approval, PR rework's sole write/run exception outside the spec directories permits only the base merge, each admitted member-head merge, their conflict helpers' edits to the conflicted files, and their scoped conflict tests; other subjects have no implementation code yet.
40
40
  2. By default, **`writing-plans`** decomposes the approved spec into atomic, independently-verifiable tasks, grouped into parallel waves where they don't touch the same files. Experimental approval options 4/5 instead select **`loop-implementation`**: the plan phase is skipped and a stamped acceptance-criteria ledger replaces the task plan. Option 4 retains amendment review; option 5 grants auto-apply amends, with redraws still stopping. See [Loop engine operations](doc/configuration.md#loop-engine-operations).
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
  The loop alternative to step 3 runs one fresh `loop-implementer` per seed or row iteration, without implement-phase reviewers. It stops for a human decision on stagnation or a failed exit verification; passing full verification with every row closed enters the same verify gates.
43
43
 
44
44
  4. **verify**: the parent first runs the plan's full verification command set (the ledger's `verification:` command for loop); only a passing result permits whole-diff code review, then the **conformance gate**. A review fix invalidates that result, so the parent reruns 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.
45
- 5. **`finishing-a-development-branch`**: PR, draft PR, squash, keep, or discard; PR rework also offers a non-force push to the existing PR branch. That push proves every recorded original head remains an ancestor, preserves history, and appends a `## Rework` block naming absorbed PRs while retaining the original description bytes. Only after a successful push and home-description edit does one gated confirmation show the exact close comments and eligible member targets, linking home; declining or any other finish option leaves members open. Closing never deletes member branches, and finish posts no review-thread replies. Its `Before:` handle includes the full portable pre-rework SHA and the local `refs/gauntlet/pre-rework/pr-<N>` ref in the rework checkout. The [finishing owner](skills/finishing-a-development-branch/SKILL.md#pr-subject-row-1-push-to-the-pr-branch) defines the landing and body-update contract. Once a PR exists, run `/skill:gatekeep-pr <pr>` to verify it before merging - it judges the diff against the spec at the PR's head (the acceptance-criteria dispositions and Design you approved; the PR description when no spec applies) - rows the spec defers or deviates are settled, every other row needs its mechanism (code, tests, docs) - and against the rubric; whatever can be seen only after merge is left to step 6. **Human gate 2** - the only other decision you make.
45
+ 5. **`finishing-a-development-branch`**: PR, draft PR, squash, keep, or discard; PR rework also offers a non-force push to the existing PR branch. A spec whose header carries `**PR:**` (approved at a spec-PR re-gate) and no `## Rework record` replaces the two create rows with `Push to PR #N and mark it ready for review` and `Push to PR #N, keep it a draft` (`Push to PR #N (already ready for review)` when the PR is already ready): both push without force after strip-and-seal, the first then runs `gh pr ready`, neither rewrites the PR body, and both are withheld when origin's branch head is no longer an ancestor of local HEAD. A spec still carrying `**Engine:** deferred` stops finishing (and `gauntlet-resume`) with `spec approved for handoff only - run brainstorming #N` before any phase change, verification, or push. The PR-rework push proves every recorded original head remains an ancestor, preserves history, and appends a `## Rework` block naming absorbed PRs while retaining the original description bytes; the header-linked `**PR:**` push leaves the body untouched. Only after a successful rework push and home-description edit does one gated confirmation show the exact close comments and eligible member targets, linking home; declining or any other finish option leaves members open. Closing never deletes member branches, and finish posts no review-thread replies. Its `Before:` handle includes the full portable pre-rework SHA and the local `refs/gauntlet/pre-rework/pr-<N>` ref in the rework checkout. The [finishing owner](skills/finishing-a-development-branch/SKILL.md#pr-subject-row-1-push-to-the-pr-branch) defines the landing and body-update contract. Once a PR exists, run `/skill:gatekeep-pr <pr>` to verify it before merging - it judges the diff against the spec at the PR's head (the acceptance-criteria dispositions and Design you approved; the PR description when no spec applies) - rows the spec defers or deviates are settled, every other row needs its mechanism (code, tests, docs) - and against the rubric; whatever can be seen only after merge is left to step 6. **Human gate 2** - the only other decision you make.
46
46
  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.
47
47
 
48
48
  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.
@@ -54,6 +54,8 @@ flowchart LR
54
54
  T -.-> R
55
55
  B --> G1{{human gate 1:<br/>approve spec}}
56
56
  G1 --> P[plan]
57
+ G1 -.option 6.-> H[draft spec PR]
58
+ H -.brainstorming re-entry.-> G1
57
59
  P --> I[implement<br/>waves + reviews]
58
60
  I --> V[verify]
59
61
  V --> M{{machine gate:<br/>conformance vs<br/>original words}}
@@ -69,7 +71,7 @@ In create mode, `shape-ticket` runs one bounded overlap check after clarificatio
69
71
 
70
72
  Use `/skill:shape-ticket --skip-overlap <ask>` to bypass discovery explicitly. Repair mode never discovers candidates. Bypass still retains source reads, known conflicts, integrity checks, roast, approval, and source revalidation. Incomplete search coverage is disclosed, not treated as proof of no overlap; independent sessions can still race, so this is not a uniqueness guarantee.
71
73
 
72
- Everything between gate 1 and gate 2 - task breakdown, implementation, both review passes - runs without you in the loop. Changing an approved spec later goes through brainstorming's `Amending an approved spec`: a fresh-context reviewer clears evidence-backed factual corrections on its own, escalations reach you as one readable batch, and only a redraw is a full stop - not a third numbered gate. That's the mechanism. What follows is the machinery behind it.
74
+ Everything between gate 1 and gate 2 - task breakdown, implementation, both review passes - runs without you in the loop, once gate 1 picks an engine; option 6 parks the approved spec in a draft PR and planning starts only when someone runs `brainstorming #N` on it and approves at the re-gate. Changing an approved spec later goes through brainstorming's `Amending an approved spec`: a fresh-context reviewer clears evidence-backed factual corrections on its own, escalations reach you as one readable batch, and only a redraw is a full stop - not a third numbered gate. That's the mechanism. What follows is the machinery behind it.
73
75
 
74
76
  ## Architecture
75
77
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-gauntlet",
3
- "version": "7.38.0",
3
+ "version": "7.39.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",
@@ -34,7 +34,7 @@ Treat the flag as discovery control, not harness authorization. The command reli
34
34
 
35
35
  ## Checklist
36
36
 
37
- Work through the items below **in order**. After a user answer or completed side task, resume the current checklist step and perform the next authorized action in the same turn, advancing once that step's required decisions and approvals are satisfied. Continue until a required question is unanswered, an existing approval is pending, the user explicitly pauses, or a failed required tool or unavailable required resource blocks progress. This is your own checklist to follow, not a `plan_tracker` plan — brainstorming is open-ended exploration, and `plan_tracker` is execution-only (the implement phase). The terminal state is the user review gate; after approval route 1/2 to `/skill:writing-plans` and 4/5 to `/skill:loop-implementation` per the gate. Do not jump ahead of approval, and do not silently drop the critique pass.
37
+ Work through the items below **in order**. After a user answer or completed side task, resume the current checklist step and perform the next authorized action in the same turn, advancing once that step's required decisions and approvals are satisfied. Continue until a required question is unanswered, an existing approval is pending, the user explicitly pauses, or a failed required tool or unavailable required resource blocks progress. This is your own checklist to follow, not a `plan_tracker` plan - brainstorming is open-ended exploration, and `plan_tracker` is execution-only (the implement phase). The terminal state is the user review gate; after approval route 1/2 to `/skill:writing-plans` and 4/5 to `/skill:loop-implementation` per the gate; 6 ends the flow after publishing. Do not jump ahead of approval, and do not silently drop the critique pass.
38
38
 
39
39
  1. **Start brainstorm tracking (fresh epoch)** - as the first action on authorized fresh entry, before reading code, the worktree, or answering the user, reset both trackers and start the phase. A new brainstorm owns a clean slate, so stale phases and tasks from earlier work are cleared; re-entering mid-brainstorm is safe (nothing to lose, same clean slate):
40
40
 
@@ -44,7 +44,7 @@ Work through the items below **in order**. After a user answer or completed side
44
44
  phase_tracker({ action: "start", phase: "brainstorm" })
45
45
  ```
46
46
 
47
- 2. **Set up the worktree** - resolve the leading run per `reference/pr-subject.md`; pass the ordered per-PR array (home first) to `/skill:using-git-worktrees`' PR-head path. Then see [Worktree First](#worktree-first).
47
+ 2. **Set up the worktree** - resolve the leading run per `reference/pr-subject.md`; pass the ordered per-PR array (home first) to `/skill:using-git-worktrees`' PR-head path. For a marked spec PR, follow `reference/spec-pr.md`'s re-gate after provisioning (steps 3-11 skipped); otherwise see [Worktree First](#worktree-first).
48
48
  3. **Gather context** - read [Ticket Handling](#ticket-handling), then follow [`gatherer.md`](gatherer.md) without a human stop.
49
49
  4. **Understand the idea against the draft** - if `reference/ticket-acceptance.md` is not already in context this session (restored entry, or a redraw after a fresh start), read [Ticket Handling](#ticket-handling) before the rest of this step; then see [Understand the idea](#3-understand-the-idea).
50
50
  5. **Propose 2-3 approaches** - see [Explore approaches](#4-explore-approaches).
@@ -55,7 +55,7 @@ Work through the items below **in order**. After a user answer or completed side
55
55
  10. **Re-run placeholder scan** - follow [Spec Self-Review](#spec-self-review-before-user-review-gate).
56
56
  11. **Generate spec summary** - follow [User Review Gate](#user-review-gate).
57
57
  12. **User review gate** - follow [User Review Gate](#user-review-gate).
58
- 13. **Transition** - after approval, invoke `/skill:writing-plans` on 1/2 or `/skill:loop-implementation` on 4/5 per [User Review Gate](#user-review-gate).
58
+ 13. **Transition** - after approval, invoke `/skill:writing-plans` on 1/2 or `/skill:loop-implementation` on 4/5 per [User Review Gate](#user-review-gate); 6 ends the flow after publishing.
59
59
 
60
60
  ## Project Routing
61
61
 
@@ -164,7 +164,7 @@ Inside an opted-in flow, shared schemas, contracts, and invariants require a spe
164
164
 
165
165
  Write under the routed spec dir: pick the routing prose's dir (overrides file, `AGENTS.md`) when it is one of the resolved dirs, else the one resolved dir from `gauntlet_setting({ key: "flowGuards" })` that already exists in the repo, else the first resolved dir (`doc/specs` under the default). Name ticketed files `YYYY-MM-DD-<ticket-id>-<topic>.md`, otherwise `YYYY-MM-DD-<topic>.md`. Use a filename-safe tracker slug (`E-12345`, `gh-123`), but native references in plan headers and commits. `<topic>` is 3-6 kebab-case words without `-design` or another suffix.
166
166
 
167
- For a PR subject, apply `reference/pr-subject.md`: keep the bound-ticket filename; name an unbound spec `YYYY-MM-DD-pr-<N>-<topic>.md` from the PR title.
167
+ For a PR subject, apply `reference/pr-subject.md`: keep the bound-ticket filename; name an unbound rework spec `YYYY-MM-DD-pr-<N>-<topic>.md` from the PR title; the unmarked spec-only route keeps the carried spec path.
168
168
 
169
169
  Mint the slug once during gather and reuse it. If questionary invalidates it, write to the new path and delete the uncommitted draft.
170
170
 
@@ -178,7 +178,7 @@ Follow [Spec Council](reference/spec-finalization.md#spec-council) for the manda
178
178
 
179
179
  ## User Review Gate
180
180
 
181
- Follow [User Review Gate](reference/spec-finalization.md#user-review-gate) for summary, commit, approval, and automatic planning.
181
+ Follow [User Review Gate](reference/spec-finalization.md#user-review-gate) for summary, commit, approval, and selected-engine transition or option-6 publication.
182
182
 
183
183
  ## Amending an approved spec
184
184
 
@@ -198,13 +198,13 @@ Redraw: keep the worktree and the approved spec file. `plan_tracker({ action: "c
198
198
  - Draft overwrite without the same-turn full read, or overwrite via `edit` ([owner](#spec-self-review-before-user-review-gate)).
199
199
  - Dispatch while line 1 is the context-draft marker ([owner](#spec-self-review-before-user-review-gate)).
200
200
  - Inline scope or ambiguity checks ([owner](#spec-council)).
201
- - Gate after failed/skipped critique or before placeholder re-scan ([owner](#spec-self-review-before-user-review-gate)).
201
+ - Gate after failed/skipped critique or before placeholder re-scan, except the marked spec-PR re-gate ([owner](#spec-self-review-before-user-review-gate)).
202
202
  - Gate without summary `Read` last, or with a paraphrased summary ([owner](#user-review-gate)).
203
203
  - Human stop between gather and question one ([owner](gatherer.md)).
204
204
  - Proposed-change execution before approval ([owner](#hard-constraint)).
205
205
  - Plan before approval; brainstorming invocation for an amend ([owner](#user-review-gate)).
206
206
  - Missing predecessor banner; invalid multi-spec split ([owner](#spec-self-review-before-user-review-gate); [owner](#2-scope-check)).
207
- - Gate reached without the second predecessor pass ([owner](#spec-self-review-before-user-review-gate)).
207
+ - Gate reached without the second predecessor pass, except the marked spec-PR re-gate ([owner](#spec-self-review-before-user-review-gate)).
208
208
  - Approaches before the premise note states a contradicted claim's correction ([owner](#3-understand-the-idea)).
209
209
  - Approaches before the framing question or the holds-statement (either may follow the premise correction in the same message); a holds-statement that names nothing checked ([owner](#3-understand-the-idea)).
210
210
  - Amend without `reference/amendment-surface.md`; waiting after an amend grant; auto-applying a redraw ([owner](#amending-an-approved-spec)).
@@ -125,8 +125,8 @@ Scout (always dispatched):
125
125
  > "Open questions that matter for the spec"
126
126
  > section. Compact handoff, not a dump.
127
127
 
128
- For a PR subject, supply this additional scout block as values from
129
- `reference/pr-subject.md` (keep scout unconditional):
128
+ For a rework PR subject (shape fails), supply this additional scout block as values
129
+ from `reference/pr-subject.md` (keep scout unconditional):
130
130
 
131
131
  > Require every retained PR's title/body, carried specs, and full threads before
132
132
  > gather, including N=1. Stop on query failure: `threads for #<N> not fetched (<gh error>)`.
@@ -230,7 +230,7 @@ convention; slug minted from the initial prompt):
230
230
  <scout output, or the degraded text>
231
231
 
232
232
  ## PR under rework
233
- <PR subject only: every per-PR scout subsection, ordered original heads, threads,
233
+ <rework PR subject only: every per-PR scout subsection, ordered original heads, threads,
234
234
  member-carried spec paths, and supplied Member merge/base values per
235
235
  reference/pr-subject.md; retain these values even when scout failed>
236
236
 
@@ -142,7 +142,33 @@ Before the aftermath, `read` this section again; never run it from memory.
142
142
 
143
143
  Apply accepted items only: reviewer clears, `accept`, `alt-n`, and state-changing `custom`. Print one line per applied item: `amended the spec: <title> - <what>`.
144
144
 
145
- Aftermath, once per batch, only when at least one item applied (nothing applied -> skip to the commit below). Ledger exists (line 1 `# Ledger - loop engine` in the resolved plan dir) -> skip `plan-writer`, `plan_check`, and `plan_tracker`. Reconcile the ledger against the approved spec dispositions: `deviates:`, `deferred:`, or `elsewhere:` -> `cut`, evidence = the disposition; factual or requirement-preserving amendment -> preserve rows; re-bounded `done` row -> `open`, evidence = `reopened by amendment`. Preserve every row's attempts and the ledger's iterations. Never auto-edit ticket or approved drafted AC row texts; reconcile dispositions only, never text/add/remove changes. Commit spec + ledger together with subject `loop: cut row <n>` for a batch containing only one cut, otherwise `loop: amend` (including mixed batches), carrying the amendment audit body below (including each `granted` record and granting sentence); continue without task-plan aftermath. No plan yet -> commit the spec; continue. Plan exists -> read `git -C "<abs worktree path>" status --porcelain` (plain jj: `jj -R "<abs worktree path>" diff --summary`); collect the parent's in-flight workflow edits as worktree-relative paths, including the amended spec and staged in-place wave-repair deliverables. Dispatch `plan-writer` per `writing-plans` `## Author the plan` step 3 with an `Amend:` block naming the amended spec sections, an `In-flight:` list of those paths (the parent supplies the set; the child never infers it), and the rule "preserve every task title and wave position the amendment does not touch; edit only affected anchors and tasks", then run that section's steps 5-6 (the parent `plan_check` and its branches), then read the amended plan once (step 7's read, without its phase completion or `plan_tracker` init) - the main loop never edits the plan text; then update the tracker: `plan_tracker` `add` for new tasks; anchor-changed completed tasks are reopened as `in_progress` and re-run the task loop (`update` never sets `pending`). A removed task is deleted from the plan; then re-`init` the tracker with `{ name, status }` elements: preserved tasks keep their order and statuses, reopened tasks are `in_progress` in place, every still-`pending` task (including newly added ones, whatever wave label they carry) trails the non-pending ones, removed tasks are the only deletions (the only permitted `init` after handoff; never `clear`). Commit spec + plan together; continue. A task reopened while `verify` or `ship` is in progress stays in that phase - no `phase_tracker` call. Repair it through the current phase's fix loop and `plan_tracker({ action: "update", index: N, status: "complete" })` it once that repair's review or re-audit accepts; open tasks block `complete verify`, and in `ship` nothing checks them, so close them explicitly.
145
+ Aftermath, once per batch, only when at least one item applied (nothing applied -> skip to the commit below). Ledger exists (line 1 `# Ledger - loop engine` in the resolved plan dir) -> skip `plan-writer`, `plan_check`, and `plan_tracker`. Reconcile the ledger against the approved spec dispositions: `deviates:`, `deferred:`, or `elsewhere:` -> `cut`, evidence = the disposition; factual or requirement-preserving amendment -> preserve rows; re-bounded `done` row -> `open`, evidence = `reopened by amendment`. Preserve every row's attempts and the ledger's iterations. Never auto-edit ticket or approved drafted AC row texts; reconcile dispositions only, never text/add/remove changes. Commit spec + ledger together with subject `loop: cut row <n>` for a batch containing only one cut, otherwise `loop: amend` (including mixed batches), carrying the amendment audit body below (including each `granted` record and granting sentence); continue without task-plan aftermath. No plan yet -> commit the spec; continue. Plan exists -> read `git -C "<abs worktree path>" status --porcelain` (plain jj: `jj -R "<abs worktree path>" diff --summary`); collect the parent's in-flight workflow edits as worktree-relative paths, including the amended spec and staged in-place wave-repair deliverables. Dispatch `plan-writer` per `writing-plans` `## Author the plan` step 3 with an `Amend:` block naming the amended spec sections, an `In-flight:` list of those paths (the parent supplies the set; the child never infers it), and the rule "preserve every task title and wave position the amendment does not touch; edit only affected anchors and tasks", then run that section's steps 5-6 (the parent `plan_check` and its branches).
146
+
147
+ At that return point, classify human-facing outcomes with this table; let writing-plans' first `Findings:` repair run as written.
148
+
149
+ | Outcome | Enter the attribution check |
150
+ |---|---|
151
+ | Second identical `plan_check` FAIL | compare the FAIL lines and their quoted plan text |
152
+ | First `- Task N: ... fails on <sha>` or `dirtied tracked source` row | compare the row's baseline command |
153
+
154
+ Compare the quoted FAIL plan text or baseline command with this batch's edits: use the owning task's `Spec:` anchors to an amended section or its changed `Tests:` text against `git -C "<abs worktree path>" show HEAD:<plan path>`. Require text this batch added or changed; neither a plan line number, task membership, nor retained baseline evidence proves attribution. For unchanged text and writer-only defects (such as missing `baseline:` without spec text behind it), render the writing-plans step-6 branch in full from the outcome already in hand: quote the FAIL lines verbatim as the open question; state the task, command, SHA, exit, and summary with `fix-first`, `narrow`, and `amend` options on their own lines and `Recommendation: <option> - <reason>`, then pause; name dirty paths and cause; clear the parent's own wave/amendment source work through its own commit step and list doc-only work under `In-flight:` before re-dispatch; take every other path, including every test-dirtied path, to the human to commit, discard, or move, without restoration - never name step 6 and defer the exit. Partition mixed output: form items only from attributable lines and render the unrelated lines' step-6 branches in full by the same rule. Classify attributable outcomes as amendment items independent of candidate answers and grant state. Keep findings from this batch's own aftermath in this batch until commit; apply section 1's later-finding rule after commit.
155
+
156
+ Apply at most two aftermath items per batch. Send a third human-facing outcome, or evidence repeating an already-applied item's evidence, to step 6 as written without restoration, rendering the exit in full and listing the batch's retry items and evidence. Before restoring any path, handle a redraw-class finding by committing the batch as-is, handing dirty paths to step 6 without restoration, then taking `../SKILL.md`'s redraw path. Treat the spec/plan commit as batch preservation, not cleanup. For an amend-class `dirtied tracked source` row, check every named path with `git -C "<abs worktree path>" ls-files -- "<path>"` and against the spec, plan, and `In-flight:` list. Require every path to print as tracked and to be outside those protected paths before restoring any. Route an entire row with any untracked or protected path through step 6, without partial restoration; a new `??` at a `Create:`/`Test:` path is ineligible. Preserve `artifacts:` and `In-flight:` paths. Restore exactly the eligible row's paths, one quoted path per command, in the explicit worktree; for example:
157
+
158
+ ```bash
159
+ git -C /tmp/report-worktree ls-files -- "eval/report-runner/report.md"
160
+ git -C /tmp/report-worktree checkout -- "eval/report-runner/report.md"
161
+ # Plain jj: root the fileset; -R alone does not root paths.
162
+ jj -R /tmp/report-worktree restore -- 'root:"eval/report-runner/report.md"'
163
+ ```
164
+
165
+ Use the checkout command for git or the restore command for plain jj, not both. Stop on a nonzero restore and print the shell error. Keep this narrow restore with the orchestrator, never the plan-writer or implementer; grant no general permission to restore test damage. Preserve the pre-batch working tree except for batch edits.
166
+
167
+ Hold each eligible item with verbatim FAIL lines or baseline row as `evidence`, the correction as `recommended: accept` or a named `alt-n`, and the amended-section `location`. Re-read the grant through section 1's predicate and Value decoding before applying: malformed -> stop and quote the offending lines; amend permission -> apply the recommended edit and print `amended the spec: <title> - <what>`; budget-only, `none`, or absent -> run sections 2-4 and end the turn without re-dispatch. After the reply, apply only the chosen edit; return a redirect or drop to the original step-6 exit without re-dispatch over the unfixed spec.
168
+
169
+ After an applied aftermath item, re-dispatch the plan-writer with only an `Amend:` block naming the amended sections and quoting the FAIL lines or baseline row inside its rule sentence, plus `In-flight:` including both spec and plan. Preserve unaffected task titles and wave positions. Run the parent's steps 5-6 again through this return point; retain the ledger/no-plan bypass above before any retry.
170
+
171
+ Finalize every plan aftermath path once, only after steps 5-6 return `PASS`, including the first dispatch's `PASS` without a retry: read the amended plan once (step 7's read, without its phase completion or `plan_tracker` init) - the main loop never edits the plan text; then update the tracker: `plan_tracker` `add` for new tasks; anchor-changed completed tasks are reopened as `in_progress` and re-run the task loop (`update` never sets `pending`). A removed task is deleted from the plan; then re-`init` the tracker with `{ name, status }` elements: preserved tasks keep their order and statuses, reopened tasks are `in_progress` in place, every still-`pending` task (including newly added ones, whatever wave label they carry) trails the non-pending ones, removed tasks are the only deletions (the only permitted `init` after handoff; never `clear`). Commit spec + plan together; continue. A task reopened while `verify` or `ship` is in progress stays in that phase - no `phase_tracker` call. Repair it through the current phase's fix loop and `plan_tracker({ action: "update", index: N, status: "complete" })` it once that repair's review or re-audit accepts; open tasks block `complete verify`, and in `ship` nothing checks them, so close them explicitly.
146
172
 
147
173
  One commit per batch:
148
174
 
@@ -153,7 +179,7 @@ amend: <N> item(s) - <first title>[, <second title>]
153
179
  <the granting sentence, quoted, when a grant applied>
154
180
  ```
155
181
 
156
- For a ledger batch, use the loop subject above and retain this same audit body. `amend:` is the subject marker `finishing-a-development-branch` Step 4 greps for its digest; `<what>` is the item's one-sentence what-changes field, so the digest renders `<title> - <what changed>` from the body alone. When no item applied (every item dropped or redirected), nothing changed on disk; the commit still lands, with `git commit --allow-empty`, so the per-item `custom(<effect>)` records stay in the batch body - the digest ignores them because it reads only `auto-apply` and `granted` records. Wrong apply -> `git revert` the batch commit; then read the `**Amend-grant:**` line from the pre-revert HEAD (`git -C <abs worktree path> show HEAD^:<spec path>` through the predicate) and, if the working tree's line differs, restore that value and persist it per [Standing grants](#standing-grants) before re-entering this surface for the items to keep - the pre-revert HEAD holds every consent change committed so far, revocations included.
182
+ Record aftermath items in this same audit as `granted` or `accepted`/`alt-n` with their evidence, in the single `amend:` commit whose `git revert` undoes the retries with the batch. For a ledger batch, use the loop subject above and retain this same audit body. `amend:` is the subject marker `finishing-a-development-branch` Step 4 greps for its digest; `<what>` is the item's one-sentence what-changes field, so the digest renders `<title> - <what changed>` from the body alone. When no item applied (every item dropped or redirected), nothing changed on disk; the commit still lands, with `git commit --allow-empty`, so the per-item `custom(<effect>)` records stay in the batch body - the digest ignores them because it reads only `auto-apply` and `granted` records. Wrong apply -> `git revert` the batch commit; then read the `**Amend-grant:**` line from the pre-revert HEAD (`git -C <abs worktree path> show HEAD^:<spec path>` through the predicate) and, if the working tree's line differs, restore that value and persist it per [Standing grants](#standing-grants) before re-entering this surface for the items to keep - the pre-revert HEAD holds every consent change committed so far, revocations included.
157
183
 
158
184
  ## Conformance entry
159
185
 
@@ -23,6 +23,16 @@ Parse the PR base repository from `url` and this checkout's repository from `git
23
23
 
24
24
  Append this paragraph only for foreign-repository, fork, and mixed-base failures: To rework these together anyway, merge the heads into one branch by hand, open one PR, and brainstorm that PR.
25
25
 
26
+ ## Spec-PR classifier
27
+
28
+ Immediately after ordered admission and before binding, classify N=1 read-only. Derive ROOT from the absolute git common directory using pr-head's Step 0 submodule guard before fetching. N>1 always follows relatedness and rework. Fetch `git -C "$ROOT" fetch origin <baseRefName> <headRefName>`, resolve `BASE_SHA=$(git -C "$ROOT" rev-parse origin/<baseRefName>)`, and inspect `git -C "$ROOT" diff --name-status <BASE_SHA>...<headRefOid>`. Stop on command errors. Apply [spec-pr.md](spec-pr.md)'s shared shape predicate with pinned BASE_SHA/headRefOid, inspecting modified hunks; read the added spec through `git show <headRefOid>:<path>` before testing its exact deferred header marker.
29
+
30
+ | Observation | Route |
31
+ |---|---|
32
+ | Shape fails | Continue unchanged through bind, gather, scout, and Rework record. |
33
+ | Shape passes, marker absent | Print `spec-only PR without the gate marker - running lint and council`. Provision the one-element admitted PR array through pr-head's checkout, base merge, and Step 4 report with no thread fetch (bypass its `## Fetch unresolved review threads` as on the marked route). Skip ticket binding, context-builder, the PR scout block, and gather; never write a `## Rework record`. Resume at checklist step 4 with the carried spec file at `<worktree>/<path>` as the draft, as a redraw does (recon falls to the questionary); spec-writing overwrites that file at its carried path. Run lint, council, and the gate as for any spec, with 6 withheld (`Withheld: draft PR - #N already exists`). On approval 1/2/4/5 persist `**Engine:**`, `**Amend-grant:**`, and `**PR:** <owner/repo#N>` as a new commit per spec-pr.md's re-gate persistence. |
34
+ | Shape and marker pass | Provision the one-element admitted PR array through pr-head's checkout/base merge/Step 4, then follow spec-pr.md's re-gate. Skip binding and all before-gather thread queries. Treat draft and ready PRs equally. |
35
+
26
36
  ## Relatedness before provisioning
27
37
 
28
38
  For N>1, fetch every admitted PR's title/body with `gh pr view <N> -R <owner/repo> --json title,body` and actual diff with `gh pr diff <N> -R <owner/repo>`. On failure stop before provisioning naming the ref and observed reason: `<ref>: title/body not fetched (<gh error>)` or `<ref>: diff not fetched (<gh error>)`.
@@ -41,7 +51,7 @@ Pass an ordered array, home first, of exactly `{ number, url, title, headRefName
41
51
 
42
52
  ## Gather from the PR and fetched base
43
53
 
44
- Require every retained PR's title/body, carried specs, and full threads before spec-writing. Stop before gather on any query failure, N=1 included: `threads for #<N> not fetched (<gh error>)`; name the ref and reason for unreadable title/body/specs too. Discover PR-carried specs per PR with `git diff --name-only <BASE_SHA>...<that PR's headRefOid> -- <each flowGuards.specDirs dir>` using the resolved spec directories. Read every carried spec's contents with `git show <that PR's headRefOid>:<path>` as that PR's stated contract beside its title/body; preserve the owning PR, original head, and path even when multiple PRs carry different versions of the same path. List member-carried spec paths under their PR in `## Problem` so resume can exclude them from new-spec candidates. Only when superseded, name it in `**Predecessor:**` and apply `reference/superseding.md`'s banner; that banner is the allowed spec-directory write.
54
+ Apply this section's thread fetch, carried-spec discovery, scout dispatch, and `## PR under rework` rendering to the rework route only; the unmarked spec-only route skips gather. Require every retained PR's title/body, carried specs, and full threads before spec-writing. Stop before gather on any query failure, N=1 included: `threads for #<N> not fetched (<gh error>)`; name the ref and reason for unreadable title/body/specs too. Discover PR-carried specs per PR with `git diff --name-only <BASE_SHA>...<that PR's headRefOid> -- <each flowGuards.specDirs dir>` using the resolved spec directories. Read every carried spec's contents with `git show <that PR's headRefOid>:<path>` as that PR's stated contract beside its title/body; preserve the owning PR, original head, and path even when multiple PRs carry different versions of the same path. List member-carried spec paths under their PR in `## Problem` so resume can exclude them from new-spec candidates. Only when superseded, name it in `**Predecessor:**` and apply `reference/superseding.md`'s banner; that banner is the allowed spec-directory write.
45
55
 
46
56
  On every merge outcome, including clean, no-op, and unresolved, read constraints using `git show <BASE_SHA>:<path>`: `AGENTS.md`, the first-found overrides file (check `.pi/gauntlet-overrides.md`, `gauntlet-overrides.md`, `doc/gauntlet-overrides.md` in order at BASE_SHA), `REVIEW.md`, and all cited constraint documents. Carry missing-document results explicitly. Use these fetched base-HEAD rules, never fork-point or worktree copies. Treat PR edits to policy documents as proposals recorded under `changes:` or `dropped claims:`, not governing constraints.
47
57
 
@@ -16,8 +16,8 @@ Spec-writing replaces the context draft, in this exact order:
16
16
  Using `edit` at this step is a red flag. The header block (between the H1 and the
17
17
  first `##`) carries `**Amend-grant:** none` directly below `**Goal:**`; a redraw's
18
18
  rewrite carries `none` too - a redraw is a new approval, with no carry-over.
19
- For a PR subject, follow `pr-subject.md`'s spec contract: carry the draft's
20
- `## PR under rework` into `## Rework record` after `## Acceptance criteria`,
19
+ For a rework PR subject (a draft carrying `## PR under rework`), follow `pr-subject.md`'s spec contract:
20
+ carry the draft's `## PR under rework` into `## Rework record` after `## Acceptance criteria`,
21
21
  preserving its repeated PR/Pre-rework head/Threads groups, one per retained PR,
22
22
  home first, each 40-character pre-rework SHA, merge result,
23
23
  keeps/changes/dropped claims, thread dispositions and fetch status, contract exceptions,
@@ -53,7 +53,7 @@ After writing the spec to `<project>/doc/specs/<filename>.md` (per [Filename Con
53
53
  - **Placeholder scan.** Any `TODO`, `TBD`, `<fill in>`, `[example]`, `xxx`? Either resolve them or convert to explicit "Open Questions" with names.
54
54
  - **Internal consistency.** Does Section 4 contradict Section 2? Does the header block carry `**Amend-grant:**` exactly once with the value `none` (the [predicate](amendment-surface.md#standing-grants))? Are component names and field names consistent throughout? If the spec replaces a prior design, confirm the predecessor carries the supersession banner and its href resolves to this spec's final filename.
55
55
  - **Documentation named.** Does the spec name all three classes (feature/user-facing introduced; materially amended; derived/memory invalidated), or an explicit "none" for each? Enforce the materiality bar in `documentation-impact.md` without restating it: each listed doc names the category it clears, none is a code-mirror, amend-over-create was applied, and skill/agent bodies are implementation surface, not doc-impact entries here.
56
- - **Ticket contract present.** Require `## Acceptance criteria` in exactly three forms: ticket provenance (`Ticket <ref>, <heading or "checkbox list">, rows verbatim:`) with verbatim rows and dispositions; drafted provenance (`Drafted from the design, no ticket rows:` or `Drafted from the design, ticket <ref> has no acceptance criteria:`) with at least one `- [ ]` row and a disposition on every row; or the single line `none - ticket not fetched (<reason>)`. Reject `none - no ticket` and `none - ticket has no acceptance criteria` as final bodies. For a PR subject, require the complete `## Rework record` per `pr-subject.md`; absence fails inline lint, including after a full replacement or redraw. Build expected identities and original heads from the provisioning Step 4 report (home plus `MEMBER_HEADS`), not from the record itself. Require each expected identity's `PR:`/`Pre-rework head:`/`Threads:` group with its full matching head and a `### PR #<N>` provenance subsection; reject a missing group or subsection naming the missing PR. Apply the same predicate for N=1.
56
+ - **Ticket contract present.** Require `## Acceptance criteria` in exactly three forms: ticket provenance (`Ticket <ref>, <heading or "checkbox list">, rows verbatim:`) with verbatim rows and dispositions; drafted provenance (`Drafted from the design, no ticket rows:` or `Drafted from the design, ticket <ref> has no acceptance criteria:`) with at least one `- [ ]` row and a disposition on every row; or the single line `none - ticket not fetched (<reason>)`. Reject `none - no ticket` and `none - ticket has no acceptance criteria` as final bodies. For a rework PR subject (a draft carrying `## PR under rework`), require the complete `## Rework record` per `pr-subject.md`; absence fails inline lint, including after a full replacement or redraw. Build expected identities and original heads from the provisioning Step 4 report (home plus `MEMBER_HEADS`), not from the record itself. Require each expected identity's `PR:`/`Pre-rework head:`/`Threads:` group with its full matching head and a `### PR #<N>` provenance subsection; reject a missing group or subsection naming the missing PR. Apply the same predicate for N=1.
57
57
  - **Scope check.** Does every paragraph serve the goal? Cut filler. If something is out of scope, say it's out of scope.
58
58
  - **Ambiguity check.** Is every "we should..." backed by a concrete decision? Replace "we could probably" with "we will" or "we won't".
59
59
 
@@ -151,12 +151,15 @@ New predecessor candidates at spec-writing: <path> (<title>), ... - index rows a
151
151
  3 - show council dispositions: prints the council audit verbatim, then re-presents this gate. Not an approval.
152
152
  4 - approve, loop engine (experimental): skip the plan; iterate a fresh loop-implementer over the acceptance-criteria ledger; amendments stop for your review as under 1.
153
153
  5 - approve, loop engine, auto-apply amends: as 4 with option 2's amendment grant.
154
+ 6 - approve, hand off as draft PR: approve the spec's content only; push this branch and open a draft PR carrying just the spec; engine and amendment grant are chosen later by whoever runs `brainstorming #N` on that PR. Ends this flow without planning.
154
155
  Add "; fund N fix rounds" (or "N more fix rounds") to 1, 2, 4, or 5 to fund N extra attempts per stagnant loop row or N implement fix rounds past the escalated waves round.
155
156
 
156
157
  Or tell me what to change in the spec, or say "revert applied council edit <X>" to undo a specific applied edit.
157
158
  ```
158
159
 
159
- For zero `- [ ]` rows under `## Acceptance criteria`, render only options 1-3 and explain: "Loop engine unavailable: this spec has no acceptance-criteria rows." The only legal zero-row body is `none - ticket not fetched (<reason>)`; retain its paste-rows affordance. Whenever rows exist, render options 4/5. Keep the worker-path omission of option 3; do not invent a council audit.
160
+ For zero `- [ ]` rows under `## Acceptance criteria`, render only options 1, 2, 3, 6 (PR subject: 1, 2, 3) and explain: "Loop engine unavailable: this spec has no acceptance-criteria rows." The only legal zero-row body is `none - ticket not fetched (<reason>)`; retain its paste-rows affordance. Whenever rows exist, render options 4/5. Keep the worker-path omission of option 3; do not invent a council audit.
161
+
162
+ On every PR subject omit row 6 and print `Withheld: draft PR - #N already exists` under the list, reusing finishing's withheld-row layout; a hidden 6 gets the clarifying question naming rendered choices. Read [spec-pr.md](spec-pr.md) for option-6 reply decoding, publication, and marked-PR re-gating; its published-branch persistence replaces the local amend recipe below on the marked re-gate and the unmarked spec-only route only; a rework PR subject keeps the amend recipe.
160
163
 
161
164
  Render the drafted-only block in the template from the applied spec section, never from the summarizer: copy every row and disposition verbatim. Include it for a fetched ticket without ACs; omit it for ticket-row provenance. Approval ratifies these rows at this gate, with no pre-gate acceptance stop. On reply `3`, keep the block reused verbatim with the briefing; on a row-touching change request, render from the recommitted section; on redraw, render from the re-drafted section.
162
165
 
@@ -180,11 +183,11 @@ Wait for the user. Interpret funded replies with this table before routing chang
180
183
 
181
184
  For every value to persist, read [Standing grants](amendment-surface.md#standing-grants) and run Value decoding. Decode before `edit` or `--amend`; never persist a malformed token. Use the decoded table value in the approval persistence below, including budget-only approvals. In persistence narration, quote the exact resulting `**Amend-grant:**` value in full, including any funding suffix; never substitute an option name or "option-2 description plus suffix" for the persisted text.
182
185
 
183
- On a change request (including a revert), revise the spec and re-present - mint a **fresh** temp path for the re-dispatched summarizer (never reuse a prior round's path, so stale content can never be mistaken for the new summary). On `3` or its label alone: print the audit verbatim from `git -C <abs worktree path> show -s --format=%b HEAD` (never from a held tool result; the body survives the grant's `--amend --no-edit`), then re-present the same gate - the briefing text of the gate message just rendered, reused verbatim (no summarizer re-dispatch, no read of the removed `$SUMMARY_PATH`; if that text is no longer in context, the one-line degrade note takes its place), the `Council:` line, the adjacent lines, the rendered option rows; nothing in the spec or the commit changes. `3` plus a change request is a change request. `3` plus `1`/`2`/`4`/`5` prints and re-presents, and the approval is read only from a clean `1`/`2`/`4`/`5` on the re-presented gate - a reply carrying `3` never grants. A gate-round recommit (change request or revert) re-runs the same heredoc commit with the audit as its body, so HEAD always carries it; on a revert of edit X, move X's `Applied:` line to `Rejected:` with `-> reverted at gate` and recompute the `Council:` counts from the revised audit. On approval - `1`, `approve`, or equivalent prose approves without a grant; `2`, `approve, auto-apply amends`, or equivalent prose approves and grants; `4` approves without a grant; `5` approves and grants using option 2's description - first read [Standing grants](amendment-surface.md#standing-grants) (stop if unreadable). On every approval, `edit` the spec's `**Amend-grant:**` value to the decoded table value for funded replies, otherwise the granting sentence for 2/5 or `none` for 1/4. Write exactly one `**Engine:** loop` for 4/5 or `**Engine:** waves` for 1/2 directly below `**Amend-grant:**` in the header block (readers: absent -> `waves`). Then `git -C <abs worktree path> add -- <spec path>` and `git -C <abs worktree path> commit --amend --no-edit -q`, keeping the council-audit body; confirm `git -C <abs worktree path> show HEAD:<spec path>` contains both fields with the selected values and satisfies the grant predicate and Value decoding. A reply that mixes approval with a change request ("2 but rename the section") is a change request: revise, re-present, and read the grant only from the reply to the re-presented gate. If the amend or the HEAD check fails, stop and report; never proceed as granted. The plan and execution mode are mechanical derivatives, so the only human gate here is spec approval itself. Don't land the spec on `main`; it stays in the worktree and ships in the same squash commit as the implementation.
186
+ On a change request (including a revert), revise the spec and re-present - mint a **fresh** temp path for the re-dispatched summarizer (never reuse a prior round's path, so stale content can never be mistaken for the new summary). On `3` or its label alone: print the audit verbatim from `git -C <abs worktree path> show -s --format=%b HEAD` (never from a held tool result; the body survives the grant's `--amend --no-edit`), then re-present the same gate - the briefing text of the gate message just rendered, reused verbatim (no summarizer re-dispatch, no read of the removed `$SUMMARY_PATH`; if that text is no longer in context, the one-line degrade note takes its place), the `Council:` line, the adjacent lines, the rendered option rows; nothing in the spec or the commit changes. `3` plus a change request is a change request. `3` plus `1`/`2`/`4`/`5` prints and re-presents, and the approval is read only from a clean `1`/`2`/`4`/`5` on the re-presented gate - a reply carrying `3` never grants. A gate-round recommit (change request or revert) re-runs the same heredoc commit with the audit as its body, so HEAD always carries it; on a revert of edit X, move X's `Applied:` line to `Rejected:` with `-> reverted at gate` and recompute the `Council:` counts from the revised audit. On approval - `1`, `approve`, or equivalent prose approves without a grant; `2`, `approve, auto-apply amends`, or equivalent prose approves and grants; `4` approves without a grant; `5` approves and grants using option 2's description - first read [Standing grants](amendment-surface.md#standing-grants) (stop if unreadable). On every implementation approval (1/2/4/5), `edit` the spec's `**Amend-grant:**` value to the decoded table value for funded replies, otherwise the granting sentence for 2/5 or `none` for 1/4. Write exactly one `**Engine:** loop` for 4/5 or `**Engine:** waves` for 1/2 directly below `**Amend-grant:**` in the header block (readers: absent -> `waves`). Then `git -C <abs worktree path> add -- <spec path>` and `git -C <abs worktree path> commit --amend --no-edit -q`, keeping the council-audit body; confirm `git -C <abs worktree path> show HEAD:<spec path>` contains both fields with the selected values and satisfies the grant predicate and Value decoding. A reply that mixes approval with a change request ("2 but rename the section") is a change request: revise, re-present, and read the grant only from the reply to the re-presented gate. If the amend or the HEAD check fails, stop and report; never proceed as granted. The plan and execution mode are mechanical derivatives, so the only human gate here is spec approval itself. Don't land the spec on `main`; it stays in the worktree and ships in the same squash commit as the implementation.
184
187
 
185
188
  Post-approval changes follow [Amending an approved spec](../SKILL.md#amending-an-approved-spec).
186
189
 
187
- After approval, mark the brainstorm phase complete:
190
+ After implementation approval (1/2/4/5), mark the brainstorm phase complete:
188
191
 
189
192
  ```
190
193
  phase_tracker({ action: "complete", phase: "brainstorm" })
@@ -0,0 +1,62 @@
1
+ # Spec-only PR publication and re-gate
2
+
3
+ ## Shared predicate and marker
4
+
5
+ Resolve `gauntlet_setting({ key: "flowGuards" })` and use its `specDirs`. Inspect `git diff --name-status <base>...<head>` and every modified file's hunks against the same pinned endpoints. Require exactly one `A` under a resolved spec dir: the selected spec. Require every other entry to be an `M` under a spec dir that adds only active supersession-banner lines plus adjacent blank lines and removes nothing. Read [superseding.md](superseding.md): use `> **Superseded by:**` by default or the declared override syntax; enforce title-adjacent placement and append-only insertion below existing banners. Reject renames, deletes, multiple additions, non-spec paths, and arbitrary modifications. Evaluate the whole diff, not commit count: earlier implementation, non-default-source changes, and an ignore-file commit all count.
6
+
7
+ Keep shape separate from approval. Read the added spec with `git show <head>:<spec path>`; match `^\*\*Engine:\*\*[ \t]+deferred[ \t]*$` only in the header before the first `## `. Use that marker plus shape for re-gating. Use shape alone for publication. Ignore draft status, labels, PR body, telemetry, and audit presence as classification proof. Route N>1 through rework.
8
+
9
+ ## Publish option 6
10
+
11
+ Decode the reply before writes. A hidden `6` gets the clarifying question naming rendered choices. A funded `6` is malformed: re-present, write nothing. `3` plus `6` prints the audit and re-presents without approval; `6` plus a change request revises and re-presents.
12
+
13
+ On clean `6`, edit `**Amend-grant:** none` and exactly one `**Engine:** deferred` directly below it. A 6 never grants. Stage the spec with `git -C <worktree> add -- <spec path>`, then `git -C <worktree> commit --amend --no-edit -q`; verify both lines through `git -C <worktree> show HEAD:<spec path>`. Stop on failure.
14
+
15
+ Resolve the default base once, never substitute the worktree creation ref:
16
+
17
+ ```bash
18
+ DEFAULT=$(gh repo view --json defaultBranchRef -q .defaultBranchRef.name)
19
+ git -C <worktree> fetch origin "$DEFAULT"
20
+ git -C <worktree> diff --name-status origin/$DEFAULT...HEAD
21
+ ```
22
+
23
+ Prove the shared predicate against `origin/$DEFAULT` before pushing. Stop on command errors. On invalid shape print the offending name-status lines and `origin/$DEFAULT`, retain the amended spec and checkout, and redraw with `Withheld: draft PR - diff against origin/$DEFAULT is not spec-only (<paths>)` replacing 6. Keep implementation approvals available.
24
+
25
+ Push, then create with explicit head/base and the spec H1 as title. Run gh against the worktree repository:
26
+
27
+ ```bash
28
+ git -C <worktree> push -u origin <branch>
29
+ gh pr create --draft --head <branch> --base "$DEFAULT" --title "<spec H1 text>" --body-file - <<'EOF'
30
+ <gate summary verbatim, or the **Goal:** line on the degraded-summary path>
31
+ EOF
32
+ ```
33
+
34
+ | Observation | Action |
35
+ |---|---|
36
+ | Push rejected | Print git output; retain amended spec and checkout; re-present with 6 retryable. |
37
+ | Create fails after push | Print error and pushed branch. Keep brainstorm incomplete and checkout intact. Offer only `6 - retry opening the draft PR` and `Withheld: implementation approvals - the handoff commit is published; an approval would amend it`. |
38
+ | Retry 6 after published handoff | Refresh origin's branch head; require `origin/<branch>` == HEAD. On mismatch print both full SHAs and stop. On equality rerun create only, no push, no amend. |
39
+ | Create succeeds | Print URL before completing brainstorm; then perform ownership-based cleanup below. |
40
+
41
+ After URL output call `phase_tracker({ action: "complete", phase: "brainstorm" })`. Read finishing's [Step 6](../../finishing-a-development-branch/SKILL.md#step-6-cleanup-workspace), using only its ownership test and wrapper selection: resolve home/destroy, legacy native script, or native remove/prune. Disable every branch-deletion step, including within a destroy wrapper: verify the wrapper preserves the branch before running it; stop cleanup and report when it cannot. Never delete the local branch. Report host-owned or failed removal with checkout path and command output; explain that later `brainstorming #N` hits pr-head's checked-out-at-another-path stop until that checkout is gone. Start no plan or loop, produce no handoff brief, and leave telemetry unchanged.
42
+
43
+ ## Re-gate a marked spec PR
44
+
45
+ Reuse [pr-head](../../using-git-worktrees/reference/pr-head.md)'s checkout, base merge, and Step 4 report, not its before-gather thread fetch. Preserve its checked-out-at-another-path stop. On observed `merge: unresolved - <files>`, print `base merge unresolved for PR #N (<files>) - merge origin/<base> by hand in <worktree> and rerun brainstorming #N`; preserve checkout, render no gate, write no approval or repair task.
46
+
47
+ Skip ticket binding, context-builder, review threads, gather, questionary, spec-writing, inline lint, council, worker, and the second predecessor pass. Carry trailing intent as `Intent carried from the command: <text>` beside the gate.
48
+
49
+ Pin the originating audit once on the PR branch:
50
+
51
+ ```bash
52
+ AUDIT_SHA=$(git -C <worktree> log -1 --diff-filter=A --format=%H -- <spec path>)
53
+ git -C <worktree> show -s --format=%b "$AUDIT_SHA"
54
+ ```
55
+
56
+ Recognize an audit only with all `Applied:`, `Deferred:`, and `Rejected:` labels. A drafted-AC repair line alone is not an audit. Count Council from the pinned body; offer row 3 only with that audit and read that same body on 3, never HEAD. Audit absence does not block re-gating.
57
+
58
+ Reuse [User Review Gate](spec-finalization.md#user-review-gate)'s summarizer dispatch, fresh temp path, last content-producing Read, verbatim render, degraded path, and unconditional temp cleanup, but skip its unconditional initial spec commit. Render Scope cuts and drafted rows from the carried spec. Offer 1/2/4/5 and optional 3; with zero AC rows omit 4/5 and explain `Loop engine unavailable: this spec has no acceptance-criteria rows.` Withhold 6 with `Withheld: draft PR - #N already exists`; clarify a 6 reply by naming rendered choices.
59
+
60
+ For a change request, revise and stage the spec and reconciled banners; make a new commit without the old audit body (no new council ran). Re-dispatch the summarizer with a fresh temp path and re-present.
61
+
62
+ For approval 1/2/4/5, decode grant/funding under the ordinary gate. Replace deferred with waves or loop, write the decoded `**Amend-grant:**`, and write exactly one `**PR:** <owner/repo#N>` directly below Engine, lowercasing owner/repo parsed from the admitted PR URL. Stage and make a new commit `spec: select engine and grant for PR #N`; never amend a published commit. Verify all three fields through `git show HEAD:<spec path>` before brainstorm completion and the selected writing-plans/loop-implementation chain. Stop on persistence or verification failure. The unmarked route's gate approval (1/2/4/5) applies this same new-commit persistence: `waves` or `loop` as the engine, the decoded grant, and `**PR:**` directly below `**Engine:**`, never `--amend`.
@@ -22,7 +22,7 @@ PRIMARY=$(dirname "$(git -C "$WORKTREE" rev-parse --path-format=absolute --git-c
22
22
  FEATURE=$(git -C "$WORKTREE" branch --show-current)
23
23
  ```
24
24
 
25
- The process cwd never changes; every command targets `$WORKTREE` or `$PRIMARY` explicitly.
25
+ The process cwd never changes; every command targets `$WORKTREE` or `$PRIMARY` explicitly. Resolve the selected run spec now per the Input rules in [header-linked PR finishing](reference/spec-pr.md) and read its header before announcing: an exact `**Engine:** deferred` before the first `##` stops here with `spec approved for handoff only - run brainstorming #N` (no phase change, verification, strip, seal, or push); `**PR:**` without a Rework record takes that reference's live identity checks before Step 1 and its Step 4 menu and push recipe instead of the ordinary create rows.
26
26
 
27
27
  **Announce at start:** "I'm using the finishing-a-development-branch skill to complete this work."
28
28
 
@@ -32,8 +32,8 @@ Then call `phase_tracker({ action: "start", phase: "ship" })`.
32
32
 
33
33
  ### Step 1: Verify Tests
34
34
  **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.
35
- Read the selected run spec before verification. Detect a PR subject only by its `## Rework record`, never by an open PR on `$FEATURE`. Read every top-level `PR:`/`Pre-rework head:` pair, home first, retaining each full SHA; missing pre-head -> stop naming the spec path. Set `PRE_REWORK_HEAD` to home's SHA. Read only combined capitalized `Base:`, `Keeps:`, `Changes:`, `Dropped claims:`, `Scoped tests:` fields; ignore lowercase provenance under `### PR #<N>`. For N=1, read `Threads:` directly after `Pre-rework head:` and retain the provenance subsection without changing finish output. Confirm only home with `gh pr view <N> --json number,url,headRefName,baseRefName,state` (use the record's repository): non-`OPEN` -> stop: `PR #N is <state>; the rework cannot be pushed to it.`; headRefName != `$FEATURE` -> stop naming both branches. Retain baseRefName for Step 3.
36
- Recognize a ledger by line 1 exactly `# Ledger - loop engine`. For a ledger, use its `verification:` command throughout finish, including the minors round. For a PR subject with a task plan, use the union of every plan task's `Tests:` commands plus the executable lint/format commands in the header's `**Verification:**` line; treat `none - PR subject, scoped` as no header commands, not an empty task union. Capture this set and accepted-complete task evidence before stripping the plan. Apply the hard gate and skip rule below to this set. For every other subject with a task plan, 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).
35
+ Reuse the selected run spec read in Input. Detect a rework PR subject by its `## Rework record`; use Input's header-linked route for `**PR:**`, never discover by an open PR on `$FEATURE`. For the rework route only, read every top-level `PR:`/`Pre-rework head:` pair, home first, retaining each full SHA; missing pre-head -> stop naming the spec path. Set `PRE_REWORK_HEAD` to home's SHA. Read only combined capitalized `Base:`, `Keeps:`, `Changes:`, `Dropped claims:`, `Scoped tests:` fields; ignore lowercase provenance under `### PR #<N>`. For N=1, read `Threads:` directly after `Pre-rework head:` and retain the provenance subsection without changing finish output. Confirm only home with `gh pr view <N> --json number,url,headRefName,baseRefName,state` (use the record's repository): non-`OPEN` -> stop: `PR #N is <state>; the rework cannot be pushed to it.`; headRefName != `$FEATURE` -> stop naming both branches. Retain baseRefName for Step 3.
36
+ Recognize a ledger by line 1 exactly `# Ledger - loop engine`. For a ledger, use its `verification:` command throughout finish, including the minors round. For a rework PR subject with a task plan, use the union of every plan task's `Tests:` commands plus the executable lint/format commands in the header's `**Verification:**` line; treat `none - PR subject, scoped` as no header commands, not an empty task union. Capture this set and accepted-complete task evidence before stripping the plan. Apply the hard gate and skip rule below to this set. For every other subject with a task plan, 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).
37
37
  **Skip rule.** Skip the run only when this set passed on a known clean commit in the verify phase of this session and no edit or write landed outside `<telemetry.dir>` since. Check the current tree: `git -C "$WORKTREE" diff --quiet <commit the run passed on> -- . ':!<telemetry.dir>'` must exit 0, and `git -C "$WORKTREE" status --porcelain --untracked-files=all -- . ':!<telemetry.dir>'` must exit 0 with empty output (`<telemetry.dir>` defaults to `.pi/gauntlet/telemetry`). These checks cover committed, staged, unstaged, and untracked changes outside telemetry. Otherwise run it once; a missing verified commit, a failed check, or uncertainty means run.
38
38
  **Scoping caveat — pre-existing findings.** Some services carry lint findings unrelated to the diff. If verification fails on lines you didn't touch:
39
39
  Confirm with `git -C "$WORKTREE" diff <base>...HEAD --name-only` that the offending file isn't in your diff. Surface the pre-existing finding to the user as a separate issue - do **not** auto-fix it in this completion ("surface, don't auto-fix"). Proceed only after the user acknowledges.
@@ -48,11 +48,11 @@ Cannot proceed until tests pass.
48
48
  Stop. Don't proceed to Step 2. **If tests pass:** Continue to Step 2. No documentation prompt here: Documentation impact is decided at spec time (`/skill:brainstorming` section 6, gated by `brainstorming/reference/documentation-impact.md`) and has already shipped in the diff by the time you reach finishing.
49
49
  ### Step 2: Detect Environment
50
50
 
51
- For a PR subject, use the Step 4 PR menu. For other subjects: detached HEAD (`git -C "$WORKTREE" symbolic-ref -q HEAD` prints nothing) -> reduced 4-option menu (no merge), no cleanup. Otherwise the standard 5 options.
51
+ For a header-linked PR, use the reference's five-row menu; for a rework PR subject, use the Step 4 PR menu. For other subjects: detached HEAD (`git -C "$WORKTREE" symbolic-ref -q HEAD` prints nothing) -> reduced 4-option menu (no merge), no cleanup. Otherwise the standard 5 options.
52
52
 
53
53
  ### Step 3: Determine Base Branch
54
54
 
55
- For a PR subject, set `<base-branch>` to the confirmed `baseRefName` and skip the common-base probe below.
55
+ For either PR route, set `<base-branch>` to the confirmed `baseRefName` and skip the common-base probe below.
56
56
 
57
57
  ```bash
58
58
  # Try common base branches
@@ -167,7 +167,7 @@ Amendments auto-applied (N):
167
167
 
168
168
  Omit the block when N = 0.
169
169
 
170
- **PR subject - preflight and six-row menu.** Fetch origin with `git -C "$WORKTREE" fetch origin`; stop on failure. Run these proofs in order, against this worktree's HEAD:
170
+ **Rework PR subject - preflight and six-row menu.** Fetch origin with `git -C "$WORKTREE" fetch origin`; stop on failure. Run these proofs in order, against this worktree's HEAD:
171
171
  | Proof | Exit 0 | Exit 1 |
172
172
  |---|---|---|
173
173
  | `git merge-base --is-ancestor <PRE_REWORK_HEAD> HEAD` | Continue | Stop: `PR branch history was rewritten: <PRE_REWORK_HEAD7> is not an ancestor of HEAD; the rework must be re-merged, not rebased.` |
@@ -0,0 +1,39 @@
1
+ # Finish a header-linked spec PR
2
+
3
+ ## Input
4
+
5
+ Resolve the selected run spec once: use the carried spec path or the active plan/ledger's path-only `**Spec:**` header; with neither, enumerate candidates under resolved `flowGuards.specDirs`, read them, and ask on ambiguity. Carry this path through finish; perform no second discovery. Read its header before announcing or starting ship. An exact `**Engine:** deferred` before the first `##` stops with `spec approved for handoff only - run brainstorming #N`; perform no phase change, verification, strip, seal, or push. A `## Rework record` wins over `**PR:**` (record wins when both exist): follow the ordinary rework path. For a header-only `**PR:** <owner/repo#N>`, use the header's repository for every gh call and run this check before Step 1 verification:
6
+
7
+ ```bash
8
+ gh pr view <N> -R <owner/repo> --json number,url,state,isDraft,headRefName,baseRefName
9
+ ```
10
+
11
+ Stop on query failure. Require OPEN, otherwise print `PR #N is <state>; the branch cannot be pushed to it.` Require headRefName == `$FEATURE`, otherwise stop naming both branches. Retain the live baseRefName for Step 3 (skip common-base probing), sealing, and squash. Run full ordinary verification for a header-only PR, not rework-scoped verification. Keep ordinary closure/conformance gates.
12
+
13
+ ## Menu and preflight
14
+
15
+ At Step 4, the header-linked route bypasses both menus below the amendment digest in SKILL.md and uses this preflight, five-row menu, and rows 1/2 push recipe; retain the shared amendment digest and informational lines. At Step 4 fetch `git -C "$WORKTREE" fetch origin` and prove `git -C "$WORKTREE" merge-base --is-ancestor origin/<headRefName> HEAD`. Stop on fetch failure or proof exits other than 0/1. Exit 1 omits rows 1/2 and prints `Withheld: push - origin/<headRefName> is at <sha7>, local HEAD at <sha7>; a non-force push cannot land`; retain numbers 3-5. A hidden 1/2 gets the clarifying question naming rendered rows. Recompute this proof on every menu return.
16
+
17
+ Render exactly these five rows (plus ordinary nonblocking informational lines):
18
+
19
+ ```text
20
+ Implementation complete. What would you like to do?
21
+
22
+ 1. Push to PR #N and mark it ready for review
23
+ 2. Push to PR #N, keep it a draft
24
+ 3. Squash-merge to <base-branch> (no PR, no surviving branch; orphans PR #N - close it by hand)
25
+ 4. Keep the branch as-is (I'll handle it later; nothing is pushed)
26
+ 5. Discard this work (removes the worktree and local branch; the PR branch on origin is untouched)
27
+ ```
28
+
29
+ For observed isDraft false replace row 2 with `2. Push to PR #N (already ready for review)`. Never convert ready to draft. Map rows 3-5 to ordinary Options 3-5, retaining typed discard confirmation and Step 6 ownership/cleanup. Option 3 squash seal uses `--option squash --base origin/<baseRefName>` and the selected spec.
30
+
31
+ ## Push rows 1/2
32
+
33
+ Run the ordinary strip-and-seal block first, with `--option pr --base origin/<baseRefName>` and the selected spec. Preserve every seal failure stop. Then push non-force:
34
+
35
+ ```bash
36
+ git -C "$WORKTREE" push --no-follow-tags origin HEAD:refs/heads/<headRefName>
37
+ ```
38
+
39
+ Only after successful push on row 1 run `gh pr ready <N> -R <owner/repo>`. Row 2 pushes only. Report a rejected push once, skip ready, and return to the menu without force or automatic retry. On ready failure report the completed push and that the PR remains a draft for manual action or a later retry; preserve checkout. Preserve the PR body without a Rework block. Complete ship after successful delivery; keep the worktree for both push rows.
@@ -97,24 +97,18 @@ checks 2, 4, 5 do not apply; check 6 runs on the seed's pinned spec path.
97
97
  `skills/*/SKILL.md` in this package; `Read` each match's complete file into the
98
98
  transcript; list non-matches as skipped. Loaded bodies are context only - no skill's
99
99
  entry actions run until Dispatch names one.
100
- 6. **Grant field.** Runs once the route has resolved `<spec path>` - the `S` path that
101
- `reference/brief-contract.md` "Process-state restore" resolves for `skip brainstorm`
102
- (process-state briefs), the spec reconstruction resolves and the human approves
103
- (Spec without plan) or confirms (Spec with ledger or Spec with plan) (`reference/reconstruction.md`), or
104
- the pinned `<full-path>/<rel>` of a spec tracked on `main` (`reference/seed.md`) -
105
- and before that route's first tracker call; the path is carried, never re-resolved.
106
- Read the spec's header block (between the H1 and the first `##`) through the
107
- predicate in
100
+ 6. **Grant field.** Run deferred-header admission whenever a route resolves an existing spec, including brainstorm-stage process-state restore and reconstruction's unapproved-draft handoff, before any tracker mutation or brainstorming invocation. Carry the resolved `<spec path>` without re-resolving it: use `reference/brief-contract.md` "Process-state restore", `reference/reconstruction.md`, or the seed's pinned `<full-path>/<rel>` (`reference/seed.md`).
101
+ Read the spec's header block (between the H1 and the first `##`). An exact `**Engine:** deferred` stops with `spec approved for handoff only - run brainstorming #N`; make no phase_tracker or plan_tracker mutation. After deferred-header admission, apply the grant predicate only for an approved spec in
108
102
  [Standing grants](../brainstorming/reference/amendment-surface.md#standing-grants): no
109
103
  `**Amend-grant:**` line -> no grant (legacy spec);
110
104
  exactly one line whose trimmed value is `none` -> no grant;
111
105
  exactly one line whose trimmed value is any other non-empty single-line text ->
112
106
  grant active, the sentence is that value;
113
107
  two or more lines, one line with an empty value, or a value continued onto the next physical line ->
114
- malformed, stop, print the offending line(s), no tracker call. Routes that resolve no
108
+ malformed, stop, print the offending line(s), no tracker call. Skip only grant decoding for routes that resolve no
115
109
  approved spec (hotfix, `worktree: no`, a brief whose active phase is brainstorm,
116
- reconstruction's unapproved-draft brainstorming handoff) skip this check and print
117
- no grant line. Resume reports the line; it never writes it.
110
+ reconstruction's unapproved-draft brainstorming handoff); print no grant line.
111
+ Resume reports the line; it never writes it.
118
112
 
119
113
  ## Dispatch
120
114
 
@@ -136,7 +130,7 @@ re-derive the record.
136
130
  ## Post-restore continuation
137
131
 
138
132
  After a successful restore, print the closing line from `reference/brief-contract.md`
139
- (gate history not restored; the task to re-validate), then on its own line exactly one of `Standing grant active: <sentence>` or `No standing grant.` from check 6 (nothing when the check was skipped), then continue in the stage's
133
+ (gate history not restored; the task to re-validate), then on its own line exactly one of `Standing grant active: <sentence>` or `No standing grant.` from check 6 (nothing when grant decoding was skipped), then continue in the stage's
140
134
  owning skill **without** its reset-bearing entry:
141
135
 
142
136
  | Active after restore | Continue in | Entry point |
@@ -154,6 +154,8 @@ a plan added after base pairs with it by basename. Zero specs -> stop; more than
154
154
  human picks. The consumer carries this path to its entry check 6 and its post-restore
155
155
  announcement without re-resolving it.
156
156
 
157
+ Honor SKILL.md entry check 6's deferred stop before any process-state arming call below; carry the resolved spec path without re-discovery. For brainstorm-stage briefs, resolve any existing spec through these candidate rules and run entry check 6's deferred-header admission before `start brainstorm`; with zero specs, restore brainstorm without a spec. Keep grant decoding exempt for this stage. A handoff after option 6's push succeeded but PR creation failed still has brainstorm in_progress; its deferred header stops restoration, not the ordinary gate.
158
+
157
159
  | Active | Calls, in order |
158
160
  |---|---|
159
161
  | brainstorm | `start brainstorm`; `substep` if the brief shows one |
@@ -65,11 +65,13 @@ plan commit; treat every task as `pending`.
65
65
 
66
66
  ## Spec without plan
67
67
 
68
+ Run SKILL.md entry check 6's deferred-header admission on the resolved spec before the approval/handoff question below; apply it to both routes, including the unapproved-draft brainstorming handoff. Keep grant decoding exempt for the unapproved route.
69
+
68
70
  Ask exactly one question: is this spec approved, or do you select `/skill:brainstorming`
69
71
  with this unapproved spec as the draft? Show the spec path (and the brief's
70
72
  `## Intent`/`## Decisions` when present).
71
73
 
72
- - Approved: run SKILL.md entry check 6 on `<spec path>` first (a malformed `**Amend-grant:**` line stops here, no tracker call). Read the spec's `**Engine:**` line and take the matching route:
74
+ - Approved: honor SKILL.md entry check 6's deferred stop before any arming; run SKILL.md entry check 6 on `<spec path>` first (a malformed `**Amend-grant:**` line stops here, no tracker call). Read the spec's `**Engine:**` line and take the matching route:
73
75
  - `loop`: call `start brainstorm`, then `skip brainstorm` with reason `resume: <spec path>` to arm the flow before `plan_check`. Carry absolute worktree/spec paths and the resolved plan directory into `/skill:loop-implementation` Entry steps 1-5: resolve settings at step 1 and verification at step 2, retain the driver's `skip plan` at step 3, create the ledger at step 4, then check/commit it and start implement at step 5. Never enter the writing-plans body or initialize a task tracker.
74
76
  - `waves` or absent: `start brainstorm`; `skip brainstorm resume: <spec path>`; `start plan`; continue in writing-plans, skipping its `start plan` call.
75
77
  - Selected unapproved-draft brainstorming handoff: invoke [`/skill:brainstorming`](../../brainstorming/SKILL.md) with