pi-gauntlet 7.24.0 → 7.25.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # Changelog
2
2
 
3
+ ## v7.25.1 - 2026-10-22
4
+
5
+ ### Changed
6
+
7
+ - **shape-ticket carries every Problem example's source into the ticket body.** A URL, attachment, or pasted screenshot the reporter supplied lands as a `source:` footer line under the Problem example it supports, in every ticket type. A non-discovery example with no source renders a named `source missing:` gap at the existing approval gate; the reply supplies the link, a reason, or "proceed without" (bug tickets list the gap first and re-ask on a plain `yes`), and the drafter never authors the reason. Repair prefills `source: none (not recorded at filing)` for a hand-filed body so a plain `yes` accepts it, and never reports "conforms" for a body missing the footer. Ticket-wording rules 7 and 8 exempt the footer from pointer demotion. The Roast's inline chair call names `cwd` = repo root like the member fan-out. (#76)
8
+
9
+ ### Added
10
+
11
+ - Eval samples `source-carried`, `source-missing`, `bug-source-ack`, and `repair-source` under `eval/shape-ticket/`; the target's SKILL.md slice now reaches `## Evidence gate`. (#76)
12
+
13
+ ## v7.25.0 - 2026-10-21
14
+
15
+ ### Changed
16
+
17
+ - **Decision menus render 1-N after a numbered list.** A numbered option menu placed directly below an ordered list, separated only by a blank line, rendered as `4.`-`6.` because CommonMark merged the two lists; a human replying `5` was then read against a three-option menu. One shared reference, `skills/brainstorming/reference/menu-layout.md`, owns the three permitted layouts (a prose line, a `---` rule, or bullets above the menu) and the reply mapping: a bare reply above the option count resolves to `R - L` when it lands in range, the agent echoes the resolved option in one sentence (`Taking 5 as option 2 - merge`) before acting, and any other out-of-range reply gets a clarifying question. Every menu site in shape-ticket, chase-bug, gatekeep-pr, check-delivery, finishing-a-development-branch, and gauntlet-resume cites it with one line; no site restates the rule. (#73)
18
+ - **check-delivery's confirmation gate is a two-option menu** (`1. approve the write` / `2. decline`); a typed `yes` still approves. (#73)
19
+
20
+ ### Added
21
+
22
+ - Eval target `check-delivery` and a `menu-after-numbered-findings` sample in six targets; `shape-ticket`, `gatekeep-pr`, and `check-delivery` load the shared reference through `target.json`. (#73)
23
+
3
24
  ## v7.24.0 - 2026-10-21
4
25
 
5
26
  ### Changed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-gauntlet",
3
- "version": "7.24.0",
3
+ "version": "7.25.1",
4
4
  "description": "Opinionated, gated workflow skills, subagent personas, and runtime extensions for the pi coding agent.",
5
5
  "author": "Jacek Juraszek",
6
6
  "type": "module",
@@ -0,0 +1,37 @@
1
+ ## Exposure
2
+ A numbered option list directly after an ordered list with only a blank line merges under CommonMark, displaying `N+1.`-`N+k.` after `N` preceding items. This control renders the options as `4.`-`6.`:
3
+ ```markdown
4
+ 1. Finding A
5
+ 2. Finding B
6
+ 3. Finding C
7
+
8
+ 1. Keep
9
+ 2. Merge
10
+ 3. Stop
11
+ ```
12
+
13
+ ## Permitted layouts
14
+ Separate numbered options from preceding ordered content. Default to a prose line (`Pick one:` or `Verdict:`); alternatively insert a `---` rule or write preceding content as bullets:
15
+ ```markdown
16
+ 1. Finding
17
+
18
+ Pick one:
19
+ 1. Merge
20
+ ```
21
+ ```markdown
22
+ 1. Finding
23
+
24
+ ---
25
+
26
+ 1. Merge
27
+ ```
28
+ ```markdown
29
+ - Finding
30
+
31
+ 1. Merge
32
+ ```
33
+
34
+ ## Reply mapping
35
+ Apply only to bare numeric replies to numbered option menus. Leave #63 compound replies such as `1: cache=A` and its bare-`1` shortcut to [disposition-protocol.md](../../finishing-a-development-branch/reference/disposition-protocol.md).
36
+ Count `N` options and let `L` count every preceding item in the entire contiguous ordered run adjoining the options through blank lines alone. Stop at prose, a rule, or bullets; earlier separated lists contribute nothing. Set `L = 0` after a separator.
37
+ Take replies `1`-`N` unchanged, without echo, even when they also equal `L + k`. Only map `R > N` with `1 <= R - L <= N` to option `R - L`; echo the resolution before acting: `Taking 5 as option 2 - merge`. For every other out-of-range reply, ask a clarifying question naming the valid range `1`-`N`.
@@ -167,6 +167,8 @@ change request, not a menu row.
167
167
  **Real bug** - four actions (all rendered unless noted), exactly one tagged
168
168
  `[recommended]`. Untracked origin:
169
169
 
170
+ Read and apply [menu-layout](../brainstorming/reference/menu-layout.md) before presenting these options and before acting on a numeric reply.
171
+
170
172
  ```
171
173
  1. [ ] File a ticket - /skill:shape-ticket, seeded with this evidence.
172
174
  2. [ ] Brainstorm now - /skill:brainstorming with this evidence as the seed.
@@ -176,6 +178,8 @@ change request, not a menu row.
176
178
 
177
179
  Tracker/GitHub origin (ticket row omitted as today, renumbered):
178
180
 
181
+ Read and apply [menu-layout](../brainstorming/reference/menu-layout.md) before presenting these options and before acting on a numeric reply.
182
+
179
183
  ```
180
184
  1. [ ] Brainstorm now - /skill:brainstorming with this evidence as the seed.
181
185
  2. [ ] Implement hotfix now - follow hotfix.md; add "as a PR" for a PR.
@@ -241,6 +245,8 @@ A verdict without its named citation is a red flag (see Red Flags - STOP).
241
245
  For a negative verdict, render the verdict with its citation, then a short
242
246
  numbered menu:
243
247
 
248
+ Read and apply [menu-layout](../brainstorming/reference/menu-layout.md) before presenting these options and before acting on a numeric reply.
249
+
244
250
  ```
245
251
  Verdict: <verdict name> - <citation>
246
252
 
@@ -254,6 +260,8 @@ way; for `cannot-replicate`, renumber the discovery-ticket row to 2.
254
260
 
255
261
  For `cannot-replicate` only, add a third row offering a discovery ticket:
256
262
 
263
+ Read and apply [menu-layout](../brainstorming/reference/menu-layout.md) before presenting these options and before acting on a numeric reply.
264
+
257
265
  ```
258
266
  3. [ ] File a discovery ticket - /skill:shape-ticket, seeded with what's missing.
259
267
  ```
@@ -379,6 +387,8 @@ rendered is out of skill scope - the skill has ended.
379
387
 
380
388
  **Real-bug example:**
381
389
 
390
+ Read and apply [menu-layout](../brainstorming/reference/menu-layout.md) before presenting these options and before acting on a numeric reply.
391
+
382
392
  ```
383
393
  Fault story: user pastes a URL with a trailing slash -> the router's path
384
394
  matcher does an exact string compare instead of normalizing -> the route
@@ -260,7 +260,18 @@ explicit yes-gate as the success path. Never posted unprompted.
260
260
  All-clear path -> **one confirmation gate**: present the shipped SHA,
261
261
  deliverable set, stage results (including any skip), the per-AC verdict
262
262
  table with evidence, the reviewer script, and the exact write about to
263
- happen. On approval, one batched write. The numbered steps below are the
263
+ happen.
264
+
265
+ Read and apply [menu-layout](../brainstorming/reference/menu-layout.md) before presenting these options and before acting on a numeric reply.
266
+
267
+ ```text
268
+ 1. approve the write
269
+ 2. decline
270
+ ```
271
+
272
+ Treat option `1` or typed `yes` as explicit approval; option `2` or any
273
+ unrecognized/non-approval reply means no write. On approval, one batched
274
+ write. The numbered steps below are the
264
275
  ordinary-run shape; when a ratified descope strike is in play, the
265
276
  body-edit half precedes step 1 - see the `descope edits` paragraph below
266
277
  for its mechanics, not repeated here:
@@ -180,6 +180,8 @@ Omit the block when N = 0.
180
180
 
181
181
  **Normal repo and named-branch worktree — present exactly these 5 options:**
182
182
 
183
+ Read and apply [menu-layout](../brainstorming/reference/menu-layout.md) before presenting these options and before acting on a numeric reply.
184
+
183
185
  ```
184
186
  Implementation complete. What would you like to do?
185
187
 
@@ -194,6 +196,8 @@ Which option?
194
196
 
195
197
  **Detached HEAD — present exactly these 4 options:**
196
198
 
199
+ Read and apply [menu-layout](../brainstorming/reference/menu-layout.md) before presenting these options and before acting on a numeric reply.
200
+
197
201
  ```
198
202
  Implementation complete. You're on a detached HEAD (externally managed workspace).
199
203
 
@@ -8,6 +8,8 @@ Read from SKILL.md step 6. Input: the report's verdict and the PR state. Output:
8
8
 
9
9
  Render fix consequences with the applicable lifetime from `post-selection-loop.md` `### Continuation record`. For named fixes, state that authority retains only the selected stable IDs for later independent reassessments, with the same lifetime as broad fixes; link active pre-push retries to `fix-wave.md` `## Review before push`. For clarification-only fixes, state one-shot authority for the exactly selected payload; keep nit consequences one-shot.
10
10
 
11
+ Read and apply [menu-layout](../../brainstorming/reference/menu-layout.md) before presenting these options and before acting on a numeric reply.
12
+
11
13
  Rows are `<n>. <verb> - <consequence>`; every row, `stop` included, carries its consequence clause. `stop` is always last, before the compose hint. `show evidence` is always offered and never `[recommended]`. A row the actor cannot execute - by `## Availability` below, or because the forge would refuse it (branch protection, a withhold) - is omitted and named in the compose line's `Not offered:` sentence; it is never `[recommended]`. Exactly one row is `[recommended]`. A **terminal overlay** is `own merge`, `merge queued` (once its read returns `MERGED` it re-renders as `own merge`), `approved`, or `merged or closed PR`; every other menu is an ordinary open-PR menu. **Landed** means the PR's `state` is `MERGED`; under `approved` and under a closed-unmerged PR nothing has landed.
12
14
 
13
15
  - `accept contract change` - invoke the concrete proposal's owning amendment process through `post-selection-loop.md` `### Contract decision`; settle the baseline only after completion
@@ -93,6 +93,8 @@ Apply per `fix-wave.md`: the local conflict check, one fresh implementer helper
93
93
 
94
94
  After `gh pr merge` returns, read `gh pr view <N> --json state,mergeCommit`. `state: MERGED` -> write the returned `state` into `pr.state` and `mergeCommit.oid` into `pr.merge_commit` (the same two writes when a queued merge's `wait` re-read returns `MERGED`), render the `AC coverage` block once and re-render the menu under the `own merge` overlay (`decision-menu.md`); any other state (a merge queue) -> one `PR comments` line `The merge is queued, so coverage posts wait. (<state>)` and the menu `wait` (re-run the read) / `show evidence` / `stop`. The block, `<sha>` = `mergeCommit.oid`, one row per `scope.rows` entry in row order with its outcome (`covered`, `deferred per spec to <ref>`, `deviates per spec: <why>`, `elsewhere per spec: <repo>`, `venue: <env> - <observation>, checked before prod deploy`); with no rows (`source: pr`, or an empty `scope.rows`) the block has no row lines and `post coverage to ticket` is not offered. With `source: pr` the header line drops `, spec <path>`. An `in-scope` row whose observation half is `not judged here` renders `covered; observable half checked after merge`.
95
95
 
96
+ Read and apply [menu-layout](../../brainstorming/reference/menu-layout.md) before presenting these options and before acting on a numeric reply.
97
+
96
98
  ```markdown
97
99
  ## AC coverage
98
100
  Informational - the ticket's rows are unchanged. PR <url>, merged <sha>, spec <path>
@@ -8,6 +8,8 @@ Render bottom-up for a terminal: least important first, verdict and menu last. E
8
8
 
9
9
  Section order is fixed:
10
10
 
11
+ Read and apply [menu-layout](../../brainstorming/reference/menu-layout.md) before presenting these options and before acting on a numeric reply.
12
+
11
13
  ```
12
14
  Delivers: <one sentence: what the PR does. With source: spec, a second sentence built from these clauses in
13
15
  order, each present only when it applies, joined with semicolons: covered rows ("ACs 1, 2, 4";
@@ -39,6 +39,8 @@ optional pasted text after the command line. Count tokens first; then first matc
39
39
  Spec dirs resolve per `reference/reconstruction.md` "Candidates" (`flowGuards.specDirs`
40
40
  precedence).
41
41
 
42
+ Read and apply [menu-layout](../brainstorming/reference/menu-layout.md) before presenting these options and before acting on a numeric reply.
43
+
42
44
  | Input | Route |
43
45
  |---|---|
44
46
  | no tokens, no pasted text | discovery: `<tmpdir>` via `node -p "require('os').tmpdir()"`; candidates are the regular files directly under `<tmpdir>/pi-handoff/` ending `.md` (non-recursive) whose line 1 starts `# Handoff:`; sorted by mtime, newest first; displayed one per line as `<n>. <title line> - <worktree: field value> - <mtime ISO-8601>` with `worktree: unavailable` when the field is absent; the human picks `<n>` (a single candidate is still confirmed); none -> STOP "no handoff briefs found under <tmpdir>/pi-handoff" |
@@ -34,7 +34,7 @@ It is a tool, not a phase: no `plan_tracker`, no `phase_tracker`, no worktree re
34
34
 
35
35
  ## Hard constraint
36
36
 
37
- **Every tracker write sits behind exactly one confirmation gate, presented as an explicit old->new (or as-new) diff. No affirmative answer on that exact diff = no write.** This includes create, repair, split writes, and discovery-conversion writes - one gate covers the whole batch. A headless or unattended run (no interactive response available) stops at the gate. There is no timeout-approve, no "the user implied yes earlier," no partial write before the gate.
37
+ **Every tracker write sits behind exactly one confirmation gate, presented as an explicit old->new (or as-new) diff. No affirmative answer on that exact diff = no write.** Approve the exact presented diff plus only the `source:` footer substitutions resolved by that same approving reply under step 8; make no other post-approval edit and add no second gate. This includes create, repair, split writes, and discovery-conversion writes - one gate covers the whole batch. A headless or unattended run (no interactive response available) stops at the gate. There is no timeout-approve, no "the user implied yes earlier," no partial write before the gate.
38
38
 
39
39
  ## Mode routing
40
40
 
@@ -86,24 +86,24 @@ Accumulate step-4 demotion, step-5 moves, and roast-removed mechanism verbatim u
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), and this displaced-detail check:
89
+ Before any subagent dispatch, inline and cheap: AC integrity gate, evidence gate, metadata audit, split detection (all below), and this displaced-detail check. After the evidence gate's existing checks, run its source-gap rule and carry gap rows to step 8:
90
90
 
91
91
  | Section | Move to accumulated Reporter note |
92
92
  |---|---|
93
93
  | Idea | Beyond the one attributed sketch line: a second paragraph, a list, or a code block |
94
94
  | Context, Problem | Implementer inventories: file paths; module/script/function/setting identifiers; sizes and line counts; lists of those; code blocks |
95
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.
96
+ Exempt one deletion-safe rule-7 pointer per failure, rule-5 one-sentence/one-number examples, requester-used dual-use terms, plain-words failure/impact lists, and `source:` footers (Evidence gate). 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.
97
97
 
98
98
  ### 6 - No-op check
99
99
 
100
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.
101
101
 
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.
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, with the named example serving as a source footer's summary)? every gathered URL, attachment, or pasted screenshot is carried in a source: footer under its example (Evidence gate carry rule)? every non-discovery Problem example has a source: footer (Evidence gate gap rule)? 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. Check source carrying for every title; check source gaps only for non-discovery bodies. Preserve existing `source:` lines verbatim. For missing-footer-only repair, add only the footer under step 8 and leave existing prose and AC bytes unchanged; never report "conforms, no changes proposed".
103
103
 
104
104
  ### 7 - Roast
105
105
 
106
- See Roast below. Unambiguous findings are applied to the draft (one re-pass max - never a third pass). Ambiguous findings are surfaced at the confirmation gate, never auto-applied. Any roast-applied edit re-runs step 5's deterministic gates before the draft reaches the gate - a fix must not reintroduce a failing AC.
106
+ See Roast below. Surface source-gap findings at step 8; never apply them by inventing a reason or inserting a `none` footer. Restore an actual dropped gathered URL or attachment as an ordinary concrete fix. Unambiguous findings are applied to the draft (one re-pass max - never a third pass). Ambiguous findings are surfaced at the confirmation gate, never auto-applied. Any roast-applied edit re-runs step 5's deterministic gates before the draft reaches the gate - a fix must not reintroduce a failing AC.
107
107
 
108
108
  ### 8 - Confirmation gate
109
109
 
@@ -113,16 +113,30 @@ Present, per proposed issue:
113
113
  - Body old->new (repair) or as-new (create).
114
114
  - Metadata changeset: `field: current -> proposed -- why` lines.
115
115
  - Evidence list.
116
+ - Source gaps: render the Evidence gate's rows as `source missing: <label>`, matching multi-example footer labels exactly; for one example use its sentence or opening words, e.g. `source missing: import run 42 finished with zero rows`. For bugs with repro steps, render these rows first in the gate message, before Title; otherwise render them after Evidence. Offer the write despite gaps.
116
117
  - Roast dispositions: applied / surfaced-ambiguous.
117
118
  - Split proposal, if any: per slice, the three-line justification block (see Split rule). A withdrawn split is reported with the `split-axis:` finding that killed it, so the user can re-request it (sticky; see Split rule).
118
119
  - Proposed comment and supported relations, verbatim, if any - one approval covers the exact title + body + metadata + comment + relation payload.
119
120
  - For overlap, show mutually exclusive supported enrichment/create-anyway/no-write alternatives and coverage under the gathered reference; show failing alternatives unavailable. Selecting an option approves that displayed payload without another authorization prompt.
120
121
 
121
- Number the options. A split offers per-issue subset selection, e.g. "approve 1,3; decline 2". **No affirmative answer on the exact presented diff = no write.**
122
+ At gate-open, leave create-mode gap footer slots absent. Render create-gap approval choices as "Approve with a link, attachment, or reason" and "Approve and proceed without"; request the reply without printing any hypothetical `source:` value in commentary or options. Print resolved footer values only after the approving reply. In repair, prefill each gap with `source: [<label> - ]none (not recorded at filing)` and show the addition in the old->new diff. Missing-footer-only repair changes no existing prose or AC bytes.
123
+
124
+ Resolve each named gap under the same gate:
125
+
126
+ | Mode | Approving reply supplies link/attachment or reason | Plain "yes" | Explicit "proceed without" |
127
+ |---|---|---|---|
128
+ | Create, bug or non-bug | Replace only that named footer slot with the supplied URL/attachment or `none (<human reason verbatim>)` | No write; re-ask every unresolved gap: `source missing: <label or example opening> - link, reason, or "proceed without"?`; repeat on another plain yes | Fill only the acknowledged slots with `none (proceed without - <YYYY-MM-DD>)` |
129
+ | Repair | Replace only that named prefilled footer with the supplied URL/attachment or `none (<human reason verbatim>)` | Accept the displayed `none (not recorded at filing)` constant without re-ask | Replace only the acknowledged slots with the dated form above |
130
+
131
+ Keep partially resolved create gates open with only unresolved rows; never fill unnamed create gaps with a constant. Keep the gate open on a non-approval reply. For proceed-without, use `date +%F` when a shell exists, else the session date. Discovery/Spike carries supplied sources but renders no gaps and needs no source re-ask.
132
+
133
+ Read and apply [menu-layout](../brainstorming/reference/menu-layout.md) before presenting these options and before acting on a numeric reply.
134
+
135
+ Number the options. A split offers per-issue subset selection, e.g. "approve 1,3; decline 2". **No affirmative answer on the exact presented diff plus only the `source:` substitutions resolved by that same approving reply = no write; make no other post-approval edit and add no second gate.**
122
136
 
123
137
  ### 9 - Write
124
138
 
125
- Immediately before any mutation, including comments - after approval, not at gate-open - re-fetch the relevant body, discussion, and workflow of any existing ticket underlying the selected changeset (repair, enrichment, or override-create). Compare against the exact snapshot the user approved; only a change loops back to step 8 with the delta. Use tracker version/ETag preconditions where supported. Treat unrelated hits listed as rejected coverage as non-sources; a plain create with no underlying existing ticket has nothing to revalidate. For overlap, follow the gathered reference's selected-operation rules. Then one batched write per approved issue, body first, then the approved Reporter-note comment if any; a split is N gated writes under the one approval, honoring subset selection. Mid-batch failure: report exactly what landed; the remaining changeset is preserved for retry.
139
+ Immediately before any mutation, including comments - after approval, not at gate-open - re-fetch the relevant body, discussion, and workflow of any existing ticket underlying the selected changeset (repair, enrichment, or override-create). Write the resolved source footers in the approved payload. Compare against the original gathered ticket snapshot the user approved, not the pending footer-bearing replacement; only a change loops back to step 8 with the delta. Use tracker version/ETag preconditions where supported. Treat unrelated hits listed as rejected coverage as non-sources; a plain create with no underlying existing ticket has nothing to revalidate. For overlap, follow the gathered reference's selected-operation rules. Then one batched write per approved issue, body first, then the approved Reporter-note comment if any; a split is N gated writes under the one approval, honoring subset selection. Mid-batch failure: report exactly what landed; the remaining changeset is preserved for retry.
126
140
 
127
141
  ## AC integrity gate
128
142
 
@@ -186,7 +200,7 @@ No block, no split. A block failing the identity or outcome test, or naming a no
186
200
  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.
187
201
 
188
202
  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.
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.
203
+ 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 `cwd` = repo root, 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.
190
204
  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.
191
205
  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
206
  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).
@@ -253,7 +267,15 @@ Runs every invocation, not just on request. Scope: every field the tracker expos
253
267
 
254
268
  ## Evidence gate
255
269
 
256
- Claims about user-visible/UI behavior need evidence: screenshots/artifacts via repo-documented capture tooling (resolved through the ladder), else ask the user to supply them. Label provenance (which env, when). `none (<reason>)` is a valid explicit outcome. Bug tickets require repro steps + observed-vs-expected. No project-specific mechanics (asset URL schemes, session tables) live in this skill body - they belong in the overrides file.
270
+ Claims about user-visible/UI behavior need evidence: screenshots/artifacts via repo-documented capture tooling (resolved through the ladder), else ask the user to supply them. Label provenance (which env, when). `none (<reason>)` is a valid explicit outcome. Require bug repro steps + observed-vs-expected in the gate's Evidence list and the AC rows' setup/action/result; keep each Problem example to rule 5's one sentence or one number, followed by its source footer. No project-specific mechanics (asset URL schemes, session tables) live in this skill body - they belong in the overrides file.
271
+
272
+ Gather provenance separately from example text: read the ask/session and, in repair, the existing body, comments and attachment list. Treat URLs (`http(s)://...`), named or uploaded attachment references, and pasted images (cite as `pasted screenshot`) as sources. Treat quoted log lines, errors and other pasted text as examples/evidence, never their own sources. Never invent a URL or attachment reference.
273
+
274
+ Carry every gathered source in Problem, including Discovery/Spike bodies. After the Problem prose, at the end of that section, emit one footer per example: `source: <label> - <value>`, using a short stable example label and a value of URL, `attachment: <name>`, `pasted screenshot`, or `none (<reason>)`. Omit the label for a single example. Two examples sharing a URL each get a footer. Carry unrelated URLs with label `other`; these create no gap. Keep footers deletion-safe and associate each with its example.
275
+
276
+ Collect a source gap for each actual rule-5 example without its footer only when the title lacks `Discovery:` / `Spike:`. A rule-5 `none (<reason>)` example slot needs no source. Carry gaps to step 8 without blocking its write offer. Keep the two `none`s distinct: rule 5 permits drafter-authored example explanations; source reasons are only human reply text verbatim, the fixed repair constant, or step 8's dated proceed-without form.
277
+
278
+ Route each footer with its example on a split. For overlap enrichment, carry sources only for added/changed Problem prose; preserve legacy bodies and evidence-only operations under the overlap reference's payload-local rules. A displaced pasted log block remains evidence in the Reporter note, never a source.
257
279
 
258
280
  ## Ticket wording
259
281
 
@@ -320,7 +342,7 @@ Read this when applying the AC integrity gate (drafting, repairing, or adjudicat
320
342
 
321
343
  ## Red flags - STOP
322
344
 
323
- - About to write to the tracker without the confirmation gate's explicit yes on the exact presented diff
345
+ - About to write without the gate's explicit approval of the exact displayed diff plus only the `source:` substitutions resolved by that same approving reply, or making another post-approval edit or adding a second gate
324
346
  - Inventing a number, list, label, assignee, or URL to pass a gate
325
347
  - An AC gated on a set this ticket itself will produce
326
348
  - A prod-only observation left in the AC list
@@ -17,8 +17,8 @@ Scope: Context/Problem/Idea prose only. ACs, split justification blocks, metadat
17
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.)
18
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
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.
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).
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
+ 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). Keep the Evidence gate's `source:` footer in Problem as the sanctioned deletion-safe parenthetical reference; step 5 never moves it to the Reporter note.
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. Treat the example a `source:` footer names as its summary; require no second plain-words sentence.
22
22
 
23
23
  ## Exemplar
24
24