pi-gauntlet 7.22.1 → 7.24.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,30 @@
1
1
  # Changelog
2
2
 
3
+ ## v7.24.0 - 2026-10-21
4
+
5
+ ### Changed
6
+
7
+ - **shape-ticket bodies are written for a product owner, not an implementer.** The reader is someone who knows the product and its customers but has never opened the repo: examples are one sentence or one number per failure, Context carries only the trigger and what exists today, repo-native terms are defined at first use or dropped while requester terms stay undefined, and the Idea keeps one attributed sketch line. A closed-list step-5 gate moves paths, identifiers, sizes, line counts, lists, code blocks, and Idea overflow verbatim into the gated `Reporter note:` comment - never dropped, and never the plain-words cause-and-effect sentence a triager needs. Repair mode treats an overflowing Idea as non-conforming (body rewrite plus a new note, AC section byte-identical), and the roast brief names the bounds and protects the plain-words lead from being cut. (#75)
8
+ - **brainstorming reads the Reporter note.** The gatherer pages through every ticket comment and quotes each `Reporter note:` verbatim; `ticket-acceptance.md` names those notes beside Context/Problem/Idea as sources of implied requirements, so implementer detail moved out of the body still reaches the spec. (#75)
9
+
10
+ ### Added
11
+
12
+ - Eval samples `domain-reader`, `bounded-prose`, `displaced-detail`, `repair-overflow` (shape-ticket), `ticket-idea-overflow` (spec-council-member, bundling the shape-ticket brief), and `reporter-note`, `reporter-note-fetch` (brainstorming). (#75)
13
+
14
+ ## v7.23.0 - 2026-10-20
15
+
16
+ ### Changed
17
+
18
+ - **Skill references are read once per session.** `/skill:brainstorming` reads `reference/ticket-acceptance.md` at first use; checklist steps 4 and 8 read it only when a restored session or a fresh-start redraw has nothing in context. The shared "Project overrides" block in all 20 skills reads the overrides file once per session and skips the read when an earlier skill already loaded it.
19
+ - **`/skill:subagent-driven-development` fits one read.** SKILL.md drops the older-runtime plain-`tasks:` fallback and the hardcoded 7.4.0 preflight; one guard before the first wave reads the pi-cohort floor from the installed pi-gauntlet `package.json`, resolves both packages from `pi list` by their installed package name (pinned, local-path, and filtered entries resolve), and stops with `pi-cohort >= X.Y.Z required, found <version>`, `pi-cohort not installed`, `cannot read peer floor`, or `cannot parse pi-cohort version <value>` before any dispatch. The happy-path runner moves verbatim to `reference/happy-path-run.md`, read only when a plan declares a happy path.
20
+ - **Implementer dispatch template is scope plus pointer.** `implementer-prompt.md` keeps the task paste, `SCOPED_TEST_COMMANDS`, `TEST_CONTRACT`, the met/unmet evidence lines, and the `**Status:**` enum; escalation, self-review, code-organization, and commit prose now live only in the `implementer` persona.
21
+ - **pi-cohort floor is 7.4.3**, pinned to the newest published pi-cohort at release time; `/skill:release` refuses a release whose declared floor is behind `npm view pi-cohort version`.
22
+
23
+ ### Added
24
+
25
+ - **`npm test` size and floor lints.** Every `skills/**/*.md` and `agents/*.md` must stay under 50,000 bytes and 2,000 lines (the `read` tool's single-call cap); `package.json`'s `peerDependencies["pi-cohort"]` must be exactly `>=X.Y.Z` and match the README install floor.
26
+ - Eval samples for the read-once brainstorming steps, the package-derived preflight stop and late happy-path read, and the trimmed implementer template (`eval/{brainstorming,subagent-driven-development,implementer}`).
27
+
3
28
  ## v7.22.1 - 2026-10-20
4
29
 
5
30
  ### Fixed
package/README.md CHANGED
@@ -35,7 +35,7 @@ pi-gauntlet's only hard dependency is pi-cohort - every gate that dispatches a r
35
35
 
36
36
  Concretely, one change through the gauntlet:
37
37
 
38
- 0. *(Optional)* Before there's even a spec, `/skill:shape-ticket` can create or repair a single tracker issue - shaping a raw ask into a Context/Problem/Idea/Acceptance Criteria ticket, gated by an AC integrity check, a cheap council roast, and one human-confirmed write that may include one optional gated comment for a Reporter note or overlap evidence. 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.
38
+ 0. *(Optional)* Before there's even a spec, `/skill:shape-ticket` can create or repair a single tracker issue - shaping a raw ask into a Context/Problem/Idea/Acceptance Criteria ticket, gated by an AC integrity check, a cheap council roast, and one human-confirmed write that may include one optional gated comment for a Reporter note or overlap evidence. 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
39
  1. Opt in with `/skill:brainstorming` and describe the change. The command is the reliable discovery-and-entry path; explicit prose requesting brainstorming/the gauntlet also supplies consent when the skill is already loaded or an available instruction or route identifies it. An ordinary implementation request or an agent recommendation is not consent. **`brainstorming`** sets up an isolated worktree, explores the codebase, and turns your description into a written spec - when its recon finds a cited case that the ask is the wrong change (misdiagnosed, wrong-sized, already solved, a band-aid, or cutting across a sound pattern - including a repo convention that is itself debt) and can name the alternative, question one is a framing question (`as framed`, `pivot: <alternative>`, or `smaller or none`); otherwise it opens with one sentence naming what it checked, and every approach it proposes ends with a `Pattern:` line naming what it follows or cuts across; when the run starts from a ticket, the spec carries the ticket's acceptance criteria verbatim, each with a disposition (`in-scope`, `deviates:`, `deferred:`, `venue:`, `elsewhere:` for a row another repo's part delivers), scope cuts come only from your answer to a cut question and are listed at the gate, the conformance gate checks the in-scope ones, and `/skill:check-delivery` verifies `venue:` rows before the prod deploy. A multi-model critique runs on it automatically. If the spec replaces a known prior spec, brainstorming marks the predecessor with a `> **Superseded by:**` banner under its title (default format, syntax overridable via `.pi/gauntlet-overrides.md`; candidates come from brainstorming's scout recon, never a mechanical sweep). **You read and approve the spec - human gate 1.** No implementation code exists yet.
40
40
  2. **`writing-plans`** decomposes the approved spec into atomic, independently-verifiable tasks, grouped into parallel waves where they don't touch the same files.
41
41
  3. **`subagent-driven-development`** executes the plan one task at a time, each in a fresh subagent, behind spec-compliance review then code-quality review. TDD-locked: red, green, refactor. Independent implementation, review, and council batches remain parallel, but their dispatches are foreground: the orchestrator waits for terminal results before accepting work or advancing a phase.
@@ -122,9 +122,9 @@ Run by a human against pi-cohort >= 7.1.0, before a pi-gauntlet release claims t
122
122
  ## Requirements
123
123
 
124
124
  - [pi-coding-agent](https://github.com/earendil-works/pi) ≥ 0.85.1 - tested minimum for sequential `phase_tracker` tool execution, which persists a tracker update before a later tool call in the same model message.
125
- - [pi-cohort](https://github.com/jjuraszek/pi-cohort) >= 7.4.1 - required peer package, including binary-safe worktree patches. Skills that dispatch agents (`requesting-code-review`, `subagent-driven-development`, `dispatching-parallel-agents`, `writing-plans`, `forge-skill`, `shape-ticket`, `roasting-the-spec`) call `subagent({})`, which pi-cohort provides. pi-gauntlet does not vendor the dispatch tool; without pi-cohort those skills have nothing to call. Gauntlet execution dispatches explicitly use `async: false`; do not enable pi-cohort's incompatible `forceTopLevelAsync` setting. See pi-cohort's [dispatch configuration](https://github.com/jjuraszek/pi-cohort/blob/main/doc/configuration.md) for that setting's owner and semantics. A wave of N >= 1 tasks dispatches its implementers and first spec reviews as one chain call.
125
+ - [pi-cohort](https://github.com/jjuraszek/pi-cohort) >= 7.4.3 - required peer package, including binary-safe worktree patches. Skills that dispatch agents (`requesting-code-review`, `subagent-driven-development`, `dispatching-parallel-agents`, `writing-plans`, `forge-skill`, `shape-ticket`, `roasting-the-spec`) call `subagent({})`, which pi-cohort provides. pi-gauntlet does not vendor the dispatch tool; without pi-cohort those skills have nothing to call. Gauntlet execution dispatches explicitly use `async: false`; do not enable pi-cohort's incompatible `forceTopLevelAsync` setting. See pi-cohort's [dispatch configuration](https://github.com/jjuraszek/pi-cohort/blob/main/doc/configuration.md) for that setting's owner and semantics. A wave of N >= 1 tasks dispatches its implementers and first spec reviews as one chain call. `subagent-driven-development` stops before dispatch on unsupported installs; there is no older-runtime fallback.
126
126
 
127
- Both packages must be listed in your `.pi/settings.json#packages` array (pi adds them automatically when you `pi install`). pi-gauntlet and pi-cohort are versioned independently but release together whenever dispatch semantics change - pin compatible versions of both.
127
+ Both packages must be listed in your `.pi/settings.json#packages` array (pi adds them automatically when you `pi install`). pi-gauntlet and pi-cohort are versioned independently but release together whenever dispatch semantics change - pin compatible versions of both. At each pi-gauntlet release, set the pi-cohort peer minimum and README floor together to the newest released pi-cohort version; `/skill:release` checks the registry before proceeding.
128
128
 
129
129
  ## Install
130
130
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-gauntlet",
3
- "version": "7.22.1",
3
+ "version": "7.24.0",
4
4
  "description": "Opinionated, gated workflow skills, subagent personas, and runtime extensions for the pi coding agent.",
5
5
  "author": "Jacek Juraszek",
6
6
  "type": "module",
@@ -62,7 +62,7 @@
62
62
  "test": "node scripts/ci.mjs"
63
63
  },
64
64
  "peerDependencies": {
65
- "pi-cohort": ">=7.4.1"
65
+ "pi-cohort": ">=7.4.3"
66
66
  },
67
67
  "dependencies": {
68
68
  "yaml": "^2.9.0"
@@ -44,11 +44,11 @@ Work through the items below **in order**. After a user answer or completed side
44
44
 
45
45
  2. **Set up the worktree** - see [Worktree First](#worktree-first).
46
46
  3. **Gather context** - read [Ticket Handling](#ticket-handling), then follow [`gatherer.md`](gatherer.md) without a human stop.
47
- 4. **Understand the idea against the draft** - read [Ticket Handling](#ticket-handling), then see [Understand the idea](#3-understand-the-idea).
47
+ 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).
48
48
  5. **Propose 2-3 approaches** - see [Explore approaches](#4-explore-approaches).
49
49
  6. **Present the design** - see [Present the design in two rounds](#6-present-the-design-in-two-rounds).
50
50
  7. **Write the spec** - read [Spec Self-Review](#spec-self-review-before-user-review-gate) before writing; follow steps 1-5.
51
- 8. **Spec self-review (lint)** - read [Ticket Handling](#ticket-handling), then run the inline checks in [Spec Self-Review](#spec-self-review-before-user-review-gate).
51
+ 8. **Spec self-review (lint)** - 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 run the inline checks in [Spec Self-Review](#spec-self-review-before-user-review-gate).
52
52
  9. **Critique pass (auto-dispatched)** - use [Spec Council](#spec-council).
53
53
  10. **Re-run placeholder scan** - follow [Spec Self-Review](#spec-self-review-before-user-review-gate).
54
54
  11. **Generate spec summary** - follow [User Review Gate](#user-review-gate).
@@ -148,7 +148,7 @@ Use two rounds, targeting 300-500 words each, with one approval each; revisions
148
148
 
149
149
  ## Ticket Handling
150
150
 
151
- Read [Ticket Handling](reference/ticket-acceptance.md) before gathering context or step-4/8 entry, even with no ticket; unreadable -> stop with a blocking error, never reconstruct from memory.
151
+ Read [Ticket Handling](reference/ticket-acceptance.md) at first use - before gathering context, even with no ticket. Steps 4 and 8 carry the same read behind an in-context check so a restored session (`gauntlet-resume` routes there) loads it once; a same-session redraw or a second brainstorm in one session reuses the content already in context. Unreadable -> stop with a blocking error, never reconstruct from memory.
152
152
 
153
153
  ## First-Feature Oversight (Early Project Stages)
154
154
 
@@ -186,7 +186,7 @@ Classify first. Redraw test: the change alters the problem statement, adds or re
186
186
 
187
187
  Amend -> `read` `reference/amendment-surface.md` and follow it (unreadable -> stop with a blocking error; never improvise the grammar). Apply its [Standing grants](reference/amendment-surface.md#standing-grants) boundaries.
188
188
 
189
- Redraw: keep the worktree and the approved spec file. `plan_tracker({ action: "clear" })`, `phase_tracker({ action: "reset" })`, `phase_tracker({ action: "start", phase: "brainstorm" })`, delete the plan file, resume at checklist step 4 with the approved spec as the draft (steps 2-3 skipped). Spec-writing overwrites it; the full gate follows.
189
+ Redraw: keep the worktree and the approved spec file. `plan_tracker({ action: "clear" })`, `phase_tracker({ action: "reset" })`, `phase_tracker({ action: "start", phase: "brainstorm" })`, delete the plan file, resume at checklist step 4 with the approved spec as the draft (steps 2-3 skipped); step 4's first-use check covers the read. Spec-writing overwrites it; the full gate follows.
190
190
 
191
191
  ## Red Flags — STOP
192
192
 
@@ -207,6 +207,6 @@ Redraw: keep the worktree and the approved spec file. `plan_tracker({ action: "c
207
207
 
208
208
  ## Project overrides
209
209
 
210
- If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context — check it for project-specific routing tables, service paths, and verification commands.
210
+ If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it once per session - a skill that already has the file's content in context from an earlier skill's read skips the read; a restored session has nothing in context and reads it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context — check it for project-specific routing tables, service paths, and verification commands.
211
211
 
212
212
  The recognized headings, their readers, and the rules an override cannot change are listed in the [configuration front door](../../README.md#project-specific-overrides); an override extends or replaces the step it names and never lifts this skill's HARD CONSTRAINT or MUST text.
@@ -64,8 +64,13 @@ Scout (always dispatched):
64
64
  > instead; cite the old spec only for its unsuperseded sections (banner contract:
65
65
  > `reference/superseding.md`). Predecessor check: compose a 5-15 term keyword query
66
66
  > from the request (topic nouns, component names, file names - not stop words; if
67
- > the request is only a ticket reference, take the terms from the ticket title and body via
68
- > the tracker CLI when one is available, otherwise use the fallback below). Run
67
+ > the request is only a ticket reference, take the terms from the ticket title, body,
68
+ > and every `Reporter note:` labeled section in its comments via the resolved tracker
69
+ > CLI when a fetch path exists, otherwise use the fallback below). Fetch comments
70
+ > independently of context-builder, in pages of 50 until a short page. Match sections
71
+ > anywhere in each comment regardless of author; accept either ordering with
72
+ > `Overlap evidence:` and exclude that evidence part. Include every matched section's
73
+ > terms in the query. Run
69
74
  > `node <SPEC_INDEX> --query '<keywords>' --limit 10` from the worktree root,
70
75
  > keeping the keywords inside single quotes, and treat its rows as the candidate
71
76
  > list; zero rows means the index found no evidence, not that no predecessor exists -
@@ -125,10 +130,23 @@ Context-builder (conditional):
125
130
  > `<initial prompt verbatim>`. Fetch and distill these references:
126
131
  > `<detected refs, one per line>`. For each: acceptance criteria, hard constraints,
127
132
  > linked discussion that changes scope, and contradictions with the request as
128
- > stated. Quote the ticket's acceptance-criteria rows, with any repo-group headings inside that section, verbatim under their own
129
- > `## Ticket acceptance criteria (verbatim)` heading before distilling the rest;
133
+ > stated. Fetch the ticket body and independently fetch its full comment history
134
+ > through the resolved tracker CLI in pages of 50 until a short page. Extract ACs
135
+ > from the body only; comments never contribute AC rows. Quote the ticket's
136
+ > acceptance-criteria rows, with any repo-group headings inside that section,
137
+ > verbatim under their own `## Ticket acceptance criteria (verbatim)` heading;
130
138
  > brainstorming copies these rows unchanged into the spec and the council's
131
- > `Human input` block. Write ONLY the context handoff to your output path; do NOT
139
+ > `Human input` block. After the AC rows, quote every `Reporter note:` labeled
140
+ > section verbatim in creation order under `## Reporter notes (verbatim)`, with
141
+ > `comments: N fetched, M pages`. Match sections anywhere in a comment regardless
142
+ > of author, accepting either ordering with `Overlap evidence:` and excluding that
143
+ > evidence part. Trim ordinary comments to the gather budget, never matched note
144
+ > sections. Report later notes contradicting earlier notes as contradictions without
145
+ > resolving them. On body success with comment failure, keep the AC rows and mark
146
+ > the note heading's status `comments not fetched (<reason>)` or
147
+ > `comments incomplete after page <k> (<reason>)` for a failed or budget-cut page;
148
+ > carry this status to ticket handling's gate warning without stopping.
149
+ > Write ONLY the context handoff to your output path; do NOT
132
150
  > produce a meta-prompt file. End with an "Open questions that matter for the spec"
133
151
  > section.
134
152
  > If a ref is unreadable, say so explicitly and continue.
@@ -1,6 +1,6 @@
1
1
  # Ticket Handling
2
2
 
3
- A ticket is guidance, not sole truth. Fetch it; propose scope, approach, or acceptance changes when code disagrees, and record deviations in the spec. Implied requirements in the ticket body (Context, Problem, Idea) land in the spec body as any other requirement; the ticket's explicit acceptance criteria land verbatim in the section below.
3
+ A ticket is guidance, not sole truth. Fetch it; propose scope, approach, or acceptance changes when code disagrees, and record deviations in the spec. Carry implied requirements and terms from the ticket body (Context, Problem, Idea) and every `Reporter note:` comment section into the spec as any other requirement; keep the ticket body's explicit acceptance criteria verbatim in the section below. Extract ACs from the body only, never comments. With no fetch path or a whole-ticket fetch failure, list the unfetched ref and use `none - ticket not fetched (<reason>)` in `## Acceptance criteria`; show that existing `none` line at the gate so the user can paste rows. On body success with comments marked `comments not fetched (<reason>)` or `comments incomplete after page <k> (<reason>)`, retain the fetched AC rows and carry an adjacent gate-summary line: `Implied requirements came from the body only - <comment status>; paste missing comment text.` Continue to the gate without a new stop.
4
4
 
5
5
  **Extract the ticket's ACs.** When the ticket body has a heading matching `/acceptance criteria/i`, every list item under it is an AC (numbered, bullet, or checkbox) until the next heading of that heading's level or higher, and no other list in the body is; a heading one level deeper inside the section is a repo group - it names the repo whose part delivers the rows under it and does not end extraction. When there is no such heading, every top-level checkbox row in the body is an AC, except rows under a `Post-deployment housekeeping`, `Out of scope`, or `Follow-up` heading. Otherwise the ticket has no ACs. A nested list under an AC row rides with its parent as one row; an AC heading holding prose and no list makes each paragraph one row. Carry checked and unchecked rows alike, all written `- [ ]`. Take the rows and their repo-group headings from the gather draft's `## Ticket acceptance criteria (verbatim)` heading; when the ticket was not fetched, the gate summary shows the `none` line so the user can paste the rows, which then become rows.
6
6
 
@@ -440,6 +440,6 @@ nested resources" (the decision that made it so).
440
440
 
441
441
  ## Project overrides
442
442
 
443
- If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context - check it for project-specific routing tables, service paths, and verification commands. `## Response channels` and `## Issue tracker` are the named extension points for this skill.
443
+ If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it once per session - a skill that already has the file's content in context from an earlier skill's read skips the read; a restored session has nothing in context and reads it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context - check it for project-specific routing tables, service paths, and verification commands. `## Response channels` and `## Issue tracker` are the named extension points for this skill.
444
444
 
445
445
  The recognized headings, their readers, and the rules an override cannot change are listed in the [configuration front door](../../README.md#project-specific-overrides); an override extends or replaces the step it names and never lifts this skill's HARD CONSTRAINT or MUST text.
@@ -408,7 +408,7 @@ unset (no body edits).
408
408
 
409
409
  If a gauntlet overrides file exists - checked in order:
410
410
  `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`,
411
- `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it. Read
411
+ `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it once per session - a skill that already has the file's content in context from an earlier skill's read skips the read; a restored session has nothing in context and reads it. Read
412
412
  and apply `## conventions` whenever present, without a relevance
413
413
  judgment.
414
414
  Give this skill's named section precedence over conflicting
@@ -224,6 +224,6 @@ After agents return:
224
224
 
225
225
  ## Project overrides
226
226
 
227
- If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context — check it for project-specific routing tables, service paths, and verification commands.
227
+ If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it once per session - a skill that already has the file's content in context from an earlier skill's read skips the read; a restored session has nothing in context and reads it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context — check it for project-specific routing tables, service paths, and verification commands.
228
228
 
229
229
  The recognized headings, their readers, and the rules an override cannot change are listed in the [configuration front door](../../README.md#project-specific-overrides); an override extends or replaces the step it names and never lifts this skill's HARD CONSTRAINT or MUST text.
@@ -434,6 +434,6 @@ Once the merge (and any deploy) has landed, `/skill:check-delivery <ticket-ref>`
434
434
 
435
435
  ## Project overrides
436
436
 
437
- If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context — check it for project-specific routing tables, service paths, and verification commands.
437
+ If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it once per session - a skill that already has the file's content in context from an earlier skill's read skips the read; a restored session has nothing in context and reads it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context — check it for project-specific routing tables, service paths, and verification commands.
438
438
 
439
439
  The recognized headings, their readers, and the rules an override cannot change are listed in the [configuration front door](../../README.md#project-specific-overrides); an override extends or replaces the step it names and never lifts this skill's HARD CONSTRAINT or MUST text.
@@ -81,6 +81,6 @@ Run after adding a rule or rewording a discipline rule.
81
81
 
82
82
  ## Project overrides
83
83
 
84
- If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context - check it for project-specific routing tables, service paths, and verification commands.
84
+ If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it once per session - a skill that already has the file's content in context from an earlier skill's read skips the read; a restored session has nothing in context and reads it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context - check it for project-specific routing tables, service paths, and verification commands.
85
85
 
86
86
  The recognized headings, their readers, and the rules an override cannot change are listed in the [configuration front door](../../README.md#project-specific-overrides); an override extends or replaces the step it names and never lifts this skill's HARD CONSTRAINT or MUST text.
@@ -75,6 +75,6 @@ These bind every rendered report, menu, and external payload (review bodies, rep
75
75
 
76
76
  ## Project overrides
77
77
 
78
- If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context - check it for project-specific routing tables, service paths, and verification commands. `## PR gate` keys are read in step 2 (`reference/assessment.md`); `## comms style` extends the wording rules. `## cleanup` steps run on the `cleanup` pick (`reference/cleanup.md`).
78
+ If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it once per session - a skill that already has the file's content in context from an earlier skill's read skips the read; a restored session has nothing in context and reads it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context - check it for project-specific routing tables, service paths, and verification commands. `## PR gate` keys are read in step 2 (`reference/assessment.md`); `## comms style` extends the wording rules. `## cleanup` steps run on the `cleanup` pick (`reference/cleanup.md`).
79
79
 
80
80
  The recognized headings, their readers, and the rules an override cannot change are listed in the [configuration front door](../../README.md#project-specific-overrides); an override extends or replaces the step it names and never lifts this skill's HARD CONSTRAINT or MUST text.
@@ -109,7 +109,7 @@ loop: tracker state is extension state no subagent can read.
109
109
 
110
110
  If a gauntlet overrides file exists - checked in order:
111
111
  `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`,
112
- `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it. Read
112
+ `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it once per session - a skill that already has the file's content in context from an earlier skill's read skips the read; a restored session has nothing in context and reads it. Read
113
113
  and apply `## conventions` whenever present, without a relevance
114
114
  judgment.
115
115
  Give this skill's named section precedence over conflicting
@@ -36,7 +36,7 @@ Nothing else: no preamble, no restated digest, no file written before item 1 is
36
36
 
37
37
  If a gauntlet overrides file exists - checked in order:
38
38
  `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`,
39
- `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it. Read
39
+ `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it once per session - a skill that already has the file's content in context from an earlier skill's read skips the read; a restored session has nothing in context and reads it. Read
40
40
  and apply `## conventions` whenever present, without a relevance
41
41
  judgment.
42
42
  Give this skill's named section precedence over conflicting
@@ -156,7 +156,7 @@ owning skill **without** its reset-bearing entry:
156
156
  ## Project overrides
157
157
  If a gauntlet overrides file exists - checked in order:
158
158
  `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`,
159
- `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it. Read
159
+ `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it once per session - a skill that already has the file's content in context from an earlier skill's read skips the read; a restored session has nothing in context and reads it. Read
160
160
  and apply `## conventions` whenever present, without a relevance
161
161
  judgment.
162
162
  Give this skill's named section precedence over conflicting
@@ -258,6 +258,6 @@ for product behavior the CLI doesn't expose.
258
258
 
259
259
  ## Project overrides
260
260
 
261
- If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context - check it for project-specific routing tables, service paths, and verification commands. `## Issue tracker` is the named extension point for this skill.
261
+ If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it once per session - a skill that already has the file's content in context from an earlier skill's read skips the read; a restored session has nothing in context and reads it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context - check it for project-specific routing tables, service paths, and verification commands. `## Issue tracker` is the named extension point for this skill.
262
262
 
263
263
  The recognized headings, their readers, and the rules an override cannot change are listed in the [configuration front door](../../README.md#project-specific-overrides); an override extends or replaces the step it names and never lifts this skill's HARD CONSTRAINT or MUST text.
@@ -177,6 +177,6 @@ No performative agreement. Technical rigor always.
177
177
 
178
178
  ## Project overrides
179
179
 
180
- If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context — check it for project-specific routing tables, service paths, and verification commands.
180
+ If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it once per session - a skill that already has the file's content in context from an earlier skill's read skips the read; a restored session has nothing in context and reads it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context — check it for project-specific routing tables, service paths, and verification commands.
181
181
 
182
182
  The recognized headings, their readers, and the rules an override cannot change are listed in the [configuration front door](../../README.md#project-specific-overrides); an override extends or replaces the step it names and never lifts this skill's HARD CONSTRAINT or MUST text.
@@ -79,6 +79,6 @@ See template at: `code-reviewer.md` in this skill directory
79
79
 
80
80
  ## Project overrides
81
81
 
82
- If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context — check it for project-specific routing tables, service paths, and verification commands.
82
+ If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it once per session - a skill that already has the file's content in context from an earlier skill's read skips the read; a restored session has nothing in context and reads it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context — check it for project-specific routing tables, service paths, and verification commands.
83
83
 
84
84
  The recognized headings, their readers, and the rules an override cannot change are listed in the [configuration front door](../../README.md#project-specific-overrides); an override extends or replaces the step it names and never lifts this skill's HARD CONSTRAINT or MUST text.
@@ -183,6 +183,6 @@ Single pass — no automatic re-roast loop. The user can invoke this skill again
183
183
 
184
184
  ## Project overrides
185
185
 
186
- If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context — check it for project-specific routing tables, service paths, and verification commands.
186
+ If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it once per session - a skill that already has the file's content in context from an earlier skill's read skips the read; a restored session has nothing in context and reads it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context — check it for project-specific routing tables, service paths, and verification commands.
187
187
 
188
188
  The recognized headings, their readers, and the rules an override cannot change are listed in the [configuration front door](../../README.md#project-specific-overrides); an override extends or replaces the step it names and never lifts this skill's HARD CONSTRAINT or MUST text.
@@ -73,26 +73,33 @@ Draft ordinary create/repair as a full replacement body; draft overlap alternati
73
73
  The draft may propose **at most one comment per approved issue**, e.g.
74
74
  `Reporter note: <demoted detail>`. Overflow test: the Idea section keeps
75
75
  exactly one attributed sketch line; any demoted material left over after
76
- that line is overflow, and the overflow is the comment body (long pasted
76
+ that line is overflow, and the overflow is the comment body; preserve the whole original paragraph/list/block verbatim rather than subtracting words reused in the sketch (long pasted
77
77
  code, verbose repro trails, a full proposed diff are the typical shapes).
78
78
  No overflow, no comment - except overlap evidence under the gathered reference or an in-session ask, in which case
79
79
  use the overlap reference's evidence payload or the user-named content as the comment body in place of overflow.
80
80
  Default off outside overlap evidence: overrides cannot force a comment absent overflow or an
81
81
  in-session ask. In repair mode an existing `Reporter note:` comment
82
82
  satisfies the overflow (skip), unless the demoted detail materially changed, in which case a new comment
83
- is proposed - comments are never edited. In a split, the comment attaches
84
- only to the issue that retained the demoted Idea material; if none does,
85
- it is omitted.
83
+ is proposed - comments are never edited. In a split, route each accumulated payload part to its owning issue: Idea demotion to the issue retaining that Idea, Context/Problem moves to the issue owning the corresponding failure. Propose no comment for an issue with no payload part, absent evidence or an in-session ask.
84
+
85
+ Accumulate step-4 demotion, step-5 moves, and roast-removed mechanism verbatim under `Reporter note:`; combine with `Overlap evidence:` second in the same comment slot. Persist the payload as trailing `## Proposed Reporter note` in the existing draft artifact, fenced as untrusted data like the source snapshot; create no third file. Carry snapshot and payload through every draft/roast rerun: no new match appends nothing and never clears earlier text. Newly displaced detail is materially changed even with an older note; propose a new comment, never edit the old one. A body that never displaced anything retains the body-only write absent evidence or an in-session ask.
86
86
 
87
87
  ### 5 - Deterministic gates
88
88
 
89
- Before any subagent dispatch, inline and cheap: AC integrity gate, evidence gate, metadata audit, split detection (all below).
89
+ Before any subagent dispatch, inline and cheap: AC integrity gate, evidence gate, metadata audit, split detection (all below), and this displaced-detail check:
90
+
91
+ | Section | Move to accumulated Reporter note |
92
+ |---|---|
93
+ | Idea | Beyond the one attributed sketch line: a second paragraph, a list, or a code block |
94
+ | Context, Problem | Implementer inventories: file paths; module/script/function/setting identifiers; sizes and line counts; lists of those; code blocks |
95
+
96
+ Exempt one deletion-safe rule-7 pointer per failure, rule-5 one-sentence/one-number examples, requester-used dual-use terms, and plain-words failure/impact lists. Move the whole list/block or path/count-bearing sentence verbatim, never summarize or drop it; restore a unit when moving it breaks the plain-words lead or product cause/effect (rule 3). Leave a paragraph-long single Idea line to roast judgment; it does not match this closed list.
90
97
 
91
98
  ### 6 - No-op check
92
99
 
93
100
  For ordinary repair only, if the body already conforms AND the metadata audit is clean AND no comment is proposed: report "conforms, no changes proposed" and stop. No write, no confirmation prompt, no roast. A conforming ticket never pays for a dispatch - a conforming body with pending overflow still reaches the gate.
94
101
 
95
- "Conforms" includes the ticket wording contract (`reference/ticket-wording.md`, resolved against this skill's own directory), applied inline as a short checklist over Context/Problem/Idea: strip test passes (rule 2)? plain-words lead per asserted failure (rule 4)? example or `none (<reason>)` per failure (rule 5)? jargon defined or dropped (rule 6)? references parenthetical and deletion-safe (rule 7)? links summarized, no spiderman hops (rule 8)? Any "no" makes the body non-conforming: repair proposes a rewrite through the normal draft -> gates -> roast -> gate path instead of reporting "conforms" - the contract-briefed roast backstops this inline judgment. The rewrite touches Context/Problem/Idea prose only; ACs are never rewritten for self-containment.
102
+ "Conforms" includes the ticket wording contract (`reference/ticket-wording.md`, resolved against this skill's own directory), applied inline as a short checklist over Context/Problem/Idea: strip test passes (rule 2)? plain-words lead per asserted failure (rule 4)? example or `none (<reason>)` per failure (rule 5)? repo-native terms defined or dropped and requester-used terms left undefined under rule 6's attribution test? Idea within one attributed sketch line? Context/Problem free of step-5 closed-list matches? references parenthetical and deletion-safe (rule 7)? links summarized, no spiderman hops (rule 8)? Any "no" makes the body non-conforming: repair proposes a rewrite through the normal draft -> gates -> roast -> gate path instead of reporting "conforms" - the contract-briefed roast backstops this inline judgment. Route each failure through draft -> step 5 -> roast -> old/new gate, with a new comment for newly displaced detail. The conformance-only rewrite touches Context/Problem/Idea prose only: copy the original bytes under the AC heading unchanged and compare bytes before presenting the gate; any mismatch fails the repair run.
96
103
 
97
104
  ### 7 - Roast
98
105
 
@@ -121,7 +128,7 @@ Immediately before any mutation, including comments - after approval, not at gat
121
128
 
122
129
  Runs twice: during gather (recovery via targeted questions) and on the assembled draft.
123
130
 
124
- **Normalize first.** For additive overlap enrichment, preserve legacy rows verbatim and normalize only added/changed criteria under the gathered reference. In ordinary drafts and create-anyway, every criterion - numbered list, prose sentence, Given/When/Then, already-checked box - is extracted and rendered as a `- [ ]` item before gating. Drafts always emit ACs as `- [ ]` items; repair normalizes existing ACs into that form. No criterion evades the gate by syntax.
131
+ **Normalize first.** For additive overlap enrichment, preserve legacy rows verbatim and normalize only added/changed criteria under the gathered reference. For conformance-only repair, parse checked, numbered, and prose criteria for validity without serializing them as `- [ ]`; preserve their raw bytes under step 6 while retaining every integrity outcome and hard stop. In other ordinary drafts and create-anyway, every criterion - numbered list, prose sentence, Given/When/Then, already-checked box - is extracted and rendered as a `- [ ]` item before gating. Those drafts emit ACs as `- [ ]` items, including repairs other than the conformance-only exception. No criterion evades the gate by syntax.
125
132
 
126
133
  The test is structural, not keyword-based:
127
134
 
@@ -179,10 +186,10 @@ No block, no split. A block failing the identity or outcome test, or naming a no
179
186
  Inline council dispatch, reusing spec-council config and personas - **not** `/skill:roasting-the-spec` (that skill's contract is spec-file apply mechanics; a tracker draft is not a spec file). No new agents.
180
187
 
181
188
  1. Resolve `gauntlet_setting({ key: "specCouncil" })` when the tool exists. Verdict `council` -> dispatch `spec-council-member`s in parallel plus a `spec-council-synthesizer` chair. Verdict `worker` (or empty members) -> one fresh `worker` critique with the four-axis brief of item 4, its task text carrying the absolute path to `reference/ticket-wording.md` (resolved against this skill's own directory). Malformed config -> one warning line, then branch on verdict.
182
- 2. **Dispatch shape**, mirroring `/skill:roasting-the-spec`: write the draft body and the source snapshot (original ticket + comments, or the create-mode inputs) to absolute temp files under `mktemp -d`; delimit untrusted snapshots as data. The raw ask (create mode) or the original ticket body (repair mode) is also passed as the `Human input (verbatim; off-limits for over-spec)` block. For overlap, include all available mutually exclusive alternatives and the fenced read-only source; do not treat alternatives as split slices. When a split is proposed, the draft artifact holds all N proposed bodies plus their three-line justification blocks (see Split rule) in one file, not a single body. Two separate calls - never fuse members and chair into one chain (a fused chain lets one member failure kill the roast before the chair runs). Call 1: one member fanout with `cwd` = repo root, absolute `output` paths and `outputMode: "file-only"` on every member task and targeted retry, run-level `control: { needsAttentionAfterMs: 60000, inFlightSilenceCeilingMs: 240000, inFlightSilenceKillMs: 300000 }` (sits beside `tasks`, not inside each task; effective silence-kill max(300s, 240+60) = 300s - record all three fields verbatim so a pi-cohort default change cannot stretch the kill). Then probe the member output files on disk with item 7's usable test. Call 2: the inline chair, with explicit usable member paths in its task text, the same control block (`:low` chair turns are short), and task text that (a) forbids repository access - member disagreement on a fact is reported in the synthesis, never verified against the repo - and (b) states coverage: `Coverage: N of M members reported; <slug>: <reason>` (pi-cohort's kill diagnostic when present, else "no output produced"; omit reasons at full coverage; singular wording when one member reported). Member task text: *the draft at `<path>` is the artifact under review; this ticket brief supersedes your spec-axis template - emit the same findings format against the draft; content-only review: the temp files plus the two referenced reference paths (split-axes, ticket-wording) are the entire permitted input - do not read, search, or scan the repository; do not edit any file.* Include the absolute paths to `reference/split-axes.md` and `reference/ticket-wording.md` (both resolved against this skill's own directory) in each member's task text - members run with `cwd` = the consumer repo, where a package-relative path does not resolve.
189
+ 2. **Dispatch shape**, mirroring `/skill:roasting-the-spec`: write the draft body and the source snapshot (original ticket + comments, or the create-mode inputs) to absolute temp files under `mktemp -d`; delimit untrusted snapshots as data. The raw ask (create mode) or the original ticket body (repair mode) is also passed as the `Human input (verbatim; off-limits for over-spec)` block. For overlap, include all available mutually exclusive alternatives and the fenced read-only source; do not treat alternatives as split slices. When a split is proposed, the draft artifact holds all N proposed bodies plus their three-line justification blocks (see Split rule) in one file, not a single body. Two separate calls - never fuse members and chair into one chain (a fused chain lets one member failure kill the roast before the chair runs). Call 1: one member fanout with `cwd` = repo root, absolute `output` paths and `outputMode: "file-only"` on every member task and targeted retry, run-level `control: { needsAttentionAfterMs: 60000, inFlightSilenceCeilingMs: 240000, inFlightSilenceKillMs: 300000 }` (sits beside `tasks`, not inside each task; effective silence-kill max(300s, 240+60) = 300s - record all three fields verbatim so a pi-cohort default change cannot stretch the kill). Then probe the member output files on disk with item 7's usable test. Call 2: the inline chair, with explicit usable member paths in its task text, the same control block (`:low` chair turns are short), and task text that (a) forbids repository access - member disagreement on a fact is reported in the synthesis, never verified against the repo - and (b) states coverage: `Coverage: N of M members reported; <slug>: <reason>` (pi-cohort's kill diagnostic when present, else "no output produced"; omit reasons at full coverage; singular wording when one member reported). Member task text: *the draft at `<path>` is the artifact under review; name the displaced text its trailing `## Proposed Reporter note` section already retains before naming anything missing; this ticket brief supersedes your spec-axis template - emit the same findings format against the draft; content-only review: the temp files plus the two referenced reference paths (split-axes, ticket-wording) are the entire permitted input - do not read, search, or scan the repository; do not edit any file.* Include the absolute paths to `reference/split-axes.md` and `reference/ticket-wording.md` (both resolved against this skill's own directory) in each member's task text - members run with `cwd` = the consumer repo, where a package-relative path does not resolve.
183
190
  3. **Effort: cheap by default.** Append a `:low` thinking suffix to each member's model string at dispatch (this beats the persona's frontmatter `xhigh` pin). Same for the chair: a configured chair string gets any existing suffix replaced with `:low`; an unconfigured chair is dispatched with the main loop's own string, read from `$PI_PROVIDER`/`$PI_MODEL` with the bash tool, plus `:low`. The `worker` fallback carries no thinking pin - it runs at the preset's default. **Full-roast escape:** the user may request a full roast, dispatching all model strings bare/as-configured, restoring the xhigh pins; a full roast reuses the spec-roast control blocks (members `{ needsAttentionAfterMs: 300000, inFlightSilenceCeilingMs: 300000, inFlightSilenceKillMs: 600000 }`, chair `{ needsAttentionAfterMs: 300000, inFlightSilenceCeilingMs: 600000, inFlightSilenceKillMs: 900000 }`) - the 5-minute figures in item 2 are `:low`-only.
184
- 4. **Brief covers four axes**, absorbing the fidelity-review role without a new persona: *fidelity* - compare draft against source intent (original ticket + comments in repair; prompt + answers in create), flag `lost` / `added` / `gap` (unpacking existing claims to satisfy the ticket wording contract is not `added`; contract-conformance findings on Context/Problem/Idea outrank fidelity flags that only object to extra explanation of the same claims); and *quality* - problem framing, AC integrity beyond the deterministic gate, scope, wording, and conformance to the ticket wording contract (reference path provided in every roast brief); and *split soundness* - if the draft proposes a split, test each slice against the split-axes reference (path provided in the task text); an architecture-shaped boundary is reported as a finding line containing the marker `split-axis:` (members keep their existing spec-axis findings template; the marker is a substring flag within it, not a new findings kind), e.g. `- [major] split-axis: <slice> - <why> -> merge`. Members may argue toward one ticket, never propose or endorse a split. And *attribution* - when the Acceptance Criteria section carries `### <repo>` groups, every row sits under the repo that can observe it; a misplaced row is a finding naming the group it belongs to, applied like any other concrete fix; a repo group is never a `split-axis:` finding.
185
- 5. Disposition: unambiguous concrete fixes applied to the draft (one re-pass max); ambiguous findings surfaced at the confirmation gate. Roast edits affect the body draft pre-write only, never posted as a tracker comment, and re-run the deterministic gates (pipeline step 5). Additionally, the parent scans the **usable member output files (item 7's structural test) directly** for lines containing `split-axis:` (substring match), independent of the chair synthesis; any such finding on an actual split (never mutually exclusive overlap alternatives) auto-applies a merge - the split is withdrawn and the draft becomes one ticket with phased AC groups, inside the same one-re-pass budget, and the pre-merge N-body draft is kept alongside: a human re-request of the split at the gate re-presents those N bodies old->new as the approval diff (see the Split rule's sticky override). The chair keeps every other axis; clearing a `split-axis:` finding is not on its path. The same directional rule - toward one ticket, never toward a split - binds the `worker` fallback and the runtime conditional (item 6).
191
+ 4. **Brief covers four axes**, absorbing the fidelity-review role without a new persona: *fidelity* - compare draft against source intent (original ticket + comments in repair; prompt + answers in create), flag `lost` / `added` / `gap` (unpacking existing claims to satisfy the ticket wording contract is not `added`; contract-conformance findings on Context/Problem/Idea outrank fidelity flags that only object to extra explanation of the same claims); and *quality* - problem framing, AC integrity beyond the deterministic gate, scope, wording, and conformance to the ticket wording contract (reference path provided in every roast brief). Flag quality findings for the product-aware repo-stranger reader, one-sentence/one-number examples, trigger/current-state Context without mechanism, and Idea overflow including a paragraph-long single line; apply rule 3's comprehension precedence: never remove a plain-words Problem lead or a product-level cause-and-effect sentence through a cut, compression, or redundancy finding. And *split soundness* - if the draft proposes a split, test each slice against the split-axes reference (path provided in the task text); an architecture-shaped boundary is reported as a finding line containing the marker `split-axis:` (members keep their existing spec-axis findings template; the marker is a substring flag within it, not a new findings kind), e.g. `- [major] split-axis: <slice> - <why> -> merge`. Members may argue toward one ticket, never propose or endorse a split. And *attribution* - when the Acceptance Criteria section carries `### <repo>` groups, every row sits under the repo that can observe it; a misplaced row is a finding naming the group it belongs to, applied like any other concrete fix; a repo group is never a `split-axis:` finding.
192
+ 5. Disposition: unambiguous concrete fixes applied to the draft (one re-pass max); ambiguous findings surfaced at the confirmation gate. Apply roast edits to the body draft pre-write and re-run step 5; append removed Context/Problem mechanism verbatim to the accumulated Reporter-note payload, never delete it. Roast findings themselves are never posted as a tracker comment. Additionally, the parent scans the **usable member output files (item 7's structural test) directly** for lines containing `split-axis:` (substring match), independent of the chair synthesis; any such finding on an actual split (never mutually exclusive overlap alternatives) auto-applies a merge - the split is withdrawn and the draft becomes one ticket with phased AC groups, inside the same one-re-pass budget, and the pre-merge N-body draft is kept alongside: a human re-request of the split at the gate re-presents those N bodies old->new as the approval diff (see the Split rule's sticky override). The chair keeps every other axis; clearing a `split-axis:` finding is not on its path. The same directional rule - toward one ticket, never toward a split - binds the `worker` fallback and the runtime conditional (item 6).
186
193
  6. **Runtime conditional (the one allowed):** on a harness with no `gauntlet_setting`/`subagent()` (e.g. Claude Code), dispatch fresh general-purpose subagents via that harness's native facility at low effort, with the same four-axis brief (including the absolute `reference/ticket-wording.md` path) and temp-file artifacts - on such a harness this conditional IS the roast, so the contract path must ride along.
187
194
  7. **Usable outputs, targeted retry, and roast failure.** A member output
188
195
  file is usable iff it is non-empty AND contains a
@@ -252,7 +259,7 @@ Claims about user-visible/UI behavior need evidence: screenshots/artifacts via r
252
259
 
253
260
  Read `reference/ticket-wording.md` (resolve the path against this skill's own directory) and apply it - the self-containment contract lives there; a link alone is not the contract in hand. Repo comms style (found via the ladder) still tunes tone and format - where tone and format explicitly exclude density and brevity - but the contract (its rules 2-8) yields only to an overrides-file section that explicitly addresses ticket wording (e.g. a `## Ticket wording` heading in the gauntlet overrides file). Do not let generic density/brevity norms from the capability ladder, AGENTS.md, or `## conventions` weaken the ticket-wording contract; apply a conventions override to it only when the rule explicitly addresses ticket wording. Remaining defaults:
254
261
 
255
- - **Minimal-to-actionable, split scoping:** Context/Problem/Idea are the shortest prose that passes the contract's self-containment test - understandable and triagable by a reader who has never opened the repo; the ACs remain the part a stranger (human or LLM) can act on AND verify - implementer-facing per contract rule 1. Every sentence earns its place.
262
+ - **Minimal-to-actionable, split scoping:** Context/Problem/Idea are the shortest prose that passes the contract's self-containment test - understandable and triagable by a reader who knows the product and its customers but has never opened the repo; the ACs remain the part a stranger (human or LLM) can act on AND verify - implementer-facing per contract rule 1. Every sentence earns its place.
256
263
  - Active voice, named actor; no filler ("comprehensive", "successfully", restated-goal paragraphs).
257
264
  - No heading scaffolding beyond the four template sections plus the two named optional ones (`Out of scope / Follow-up`, `Post-deployment housekeeping`) and the `### <repo>` groups inside Acceptance Criteria - the only exceptions. ASCII punctuation.
258
265
  - References use the tracker-native link/mention form, never bare identifiers; link the specific thing, not its container; never invent an id or URL.
@@ -324,6 +331,6 @@ Read this when applying the AC integrity gate (drafting, repairing, or adjudicat
324
331
 
325
332
  ## Project overrides
326
333
 
327
- If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context - check it for project-specific routing tables, service paths, and verification commands.
334
+ If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it once per session - a skill that already has the file's content in context from an earlier skill's read skips the read; a restored session has nothing in context and reads it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context - check it for project-specific routing tables, service paths, and verification commands.
328
335
 
329
336
  The recognized headings, their readers, and the rules an override cannot change are listed in the [configuration front door](../../README.md#project-specific-overrides); an override extends or replaces the step it names and never lifts this skill's HARD CONSTRAINT or MUST text.
@@ -4,7 +4,9 @@ Consumed by `shape-ticket`'s SKILL.md (draft step, no-op check, and every roast
4
4
 
5
5
  ## Reader and scope
6
6
 
7
- 1. **Reader definition.** The "stranger" the ticket body serves is a reader who has never opened the repo. Acceptance Criteria are exempt throughout this contract - they address the implementer and may name files, symbols, and settings freely.
7
+ 1. **Reader definition.** Write for a reader who knows the product and its customers but has never opened the repo. Acceptance Criteria are exempt throughout this contract - they address the implementer and may name files, symbols, and settings freely.
8
+
9
+ Bound Context to the trigger of the ask and what exists today; put needed mechanism in Problem's rule-7 parenthetical pointer. Treat mechanism as internal implementation explanation: which module, step, store, or call does the work and in what order. Move "the export job writes the CSV through the mail queue before the row count is known" to the pointer or note; retain product-level cause and effect such as "the export email arrives before the file is complete, so the first download is empty." Apply rule 3 beside these bounds: restore material when removing it breaks comprehension; shorten addresses and inventories, never the plain-words explanation.
8
10
 
9
11
  Scope: Context/Problem/Idea prose only. ACs, split justification blocks, metadata rationale lines, and Reporter-note comments are out of this contract's scope.
10
12
 
@@ -13,8 +15,8 @@ Scope: Context/Problem/Idea prose only. ACs, split justification blocks, metadat
13
15
  2. **Self-containment test.** Remove every code/doc reference from Context, Problem, and Idea; what remains must still make the problem and its impact understandable and triagable by that reader. Deleting the references may lose depth, never comprehension. The test is a reviewer judgment with a mechanical framing (strip, re-read, ask "triagable?"), not a keyword scan.
14
16
  3. **Precedence.** Self-contained human comprehension wins over brevity and retrieval-density norms; compression applies only after the test passes. "Shortest body" survives as a constraint on what may be omitted, never a license to leave jargon undefined or mechanisms unexplained.
15
17
  4. **Plain-words lead.** Each independently asserted failure or impact in Problem opens with a plain-words sentence of what goes wrong and what it costs, before any mechanism. (The lead and example rules bind Problem; Context and Idea are bound by the general self-containment test.)
16
- 5. **Example per failure.** Each independently asserted failure carries a concrete example: real numbers, a before/after, or a short transcript. One example may serve multiple sentences describing the same failure. `none (<reason>)` is permitted only when no observable exists yet (pure rename/removal, or discovery work whose deliverable is the observable); the reason is part of the draft and thus roast-reviewable. A disputed reason is an ordinary roast finding handled by the existing disposition machinery (applied if unambiguous, surfaced at the gate if not) - no new disposition class.
17
- 6. **Jargon.** Domain jargon - including repo-native terms - is defined at first use in plain words, or dropped. A link is not a definition when the term is load-bearing for triage.
18
+ 5. **Example per failure.** Give each independently asserted failure a concrete example limited to one sentence or one number: real numbers, a before/after, or a short transcript. One example may serve multiple sentences describing the same failure. `none (<reason>)` is permitted only when no observable exists yet (pure rename/removal, or discovery work whose deliverable is the observable); the reason is part of the draft and thus roast-reviewable. A disputed reason is an ordinary roast finding handled by the existing disposition machinery (applied if unambiguous, surfaced at the gate if not) - no new disposition class.
19
+ 6. **Jargon.** Define repo-native terms (module, script, internal tool, extension, or setting names) at first use in plain words, or drop them. Leave product and domain terms the requester used undefined; requester usage wins for terms that are also internal names. Establish requester usage from the ask's own words, reporter-authored comments, a quoted ask, or explicit attribution ("the reporter calls this ..."), never from unattributed existing body prose. Keep an internal term's definition when its only usage evidence is the existing body. A link is not a definition when the term is load-bearing for triage.
18
20
  7. **Pointer demotion.** Code/doc references in Context/Problem/Idea are demoted to parenthetical pointers whose deletion loses no meaning, e.g. "(Pointer for the implementer: detectChains, src/chain-detector.ts.)". Composition with the tracker-native-links rule in SKILL.md's `## Ticket wording`: that rule governs *how* a reference is written (native link/mention form, never bare identifiers); pointer demotion governs *where* it may sit (parenthetical, deletion-safe).
19
21
  8. **Link-vs-inline (anti-spiderman).** Linking stays legitimate for targets impractical to inline - a whole design doc, a KB page, a long log - and for general-knowledge material; every such link carries a one-line plain-words statement of what the reader needs from it. What is forbidden is the spiderman shape: many small load-bearing hops, where the full picture must be assembled from N places even when each individual inline would be cheap. Discriminator: "is this definition load-bearing for triage?" - load-bearing small definitions get inlined; big chunks get linked with a summary line.
20
22
 
@@ -120,6 +120,8 @@ Implementer prompt templates must instruct subagents to return one of these stat
120
120
 
121
121
  ## Dispatch
122
122
 
123
+ For the fan-out + worktree + patch-integration + conflict mechanics, see `dispatching-parallel-agents`.
124
+
123
125
  Pass the implementation worktree as top-level `cwd`. For per-patch spec reviews, use [Spec-review snapshots](#spec-review-snapshots) instead.
124
126
 
125
127
  ```ts
@@ -164,7 +166,7 @@ Run every plan task through this loop in a wave of N >= 1 tasks. Run waves in se
164
166
  **Per-wave loop:**
165
167
 
166
168
  1. **Independence check.** Parse the wave's tasks' `Files:` blocks; assert pairwise-disjoint (mechanical, mirroring `wave-file-disjointness`: `Test`/`Test` on one path is not overlap, `Test` vs another task's `Create`/`Modify` is, `Modify`/`Modify` is). Runtime-resource disjointness (DB/schema, port, fixture, external service, shared temp path) is not machine-checkable here — trust the plan's wave grouping, which `writing-plans`' D5 contract guarantees. Either kind of overlap → the wave is mis-grouped; split it into one-task waves and note it.
167
- 2. **Start, then dispatch.** Record `WAVE_BASE_SHA` with `git -C <worktree> rev-parse HEAD` before dispatch; keep it fixed through the wave's commit. Mark every wave index `in_progress` in increasing index order. Use the once-per-phase preflight below to choose exactly one initial chain (including one-task waves), or the fallback implementer fan-out.
169
+ 2. **Start, then dispatch.** Record `WAVE_BASE_SHA` with `git -C <worktree> rev-parse HEAD` before dispatch; keep it fixed through the wave's commit. Mark every wave index `in_progress` in increasing index order. Run the once-per-phase preflight below before dispatching exactly one initial chain (including one-task waves).
168
170
  3. **Read the result once.** Read statuses, verdicts, patches, and reports as specified below. All implementers `DONE` and all verdicts `COMPLIANT` -> step 4. Any other outcome -> [Chain stopped or failed](#chain-stopped-or-failed). The ticket's `FAIL` means a spec gap (`NEEDS_REWORK`), not a structured verdict or an SR `stopOn` condition.
169
171
  4. **Integrate.** Run `git -C <worktree> apply --index <patch-path>` for each accepted task's patch sequentially. This stages additions as well as tracked changes for review. On an apply failure, drop that task from the wave; finish steps 5-7 for the survivors, then re-dispatch the dropped task as a one-task wave from the new committed HEAD. With zero surviving patches, skip steps 5-7 and retry the failed task from the unchanged clean HEAD under [When a Subagent Fails](#when-a-subagent-fails)'s two-attempt limit; dispatch no empty review or commit. Keep its tracker index `in_progress` until its own wave commits.
170
172
  5. **Test gate.** Run the wave's `SCOPED_TEST_COMMANDS` (union of its tasks' `Tests:` commands) on the integrated tree as `(cd "<worktree>" && <command>)` for each command — the full verification set is the verify phase's job, run once. On failure, dispatch one plain in-place `implementer` in the branch checkout with the failing output, the owning task's full text, and the wave's `SCOPED_TEST_COMMANDS`, under [When a Subagent Fails](#when-a-subagent-fails), then rerun the scoped gate. After the repaired tree passes, stage repair deliverables with `git -C <worktree> add -A` and dispatch spec review for every affected task against the integrated checkout before the initial CR; prior SR acceptance does not cover the repair. Pass each affected task's full text, absolute spec path, `Spec:` anchors, `Tests:` block, and `- Test:` paths; record its review tree per [Fix delta](#fix-delta). Resolve SR findings through [Fix-Loop Rounds](#fix-loop-rounds), with repairs in place and the scoped gate rerun. Never dispatch a nested wave from this dirty checkout: children cannot see integrated siblings from the old HEAD.
@@ -177,18 +179,51 @@ Run every plan task through this loop in a wave of N >= 1 tasks. Run waves in se
177
179
 
178
180
  **Caveat:** each task must be independently runnable and verifiable in a fresh worktree — no reliance on uncommitted local state. `pi-cohort` symlinks `node_modules`; repos needing other per-worktree setup must account for it.
179
181
 
180
- Requires pi-cohort >= 7.4.0 for `treePath` (`stopOn` is 7.3.0); below it, the preflight turns the chain off and the wave runs as today's two fan-outs.
181
-
182
- Before the first wave, run this lookup once per implement phase, observing both commands' failures (use shell pipeline failure detection):
182
+ Run this guard once per implement phase before the first wave. Stop on any error before dispatch; read the peer floor from the installed gauntlet package, not the consumer repository.
183
183
 
184
+ <!-- pi-cohort-preflight-shell -->
184
185
  ```bash
185
- set -o pipefail
186
- COHORT_DIR=$(pi list | grep -A1 'pi-cohort$' | tail -1 | tr -d ' ')
187
- COHORT_VERSION=$(node -p "require('$COHORT_DIR/package.json').version")
186
+ PI_PACKAGES=$(pi list) || { echo 'pi-cohort not installed' >&2; exit 1; }
187
+ export PI_PACKAGES
188
+ node <<'NODE'
189
+ const { readFileSync } = require('node:fs');
190
+ const { join } = require('node:path');
191
+ const lines = process.env.PI_PACKAGES.split('\n');
192
+ function directory(name) {
193
+ for (let i = 0; i < lines.length - 1; i++) {
194
+ const source = lines[i].match(/^(\s+)\S/);
195
+ const path = lines[i + 1].match(/^(\s+)\S/);
196
+ if (!source || !path || path[1].length <= source[1].length) continue;
197
+ const dir = lines[++i].trim();
198
+ try {
199
+ if (JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8')).name === name) return dir;
200
+ } catch {}
201
+ }
202
+ }
203
+ function fail(message) { console.error(message); process.exit(1); }
204
+ const cohort = directory('pi-cohort');
205
+ if (!cohort) fail('pi-cohort not installed');
206
+ let installed;
207
+ try { installed = JSON.parse(readFileSync(join(cohort, 'package.json'), 'utf8')).version; }
208
+ catch { fail('pi-cohort not installed'); }
209
+ let peer;
210
+ try {
211
+ peer = JSON.parse(readFileSync(join(directory('pi-gauntlet'), 'package.json'), 'utf8')).peerDependencies['pi-cohort'];
212
+ } catch { fail('cannot read peer floor'); }
213
+ if (typeof peer !== 'string' || !/^>=\d+\.\d+\.\d+$/.test(peer)) fail('cannot read peer floor');
214
+ const floor = peer.slice(2);
215
+ if (typeof installed !== 'string' || !/^\d+\.\d+\.\d+$/.test(installed)) fail(`cannot parse pi-cohort version ${installed}`);
216
+ const minimum = floor.split('.').map(Number);
217
+ const actual = installed.split('.').map(Number);
218
+ for (let i = 0; i < 3; i++) {
219
+ if (actual[i] < minimum[i]) fail(`pi-cohort >= ${floor} required, found ${installed}`);
220
+ if (actual[i] > minimum[i]) break;
221
+ }
222
+ NODE
223
+ PREFLIGHT_STATUS=$?
224
+ [[ "$PREFLIGHT_STATUS" == 0 ]] || exit "$PREFLIGHT_STATUS"
188
225
  ```
189
226
 
190
- Compare the three semver components numerically against 7.4.0, not lexicographically. On a lower or unparseable version, or either command's failure, use the two fan-outs for every wave in this run. Note `pi-cohort <version>: chain disabled` once with the observed version; display `unknown` and the lookup failure when discovery failed. A 7.3.x runtime must never receive the chain: it passes the literal tree reference to SR. The package peer floor is declarative; pi-managed packages do not auto-install peers.
191
-
192
227
  Pass the implementation worktree's absolute path as top-level `cwd`. Per-task `cwd` outranks step and run `cwd`; only the SR tasks override it. Rule and rationale for editing dispatches: `dispatching-parallel-agents` "pi-cohort Integration".
193
228
 
194
229
  ```bash
@@ -234,29 +269,10 @@ subagent({
234
269
 
235
270
  Count the clean code-wave path as one chain plus one separate CR `subagent()` call; integration and tests remain parent actions between them. Use positional 1-based `impl_<n>` and `sr_<n>` names; map results to plan indices by wave position. Keep `context`, `async`, and top-level `cwd` invocation-level; `worktree`, `concurrency`, and `stopOn` step-level; `as`, `outputSchema`, `cwd`, `output`, `acceptance`, and `task` per-task. Give the SR step neither `worktree` nor `stopOn`, and its tasks no `outputSchema`.
236
271
 
237
- Tell SR to start from diff hunks carrying `file:line`, read every touched file in full from its materialized tree, read deleted files from `WAVE_BASE_SHA`, and never run tests. Pass the authoritative spec's absolute implementation-worktree path; SR reads the anchored ranges itself (never inline excerpts; authority hierarchy in `./spec-reviewer-prompt.md`; anchor-less tasks are task-text-only). Output references resolve only in `task` strings and `cwd` (`treePath` only), never `reads:`; paste no diff into the chain payload. Rely on pi-cohort's `structured_output` injection only for implementers carrying `outputSchema`; 7.4.0 orders an enabled acceptance report before that call. Keep SR schema-free because no `stopOn` reads its verdict. Disable acceptance on each initial chained SR task with `none` and a nonempty reason because the parent reads each `Verdict:` line and review trees are staged by design: risky-word inference precedes read-only inference, non-none explicit levels only raise the inferred level, and `checked` or higher requires no staged files; snapshot-backed spec reviews and code review carry no `acceptance` field. Keep prompts and persona vocabularies unchanged.
272
+ Tell SR to start from diff hunks carrying `file:line`, read every touched file in full from its materialized tree, read deleted files from `WAVE_BASE_SHA`, and never run tests. Pass the authoritative spec's absolute implementation-worktree path; SR reads the anchored ranges itself (never inline excerpts; authority hierarchy in `./spec-reviewer-prompt.md`; anchor-less tasks are task-text-only). Output references resolve only in `task` strings and `cwd` (`treePath` only), never `reads:`; paste no diff into the chain payload. Rely on pi-cohort's `structured_output` injection only for implementers carrying `outputSchema`; the runtime orders an enabled acceptance report before that call. Keep SR schema-free because no `stopOn` reads its verdict. Disable acceptance on each initial chained SR task with `none` and a nonempty reason because the parent reads each `Verdict:` line and review trees are staged by design: risky-word inference precedes read-only inference, non-none explicit levels only raise the inferred level, and `checked` or higher requires no staged files; snapshot-backed spec reviews and code review carry no `acceptance` field. Keep prompts and persona vocabularies unchanged.
238
273
 
239
274
  Read the tool-result text, not `details`: read implementer statuses from fenced JSON in `## Outputs` and the `## Stop` line; read SR verdicts from the `Verdict:` line of each SR `output:` report, one of `COMPLIANT`, `NEEDS_REWORK`, or `OUT_OF_SCOPE_CHANGES`. Read patch locations from `Artifacts:`: `<Artifacts dir>/worktree-diffs/step-0/task-<i>-implementer.patch`, with 0-based wave position `<i>`. Use these artifact patches for integration and later repairs. Exit-0 reports are the known `output:` files. A nonzero task has no `output:` file and no bound output. Recover its prose from its session `subagent-artifacts` output file (`<runId>_implementer_<index>_output.md`, defined by pi-cohort `src/shared/artifacts.ts`), matching the run/task identity in the result or session transcript. Use the same source-defined per-agent naming for a failed reviewer. Do not use the chain's empty `parallel-0/` directories for failed prose. If artifacts are disabled, missing, or cannot be unambiguously matched, enter [When a Subagent Fails](#when-a-subagent-fails) with the visible diagnostic; never invent a status. Keep SR's large-wave `outputMode: "file-only"` hint; read the report itself, not its `Output saved to:` pointer. Carry its full contents verbatim under `## Previous review report (re-review trigger)` on re-review.
240
275
 
241
- **Older-runtime fallback only:** use this plain implementer fan-out, then the snapshot-backed SR fan-out below. Keep the same report-path wave/task mapping.
242
-
243
- ```ts
244
- subagent({
245
- context: "fresh",
246
- async: false,
247
- cwd: "/abs/path/to/this/worktree", // REQUIRED: the worktree path, else children branch from main
248
- worktree: true, // each task in its own git worktree, branched from cwd's HEAD
249
- concurrency: 4, // default; cap = wave size
250
- tasks: [
251
- // do NOT set per-task cwd under worktree:true — it must equal the top-level cwd or the run errors
252
- { agent: "implementer", task: "<task text + owned files + SCOPED_TEST_COMMANDS + status protocol>", output: "<REPORT_DIR>/wave1-task1.md" },
253
- { agent: "implementer", task: "<task text + owned files + SCOPED_TEST_COMMANDS + status protocol>", output: "<REPORT_DIR>/wave1-task2.md" },
254
- ],
255
- })
256
- ```
257
-
258
- For the fan-out + worktree + patch-integration + conflict mechanics, see `dispatching-parallel-agents`.
259
-
260
276
  ### Chain stopped or failed
261
277
 
262
278
  Route the result already read in step 3; retain all successful sibling patches and verdicts. Inspect failed tasks regardless of whether `## Stop` is also present: pi-cohort evaluates the stop condition before checking sibling failures, so both can coexist. Read exit-0 statuses from `## Outputs` when present or their `output:` reports; recover failed-task prose using the session-artifact rule above, including its unavailable-artifact fallback. Treat `## Stop` as a matched exit-0 status, not proof that every sibling succeeded. For `DONE_WITH_CONCERNS` alongside a nonzero `BLOCKED`, judge the concerns, diagnose the failed task, and retain accepted siblings:
@@ -266,7 +282,6 @@ Route the result already read in step 3; retain all successful sibling patches a
266
282
  | Exit-0 stop (`## Stop`) with no failed siblings | Siblings finished, statuses remain in `## Outputs`, and no SR step ran. Judge `DONE_WITH_CONCERNS`, handle `NEEDS_CONTEXT` and `BLOCKED` per the status table, then snapshot accepted patches and use the ordinary SR fan-out below. |
267
283
  | Chain error, with or without `## Stop` | Identify and diagnose every failed task from the result, including prose `**Status:**` / `Verdict:` recovered through the session-artifact rule above. Completion-guard failure with no edits, rejected/missing `structured_output`, failed `treePath`, and sibling process failure all take this route. Handle a recoverable `BLOCKED` or `NEEDS_CONTEXT` through its status matrix even when that unaccepted task has no patch. Route a task with no recoverable status, or an accepted task with a missing/empty patch, to [When a Subagent Fails](#when-a-subagent-fails) with the visible diagnostic; never invent a status or review an unchanged tree. Retain exit-0 SR verdicts obtained in a materialized tree; dispatch only accepted patches without a verdict. Successful siblings are never re-run. |
268
284
  | Completed chain with `NEEDS_REWORK` or `OUT_OF_SCOPE_CHANGES` | Repair only those tasks using the spec-gap loop below. Preserve passing sibling patches/verdicts. |
269
- | Older-runtime fallback | Parse the plain fan-out statuses, then use the same snapshot-backed SR and fix loop below. |
270
285
 
271
286
  Parse each `DONE`/`BLOCKED`/etc. (see [Implementer Status](#implementer-status)) **first**. Then **dispatch a `spec-reviewer` per accepted patch** (`DONE`, or a `DONE_WITH_CONCERNS` you proceeded with) still missing a verdict in one parallel fan-out - `context: "fresh"`, each task's `cwd` = its [Spec-review snapshot](#spec-review-snapshots), **no `worktree` flag** (read-only) - each passed its full task text, the returned **patch diff**, the absolute spec path, and the task's `**Spec:**` anchors, plus its `**Tests:**` block and `- Test:` paths as contract. SR reads the anchored ranges itself (never inline excerpts; authority hierarchy in `./spec-reviewer-prompt.md`; anchor-less tasks are task-text-only). Review starts from the diff (its hunks carry `file:line`) and reads each touched file in full; test execution is never the reviewer's job (step 5 runs the wave's `SCOPED_TEST_COMMANDS`). Inline verdicts are fine at normal wave sizes; large waves use `output:` + `outputMode: "file-only"`; read the full report file itself.
272
287
 
@@ -274,7 +289,7 @@ Parse each `DONE`/`BLOCKED`/etc. (see [Implementer Status](#implementer-status))
274
289
 
275
290
  ## Spec-review snapshots
276
291
 
277
- Materialize each accepted patch for every pre-integration review not run by the chain: accepted siblings after errors/stops, replacement patches on re-review, and older-runtime fallback. Keep the implementation worktree unchanged; pi-cohort removes its worker checkouts before returning patches.
292
+ Materialize each accepted patch for every pre-integration review not run by the chain: accepted siblings after errors/stops, replacement patches on re-review. Keep the implementation worktree unchanged; pi-cohort removes its worker checkouts before returning patches.
278
293
 
279
294
  Substitute shell-quoted literals for the implementation worktree, the recorded `WAVE_BASE_SHA`, and the absolute patch path. Run this block once per patch:
280
295
 
@@ -314,67 +329,7 @@ Record its review tree per [Fix delta](#fix-delta) before every parent-dispatche
314
329
  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. Act on the verdict per `/skill:requesting-code-review` Fix rounds; carry the final `SHIP` report's Minor finding lines verbatim into the closure block's `whole-diff minors:` section (`verification-before-completion/reference/conformance-check.md` "Closure / conformance"), or `whole-diff minors: none`. 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.
315
330
  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.
316
331
 
317
- **Happy-path run - first action of this step, only when the plan header carries a `**Happy path:**` line or the diff selects a row.** The overrides file's `## Happy path` table (schema in the README overrides contract) names path-prefixed rows; the plan header's line is the plan-time default.
318
-
319
- 1. Re-derive the row from `git -C "<worktree>" diff --name-only <base>..HEAD` (`<base>` = the branch point): two or more non-`cross-cutting` rows, or a path inside the `cross-cutting` row's own `Paths` and inside no other row's -> `cross-cutting`, taking precedence (no `cross-cutting` row -> no run and no outcome line); else paths inside exactly one non-`cross-cutting` row's `Paths` -> that row; none -> no run and no outcome line. Run the diff-derived row; when it differs from the header label, record `row: <diff-derived> (header: <label>)` in `summary.txt`.
320
- 2. Substitute shell-quoted literal values for every placeholder in this one bash block: the absolute worktree path, command verbatim, first command token after leading `NAME=value` assignments, duration (default `10m`), diff-derived row, and optional header label (use the row label when absent). Derive the token from the declared command without evaluating it or parsing general shell grammar. Run the entire block in one tool call; do not carry shell variables between calls. Read its printed summary path and outcome for subsequent tools.
321
-
322
- <!-- happy-path-shell -->
323
- ```bash
324
- HP_WORKTREE={{HP_WORKTREE}}
325
- HP_CMD={{HP_COMMAND}}
326
- HP_TOKEN={{HP_TOKEN}}
327
- HP_DURATION={{HP_DURATION}}
328
- HP_ROW={{HP_ROW}}
329
- HP_HEADER={{HP_HEADER}}
330
- HP_DIR=$(mktemp -d) || exit 1
331
- HEAD=$(git -C "$HP_WORKTREE" rev-parse HEAD) || exit 1
332
- HP_LABEL=$HP_ROW
333
- if [[ "$HP_HEADER" != "$HP_ROW" ]]; then HP_LABEL="$HP_ROW (header: $HP_HEADER)"; fi
334
- if ! TO=$(command -v timeout || command -v gtimeout); then
335
- OUTCOME='happy-path: not run - no timeout binary'
336
- elif [[ -z "$HP_TOKEN" || -z "${HP_CMD//[[:space:]]/}" ]] || ! (cd "$HP_WORKTREE" && command -v "$HP_TOKEN" >/dev/null); then
337
- OUTCOME='happy-path: not run - command not found'
338
- else
339
- BEFORE=$(git -C "$HP_WORKTREE" status --porcelain --untracked-files=all) || exit 1
340
- if (cd "$HP_WORKTREE" && "$TO" -k 30s "$HP_DURATION" bash -c "$HP_CMD") >"$HP_DIR/transcript.log" 2>&1; then
341
- EXIT=0
342
- else
343
- EXIT=$?
344
- fi
345
- AFTER=$(git -C "$HP_WORKTREE" status --porcelain --untracked-files=all) || exit 1
346
- if [[ "$BEFORE" != "$AFTER" ]]; then
347
- OUTCOME="happy-path: failed - dirtied worktree: ${AFTER//$'\n'/; }"
348
- elif [[ "$EXIT" == 0 ]]; then
349
- OUTCOME='happy-path: passed'
350
- elif [[ "$EXIT" == 75 ]]; then
351
- OUTCOME="happy-path: not run - environment unavailable: $(tail -n 1 "$HP_DIR/transcript.log")"
352
- elif [[ "$EXIT" == 124 || "$EXIT" == 137 ]]; then
353
- OUTCOME="happy-path: failed - timed out after $HP_DURATION"
354
- elif [[ "$EXIT" == 126 ]]; then
355
- OUTCOME='happy-path: not run - not executable'
356
- else
357
- OUTCOME="happy-path: failed (exit $EXIT)"
358
- fi
359
- fi
360
- { printf '%s\nhead: %s\nrow: %s\n' "$OUTCOME" "$HEAD" "$HP_LABEL"; if [[ -f "$HP_DIR/transcript.log" ]]; then printf '\n'; tail -n 200 "$HP_DIR/transcript.log"; fi; } >"$HP_DIR/summary.txt" || exit 1
361
- printf 'summary: %s\noutcome: %s\n' "$HP_DIR/summary.txt" "$OUTCOME"
362
- ```
363
-
364
- 3. If the block exits non-zero or its printed summary is missing/unreadable, stop verification and report the shell error; never dispatch conformance with the selected run omitted. Distinguish this runner failure from a command's `failed`/`not run` outcome recorded in a readable summary. Treat any status difference (tracked or untracked residue) as failed regardless of exit code. Never stage or commit the listed paths as deliverables; remove untracked residue and restore tracked residue (`git -C "<worktree>" checkout -- <paths>`) explicitly before the conformance dispatch, so the tree is clean when the audit-time input rule runs.
365
-
366
- | Condition | Outcome line |
367
- |---|---|
368
- | worktree differs after run | `happy-path: failed - dirtied worktree: <paths>` |
369
- | exit 0, worktree clean | `happy-path: passed` |
370
- | exit 75 | `happy-path: not run - environment unavailable: <last line of transcript.log>` |
371
- | exit 124, or 137 after the `-k` kill | `happy-path: failed - timed out after <duration>` |
372
- | exit 126 | `happy-path: not run - not executable` |
373
- | pre-check failed | `happy-path: not run - <reason>` |
374
- | any other non-zero | `happy-path: failed (exit <n>)` |
375
- | no header line and no diff-derived row | no run, no outcome line |
376
-
377
- A timeout is `failed`, not `not run`: a consumer that never receives its message hangs, and the reviewer must see it; `not run` is reserved for a command that never executed. `timeout -k 30s` sends `TERM` then `KILL`; a script that does not trap `TERM` leaves its stack up, and the next run's exit 75 surfaces that. The full `transcript.log` stays in `$HP_DIR` for the human; the reviewer receives `summary.txt` only (outcome, `head:`, `row:`, 200-line tail). A `failed` or `not run` outcome never stops the flow and never becomes a repair item at this step - it is evidence for the audit; `$HP_DIR` and the outcome carry into the fix loop per `conformance-check.md`. Never split the shell block across calls.
332
+ **Happy-path run:** When the plan header carries a `**Happy path:**` line or the diff selects a row, `read` `reference/happy-path-run.md` at its absolute path beside this skill and follow its instructions. On an unreadable reference, stop with a blocking error; never reconstruct the runner.
378
333
 
379
334
  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, the full diff, and - when a run happened - `Happy path: <abs path to $HP_DIR/summary.txt> (<outcome>)` (`<outcome>` = the outcome line without its `happy-path: ` prefix). 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.
380
335
  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 sentinel (`status: CONFORMS (0 open)` or `status: GAPS (N open)`, then `audited-base: <full HEAD SHA>`, then - exactly when a happy-path run happened - `happy-path: <value of the reviewer's Happy path: line from the final audit, the text after Happy path: >`), 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.
@@ -409,6 +364,6 @@ Record its review tree per [Fix delta](#fix-delta) before every parent-dispatche
409
364
 
410
365
  ## Project overrides
411
366
 
412
- If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context — check it for project-specific routing tables, service paths, and verification commands.
367
+ If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it once per session - a skill that already has the file's content in context from an earlier skill's read skips the read; a restored session has nothing in context and reads it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context — check it for project-specific routing tables, service paths, and verification commands.
413
368
 
414
369
  The recognized headings, their readers, and the rules an override cannot change are listed in the [configuration front door](../../README.md#project-specific-overrides); an override extends or replaces the step it names and never lifts this skill's HARD CONSTRAINT or MUST text.
@@ -14,114 +14,26 @@ Dispatch a subagent with this prompt:
14
14
 
15
15
  ## Context
16
16
 
17
- [Scene-setting: where this fits, dependencies, architectural context]
18
-
19
- ## Before You Begin
20
-
21
- If you have questions about:
22
- - The requirements or acceptance criteria
23
- - The approach or implementation strategy
24
- - Dependencies or assumptions
25
- - Anything unclear in the task description
26
-
27
- **Ask them now.** Raise any concerns before starting work.
28
-
29
- ## Your Job
30
-
31
- Once you're clear on requirements:
32
- 1. Implement exactly what the task specifies
33
- 2. Write tests (following TDD — failing test first for production code)
34
- 3. Verify with the commands under SCOPED_TEST_COMMANDS (if `none`, state that)
35
- 4. Commit your work
36
- 5. Self-review (see below)
37
- 6. Report back
17
+ [Scene-setting: where this fits, dependencies, architectural context, task-specific clarifications]
38
18
 
39
19
  Work from: [directory]
40
20
 
41
21
  SCOPED_TEST_COMMANDS: [only the task's Tests: command bullets, backticks stripped, verbatim; exclude via:, baseline:, and none: metadata | none]
42
22
 
43
- Run ONLY these commands for verification. Never run a repo-wide suite,
44
- linter, or type-checker. If the value is `none`, run nothing and say so
45
- in your report.
46
-
47
23
  TEST_CONTRACT: [the task's **Tests:** block verbatim (commands, via:, baseline: bullets verbatim, none:) and its Files: Create:/Test: paths]
48
24
 
49
25
  Tests call the via: seam directly - not a wrapper, not the internals behind it.
50
26
  Create every Create: path at exactly that path.
51
27
 
52
- **While you work:** If you encounter something unexpected or unclear, **ask questions**.
53
- It's always OK to pause and clarify. Don't guess or make assumptions.
54
-
55
- ## Code Organization
56
-
57
- You reason best about code you can hold in context at once, and your edits are more
58
- reliable when files are focused. Keep this in mind:
59
- - Follow the file structure defined in the plan.
60
- - Each file should have one clear responsibility with a well-defined interface.
61
- - If a file you're creating is growing beyond the plan's intent, stop and report it
62
- as DONE_WITH_CONCERNS — don't split files on your own without plan guidance.
63
- - If an existing file you're modifying is already large or tangled, work carefully
64
- and note it as a concern in your report.
65
- - In existing codebases, follow established patterns. Improve code you're touching
66
- the way a good developer would, but don't restructure things outside your task.
67
-
68
- ## When You're in Over Your Head
69
-
70
- It is always OK to stop and say "this is too hard for me." Bad work is worse than
71
- no work. You will not be penalized for escalating.
72
-
73
- **STOP and escalate when:**
74
- - The task requires architectural decisions with multiple valid approaches.
75
- - You need to understand code beyond what was provided and can't find clarity.
76
- - You feel uncertain about whether your approach is correct.
77
- - The task involves restructuring existing code in ways the plan didn't anticipate.
78
- - You've been reading file after file trying to understand the system without progress.
79
-
80
- **How to escalate:** Report back with status `BLOCKED` or `NEEDS_CONTEXT`. Describe
81
- specifically what you're stuck on, what you've tried, and what kind of help you need.
82
- The orchestrator can provide more context, re-dispatch with a more capable model,
83
- or break the task into smaller pieces.
84
-
85
- ## Before Reporting Back: Self-Review
86
-
87
- Review your work with fresh eyes. Ask yourself:
88
-
89
- **Completeness:**
90
- - Did I fully implement everything in the spec?
91
- - Did I miss any requirements?
92
- - Are there edge cases I didn't handle?
93
-
94
- **Quality:**
95
- - Is this my best work?
96
- - Are names clear and accurate (match what things do, not how they work)?
97
- - Is the code clean and maintainable?
98
-
99
- **Discipline:**
100
- - Did I avoid overbuilding (YAGNI)?
101
- - Did I only build what was requested?
102
- - Did I follow existing patterns in the codebase?
103
-
104
- **Testing:**
105
- - Do tests actually verify behavior (not just mock behavior)?
106
- - Did I follow TDD (step 2)?
107
- - Does each added test earn its run - extends an existing test where one covers the behavior, minimal synthetic input, shared expensive setup, right tier?
108
-
109
- If you find issues during self-review, fix them now before reporting.
110
-
111
- ## Report Format
28
+ Report test-contract evidence: one line per SCOPED_TEST_COMMANDS command - `met` (exit 0; quote the last output line) or `unmet <reason>`;
29
+ one line per via: - `met <test file:line calling it>` or `unmet <reason>`; `none` when the block is `none:`.
30
+ Any `unmet` -> `DONE_WITH_CONCERNS`.
112
31
 
113
- When done, report:
114
- - **Status:** `DONE` | `DONE_WITH_CONCERNS` | `BLOCKED` | `NEEDS_CONTEXT`
115
- - What you implemented (or what you attempted, if blocked)
116
- - What you tested and test results
117
- - Test contract: one line per SCOPED_TEST_COMMANDS command - `met` (exit 0; quote the last output line) or `unmet <reason>`;
118
- one line per via: - `met <test file:line calling it>` or `unmet <reason>`; `none` when the block is `none:`.
119
- Any `unmet` -> `DONE_WITH_CONCERNS`.
120
- - Files changed
121
- - Self-review findings (if any)
122
- - Any issues or concerns
32
+ **Status:** DONE | DONE_WITH_CONCERNS | BLOCKED | NEEDS_CONTEXT
33
+ DONE: Implemented and scoped tests pass.
34
+ DONE_WITH_CONCERNS: Implemented, with a deviation, risk, or unmet test contract.
35
+ BLOCKED: Cannot complete the task.
36
+ NEEDS_CONTEXT: Need information not provided.
123
37
 
124
- Use `DONE_WITH_CONCERNS` if you completed the work but have doubts about correctness, or when you kept a test heavy or rebuilt its setup on purpose (a declined test-economy default) - name it under issues or concerns with the reason.
125
- Use `BLOCKED` if you cannot complete the task. Use `NEEDS_CONTEXT` if you need
126
- information that wasn't provided. Never silently produce work you're unsure about.
38
+ Conduct (TDD scenarios, test economy, scope discipline, escalation, report shape) is your persona; this prompt carries only the task and its test scope.
127
39
  ```
@@ -0,0 +1,63 @@
1
+ # Happy-path run
2
+
3
+ **Happy-path run - first action of this step, only when the plan header carries a `**Happy path:**` line or the diff selects a row.** The overrides file's `## Happy path` table (schema in the README overrides contract) names path-prefixed rows; the plan header's line is the plan-time default.
4
+
5
+ 1. Re-derive the row from `git -C "<worktree>" diff --name-only <base>..HEAD` (`<base>` = the branch point): two or more non-`cross-cutting` rows, or a path inside the `cross-cutting` row's own `Paths` and inside no other row's -> `cross-cutting`, taking precedence (no `cross-cutting` row -> no run and no outcome line); else paths inside exactly one non-`cross-cutting` row's `Paths` -> that row; none -> no run and no outcome line. Run the diff-derived row; when it differs from the header label, record `row: <diff-derived> (header: <label>)` in `summary.txt`.
6
+ 2. Substitute shell-quoted literal values for every placeholder in this one bash block: the absolute worktree path, command verbatim, first command token after leading `NAME=value` assignments, duration (default `10m`), diff-derived row, and optional header label (use the row label when absent). Derive the token from the declared command without evaluating it or parsing general shell grammar. Run the entire block in one tool call; do not carry shell variables between calls. Read its printed summary path and outcome for subsequent tools.
7
+
8
+ <!-- happy-path-shell -->
9
+ ```bash
10
+ HP_WORKTREE={{HP_WORKTREE}}
11
+ HP_CMD={{HP_COMMAND}}
12
+ HP_TOKEN={{HP_TOKEN}}
13
+ HP_DURATION={{HP_DURATION}}
14
+ HP_ROW={{HP_ROW}}
15
+ HP_HEADER={{HP_HEADER}}
16
+ HP_DIR=$(mktemp -d) || exit 1
17
+ HEAD=$(git -C "$HP_WORKTREE" rev-parse HEAD) || exit 1
18
+ HP_LABEL=$HP_ROW
19
+ if [[ "$HP_HEADER" != "$HP_ROW" ]]; then HP_LABEL="$HP_ROW (header: $HP_HEADER)"; fi
20
+ if ! TO=$(command -v timeout || command -v gtimeout); then
21
+ OUTCOME='happy-path: not run - no timeout binary'
22
+ elif [[ -z "$HP_TOKEN" || -z "${HP_CMD//[[:space:]]/}" ]] || ! (cd "$HP_WORKTREE" && command -v "$HP_TOKEN" >/dev/null); then
23
+ OUTCOME='happy-path: not run - command not found'
24
+ else
25
+ BEFORE=$(git -C "$HP_WORKTREE" status --porcelain --untracked-files=all) || exit 1
26
+ if (cd "$HP_WORKTREE" && "$TO" -k 30s "$HP_DURATION" bash -c "$HP_CMD") >"$HP_DIR/transcript.log" 2>&1; then
27
+ EXIT=0
28
+ else
29
+ EXIT=$?
30
+ fi
31
+ AFTER=$(git -C "$HP_WORKTREE" status --porcelain --untracked-files=all) || exit 1
32
+ if [[ "$BEFORE" != "$AFTER" ]]; then
33
+ OUTCOME="happy-path: failed - dirtied worktree: ${AFTER//$'\n'/; }"
34
+ elif [[ "$EXIT" == 0 ]]; then
35
+ OUTCOME='happy-path: passed'
36
+ elif [[ "$EXIT" == 75 ]]; then
37
+ OUTCOME="happy-path: not run - environment unavailable: $(tail -n 1 "$HP_DIR/transcript.log")"
38
+ elif [[ "$EXIT" == 124 || "$EXIT" == 137 ]]; then
39
+ OUTCOME="happy-path: failed - timed out after $HP_DURATION"
40
+ elif [[ "$EXIT" == 126 ]]; then
41
+ OUTCOME='happy-path: not run - not executable'
42
+ else
43
+ OUTCOME="happy-path: failed (exit $EXIT)"
44
+ fi
45
+ fi
46
+ { printf '%s\nhead: %s\nrow: %s\n' "$OUTCOME" "$HEAD" "$HP_LABEL"; if [[ -f "$HP_DIR/transcript.log" ]]; then printf '\n'; tail -n 200 "$HP_DIR/transcript.log"; fi; } >"$HP_DIR/summary.txt" || exit 1
47
+ printf 'summary: %s\noutcome: %s\n' "$HP_DIR/summary.txt" "$OUTCOME"
48
+ ```
49
+
50
+ 3. If the block exits non-zero or its printed summary is missing/unreadable, stop verification and report the shell error; never dispatch conformance with the selected run omitted. Distinguish this runner failure from a command's `failed`/`not run` outcome recorded in a readable summary. Treat any status difference (tracked or untracked residue) as failed regardless of exit code. Never stage or commit the listed paths as deliverables; remove untracked residue and restore tracked residue (`git -C "<worktree>" checkout -- <paths>`) explicitly before the conformance dispatch, so the tree is clean when the audit-time input rule runs.
51
+
52
+ | Condition | Outcome line |
53
+ |---|---|
54
+ | worktree differs after run | `happy-path: failed - dirtied worktree: <paths>` |
55
+ | exit 0, worktree clean | `happy-path: passed` |
56
+ | exit 75 | `happy-path: not run - environment unavailable: <last line of transcript.log>` |
57
+ | exit 124, or 137 after the `-k` kill | `happy-path: failed - timed out after <duration>` |
58
+ | exit 126 | `happy-path: not run - not executable` |
59
+ | pre-check failed | `happy-path: not run - <reason>` |
60
+ | any other non-zero | `happy-path: failed (exit <n>)` |
61
+ | no header line and no diff-derived row | no run, no outcome line |
62
+
63
+ A timeout is `failed`, not `not run`: a consumer that never receives its message hangs, and the reviewer must see it; `not run` is reserved for a command that never executed. `timeout -k 30s` sends `TERM` then `KILL`; a script that does not trap `TERM` leaves its stack up, and the next run's exit 75 surfaces that. The full `transcript.log` stays in `$HP_DIR` for the human; the reviewer receives `summary.txt` only (outcome, `head:`, `row:`, 200-line tail). A `failed` or `not run` outcome never stops the flow and never becomes a repair item at this step - it is evidence for the audit; `$HP_DIR` and the outcome carry into the fix loop per `conformance-check.md`. Never split the shell block across calls.
@@ -236,6 +236,6 @@ phase_tracker({ action: "complete", phase: "implement" })
236
236
 
237
237
  ## Project overrides
238
238
 
239
- If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context — check it for project-specific routing tables, service paths, and verification commands.
239
+ If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it once per session - a skill that already has the file's content in context from an earlier skill's read skips the read; a restored session has nothing in context and reads it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context — check it for project-specific routing tables, service paths, and verification commands.
240
240
 
241
241
  The recognized headings, their readers, and the rules an override cannot change are listed in the [configuration front door](../../README.md#project-specific-overrides); an override extends or replaces the step it names and never lifts this skill's HARD CONSTRAINT or MUST text.
@@ -227,6 +227,6 @@ Re-run tests after rebasing.
227
227
 
228
228
  ## Project overrides
229
229
 
230
- If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context — check it for project-specific routing tables, service paths, and verification commands.
230
+ If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it once per session - a skill that already has the file's content in context from an earlier skill's read skips the read; a restored session has nothing in context and reads it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context — check it for project-specific routing tables, service paths, and verification commands.
231
231
 
232
232
  The recognized headings, their readers, and the rules an override cannot change are listed in the [configuration front door](../../README.md#project-specific-overrides); an override extends or replaces the step it names and never lifts this skill's HARD CONSTRAINT or MUST text.
@@ -168,6 +168,6 @@ phase_tracker({ action: "complete", phase: "verify" })
168
168
 
169
169
  ## Project overrides
170
170
 
171
- If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context — check it for project-specific routing tables, service paths, and verification commands.
171
+ If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it once per session - a skill that already has the file's content in context from an earlier skill's read skips the read; a restored session has nothing in context and reads it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context — check it for project-specific routing tables, service paths, and verification commands.
172
172
 
173
173
  The recognized headings, their readers, and the rules an override cannot change are listed in the [configuration front door](../../README.md#project-specific-overrides); an override extends or replaces the step it names and never lifts this skill's HARD CONSTRAINT or MUST text.
@@ -342,6 +342,6 @@ Auto-invoke `/skill:subagent-driven-development` in this session. Do not wait fo
342
342
 
343
343
  ## Project overrides
344
344
 
345
- If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context — check it for project-specific routing tables, service paths, and verification commands.
345
+ If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it once per session - a skill that already has the file's content in context from an earlier skill's read skips the read; a restored session has nothing in context and reads it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context — check it for project-specific routing tables, service paths, and verification commands.
346
346
 
347
347
  The recognized headings, their readers, and the rules an override cannot change are listed in the [configuration front door](../../README.md#project-specific-overrides); an override extends or replaces the step it names and never lifts this skill's HARD CONSTRAINT or MUST text.