pi-gauntlet 7.40.1 → 7.41.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.
Files changed (36) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +14 -2
  3. package/agents/code-reviewer.md +2 -0
  4. package/agents/implementer.md +2 -0
  5. package/agents/loop-implementer.md +10 -0
  6. package/agents/plan-writer.md +1 -1
  7. package/agents/spec-reviewer.md +2 -0
  8. package/bin/gauntlet-telemetry-seal.mjs +18 -3
  9. package/bin/gauntlet-telemetry-seal.test.mjs +30 -0
  10. package/extensions/lib/plan-check.test.ts +116 -0
  11. package/extensions/lib/plan-check.ts +149 -20
  12. package/extensions/lib/telemetry-record.test.ts +11 -0
  13. package/extensions/lib/telemetry-record.ts +7 -0
  14. package/extensions/phase-tracker.test.ts +201 -3
  15. package/extensions/phase-tracker.ts +77 -9
  16. package/extensions/verify-before-ship.test.ts +240 -2
  17. package/extensions/verify-before-ship.ts +180 -25
  18. package/package.json +2 -2
  19. package/skills/brainstorming/SKILL.md +1 -1
  20. package/skills/brainstorming/gatherer.md +14 -1
  21. package/skills/brainstorming/reference/amendment-surface.md +13 -1
  22. package/skills/brainstorming/reference/legs.md +187 -0
  23. package/skills/brainstorming/reference/spec-finalization.md +14 -0
  24. package/skills/brainstorming/reference/ticket-acceptance.md +2 -2
  25. package/skills/finishing-a-development-branch/SKILL.md +2 -2
  26. package/skills/finishing-a-development-branch/reference/legs.md +76 -0
  27. package/skills/gauntlet-handoff/SKILL.md +2 -2
  28. package/skills/gauntlet-resume/SKILL.md +3 -2
  29. package/skills/gauntlet-resume/reference/brief-contract.md +37 -3
  30. package/skills/gauntlet-resume/reference/reconstruction.md +4 -0
  31. package/skills/gauntlet-resume/reference/seed.md +2 -0
  32. package/skills/loop-implementation/SKILL.md +89 -2
  33. package/skills/subagent-driven-development/SKILL.md +10 -0
  34. package/skills/using-git-worktrees/SKILL.md +58 -21
  35. package/skills/writing-plans/SKILL.md +8 -0
  36. package/skills/writing-plans/reference/plan-contract.md +9 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-gauntlet",
3
- "version": "7.40.1",
3
+ "version": "7.41.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.6.3"
65
+ "pi-cohort": ">=7.6.4"
66
66
  },
67
67
  "dependencies": {
68
68
  "yaml": "^2.9.0"
@@ -67,7 +67,7 @@ Detection order: (1) infer from ticket labels, description, or paths; (2) use th
67
67
 
68
68
  The spec is the first commit in a dedicated worktree, never a separate commit on `main`. For a PR subject, the worktree is the PR's branch and the spec commit is appended to it.
69
69
 
70
- Invoke `/skill:using-git-worktrees`; use `.worktrees/` or the project-native location. Carry its `Worktree ready at <full-path>` value: spec path `<full-path>/<spec dir>/<filename>.md`; every dispatch uses that `cwd`; git uses `git -C <full-path>`. Keep the process cwd unchanged.
70
+ Read [reference/legs.md](reference/legs.md) and settle membership before creation. Invoke `/skill:using-git-worktrees` for each member with explicit `$ROOT` = its primary and `$BRANCH` = the shared branch; carry every `Worktree ready at <full-path>` value, home first. Root the home spec at `<home worktree>/<home spec dir>/<filename>.md`; root each dispatch and `git -C` in its owning leg's worktree. Keep the process cwd unchanged. Gather each leg's rules and record portable contracts and companion artifacts using that reference; a one-member run adds only its one-block `## Legs` section.
71
71
 
72
72
  Spec, plan, and implementation share this worktree. The spec and its telemetry record (`<telemetry.dir>/<spec path with .md -> .yaml>`, default `.pi/gauntlet/telemetry/doc/specs/<spec>.yaml`) are deliverables and ship in the squash; only the plan is stripped. `/skill:finishing-a-development-branch` strips the plan, then seals the record before landing (a `telemetry:` commit under git; the working-copy snapshot in a plain jj workspace). Explicit trivial one-off edits outside this flow need no worktree.
73
73
 
@@ -12,6 +12,11 @@ Mint a temp dir outside the worktree (never committed):
12
12
  GATHER_DIR=$(mktemp -d)
13
13
  ```
14
14
 
15
+ Read [reference/legs.md](reference/legs.md) for the settled member order and rules walk.
16
+ Expand the scout task below once per leg, home first, using that leg's worktree
17
+ as `cwd` and a distinct `<GATHER_DIR>/scout-<index>.md` output. Preserve one scout
18
+ for a single-member run. Keep context-builder home-owned and conditional.
19
+
15
20
  Set the substep, then dispatch one foreground parallel-tasks `subagent` call (`async: false`; no
16
21
  `model:` — pi-cohort `agentOverrides` owns builder models). Preserve the parallel batch and await
17
22
  its terminal result before assembling the draft:
@@ -45,6 +50,13 @@ Use that SKILL.md directory, never `reference/` as the base.
45
50
  Scout (always dispatched):
46
51
 
47
52
  > Recon for an upcoming design discussion. The request: `<initial prompt verbatim>`.
53
+ > Owning leg: `<repo>`; touched paths in this leg: `<paths or unresolved>`.
54
+ > Apply `reference/legs.md`'s rules walk: root and touched-directory `AGENTS.md`
55
+ > and `CLAUDE.md`, one hop of local documentation links in prose, bullets, and
56
+ > tables, deduped by `realpath`; linked documents contribute no more links.
57
+ > Emit repo-relative `Rules:` lines, `Rules: missing: <path>` for unresolved
58
+ > links, or `Rules: root only - paths unresolved`. Include `pkg-x/AGENTS.md`
59
+ > when touching `repo-a/pkg-x`; exclude untouched `pkg-y`.
48
60
  > Map the territory this change touches: relevant files with line ranges, existing
49
61
  > patterns and conventions the change must match, test conventions, integration
50
62
  > points, and whether the codebase or ecosystem already solves any of this. Trace retained
@@ -220,7 +232,8 @@ time:
220
232
 
221
233
  ## Draft assembly
222
234
 
223
- Read the temp files and write the draft **to the spec path** (normal filename
235
+ Read every leg's temp file in member order, retaining each leg's repo identifier,
236
+ Rules lines, recon and degraded status independently. Write the draft **to the spec path** (normal filename
224
237
  convention; slug minted from the initial prompt):
225
238
 
226
239
  ```markdown
@@ -1,6 +1,6 @@
1
1
  # Amendment surface
2
2
 
3
- `read` this file (the `read` tool at its absolute path, never a shell command) from `skills/brainstorming/SKILL.md` § Amending an approved spec, from any phase, for amend-class changes; at approval, load only [Standing grants](#standing-grants), not the batch procedure. Keep redraws outside this procedure. Classify a change to an approved drafted acceptance-criteria row - its text, a row added, a row removed - as a redraw at batch preparation, before any standing grant, never a disposition amendment: re-draft from the new design and ratify at the full gate; keep a disposition-only change to such a row in this grammar so it keeps the cut question. Apply an item the human has answered by letter or custom text as recorded. Only the main loop holding `edit`/`write` authors amendments and human-facing amendment text. Use the human last: a fresh reviewer clears evidence-backed factual corrections; present the rest to the human once per batch plainly.
3
+ `read` this file (the `read` tool at its absolute path, never a shell command) from `skills/brainstorming/SKILL.md` section Amending an approved spec, from any phase, for amend-class changes; at approval, load only [Standing grants](#standing-grants), not the batch procedure. Keep redraws outside this procedure. Classify a change to an approved drafted acceptance-criteria row - its text, a row added, a row removed - as a redraw at batch preparation, before any standing grant, never a disposition amendment: re-draft from the new design and ratify at the full gate; keep a disposition-only change to such a row in this grammar so it keeps the cut question. Apply an item the human has answered by letter or custom text as recorded. Only the main loop holding `edit`/`write` authors amendments and human-facing amendment text. Use the human last: a fresh reviewer clears evidence-backed factual corrections; present the rest to the human once per batch plainly.
4
4
 
5
5
  ## Standing grants
6
6
 
@@ -145,6 +145,18 @@ Before the aftermath, `read` this section again; never run it from memory.
145
145
 
146
146
  Apply accepted items only: reviewer clears, `accept`, `alt-n`, and state-changing `custom`. Print one line per applied item: `amended the spec: <title> - <what>`.
147
147
 
148
+ Preserve scope indices on disposition-only amendments, including cuts; validate
149
+ all blocks using [legs.md](legs.md)'s scope grammar before committing.
150
+ Apply [legs.md](legs.md)'s companion aftermath in this same amendment: changes
151
+ to Problem, shared Design/Errors/Out-of-scope, repo-binding clauses, or a leg
152
+ block rewrite each affected companion artifact. Commit home, then the affected
153
+ files through their own `git -C`; preserve the amendment audit in those commits.
154
+ Do not complete the amendment while any carried text disagrees. For specs with
155
+ `## Legs`, recorded contracts are authoritative, replacing finish Step 6's
156
+ reread rule; amend the block before using a changed contract. Legacy specs
157
+ without that section retain finish-time rereading. A one-member run has no
158
+ companion artifact or companion aftermath.
159
+
148
160
  Aftermath, once per batch, only when at least one item applied (nothing applied -> skip to the commit below). Ledger exists (line 1 `# Ledger - loop engine` in the resolved plan dir) -> skip `plan-writer`, `plan_check`, and `plan_tracker`. Reconcile the ledger against the approved spec dispositions: `deviates:`, `deferred:`, or `elsewhere:` -> `cut`, evidence = the disposition; factual or requirement-preserving amendment -> preserve rows; re-bounded `done` row -> `open`, evidence = `reopened by amendment`. Preserve every row's attempts and the ledger's iterations. Never auto-edit ticket or approved drafted AC row texts; reconcile dispositions only, never text/add/remove changes. Commit spec + ledger together with subject `loop: cut row <n>` for a batch containing only one cut, otherwise `loop: amend` (including mixed batches), carrying the amendment audit body below (including each `granted` record and granting sentence); continue without task-plan aftermath. No plan yet -> commit the spec; continue. Plan exists -> read `git -C "<abs worktree path>" status --porcelain` (plain jj: `jj -R "<abs worktree path>" diff --summary`); collect the parent's in-flight workflow edits as worktree-relative paths, including the amended spec and staged in-place wave-repair deliverables. Dispatch `plan-writer` per `writing-plans` `## Author the plan` step 3 with an `Amend:` block naming the amended spec sections, an `In-flight:` list of those paths (the parent supplies the set; the child never infers it), and the rule "preserve every task title and wave position the amendment does not touch; edit only affected anchors and tasks", then run that section's steps 5-6 (the parent `plan_check` and its branches).
149
161
 
150
162
  At that return point, classify human-facing outcomes with this table; let writing-plans' first `Findings:` repair run as written.
@@ -0,0 +1,187 @@
1
+ # Legs
2
+
3
+ Use this reference as the portable membership, leg-block, and companion-file grammar.
4
+ Keep tracker and dispatch APIs unchanged.
5
+
6
+ ## Settle membership before Worktree First
7
+
8
+ Read the home primary's first-found overrides file: `.pi/gauntlet-overrides.md`,
9
+ `gauntlet-overrides.md`, `doc/gauntlet-overrides.md`. Treat `## shape-ticket`
10
+ `- sibling: <clone url>` declarations as eligibility, not membership. Parse selected values
11
+ with shape-ticket's [shared parser](../../shape-ticket/reference/repo-audit.md);
12
+ use `PATH` = `<home PRIMARY parent>/<NAME>` as each companion primary.
13
+
14
+ Match only companions explicitly selected by the ask (repo identifier, `NAME`,
15
+ or declared clone URL) or the ticket's repo-group headings. Compare
16
+ case-insensitively, trailing `owner/name` of `IDENTITY` before `NAME`. Derive each companion's portable identifier
17
+ from the shared parser's trailing `owner/name` of `IDENTITY` for the validated stored origin
18
+ read with `git -C <primary> config --get remote.origin.url`. Derive the home's identifier
19
+ from `git -C <primary> remote get-url origin`'s `owner/name`, stripping `.git`;
20
+ without origin use `repo:` from that member's own first-found overrides
21
+ `## Issue tracker` section; without that value use the member's primary directory basename. Use the same identifier
22
+ in `### Leg:`, task `Leg:`, and brief `repo:` fields. For an ambiguous basename,
23
+ ask once before any creation; never guess. Order members home first, then selected siblings in declared order.
24
+ An existing PR alone never activates membership; PR home provisioning still uses
25
+ `using-git-worktrees/reference/pr-head.md`.
26
+
27
+ Match identifiers before any filesystem or git probe; probe only matching siblings,
28
+ or remaining declarations when nothing matches. Never probe unselected siblings. With no selected companion,
29
+ keep the single-member flow. Validate every selected declaration before creating
30
+ any tree: invalid configuration, missing `PATH`, not a checkout, no origin,
31
+ unparseable origin, wrong repo, or `PATH` equal to home stops naming the line.
32
+ Read origins with `git -C <PATH> config --get remote.origin.url` and compare the
33
+ full parsed `IDENTITY`; canonicalize paths before the home comparison. Keep these machine paths in working state and briefs, never in committed blocks.
34
+
35
+ ## Resolve each member
36
+
37
+ | Field | Contract |
38
+ |---|---|
39
+ | `repo` | Portable identifier above; preserve one spelling everywhere |
40
+ | `primary` | Home checkout at brainstorm start, or selected sibling clone URL parsed to `<home PRIMARY parent>/<NAME>`; machine-local |
41
+ | `worktree` | Absolute `Worktree ready` result; machine-local |
42
+ | `branch` | One full caller `BRANCH` shared by all members |
43
+ | `name` | Shared `NAME`, derived from `BRANCH` by replacing `/` with `-` |
44
+ | `Rules:` | Repo-relative files from the rules walk below |
45
+
46
+ Read each primary's first-found overrides using the ladder above. Read its
47
+ `.pi/settings.json` by file and apply the existing preset rules in
48
+ `extensions/lib/gauntlet-settings.ts`: repo top-level piGauntlet keys replace
49
+ preset keys wholesale; absent keys fall through. Missing configuration uses defaults.
50
+ Keep flow policy (council, grants, tracker, response channels, finish choice and
51
+ home flow guards) under home `.pi/settings.json#piGauntlet` and home overrides.
52
+ Never use `gauntlet_setting` for companions or add a `piGauntlet.*` key.
53
+
54
+ Record portable templates, not expanded absolute paths:
55
+
56
+ - Create: retain the leg's `## using-git-worktrees` keyed `home:`/`create:` contract,
57
+ native tool, discovered wrapper, or owned built-in. Resolve other wrapper tokens
58
+ from that leg's touched top-level directory; zero or several candidates ask once
59
+ for that leg. Retain the resolved portable value, not a machine path.
60
+ - Destroy: prefer the `## cleanup` worktree line, then `destroy:`, then owned
61
+ built-in removal matching `home:`. Include configured
62
+ `subagents.worktreeTeardownHook` with pi-cohort's existing semantics. Never
63
+ bypass a wrapper with `git worktree remove`; unmatched homes remain host-owned.
64
+ - Directories: resolve `flowGuards.specDirs` with the existing default
65
+ `doc/specs`, `docs/specs`; derive plan directories with `planDirsFor`.
66
+ Never read `planDirs` as settings input. Choose the leg's spec directory by the
67
+ existing spec-location convention. Keep plan and ledger home-owned.
68
+ - Verification: retain commands from `## verification-before-completion` and
69
+ `## PR gate`, plus merged `piGauntlet.verifyBeforeShip`. Preserve templates
70
+ describing execution against the leg's worktree or primary.
71
+
72
+ Invoke using-git-worktrees once per member with explicit `$ROOT` = primary and
73
+ `$BRANCH` = shared branch; require the affirmative read-back in
74
+ [Step 4](../../using-git-worktrees/SKILL.md#step-4--report-location).
75
+ Carry every `Worktree ready at <path>` result, home
76
+ first. On any failure stop naming repo and branch and list already-created legs;
77
+ leave them preserved, never auto-remove them.
78
+
79
+ ## Gather rules
80
+
81
+ Dispatch one scout per leg with its worktree as `cwd`. Collect root `AGENTS.md`
82
+ and `CLAUDE.md` when present; walk root through every touched directory and
83
+ collect those filenames on the path. For a touch in `repo-a/pkg-x`, include
84
+ `repo-a/pkg-x/AGENTS.md`, not rules from untouched `pkg-y`.
85
+ Read every local documentation link in those walked files, including prose,
86
+ bullets, and tables, exactly one hop. Resolve targets relative to the linking
87
+ file and require them to stay inside the leg. Dedupe files by `realpath` so a
88
+ symlinked `CLAUDE.md` counts once. Linked documents contribute no further links.
89
+ Emit `Rules: <repo-relative path>` for each file and `Rules: missing: <path>` for
90
+ unresolved or outside-leg targets; never invent their contents. Without touched
91
+ paths, retain root rules and emit `Rules: root only - paths unresolved`; the
92
+ plan-writer's touched-path walk fills the task rules later. Every leg block
93
+ carries at least one `Rules:` line; a block with no rules walk result carries
94
+ `Rules: root only - paths unresolved`, never an omitted key or a deferral note.
95
+
96
+ ## Home block and companion files
97
+
98
+ Place `## Legs` after `## Acceptance criteria` and optional `## Rework record`.
99
+ Write one block per member, home first. Use repo-relative rules and design paths;
100
+ the following shows the field grammar, not configuration values to copy:
101
+
102
+ ```markdown
103
+ ## Legs
104
+
105
+ ### Leg: repo-a
106
+ branch: feature/shared-change
107
+ contract:
108
+ - create: git worktree add <home> -b <branch>
109
+ - destroy: git worktree remove <home> && git worktree prune
110
+ - home: .worktrees/<name>
111
+ - spec-dir: doc/specs
112
+ - plan-dir: doc/plans
113
+ - verification: <resolved portable verification templates and policy>
114
+ Rules: AGENTS.md
115
+ Rules: pkg-x/AGENTS.md
116
+ scope: AC 1, AC 3
117
+ design: <owned paths, observable outcomes, and clauses binding this leg>
118
+ ```
119
+
120
+ ### Scope grammar and validation
121
+
122
+ Write exactly one `scope:` line in each block: `scope: none` or a comma-separated
123
+ list of `AC <index>` entries, as in the template. Use one-based original AC indices, including cut rows;
124
+ count checkbox rows in their original order, not ledger entries or disposition-filtered rows.
125
+ Repeat shared indices in each owning leg; indices unlisted across all legs default home.
126
+ When all legs say `scope: none`, every original AC defaults home.
127
+ Never infer ownership from `design:` prose or paths: `design: implements AC 2`
128
+ does not claim AC 2 without an explicit scope entry. Put owned paths and
129
+ observable outcomes in `design:` instead.
130
+
131
+ Before committing home or companion artifacts, validate every block against the
132
+ original AC count. Reject missing or duplicate scope lines, duplicate indices within one leg,
133
+ malformed lists, and nonexistent original indices; the same index in different legs is valid.
134
+ Use these rejection cases as the boundary checks:
135
+
136
+ | Invalid line | Reason |
137
+ |---|---|
138
+ | `scope: AC 0` | Zero is not one-based |
139
+ | `scope: AC 1.5` | Fractional index |
140
+ | `scope: AC 1-3` | Range rather than individual indices |
141
+ | `scope: 1` | Bare number without `AC ` |
142
+ | `scope: AC 1,` | Trailing comma / empty entry |
143
+ | `scope: none, AC 1` | Mixed sentinel and list |
144
+ | `scope: AC 1, AC 1` | Duplicate within one leg |
145
+ | `scope: AC 4` with only three original ACs | Nonexistent original index |
146
+
147
+ Reject empty values, negative indices and any other entry not matching
148
+ `AC [1-9][0-9]*`, separated by comma and space. Preserve scope indices on
149
+ disposition-only amendments, including cuts; validate again before the amendment commit.
150
+ Keep this grammar here; consumers refer to it rather than inventing ownership rules.
151
+
152
+ Keep shared Design, Errors and edge cases, and Out of scope outside `## Legs`;
153
+ those clauses bind every member. Assign member ticket groups `in-scope` and name
154
+ their ownership through original AC indices in `scope:`. Unmatched groups retain ticket-acceptance's
155
+ `this repo / elsewhere / repair` question; `elsewhere:` creates no leg.
156
+
157
+ Commit home first using spec-finalization's existing gate and audit. Then write
158
+ one companion file per companion in its own spec directory with the home's
159
+ filename. Use `git -C <companion worktree>` to add and commit that file:
160
+
161
+ ```markdown
162
+ # <home spec title>
163
+
164
+ **Home:** <home repo> <shared branch> <home repo-relative spec path>
165
+
166
+ ## Problem
167
+ <home Problem copied verbatim>
168
+
169
+ ## Decisions
170
+ <shared Design, Errors and edge cases, Out of scope, and clauses naming this
171
+ repo or its owned paths in design, copied from home>
172
+
173
+ ### Leg: repo-b
174
+ <that companion's entire block verbatim>
175
+ ```
176
+
177
+ Rewrite and commit affected companion files in the same amendment when Problem,
178
+ shared decisions, repo-binding clauses, or their block changes. Do not call an
179
+ amendment complete while a carried part disagrees.
180
+
181
+ Treat recorded `contract:` lines as authority for every spec with `## Legs`,
182
+ including one-member specs. This replaces finishing Step 6's creation-time
183
+ reread rule; legacy specs without `## Legs` retain the finish-time reread and
184
+ mean home-only. Amend a recorded contract before a later stage uses a change.
185
+
186
+ For one member add exactly one block only: no companion artifact, no `legs:`
187
+ brief block, no `--leg`, no receipt, and no companion loop.
@@ -25,6 +25,13 @@ Spec-writing replaces the context draft, in this exact order:
25
25
  `### PR #<N>` provenance subsection per PR with lowercase claims. Carry every PR's
26
26
  stated intent and constraints added since fork into Problem. Open Design with the
27
27
  unresolved sync repair when present. Omit the record from a ticket or free-text spec.
28
+ Then write `## Legs` after `## Acceptance criteria` and optional `## Rework record`,
29
+ using [legs.md](legs.md): one `### Leg: <repo>` block per member, home first,
30
+ with `branch:`, portable `contract:`, `Rules:`, exactly one `scope:` line and
31
+ `design:` prose for owned paths and observable outcomes.
32
+ Validate every block using [legs.md](legs.md)'s scope grammar before committing.
33
+ Keep machine-local paths out of committed blocks. Even a single-member spec
34
+ carries exactly one block; legacy specs without the section remain home-only.
28
35
  3. **Immediately after the write**, confirm line 1 of the file is no longer
29
36
  `# CONTEXT DRAFT - NOT A SPEC - fully replaced at spec-writing` - before
30
37
  dispatching lint, critique, council, or summarizer. The phase-tracker commit
@@ -116,6 +123,13 @@ git -C <abs worktree path> add -- <spec path> [<predecessor path>] && git -C <ab
116
123
  EOF
117
124
  ```
118
125
 
126
+ After the home commit, write and commit every companion leg file through
127
+ `git -C <companion worktree>` using [legs.md](legs.md)'s artifact grammar:
128
+ `**Home:**` tuple, copied `## Problem`, `## Decisions` from shared
129
+ Design/Errors/Out-of-scope and repo-binding clauses, and its own block verbatim.
130
+ Stop naming any failed companion; do not present artifact completion until all
131
+ files agree. A single-member run writes no companion file.
132
+
119
133
  If the council path ran, the body is its audit (`Coverage:` when present, then `Applied:` / `Deferred:` / `Rejected:`, verbatim from `/skill:roasting-the-spec`'s return) - the durable, non-contractual record a finish-time revert and row 3 below read back; the audit is never a committed spec section. On the worker path the body is empty except for a main-loop drafted-AC repair audit line when a repair occurred. Append that repair line after the council audit on the council path; never alter its labels, cluster lines, or counts. `-m`, `-F <file>`, `printf | ... -F -`, and `$'...'` strings are not used for this commit. The `add` on the same line is required because the spec is untracked at its first commit and `commit -- <path>` rejects an untracked path.
120
134
 
121
135
  Evaluate the summary in two stages (the **Degrade path** referenced in each is defined just below):
@@ -4,7 +4,7 @@ A ticket is guidance, not sole truth. Fetch it; propose scope, approach, or acce
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
 
7
- **This repo** is the `repo:` value of the overrides `## Issue tracker` section, else the `owner/name` path of `git remote get-url origin` with any `.git` suffix stripped; a repo group matches it when the group name equals that value or its basename, case-insensitive. A ticket without repo groups holds only this repo's rows; never guess attribution. A grouped ticket with no group matching this repo stops the brainstorm with that fact.
7
+ **This repo** is the `repo:` value of the overrides `## Issue tracker` section, else the `owner/name` path of `git remote get-url origin` with any `.git` suffix stripped; a repo group matches it when the group name equals that value or its basename, case-insensitive. Apply [legs.md](legs.md)'s identifier-before-basename membership resolution before attribution. A ticket without repo groups holds only this repo's rows; never guess attribution. A grouped ticket with no group matching any member stops the brainstorm with that fact.
8
8
 
9
9
  **Write the section in every spec**, after `## Problem`:
10
10
 
@@ -17,7 +17,7 @@ Ticket <ref>, <heading or "checkbox list">, rows verbatim:
17
17
  <disposition>
18
18
  ```
19
19
 
20
- Under `Ticket <ref>, <heading or "checkbox list">, rows verbatim:`, the section names the ticket contract only; the spec's own requirements stay in Design. Keep every provenance form flat - a row's repo lives in its disposition token, never in a heading. Disposition is exactly one of `in-scope`, `deviates: <why>`, `deferred: <where>`, `venue: <env> - <observation>`, `elsewhere: <repo>`; default `in-scope`. For ticket rows, never edit the row text: an ambiguous row stays `in-scope` with the chosen reading written as a Design clause, and a moved path or a workflow artifact (spec, plan, changelog, telemetry file) is a Design clause too, never a disposition and never asked. A row under a repo group that is not this repo is `elsewhere: <repo>`, stated, never asked; a group matching no repo asks `A) this repo B) elsewhere: <name> C) repair the ticket - /skill:shape-ticket <ref>`. Replace `<name>` with the supplied unmatched group heading verbatim in option B, not a request to name a repo. Name a `venue:` row's enabling change in Design; `venue:` states where the observation can happen and is never `prd`, `prod`, or `production` - a row observable only in production is a wrong row. An `in-scope` row is a requirement as written; disposition reasons are never normative for the plan or the reviewer, so a `deviates:` reason that adopts part of a row restates that part as a Design clause. A `deferred:` destination is a tracker ref (`#N`, `owner/repo#N`, `ABC-123`), a spec path, or a URL; a prose destination with none of these is a gap at the PR gate.
20
+ Under `Ticket <ref>, <heading or "checkbox list">, rows verbatim:`, the section names the ticket contract only; the spec's own requirements stay in Design. Keep every provenance form flat - a row's repo lives in its disposition token, never in a heading. Disposition is exactly one of `in-scope`, `deviates: <why>`, `deferred: <where>`, `venue: <env> - <observation>`, `elsewhere: <repo>`; default `in-scope`. For ticket rows, never edit the row text: an ambiguous row stays `in-scope` with the chosen reading written as a Design clause, and a moved path or a workflow artifact (spec, plan, changelog, telemetry file) is a Design clause too, never a disposition and never asked. A row under a repo group matching a settled member is `in-scope`; encode that member's ownership through original AC indices in its leg's `scope:` using [legs.md](legs.md), with owned paths only in `design:`. A known nonmember repo group is `elsewhere: <repo>`, stated, never asked; `elsewhere:` creates no leg. A group matching no repo asks `A) this repo B) elsewhere: <name> C) repair the ticket - /skill:shape-ticket <ref>`. Replace `<name>` with the supplied unmatched group heading verbatim in option B, not a request to name a repo. Name a `venue:` row's enabling change in Design; `venue:` states where the observation can happen and is never `prd`, `prod`, or `production` - a row observable only in production is a wrong row. An `in-scope` row is a requirement as written; disposition reasons are never normative for the plan or the reviewer, so a `deviates:` reason that adopts part of a row restates that part as a Design clause. A `deferred:` destination is a tracker ref (`#N`, `owner/repo#N`, `ABC-123`), a spec path, or a URL; a prose destination with none of these is a gap at the PR gate.
21
21
 
22
22
  **Cut question.**
23
23
 
@@ -29,9 +29,9 @@ The process cwd never changes; every command targets `$WORKTREE` or `$PRIMARY` e
29
29
  Then call `phase_tracker({ action: "start", phase: "ship" })`.
30
30
 
31
31
  ## The Process
32
-
33
32
  ### Step 1: Verify Tests
34
33
  **Hard verification gate.** Tests/format/lint must pass before presenting any options — including Discard. The user's stated intent to throw the branch away does not change whether the diff is in a verifiable state; verifying first surfaces accidental damage to unrelated code before the branch is gone forever. The skip rule below is the only exception.
34
+ Read [coordinated finish](reference/legs.md) once for `## Legs` activation, recorded contracts, per-leg Steps 1/3.5, the single Step 4 choice, Step 5 receipts and home strip-and-seal, and Step 6 cleanup. Apply its coordinated mechanics for multiple members; retain the ordinary path for one member or no section.
35
35
  Reuse the selected run spec read in Input. Detect a rework PR subject by its `## Rework record`; use Input's header-linked route for `**PR:**`, never discover by an open PR on `$FEATURE`. For the rework route only, read every top-level `PR:`/`Pre-rework head:` pair, home first, retaining each full SHA; missing pre-head -> stop naming the spec path. Set `PRE_REWORK_HEAD` to home's SHA. Read only combined capitalized `Base:`, `Keeps:`, `Changes:`, `Dropped claims:`, `Scoped tests:` fields; ignore lowercase provenance under `### PR #<N>`. For N=1, read `Threads:` directly after `Pre-rework head:` and retain the provenance subsection without changing finish output. Confirm only home with `gh pr view <N> --json number,url,headRefName,baseRefName,state` (use the record's repository): non-`OPEN` -> stop: `PR #N is <state>; the rework cannot be pushed to it.`; headRefName != `$FEATURE` -> stop naming both branches. Retain baseRefName for Step 3.
36
36
  Recognize a ledger by line 1 exactly `# Ledger - loop engine`. For a ledger, use its `verification:` command throughout finish, including the minors round. For a rework PR subject with a task plan, use the union of every plan task's `Tests:` commands plus the executable lint/format commands in the header's `**Verification:**` line; treat `none - PR subject, scoped` as no header commands, not an empty task union. Capture this set and accepted-complete task evidence before stripping the plan. Apply the hard gate and skip rule below to this set. For every other subject with a task plan, run the plan header's `**Verification:**` set in the worktree: `(cd "$WORKTREE" && <command>)`. With no plan in this session, run the verification command(s) of the affected services from the gauntlet overrides file or `AGENTS.md` (look for "verification", "CI", or "test" sections).
37
37
  **Skip rule.** Skip the run only when this set passed on a known clean commit in the verify phase of this session and no edit or write landed outside `<telemetry.dir>` since. Check the current tree: `git -C "$WORKTREE" diff --quiet <commit the run passed on> -- . ':!<telemetry.dir>'` must exit 0, and `git -C "$WORKTREE" status --porcelain --untracked-files=all -- . ':!<telemetry.dir>'` must exit 0 with empty output (`<telemetry.dir>` defaults to `.pi/gauntlet/telemetry`). These checks cover committed, staged, unstaged, and untracked changes outside telemetry. Otherwise run it once; a missing verified commit, a failed check, or uncertainty means run.
@@ -380,7 +380,7 @@ If confirmed: Cleanup worktree (Step 6), then, if Step 6 removed the worktree, `
380
380
 
381
381
  **Only runs for the Squash-merge and Discard options (3 and 5).** The PR, draft PR, and Keep options always preserve the worktree.
382
382
 
383
- Read the gauntlet overrides file now (ladder in Project overrides) and its `## using-git-worktrees` section; nothing from creation time is carried - the file is the contract (keys written like `## cleanup` items: `using-git-worktrees/SKILL.md` Step 1a).
383
+ Use recorded `contract:` lines when the spec carries `## Legs`, including one member; apply the recorded cleanup authority from the Step 1 reference. For a legacy spec without `## Legs`, read the gauntlet overrides file now (ladder in Project overrides) and its `## using-git-worktrees` section as the cleanup contract (keys written like `## cleanup` items: `using-git-worktrees/SKILL.md` Step 1a).
384
384
 
385
385
  **Keyed contract** - the section has at least one of `- home:`, `- create:`, `- destroy:`:
386
386
 
@@ -0,0 +1,76 @@
1
+ # Coordinated finish
2
+
3
+ ## Activation and authority
4
+
5
+ Read the home spec's `## Legs` once at Step 1. Use the membership, portable identifiers, scope validation and path resolution in [the leg grammar](../../brainstorming/reference/legs.md). Resolve selected primaries from home's declared siblings and worktrees from the brief or recorded `home:` pattern. Validate branch, repository identity and each companion's full `**Home:**` tuple before acting. Admit a missing delivered worktree only through a validated receipt below.
6
+
7
+ Use recorded `contract:` lines for every spec with `## Legs`, including one member. Amend the home block and affected companion file before using a changed contract; do not reread overrides to replace it. For one member, return to the ordinary finish steps using that block's contract: keep exactly one `### Leg:`, no companion artifact, `legs:` brief block, receipt, `--leg` argument or companion loop. For no `## Legs`, use the ordinary home-only flow and Step 6's overrides reread.
8
+
9
+ For more than one member, apply the following steps instead of the home-only verification, delivery and cleanup mechanics. Keep Step 3.5's disposition protocol, the home's review policy, Step 4 menu and confirmations. Keep machine-local paths out of committed bodies and messages.
10
+
11
+ ## Durable receipts
12
+
13
+ Keep one home-owned file per delivered leg at `<home git common dir>/gauntlet/receipts/<spec filename>/<repo>`, where `<home git common dir>` is `git -C <home worktree> rev-parse --path-format=absolute --git-common-dir` (the home primary's `.git`, e.g. `/work/repo-a/.git/gauntlet/receipts/shared.md/repo-b`) - never inside any worktree, so a removed home tree never takes a receipt with it. Include the full spec filename, including `.md`, and preserve repo path segments; create directories before writing. Git metadata is never tracked, so no exclude entry is needed. Treat them as flow restoration artifacts, not telemetry, approval evidence or proof without validation.
14
+
15
+ Write after each delivery attempt that produced a PR or squash commit, including failed post-squash verification:
16
+
17
+ ```text
18
+ attempted-head: <full feature SHA attempted>
19
+ delivered: pr <url> <full delivered PR head> | squash <full squash SHA>
20
+ verification: passed | <actual verification failure>
21
+ ```
22
+
23
+ Choose one `delivered:` alternative. Use `verification: passed` only for successful verification; preserve the error otherwise. Retain the selected spec path, recorded commands, membership and accepted task evidence before stripping the plan, and carry the receipt locations into the brief. On fresh-session retry admit a stripped plan only when every companion has a receipt; validate each receipt rather than inferring delivery from missing files. Recover commands from the spec's recorded contract, not the absent plan.
24
+
25
+ Before checkout-based verification and conformance fan-out, validate receipt identity against the selected spec, repo and recorded delivery choice; reconcile it with the selected action before delivery. Malformed, mismatched or unverifiable receipts leave the leg unlanded; stop on an unavailable boundary rather than creating duplicate delivery. Apply these proofs:
26
+
27
+ | Receipt | Required proof and retry action |
28
+ |---|---|
29
+ | PR | Fetch the receipt URL using `gh pr view <url> --json state,headRefOid` in its repository. Require `OPEN`, head equal to the attempted head, delivered head equal to attempted head, passed verification, and unchanged current feature head when the tree exists. A stale head must re-push the verified branch non-force and update the existing PR, not create another PR. Refresh and rewrite the receipt after success. A closed PR is not a validated skip; stop for disposition. |
30
+ | Squash | Require `verification: passed` and the squash SHA reachable from the primary's default branch: `git -C <primary> merge-base --is-ancestor <squash SHA> <default branch>` must exit 0. Confirm the current attempted feature head when available. For recorded failed post-squash verification, rerun verification, not squash, against the delivered primary state; rewrite the receipt on pass. Require the recorded squash to remain reachable and stop on unrelated primary movement requiring review. |
31
+
32
+ Never use feature-head ancestry as proof of squash delivery. Resolve the actual primary default branch, not an assumed `main`. Treat unexpected Git exits as errors, not negative proofs. Preserve receipts on every failure, including seal failure and cleanup refusal.
33
+
34
+ ## Verification and closure - Steps 1 and 3.5
35
+
36
+ Exempt a leg with a validated receipt and a missing worktree from checkout-based verification and conformance. Run fresh checks for every unlanded leg; stop on a missing unlanded worktree. Handle failed-squash verification in the delivered primary through the receipt retry action above; replace feature-checkout checks with that primary verification even when the feature tree still exists.
37
+
38
+ Before Step 4, run every leg's recorded verification set with that leg's worktree as command cwd, except the receipt-proven exemptions above, then perform conformance review with that leg's `cwd`, Rules and owned AC rows. Use original AC indices from `scope:`; shared rows belong to each named owner and unclaimed rows default home. Apply Step 1's hard gate and skip proof independently per leg. Route fixes and commits through `git -C <owning worktree>`, never home's checkout for companion code.
39
+
40
+ Retain each present member's audited head and tree, including staged, unstaged and untracked state. Immediately before delivery compare them to the current checkout; re-verify and re-review every changed leg before its delivery. Apply the same freshness check after disposition fixes and minors fixes. Aggregate closure before presenting one menu; no leg bypasses open dispositions.
41
+
42
+ Apply leg-local `piGauntlet.verifyBeforeShip` evidence to commands targeting that checkout. Read each primary's `.pi/settings.json` by file and merge the preset using the existing settings rules; do not use home's `gauntlet_setting` result or home's successful test flag as companion evidence. Use the recorded verification set, including when a retry has no plan.
43
+
44
+ ## Execute one choice - Steps 4 and 5
45
+
46
+ Apply one chosen action to companions in declared sibling order, then home. Preserve every PR, draft and keep worktree and branch. Keep reports all retained locations without strip, seal, delivery or cleanup.
47
+
48
+ For a PR-subject home, compose the supported existing home action with companion delivery: row 1 pushes and edits the existing home PR through its recipe, rows 2-3 retain the existing-PR disclosure and refusal rather than attempting a duplicate, and squash/keep/discard retain their existing disclosures and confirmations. Deliver companions before the supported home ship action; keep absorbed-PR closure authorization separate and unchanged. Do not start fan-out for a home action withheld by preflight.
49
+
50
+ For PR, draft and squash:
51
+
52
+ 1. Validate existing receipts first. Skip only receipt-proven delivery. Check freshness for every unlanded leg before its delivery.
53
+ 2. Deliver each companion: for PR/draft, push with `git -C <worktree> push -u origin <branch>`, then run `gh pr create` in that worktree's cwd, adding `--draft` on every draft create. On retry of an existing PR use its URL and edit rather than duplicate create. For squash, use the existing Option 3 primary checkout/pull/merge/commit recipe and run that leg's recorded post-squash commands in the primary. Write its receipt even when those commands fail. No companion plan strip or telemetry seal runs.
54
+ 3. Collect complete companion results, including validated skips. Capture the spec path and evidence before the home plan strip. Run home's strip-and-seal block with repeated `--leg <repo>=<sha|pr-url>`, one per companion. Never seal partial results. Compare collected `{ repo, sha }` or `{ repo, pr }` entries with an existing seal's `legs:` set; differences stop naming stored and collected results. Retain all receipts when the bin fails and print its output. Never write companion `.pi/gauntlet/telemetry/`.
55
+ 4. Deliver home through the selected existing recipe after successful sealing, without running a second seal lacking the companion arguments. For PR-subject row 1 retain the whole-PR base and all body-edit/closure rules. Write home's receipt, including post-squash failures. Run cleanup only for squash, after successful post-squash verification.
56
+
57
+ Put `Home: <repo> <shared branch> <home spec path>` in every companion PR body and squash message. Respect each leg's PR body style. List every companion PR URL in the home PR body (including the existing home PR's rework block), and every companion squash SHA in home's squash message.
58
+
59
+ On the first delivery, verification or seal failure, stop fan-out and preserve delivered work and receipts. Print actual results, including validated skips, in member order:
60
+
61
+ ```text
62
+ Shipped: <repo> <sha|pr> ...
63
+ Not shipped: <repo> <reason> ...
64
+ ```
65
+
66
+ A squash with failed post-verification belongs under Not shipped with its created SHA and error; do not conceal the commit. Include home when not delivered and every untouched remaining companion. Perform no rollback. A fresh-session retry validates the same receipts before continuing.
67
+
68
+ ## Discard and recorded cleanup - Steps 5 and 6
69
+
70
+ List every member's branch, commit count, and worktree path as a resolved absolute path (the brief's or the recorded `home:` pattern expanded for this branch, e.g. `/work/repo-b/.worktrees/feature-shared-change`; never a pattern or placeholder) before one typed `discard` confirmation. Obtain exact confirmation once for the run, then clean every member, home included, through its recorded contract regardless of other members' refusals. Do not strip or seal for discard.
71
+
72
+ For cleanup, use the recorded `## cleanup` worktree command, else `destroy:`, with the configured teardown hook using pi-cohort's existing semantics, else the owned built-in matched against that leg's recorded `home:`. Execute from that leg's primary. Expand recorded `<name>` and `<branch>` as single shell words using Step 6's escaping and ownership proof; resolve other tokens before execution. Never use `git worktree remove` past a wrapper or hook failure. Leave unmatched host-owned trees and their branches preserved.
73
+
74
+ Clean companions in declared order, then home. Report a refusal as that leg's `failed` line, leave the tree intact, and continue the remaining cleanup attempts and the remaining report lines. After squash, stop only the refused companion's cleanup and attempt every remaining companion's recorded contract from its own primary; on any companion cleanup failure, skip home's cleanup and report `<home repo>: preserved - companion cleanup failed` to retain the home checkout for a fresh-session retry via /skill:gauntlet-resume. Delete a branch only after successful removal of its worktree. Run prune only for successful owned built-in removal, not after a wrapper. Report each repo's actual removed, preserved or failed state.
75
+
76
+ Remove receipts only after home delivery and all required cleanup succeed, and report that removal in one explicit line (`Home delivery and required cleanup succeeded; receipts removed`). Receipts live in the home primary's git dir, so worktree removal never touches them; when any required cleanup failed, report `receipts retained - required cleanup failed` and leave every receipt in place for the retry. PR/draft success has no cleanup requirement and preserves every worktree, so its receipts are removed right after the home PR lands. Keep retains receipts for later validation. Mark ship complete only after the chosen action succeeds for every member; never mark discard as shipped.
@@ -65,7 +65,7 @@ Apply the first-line grammar in [menu-layout](../brainstorming/reference/menu-la
65
65
  (`disable-model-invocation: true`), so it is absent from the session skill list.
66
66
  Locate it by path: run `pi list`; the indented path under the `pi-cohort` entry
67
67
  (`npm:pi-cohort`, or a local path ending in `/pi-cohort`) is the package root. `Read` `<root>/skills/handoff/SKILL.md` and follow its procedure with the
68
- output option resolved in step 1 - the brief's core (six headings, ending at
68
+ output option resolved in step 1. Read the run home's spec; with multiple members, explicitly supply `Run worktree: <home worktree>` through cohort's "was told to work in" snapshot clause. Pin the snapshot to that path, not the most-recently-used companion and not an `Also seen:` entry. The brief's core (six headings, ending at
69
69
  `## Skills loaded`) is cohort's to write, by cohort's rules. No `pi-cohort` entry, or
70
70
  the file missing -> STOP: "cohort `handoff` skill not found at
71
71
  `<root>/skills/handoff/SKILL.md` - install or upgrade to pi-cohort >= 7.1.0". No
@@ -85,7 +85,7 @@ Apply the first-line grammar in [menu-layout](../brainstorming/reference/menu-la
85
85
  - A phase `in_progress` (verify or ship included - resume stops at verify on its own)
86
86
  -> append the process-state section exactly as `## Producers` in
87
87
  `reference/brief-contract.md` lays it out: both status outputs verbatim
88
- (`No plan active.` verbatim when there is no plan), the contract's artifact-specific fields, and the gate-history line. Recognize the loop alternative by ledger line 1; read the ledger from the run worktree for its durable last decision. Read the run worktree's spec; when it carries `## Rework record`, copy every top-level PR identity (without the title) and its full pre-rework head, home first in record order, into the optional fields in the contract's producer layout; copy the optional top-level rework base after the pairs as the contract specifies. Without that record, use the ordinary layout. Use only the contract's grammar; write no second state file. Append with a single
88
+ (`No plan active.` verbatim when there is no plan), the contract's artifact-specific fields, and the gate-history line. Recognize the loop alternative by ledger line 1; read the ledger from the run worktree for its durable last decision. Read the run worktree's spec; when it carries `## Rework record`, copy every top-level PR identity (without the title) and its full pre-rework head, home first in record order, into the optional fields in the contract's producer layout; copy the optional top-level rework base after the pairs as the contract specifies. Without that record, use the ordinary layout. For multiple members, read `reference/brief-contract.md` "Coordinated brief grammar" and append its ordered member snapshot, including missing trees and existing receipt paths, in that layout. Keep the core snapshot home-bound. Use only the contract's grammar; write no second state file. Append with a single
89
89
  `cat >> "<brief path>" <<'EOF' ... EOF` whose body is that block.
90
90
  - Re-read the file tail and confirm it ends with the gate-history line from the
91
91
  contract and nothing after.
@@ -91,12 +91,13 @@ checks 2, 4, 5 do not apply; check 6 runs on the seed's pinned spec path.
91
91
  cwd with
92
92
  `realpath "$(git -C <worktree> rev-parse --path-format=absolute --git-common-dir)"`.
93
93
  If they differ, stop, name both paths, and say the resolved worktree belongs to a
94
- different repository; restart pi in that repository's primary checkout and re-run.
94
+ different repository; restart pi in that repository's primary checkout and re-run. For member-primary entry on a coordinated brief, also print `home is <repo>; restart there`, naming the run home.
95
95
  Same-repository worktrees proceed by path: use `git -C <worktree>` for
96
96
  worktree Git commands and absolute artifact paths for `Read` and `plan_check`.
97
+ 3b. **Coordinated admission.** For a multi-member brief, read and apply `reference/brief-contract.md` "Coordinated admission" before any tracker write: resolve the home spec without inferring approval, compare ordered membership, validate each declared primary/common directory, shared branch and full home tuple, and live-validate receipts before admitting any missing tree. Preserve check 3's home binding.
97
98
  4. **Drift notice.** Compare the brief's `HEAD` and `dirty` fields in `## Repo state`
98
99
  with the live worktree (`git -C <worktree> rev-parse HEAD`, `git -C <worktree>
99
- status --porcelain`). Announce differences. Informational, never a stop.
100
+ status --porcelain`). For coordinated briefs apply `reference/brief-contract.md` "Coordinated admission" per leg. Announce differences. Informational, never a stop.
100
101
  5. **Skills loaded.** For each name in `## Skills loaded` (none for
101
102
  `## Skills loaded: none`): match against the frontmatter `name` of every
102
103
  `skills/*/SKILL.md` in this package; `Read` each match's complete file into the
@@ -27,7 +27,7 @@ Headings, fixed order. A consumer keys on headings, never prose.
27
27
  | `## Repo state` | one field per line: `toplevel`, `worktree: yes <path>` or `worktree: no`, `branch` (`detached` when none), `HEAD`, `base` (`unknown` when no remote resolves), `dirty: <porcelain>` or `dirty: clean`, `diff-stat` (`unavailable` when base unknown), `test cmd`; any field `unavailable` when its command failed; heading `## Repo state: not a git repo` outside git | always |
28
28
  | `## Decisions` | bullets; rejected alternatives marked `rejected:` | always |
29
29
  | `## Skills loaded` | frontmatter `name`s; `## Skills loaded: none` when none | always |
30
- | `## Process state` | `phase_tracker status` then `plan_tracker status` verbatim; `Active task: <name|none>`; optional one or more consecutive `PR: <owner/repo#N>` / `Pre-rework head: <40-char sha>` pairs, one per record group, home first, in record order, only for a PR subject; optional single `Rework base: <40-char sha>` after all PR pairs; the line `Gate history not restored - re-validate before advancing.` | only when a phase is `in_progress` and no hotfix flow is in context |
30
+ | `## Process state` | `phase_tracker status` then `plan_tracker status` verbatim; `Active task: <name|none>`; optional one or more consecutive `PR: <owner/repo#N>` / `Pre-rework head: <40-char sha>` pairs, one per record group, home first, in record order, only for a PR subject; optional single `Rework base: <40-char sha>` after all PR pairs; optional coordinated block defined below after that line; the line `Gate history not restored - re-validate before advancing.` | only when a phase is `in_progress` and no hotfix flow is in context |
31
31
 
32
32
  For a loop ledger (line 1 exactly `# Ledger - loop engine`), replace `Active task` with these two fields, retaining both tracker status outputs and the gate-history line:
33
33
 
@@ -53,7 +53,7 @@ one blank line, the heading on its own line, a blank line, the `phase_tracker st
53
53
  output verbatim, a blank line, the `plan_tracker status` output verbatim, a blank line,
54
54
  `Active task: <name|none>`, then, only for a PR subject, one or more consecutive
55
55
  `PR: <owner/repo#N>` / `Pre-rework head: <40-char sha>` pairs, one per record group,
56
- home first, in record order, then optional single `Rework base: <40-char sha>` after all PR pairs and before the gate-history line -
56
+ home first, in record order, then optional single `Rework base: <40-char sha>` after all PR pairs, then the optional coordinated block below, then the gate-history line after the last pair, rework-base line, or block -
57
57
  unfenced, nothing after.
58
58
  For a task plan, set `Active task` to the first `→` task name, else `none` (also for `No plan active.`). For a line-1 ledger, read its path and last decision and use the loop alternative above, retaining the optional PR pairs and rework base before the gate-history line. Copy the full rework base only from the top-level record when present; never invent a boundary for incomplete sync. Copy only top-level record pairs, without titles; `Threads:` and record `### PR #<N>` subsections are not brief fields. For N=1 emit one pair; without a Rework record use the ordinary layout.
59
59
 
@@ -80,6 +80,38 @@ Active task: W2: producer
80
80
  Gate history not restored - re-validate before advancing.
81
81
  ```
82
82
 
83
+ ## Coordinated brief grammar
84
+
85
+ For more than one member only, append this block after the optional PR pairs and before the terminal gate-history line. Emit entries in the home spec's `### Leg:` order, home first. Keep the six core headings and `## Repo state` fields unchanged and bound to the run home. Distinguish PR home (the leading PR pair) from run home (the first member); do not infer one from the other.
86
+
87
+ ```text
88
+ legs:
89
+ - repo: repo-a
90
+ worktree: <absolute home worktree>
91
+ branch: <shared branch>
92
+ HEAD: <full sha>
93
+ dirty: clean
94
+ - repo: repo-b
95
+ worktree: missing
96
+ branch: <shared branch>
97
+ HEAD: <last recorded full sha or unavailable>
98
+ dirty: unavailable
99
+ receipt: <absolute home-owned receipt path>
100
+ Gate history not restored - re-validate before advancing.
101
+ ```
102
+
103
+ Keep fields in this order. Use the portable repo identifier from `../../brainstorming/reference/legs.md`. Record the absolute worktree path or the literal `missing` when absent; record live HEAD and porcelain dirt (`clean` when empty), or last recorded HEAD and `unavailable` dirt for a missing tree. Include the optional receipt path only when a delivery receipt exists; transport is not proof. For a live tree without a receipt omit that field. Single-member and legacy briefs carry no coordinated block, leg file, receipt, `--leg` or companion loop.
104
+
105
+ ## Coordinated admission
106
+
107
+ Run resume entry check 3 against the run home unchanged. Resolve the home spec through Candidates, retaining human approval/confirmation requirements; artifact presence supplies no approval. Before any tracker write, compare ordered brief membership with the home spec's `### Leg:` blocks exactly; name the missing, extra or reordered leg and both lists on mismatch. Use `../../brainstorming/reference/legs.md` for membership, companion-file and scope grammar; keep no duplicate grammar here.
108
+
109
+ For each companion, parse the home overrides' selected sibling clone URL with shape-ticket's shared parser and use `<home PRIMARY parent>/<NAME>` as its declared primary. Canonicalize that primary's git common directory. Resolve an absent location from the leg's recorded `home:` contract and shared NAME (shared branch with `/` replaced by `-`), not a newly inferred wrapper. Require the companion worktree's canonical git common directory to equal the declared primary's, its live branch to equal the shared branch, and its leg file's full `**Home:**` tuple to equal the run home's repo, shared branch and repo-relative spec path. Stop naming the offending leg and expected/observed path, branch or full tuple. A live tree's branch or tuple mismatch is not informational drift.
110
+
111
+ Admit a missing companion tree only after live receipt validation under `../../finishing-a-development-branch/reference/legs.md`. A copied receipt alone proves nothing. Announce per-leg HEAD and dirty drift against live trees without stopping; identify each leg. Keep approval, standing-grant validation, arming order and task snapshots unchanged. Dispatch task `Leg:` work in that leg's checkout, not the home by default.
112
+
113
+ For a ship-stage retry with a correctly stripped plan, require every companion receipt to validate live before admitting the missing plan. Restore through the legal brainstorm start/skip, plan start/skip and implement skip sequence to verify, without inventing a plan_check stamp or conformance evidence. Re-validate unlanded home using recorded contracts and original scoped ACs, then run fresh home conformance and finish; use the finishing reference's retry route. Preserve receipts on seal or home delivery failure; do not repair or replace a correctly stripped plan. An absent plan without this fully validated ship retry remains a stop.
114
+
83
115
  ## Tracker output grammar
84
116
 
85
117
  Must match `formatStatus` in the phase-tracker and plan-tracker extensions.
@@ -163,7 +195,9 @@ Honor SKILL.md entry check 6's deferred stop before any process-state arming cal
163
195
  | implement with ledger | Read ledger line 1; resolve its path-only `**Spec:**` header; run entry checks 1-6, naming check 6 (Grant field); `start brainstorm`; `skip brainstorm` reason `resume: <spec path>`; `start plan`; `plan_check` on the absolute ledger path; on PASS `skip plan` reason `resume: <spec> (loop engine)` using the resolved absolute spec path as `<spec>`; `start implement`; no `plan_tracker init`; apply the shared cap boundary in `reconstruction.md` "Spec with ledger" step 4 before continuation; render cap, rows and decisions; continue at loop step 5. Follow `reconstruction.md` "Spec with ledger" for this self-contained ordered restore. On FAIL stop with findings, never `## Plan repair` or writing-plans. |
164
196
  | implement with task plan | `start brainstorm`; `skip brainstorm S`; `start plan`; `plan_check({ planPath })`; on FAIL run `## Plan repair`; on PASS `skip plan R`; `start implement`; `substep` if shown; `plan_tracker init` |
165
197
  | verify | `start brainstorm`; `skip brainstorm S`; `start plan`; `plan_check({ planPath })`; on FAIL run `## Plan repair`; on PASS `skip plan R`, then `skip implement R`; `start verify`; `substep` if shown; `plan_tracker init`. Never call `start implement`. |
166
- | ship | as verify. Restoration stops at verify in_progress: `complete verify` needs a fresh conformance dispatch and `skip verify` would bypass a real gate. Announce that the closure review re-runs before ship |
198
+ | ship | With a correctly stripped coordinated plan, apply "Coordinated admission"'s fully receipt-validated retry route instead of plan repair; otherwise as verify. Restoration stops at verify in_progress: `complete verify` needs a fresh conformance dispatch and `skip verify` would bypass a real gate. Announce that the closure review re-runs before ship |
199
+
200
+ For a coordinated ledger, apply reconstruction's pending companion return boundary before dispatch or verification, including verify/ship restores; record a validated interrupted return before continuing.
167
201
 
168
202
  For a ledger brief, pair by the ledger's path-only `**Spec:**` header, not basename; require the resolved spec under `flowGuards.specDirs` and the ledger under its sibling plans directory. Keep same-repository binding and human confirmation. For every ledger brief apply the shared cap boundary in `reconstruction.md` "Spec with ledger" step 4 before dispatch or verification, retaining its legacy stop and original-phase grant continuation. For verify/ship ledger briefs, use the ledger restore sequence through `skip plan`, then `skip implement R`; `start verify`, with no task tracker. Continue verify/ship ledger briefs in `/skill:loop-implementation` `After the loop` from step 1 (full ledger verification), after the already-restored `start verify`, retaining whole-diff code review, happy path when triggered, fresh conformance review and finishing without task-tracker calls. Ship still stops at verify for fresh conformance.
169
203
 
@@ -62,6 +62,8 @@ plan commit; treat every task as `pending`.
62
62
  | one spec with ledger | "Spec with ledger" (takes precedence over a task plan) |
63
63
  | one spec with task plan only | "Spec with plan" |
64
64
 
65
+ For a coordinated brief, use `brief-contract.md` "Coordinated admission" before tracker writes. Resolve the home spec, never a companion leg file, and retain every approval question. For a ship-stage retry whose plan is stripped, use that section's receipt-validated exception rather than proposing a new plan.
66
+
65
67
  ## Spec without plan
66
68
 
67
69
  Run SKILL.md entry check 6's deferred-header admission on the resolved spec before the approval/handoff question below; apply it to both routes, including the unapproved-draft brainstorming handoff. Keep grant decoding exempt for the unapproved route.
@@ -92,6 +94,8 @@ After confirmation:
92
94
  2. Call `phase_tracker({ action: "start", phase: "brainstorm" })`, then `phase_tracker({ action: "skip", phase: "brainstorm", reason: "resume: <spec path>" })`, then `phase_tracker({ action: "start", phase: "plan" })`.
93
95
  3. Call `plan_check({ planPath: <absolute ledger path> })`. On FAIL, stop with findings, retaining plan in_progress. Start the message with `gauntlet: stuck` followed by the findings reason on that line; never enter `## Plan repair` or writing-plans. On PASS, call `phase_tracker({ action: "skip", phase: "plan", reason: "resume: <spec> (loop engine)" })`, then `phase_tracker({ action: "start", phase: "implement" })`. Use the resolved absolute spec path as `<spec>` in the reason. Never call `plan_tracker init`.
94
96
  4. **Shared cap boundary (every ledger restore, before phase continuation).** Read `/skill:loop-implementation`. Skip Entry step 1 entirely; settings resolution and its unavailable-tool stop apply only to fresh seeding. Restore base, verification, iterations, `cap:`, row attempts, funding and retry allowances from the ledger/spec and branch without overwriting it. Render `cap: <n>`, rows, iterations, attempts, funding, retry allowances and all decisions; distinguish the latest operational `row <n> ...` decision from the last physical history line. A dirty tree takes the driver's discard-authorization stop without offering a cap grant. On a clean ledger missing `cap:`, stop with `ledger has no cap: line - seeded under the old loopEngine contract`, even when every row is closed. Use the driver's legacy `cap +N` grant (durable iterations + N), never settings. After the grant continue the original phase: implement at `Before each dispatch`; verify/ship at `After the loop` step 1, never reseed.
97
+ Before continuation on a coordinated ledger, recover the pending companion return boundary. Read the durable `pending:` tuple (target row or seed, repo, pre-dispatch HEAD) and compare that companion's live head. Accept only exactly one new companion commit matching the tuple and carrying its consumed iteration and bounded result evidence. Validate the result, record its SHA and only that leg's target result or seeded state in the home ledger, and remove `pending:` in the home-ledger commit before dispatch. Preserve consumed iterations, attempts and cap; never rerun the recovered row. Unrelated head movement, multiple commits, or missing result evidence stops naming the leg and tuple. With no new commit, use the loop driver's interrupted-dispatch boundary, not a silent redispatch. Apply this boundary before dispatch or verification for every ledger restore.
98
+
95
99
  5. Continue at loop step 5, the delivered driver's `Before each dispatch`, with durable iterations and retry data. Never reset counters or reseed a validated seed.
96
100
 
97
101
  ## Spec with plan
@@ -4,6 +4,8 @@ Consumed only by `SKILL.md` in this directory, for a one-token `.md` argument cl
4
4
  as a spec seed. `<seed>` is its `realpath`; `<rel>` is `<seed>` relative to `<primary>`.
5
5
  Entry check 1 (idle session) runs first. Then, in order; every stop names the path.
6
6
 
7
+ Before starting the seed sequence, read the seed's header. A `**Home:**` header marks a companion leg file: stop, name its home repo, branch and spec path, and direct resume to that home. Never create a run from a leg file.
8
+
7
9
  1. **Primary session.** `git rev-parse --git-dir --git-common-dir` in the session cwd
8
10
  prints two paths; their `realpath`s must agree. Otherwise stop:
9
11
  `seed from the primary checkout`.