ai-fob 1.5.0 → 1.7.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 (27) hide show
  1. package/assets/commands/modify-pi-assets.md +628 -412
  2. package/assets/pi/agents/phase-architect.md +29 -28
  3. package/assets/pi/agents/phase-build-validator.md +141 -27
  4. package/assets/pi/agents/phase-builder.md +12 -20
  5. package/assets/pi/agents/phase-explorer.md +6 -5
  6. package/assets/pi/agents/phase-plan-validator.md +13 -13
  7. package/assets/pi/extensions/subagent/agents.ts +78 -13
  8. package/assets/pi/extensions/subagent/index.ts +19 -1
  9. package/assets/pi/extensions/subagent/widget.ts +9 -1
  10. package/assets/pi/extensions/task-state/checks.ts +5 -0
  11. package/assets/pi/extensions/task-state/index.ts +96 -9
  12. package/assets/pi/extensions/task-state/reconcile.ts +73 -17
  13. package/assets/pi/extensions/task-state/state-md.ts +214 -2
  14. package/assets/pi/prompts/build-phase-pi.md +252 -110
  15. package/assets/pi/skills/phase-build-workflow/SKILL.md +93 -24
  16. package/assets/pi/skills/phase-build-workflow/references/fix-loops.md +36 -15
  17. package/assets/pi/skills/phase-build-workflow/references/phase-completion-report-template.md +105 -0
  18. package/assets/pi/skills/phase-build-workflow/references/result-vocabulary.md +49 -0
  19. package/assets/pi/skills/phase-build-workflow/references/resume-reconciliation-table.md +27 -12
  20. package/assets/pi/skills/phase-build-workflow/references/state-md-schema.md +45 -12
  21. package/assets/pi/skills/testing-and-validation/SKILL.md +7 -5
  22. package/assets/skills/pi-primitives/SKILL.md +52 -7
  23. package/assets/skills/pi-primitives/reference/pi-agents-guide.md +21 -7
  24. package/assets/skills/pi-primitives/reference/pi-asset-modification-guide.md +45 -5
  25. package/assets/skills/pi-primitives/templates/pi-agent-template.md +15 -5
  26. package/manifest.json +1 -1
  27. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  ---
2
- description: Modify an existing Pi asset (extension / agent / prompt-template / skill) from a change request plans, validates, builds with byte-for-byte preservation, and regression-tests the modification. Use when an existing Pi asset needs a targeted change rather than a new multi-asset Pi system.
3
- argument-hint: [path or name of pi asset to modify] [modification request]
2
+ description: Repair one or more existing Pi assets (extension / agent / prompt-template / skill) as a coordinated change set, from a free-form problem description OR a single asset+request pair. Discovers affected assets via parallel research, plans the coordinated change set, validates, builds with byte-for-byte preservation, and runs per-asset functional + regression exercises. Use when a Pi defect or change request affects one or many related Pi assets that must be designed, approved, and built together.
3
+ argument-hint: [problem description, or path of a single Pi asset to modify] [optional modification request when a single path is supplied]
4
4
  model: opus
5
5
  disable-model-invocation: false
6
6
  allowed-tools: Skill, Agent, Read, Write, Glob, Grep, Bash
@@ -8,13 +8,15 @@ allowed-tools: Skill, Agent, Read, Write, Glob, Grep, Bash
8
8
 
9
9
  # Modify Pi Assets
10
10
 
11
- Modify a single existing Pi asset (extension / agent / prompt-template / skill) from a targeted change request. This command runs the full `plan → validate-plan → build → validate-build → report` loop specialized for Pi-asset modification: it parses the target and the modification request, researches the target and its Subagent-Assembly-trio blast radius (two explorers — target+blast-radius and local Pi docs — and NO docs researcher), produces a validated `action: modify` design spec, builds the change with byte-for-byte preservation of everything the spec does not touch, then structurally validates the build AND runs a bounded inline headless `pi` functional exercise PLUS a second bounded regression exercise against the asset's original capability. All agent work is delegated via the Agent tool over a disk-handoff working directory (no Claude Code Teams). Designed for headless mode via `--auto-confirm`; otherwise interactive with three confirmation gates (intake / post-research / pre-build approval).
11
+ Repair one or more existing Pi assets (extension / agent / prompt-template / skill) as a **single coordinated change set** driven from a free-form problem description. This command runs the full `intake → discover → plan → validate-plan → build → validate-build → report` loop specialized for Pi-asset repair: it takes the problem statement, discovers the set of affected Pi assets via parallel research across `.pi/` and `.claude/` (two explorers — affected-asset discovery + trio blast radius, and local Pi docs — and NO docs researcher), produces a validated multi-phase `pi-assets-plan` whose every phase carries `action: modify`, then builds and tests the coordinated change set under ONE approval gate, ONE builder pass, and per-asset functional + regression exercises. The single-asset case (one entry in `AFFECTED_ASSETS`) is the trivial **N = 1** of the same contract it remains fully supported, takes the same fast path, and emits the existing single-pair artifact convention so callers and downstream tooling are unaffected. All agent work is delegated via the Agent tool over a disk-handoff working directory (no Claude Code Teams). Designed for headless mode via `--auto-confirm`; otherwise interactive with three confirmation gates (intake / post-research / pre-build approval).
12
12
 
13
- The key innovations: **trio-aware blast-radius research** — Explorer A traces the modification's ripple across the Subagent Assembly trio (extension agent `.md` prompt-template preset) and classifies it Isolated / Contained / Broad. **Regression discipline** — every modification's design spec carries a dual-criterion Test Scenario (a new-capability criterion AND a regression criterion for the preserved original capability), and the build runs a SECOND bounded headless `pi` exercise against the original capability, captured to `_regression` artifacts. **Byte-for-byte preservation** — `pi-meta-agent` reads the existing target first and applies only the spec's changes via Read-then-Edit/MultiEdit, never a whole-file rewrite. Every handoff is a file because each subagent has a fresh, isolated context and cannot see another's work.
13
+ The key innovations: **problem-first intake** — the argument is a problem description; the affected Pi asset set is *discovered* by Step 1 Explorer A, not pre-named by the user. **Multi-asset coordinated change set** — Explorer A produces a list of affected assets `[{path, type, name, proposed-modification, trio-impact}, …]`; the architect routes to `pi-assets-plan` (phased, one phase per affected asset with `action: modify`); the validator checks each phase plus an added coordination-consistency check; the builder iterates Read-then-Edit/MultiEdit over the asset set; the validator scores per-asset functional + regression captures. **Trio-aware blast-radius research per asset** — Explorer A classifies each affected asset Isolated / Contained / Broad and aggregates a set-level blast-radius. **Regression discipline per asset** — every phase's Test Scenario carries the dual-criterion (new-capability + regression) rule; the build runs a second bounded `pi` exercise per affected asset against its preserved original capability. **Byte-for-byte preservation per asset** — `pi-meta-agent` reads each existing target first and applies only the spec's changes for that phase via Read-then-Edit/MultiEdit, never a whole-file rewrite. Every handoff is a file because each subagent has a fresh, isolated context and cannot see another's work.
14
+
15
+ **Single-asset N = 1 symmetry (carry verbatim):** when `AFFECTED_ASSETS.length == 1` the workflow degenerates to the original single-asset behavior in every observable way — `WORK_DIR` still nests one phase, the artifact filenames REUSE the existing single-pair convention (`functional_run.ndjson` / `functional_run_regression.ndjson` with NO per-asset suffix — see `reference/pi-asset-modification-guide.md` §3.3), the terminal report compresses cleanly, and downstream tooling (`build-pi-assets-phases` references, the deployed mirror, manifest entries) is bit-identical to the pre-repair behavior. The per-asset suffix convention from §3.4 "Multi-Asset Coordinated Sets" applies ONLY when `AFFECTED_ASSETS.length >= 2`.
14
16
 
15
17
  **Note on `disable-model-invocation: false` (deliberate, documented exception):** Workflow commands normally set `disable-model-invocation: true`. This command deliberately sets `false` so it remains invocable headlessly. In `claude -p` mode a user-invoked `/`-typed slash command is interactive-only; headlessly the command is reached by the model **invoking it through the Skill tool**, which is only permitted when `disable-model-invocation` is `false`. This is the same deliberate choice made by the sibling `/build-pi-assets-phases` (its lines 5 and 15 are the precedent). This is a recognized exception — it is NOT a defect, and any upstream design-validation of this command must not false-flag it.
16
18
 
17
- **Required Skill**: Before starting Step 0, invoke the `pi-primitives` skill using the Skill tool. This provides the Pi primitive model, the Subagent Assembly Pattern, Model Portability, the per-type testing-validation guide that Step 5b's structural + functional checklists are sourced from, AND `reference/pi-asset-modification-guide.md` — the authoritative definer of the dual-criterion Test Scenario rule and the `_regression` artifact convention that the modify-specific checks and the regression exercise source.
19
+ **Required Skill**: Before starting Step 0, invoke the `pi-primitives` skill using the Skill tool. This provides the Pi primitive model, the Subagent Assembly Pattern, Model Portability, the per-type testing-validation guide that Step 5b's structural + functional checklists are sourced from, AND `reference/pi-asset-modification-guide.md` — the authoritative definer of the dual-criterion Test Scenario rule, the single-pair `_regression` artifact convention (§3.3 default), AND the per-asset-suffix multi-asset coordinated-set artifact convention (§3.4 "Multi-Asset Coordinated Sets") that the per-asset functional + regression captures source.
18
20
  **Required Skill**: Before starting Step 0, invoke the `brainstorm-plan` skill using the Skill tool. This provides general modification-planning principles (for refactoring/modification work, Codebase Exploration is the heaviest phase and Research is mandatory).
19
21
 
20
22
  **Headless operator note**: When invoking this command under `claude -p`, run WITHOUT `--bare` (or pass the project directory / required `--add-dir`) so the `pi-primitives` and `brainstorm-plan` skills and the four reused Pi agents auto-load. `--bare` skips skill/agent auto-discovery.
@@ -24,71 +26,107 @@ The key innovations: **trio-aware blast-radius research** — Explorer A traces
24
26
  ARGUMENTS_RAW: $ARGUMENTS
25
27
 
26
28
  Parse into:
27
- - AUTO_CONFIRM — boolean. TRUE if the literal whitespace-delimited token `--auto-confirm` (case-sensitive, exact hyphenated spelling, NO `=value` suffix, NO short alias like `-y`) appears anywhere in ARGUMENTS_RAW OUTSIDE quoted spans; else FALSE. Default: FALSE. The full tokenization-and-strip algorithm executes in Step 0a; this variable is its output. The matching token(s) MUST be stripped from ARGUMENTS_RAW before TARGET and MOD_REQUEST are derived, so the flag is never captured as either.
28
- - TARGET — after stripping `--auto-confirm`, the first whitespace-delimited token of the remaining ARGUMENTS_RAW, OR the first quoted token if the user quoted it (the path or name of the Pi asset to modify)
29
- - MOD_REQUEST — the remainder of the stripped ARGUMENTS_RAW after TARGET (the free-form modification request; may be unquoted prose or a quoted string)
30
-
31
- Derived variables (compute in Step 0):
32
- - RESOLVED_ASSET_PATHthe resolved absolute-or-project-relative path to the target Pi asset file
33
- - ASSET_TYPEone of: skill | prompt-template | agent | extension (the 4-type subset; there is no `workflow` target for this command)
34
- - ASSET_NAMEthe asset's name, derived from RESOLVED_ASSET_PATH
35
- - ASSET_ACTIONfixed string "modify" (this command ONLY modifies; never "create")
36
- - KEBAB_TARGET — kebab-case of ASSET_NAME (lowercase, non-alphanumeric → hyphens, collapse repeats)
37
- - TIMESTAMP`date +%Y%m%d-%H%M%S` via Bash
38
- - WORK_DIR — `specs/modify-pi/{KEBAB_TARGET}-{TIMESTAMP}/` (the disk-handoff working directory, created via `mkdir -p` in Step 0)
29
+ - AUTO_CONFIRM — boolean. TRUE if the literal whitespace-delimited token `--auto-confirm` (case-sensitive, exact hyphenated spelling, NO `=value` suffix, NO short alias like `-y`) appears anywhere in ARGUMENTS_RAW OUTSIDE quoted spans; else FALSE. Default: FALSE. The full tokenization-and-strip algorithm executes in Step 0a; this variable is its output. The matching token(s) MUST be stripped from ARGUMENTS_RAW before PROBLEM_INPUT is derived, so the flag is never captured as part of it.
30
+ - PROBLEM_INPUT — after stripping `--auto-confirm`, the ENTIRE remaining ARGUMENTS_RAW (trimmed) as a free-form problem description. This is NOT pre-tokenized into a target + request pair; Step 0a may classify it as one of two intake shapes (problem-first vs single-asset-shortcut) but it is captured here as opaque free-form text.
31
+
32
+ Derived variables (compute in Step 0 / Step 1):
33
+ - INTAKE_SHAPE — one of: `"problem-description"` (PROBLEM_INPUT is free-form prose describing a defect or change request — affected assets are unknown until Step 1) | `"single-asset-shortcut"` (PROBLEM_INPUT begins with a token that resolves cleanly to exactly one existing Pi asset path via the Step 0b heuristic AND the remainder is non-empty — the legacy `[path] [request]` shape, retained as the N = 1 fast path). Classified in Step 0a.
34
+ - AFFECTED_ASSETSARRAY of resolved affected-asset records, one per Pi asset the coordinated change set touches. Each record is `{ resolved_path, asset_type, asset_name, kebab_slug, proposed_modification, trio_impact_summary }`. POPULATED in Step 1c (from Explorer A's findings) — NOT in Step 0. In Step 0 this variable is `[]` (empty); after Step 1c it has length ≥ 1. The trivial single-asset case is `AFFECTED_ASSETS.length == 1`.
35
+ - AFFECTED_ASSETS_COUNTinteger; `AFFECTED_ASSETS.length`. Computed at the end of Step 1c. Used everywhere downstream to branch the single-pair vs per-asset-suffix artifact convention (see `reference/pi-asset-modification-guide.md` §3.3 default / §3.4 multi-asset extension).
36
+ - ARTIFACT_SUFFIX_POLICYone of: `"single-pair"` (N == 1, §3.3 default) | `"per-asset-suffix"` (N ≥ 2, §3.4). Computed at the end of Step 1c from AFFECTED_ASSETS_COUNT.
37
+ - PROBLEM_TITLEshort human-readable title extracted from PROBLEM_INPUT (first sentence / first ~80 chars, trimmed). Used in the HTML approval header and the terminal report.
38
+ - KEBAB_PROBLEM_SLUG — kebab-case of PROBLEM_TITLE (lowercase, non-alphanumeric → hyphens, collapse repeats, max 50 chars). Used in WORK_DIR. For the single-asset-shortcut shape, this resolves to the kebab-case of the resolved asset name to preserve visual continuity with the pre-repair WORK_DIR scheme.
39
+ - ASSET_ACTIONfixed string "modify" (this command ONLY modifies; never "create"). Applied to every phase of the coordinated change set.
40
+ - TIMESTAMP — `date +%Y%m%d-%H%M%S` via Bash.
41
+ - WORK_DIR — `specs/modify-pi/{KEBAB_PROBLEM_SLUG}-{TIMESTAMP}/` (the disk-handoff working directory, created via `mkdir -p` in Step 0d).
39
42
  - GATE_A_RESULT, GATE_B_RESULT, GATE_C_RESULT — populated by Steps 0f, 1d, 3g respectively. Each is one of: `"confirmed"`, `"skipped (--auto-confirm)"`, `"revised then confirmed (N revisions)"`, or `"stopped at gate"`. Initialize all three to `"not yet reached"` here.
40
43
 
44
+ **Per-asset record convention (used by every downstream step):** for any asset record `A` in `AFFECTED_ASSETS`, `A.kebab_slug` is the kebab-case of `A.asset_name` (lowercase, non-alphanumeric → hyphens). When `AFFECTED_ASSETS_COUNT == 1` (`ARTIFACT_SUFFIX_POLICY == "single-pair"`), every artifact filename below uses the single-pair convention with NO suffix (e.g. `functional_run.ndjson`) per `reference/pi-asset-modification-guide.md` §3.3 (default). When `AFFECTED_ASSETS_COUNT >= 2` (`ARTIFACT_SUFFIX_POLICY == "per-asset-suffix"`), every per-asset artifact filename carries the suffix `_{A.kebab_slug}` (e.g. `functional_run_{A.kebab_slug}.ndjson`) per `reference/pi-asset-modification-guide.md` §3.4 "Multi-Asset Coordinated Sets". The single-pair convention is the §3.3 default; the per-asset-suffix convention is the §3.4 additive extension.
45
+
41
46
  ## Workflow
42
47
 
43
48
  ### Step 0: Parse & Prepare (Main Agent)
44
49
 
45
50
  You (the main agent) handle this step directly. Step 0 ends with the intake confirmation gate (Step 0f) — see also the post-research gate (Step 1d) and the pre-build approval gate (Step 3g). All three gates are SKIPPED when `--auto-confirm` is present in `$ARGUMENTS`, preserving headless operation.
46
51
 
47
- #### 0a. Parse Arguments
52
+ #### 0a. Parse Arguments and Classify Intake Shape
48
53
  1. Capture ARGUMENTS_RAW from $ARGUMENTS.
49
54
  2. Detect and strip the `--auto-confirm` flag FIRST, using this deterministic algorithm:
50
55
  a. **Tokenize with quote-awareness.** Walk ARGUMENTS_RAW left-to-right and split into tokens on unquoted whitespace. A quoted span is the text between matched `"..."` or `'...'` quote characters (inclusive of the quotes themselves) and is treated as a single opaque token; its interior is NEVER scanned for the flag. Unbalanced quotes: treat the rest of the string from the unmatched quote onward as one opaque token (do not error).
51
56
  b. **Match and strip.** Scan the resulting token list for tokens whose literal value is exactly `--auto-confirm` (case-sensitive, exact hyphenated spelling, NO `=value` suffix, NO short alias like `-y`, position-independent). If at least one such token is found at a position OUTSIDE quoted spans: set `AUTO_CONFIRM = true`, remove ALL such matching tokens from the list, and rejoin the remaining tokens with single spaces to form the stripped ARGUMENTS_RAW. Otherwise: set `AUTO_CONFIRM = false` and leave ARGUMENTS_RAW unchanged.
52
- 3. From the post-strip ARGUMENTS_RAW: TARGET = the first whitespace-delimited token (if the user wrapped the first arg in quotes, take the first quoted token instead). MOD_REQUEST = everything after TARGET, trimmed.
53
- 4. If TARGET is empty OR MOD_REQUEST is empty, error and STOP with exactly:
54
- `Usage: /modify-pi-assets [path or name of pi asset to modify] [modification request]`
55
- Hint: append `--auto-confirm` (anywhere outside quoted spans) to skip the three confirmation gates and run fully headlessly.
56
-
57
- #### 0b. Resolve the Target
58
- 1. If TARGET is an existing path (Read/Glob confirms a file OR a directory containing an `index.ts`/`SKILL.md`), use it directly as RESOLVED_ASSET_PATH.
59
- 2. Else, search `.pi/` by name (Glob + Grep), in this order:
60
- - extension: `.pi/extensions/{TARGET}/index.ts`, `.pi/extensions/{TARGET}.ts`, or any `.pi/extensions/*/index.ts` / `.pi/extensions/*.ts` whose dir/file stem matches TARGET
61
- - agent: `.pi/agents/{TARGET}.md` or any `.pi/agents/*.md` whose stem matches TARGET
62
- - prompt-template: `.pi/prompts/{TARGET}.md` or any `.pi/prompts/*.md` whose stem matches TARGET
63
- - skill: `.pi/skills/{TARGET}/SKILL.md` or any `.pi/skills/*/SKILL.md` whose dir matches TARGET
64
- 3. If exactly one match RESOLVED_ASSET_PATH = that path.
65
- 4. If zero matcheserror and STOP:
66
- `Error: could not resolve Pi asset "{TARGET}". Searched .pi/extensions, .pi/agents, .pi/prompts, .pi/skills. No candidates found.`
67
- 5. If multiple matches error and STOP, listing every candidate path:
68
- `Error: "{TARGET}" is ambiguous. Candidates:` followed by a bulleted list of the matched paths. Ask the user to re-invoke with an explicit path.
69
-
70
- #### 0c. Derive Type / Name
71
- From RESOLVED_ASSET_PATH:
72
- - If it is (or is inside) `.pi/extensions/...` (a `.ts`/`index.ts`) → ASSET_TYPE = extension; ASSET_NAME = the extension directory name (or the `.ts` stem).
73
- - If it is `.pi/agents/*.md` → ASSET_TYPE = agent; ASSET_NAME = the `.md` stem.
74
- - If it is `.pi/prompts/*.md` ASSET_TYPE = prompt-template; ASSET_NAME = the `.md` stem.
75
- - If it is `.pi/skills/*/SKILL.md` ASSET_TYPE = skill; ASSET_NAME = the containing skill directory name.
76
- - Set ASSET_ACTION = "modify" (fixed never "create").
57
+ 3. Set `PROBLEM_INPUT` = the trimmed post-strip ARGUMENTS_RAW (the entire remaining string, as opaque free-form text DO NOT pre-tokenize into target + request).
58
+ 4. **Classify INTAKE_SHAPE.** Take the first whitespace-delimited token of PROBLEM_INPUT (or the first quoted token if the user quoted it); call it `FIRST_TOKEN`. Apply the Step 0b single-asset resolution heuristic to `FIRST_TOKEN` (treat it as a candidate path or name; run the same Glob/Grep search Step 0b describes but in CLASSIFY-ONLY mode — do not error on zero/multiple matches, just count them):
59
+ - If `FIRST_TOKEN` resolves to EXACTLY ONE existing Pi asset path AND `PROBLEM_INPUT` has additional non-empty content after `FIRST_TOKEN`: set `INTAKE_SHAPE = "single-asset-shortcut"`. This is the legacy `[path] [request]` N = 1 fast path — backward-compatible with all pre-repair invocations.
60
+ - Otherwise: set `INTAKE_SHAPE = "problem-description"`. The full `PROBLEM_INPUT` is treated as a free-form problem statement; affected assets are unknown until Step 1c.
61
+ 5. If `PROBLEM_INPUT` is empty (or contains only whitespace), error and STOP with exactly:
62
+ `Usage: /modify-pi-assets [problem description, or path of a single Pi asset to modify [optional modification request]]`
63
+ Hint: append `--auto-confirm` (anywhere outside quoted spans) to skip the three confirmation gates and run fully headlessly. Examples:
64
+ /modify-pi-assets "the explore-codebase chain dispatch hangs when the second agent times out"
65
+ /modify-pi-assets .pi/agents/explorer.md "tighten the system prompt to require an absolute path in the Output section"
66
+ 6. Initialize `AFFECTED_ASSETS = []` and `AFFECTED_ASSETS_COUNT = 0`. These remain empty/zero until Step 1c populates them from Explorer A's findings.
67
+ 7. Derive `PROBLEM_TITLE`:
68
+ - `INTAKE_SHAPE == "single-asset-shortcut"`: extract the resolved single asset's name and prefix it with "modify ", e.g. `"modify explorer-agent"`.
69
+ - `INTAKE_SHAPE == "problem-description"`: take the first sentence (or first ~80 chars) of `PROBLEM_INPUT`, trimmed.
70
+ 8. Derive `KEBAB_PROBLEM_SLUG` = kebab-case of `PROBLEM_TITLE` (lowercase, non-alphanumeric hyphens, collapse repeats, max 50 chars). For the single-asset-shortcut shape this resolves to the kebab-case of the asset name (e.g. `explorer-agent`), preserving visual continuity with the pre-repair WORK_DIR naming.
71
+
72
+ #### 0b. Single-Asset Shortcut Pre-Resolution (ONLY when INTAKE_SHAPE == "single-asset-shortcut")
73
+
74
+ This step pre-resolves the affected-asset set ONLY for the legacy single-asset-shortcut shape. For the problem-description shape, this step is SKIPPED entirely and the affected-asset set is discovered by Step 1c from Explorer A's findings. The Step 1c machinery is the canonical multi-asset discovery path; this step exists exclusively to preserve the N = 1 fast path for the legacy invocation.
75
+
76
+ If `INTAKE_SHAPE != "single-asset-shortcut"` → SKIP this step. Leave `AFFECTED_ASSETS = []` for now; Step 1c will populate it.
77
+
78
+ Otherwise:
79
+ 1. Re-extract `FIRST_TOKEN` and `REMAINDER` from PROBLEM_INPUT (FIRST_TOKEN is the candidate path/name; REMAINDER is everything after FIRST_TOKEN, trimmed the modification request for this asset).
80
+ 2. Resolve `FIRST_TOKEN` to a single Pi asset path:
81
+ a. If `FIRST_TOKEN` is an existing path (Read/Glob confirms a file OR a directory containing an `index.ts`/`SKILL.md`), use it directly.
82
+ b. Else, search `.pi/` by name (Glob + Grep), in this order:
83
+ - extension: `.pi/extensions/{FIRST_TOKEN}/index.ts`, `.pi/extensions/{FIRST_TOKEN}.ts`, or any `.pi/extensions/*/index.ts` / `.pi/extensions/*.ts` whose dir/file stem matches FIRST_TOKEN
84
+ - agent: `.pi/agents/{FIRST_TOKEN}.md` or any `.pi/agents/*.md` whose stem matches FIRST_TOKEN
85
+ - prompt-template: `.pi/prompts/{FIRST_TOKEN}.md` or any `.pi/prompts/*.md` whose stem matches FIRST_TOKEN
86
+ - skill: `.pi/skills/{FIRST_TOKEN}/SKILL.md` or any `.pi/skills/*/SKILL.md` whose dir matches FIRST_TOKEN
87
+ 3. If zero matches → the Step 0a classification was wrong (a false single-asset-shortcut). Re-classify `INTAKE_SHAPE = "problem-description"`, leave `AFFECTED_ASSETS = []`, and SKIP the rest of this step — Step 1c will discover the affected set from the free-form text.
88
+ 4. If multiple matches → present them informationally and re-classify `INTAKE_SHAPE = "problem-description"` (let the explorer disambiguate from blast-radius context). Leave `AFFECTED_ASSETS = []`. Do NOT STOP — multi-match is now a discovery-dispatch signal, not a hard error. Present:
89
+ `NOTE: "{FIRST_TOKEN}" matched multiple Pi assets ({list}). Treating PROBLEM_INPUT as a problem description; Explorer A will discover the affected asset set from the full problem text.`
90
+ 5. If exactly one match → derive the asset record from the resolved path:
91
+ - If it is (or is inside) `.pi/extensions/...` (a `.ts`/`index.ts`) → `asset_type = "extension"`; `asset_name = the extension directory name (or the .ts stem)`.
92
+ - If it is `.pi/agents/*.md` → `asset_type = "agent"`; `asset_name = the .md stem`.
93
+ - If it is `.pi/prompts/*.md` → `asset_type = "prompt-template"`; `asset_name = the .md stem`.
94
+ - If it is `.pi/skills/*/SKILL.md` → `asset_type = "skill"`; `asset_name = the containing skill directory name`.
95
+ - `kebab_slug = kebab-case of asset_name`.
96
+ - `proposed_modification = REMAINDER` (the user's free-text request for this asset).
97
+ - `trio_impact_summary = "to be populated by Explorer A"`.
98
+ - Append this record to `AFFECTED_ASSETS`. Set `AFFECTED_ASSETS_COUNT = 1` (provisional — Step 1c may grow it).
99
+ 6. Step 1c will VERIFY the pre-resolved single-asset entry against Explorer A's findings; if Explorer A discovers additional affected trio consumers that the user did not name in REMAINDER, Step 1c will APPEND them (the change set may grow from N = 1 to N ≥ 2 even in the shortcut shape — Gate B is the user's chance to confirm or reject the growth).
100
+
101
+ #### 0c. Confirm Defaults
102
+
103
+ `ASSET_ACTION = "modify"` (fixed — applies to every phase of the coordinated change set; this command NEVER creates a new asset).
104
+
105
+ Per-asset `asset_type` / `asset_name` derivation now happens at two points: (a) Step 0b for the optional single-asset-shortcut pre-resolution, and (b) Step 1c for every asset Explorer A discovers. Step 1c uses the IDENTICAL derivation rules as the four bullets removed from this step — they live verbatim inside Step 0b §5 (and Step 1c re-applies them per asset).
77
106
 
78
107
  #### 0d. Create the Working Directory
79
- - KEBAB_TARGET = kebab-case of ASSET_NAME.
108
+ - `KEBAB_PROBLEM_SLUG` was computed in Step 0a.
80
109
  - TIMESTAMP = output of `date +%Y%m%d-%H%M%S` via Bash.
81
- - WORK_DIR = `specs/modify-pi/{KEBAB_TARGET}-{TIMESTAMP}/`.
110
+ - WORK_DIR = `specs/modify-pi/{KEBAB_PROBLEM_SLUG}-{TIMESTAMP}/`.
82
111
  - Run `mkdir -p {WORK_DIR}` via Bash (idempotent — safe if it already exists).
83
112
 
113
+ **Visual continuity for the single-asset-shortcut shape:** because `KEBAB_PROBLEM_SLUG` resolves to the kebab-case of the resolved asset name when `INTAKE_SHAPE == "single-asset-shortcut"`, the WORK_DIR path for a legacy single-asset invocation is byte-identical in shape to the pre-repair behavior (e.g. `specs/modify-pi/explorer-agent-{TIMESTAMP}/`).
114
+
84
115
  #### 0e. Present Execution Overview
85
116
  Present:
86
117
  ```
87
- MODIFY PI ASSET
88
-
89
- Target: {RESOLVED_ASSET_PATH}
90
- Type: {ASSET_TYPE} Name: {ASSET_NAME} Action: modify
91
- Modification request: {MOD_REQUEST}
118
+ MODIFY PI ASSET — COORDINATED CHANGE SET
119
+
120
+ Problem: {PROBLEM_INPUT}
121
+ Intake shape: {INTAKE_SHAPE}
122
+ {If INTAKE_SHAPE == "single-asset-shortcut":}
123
+ Pre-resolved candidate (N = 1 fast path):
124
+ - {AFFECTED_ASSETS[0].resolved_path} ({AFFECTED_ASSETS[0].asset_type} — {AFFECTED_ASSETS[0].asset_name})
125
+ Proposed modification: {AFFECTED_ASSETS[0].proposed_modification}
126
+ Note: Explorer A may discover additional affected trio consumers in Step 1; if so, the change set will grow to N ≥ 2 and you will confirm or reject the expansion at Gate B.
127
+ {Else (INTAKE_SHAPE == "problem-description"):}
128
+ Affected Pi assets: TO BE DISCOVERED in Step 1 (Explorer A searches `.pi/` + `.claude/` from this problem description and produces the coordinated change-set candidate).
129
+ Action: modify (every phase)
92
130
  Working directory: {WORK_DIR}
93
131
  Auto-confirm: {AUTO_CONFIRM} (when true, Steps 0f / 1d / 3g gates are skipped)
94
132
  ```
@@ -101,76 +139,114 @@ If `AUTO_CONFIRM == true` (the `--auto-confirm` flag was set in `$ARGUMENTS`), S
101
139
  Otherwise present and WAIT for the user:
102
140
 
103
141
  ```
104
- INTAKE SUMMARY
105
-
106
- Target: {RESOLVED_ASSET_PATH}
107
- Type: {ASSET_TYPE} Name: {ASSET_NAME} Action: modify
108
- Modification request: {MOD_REQUEST}
142
+ INTAKE SUMMARY — COORDINATED CHANGE SET
143
+
144
+ Problem: {PROBLEM_INPUT}
145
+ Intake shape: {INTAKE_SHAPE}
146
+ {If INTAKE_SHAPE == "single-asset-shortcut":}
147
+ Pre-resolved candidate (the legacy N = 1 fast path):
148
+ - {AFFECTED_ASSETS[0].resolved_path} ({AFFECTED_ASSETS[0].asset_type} — {AFFECTED_ASSETS[0].asset_name})
149
+ Proposed modification: {AFFECTED_ASSETS[0].proposed_modification}
150
+ Step 1's Explorer A may discover additional affected trio consumers; if so, the change set will grow to N ≥ 2 and you will confirm or reject the expansion at the post-research gate (Gate B).
151
+ {Else:}
152
+ Affected Pi assets: to be discovered in Step 1 from the problem description above.
153
+ Action: modify (applies to every phase of the change set)
109
154
  Working directory: {WORK_DIR}
110
155
 
111
- Is this correct? (yes / no / revise — provide corrections)
156
+ Is this the correct problem statement? (yes / no / revise — provide corrections)
112
157
  ```
113
158
 
114
159
  **CONFIRMATION GATE**: Do NOT proceed to Step 1 until the user confirms.
115
160
 
116
161
  Branches:
117
162
  - **yes** → set `GATE_A_RESULT = "confirmed"` and proceed to Step 1.
118
- - **revise** → incorporate the user's corrections (re-resolve TARGET / re-derive ASSET_TYPE / ASSET_NAME / update MOD_REQUEST as the corrections instruct), re-present the INTAKE SUMMARY, and re-ask. Track revisions; on final confirmation set `GATE_A_RESULT = "revised then confirmed ({N} revisions)"`.
163
+ - **revise** → incorporate the user's corrections (rewrite PROBLEM_INPUT, re-classify INTAKE_SHAPE per Step 0a, re-run Step 0b shortcut resolution if applicable, refresh PROBLEM_TITLE / KEBAB_PROBLEM_SLUG / WORK_DIR do NOT re-create the working directory if WORK_DIR was already created and is non-empty; reuse it). Re-present the INTAKE SUMMARY, and re-ask. Track revisions; on final confirmation set `GATE_A_RESULT = "revised then confirmed ({N} revisions)"`.
119
164
  - **no** → set `GATE_A_RESULT = "stopped at gate"`. STOP execution with no work performed. Present:
120
165
  ```
121
- STOPPED at intake gate. No research, no design, no build performed. Re-invoke `/modify-pi-assets` with the corrected arguments when ready.
166
+ STOPPED at intake gate. No research, no design, no build performed. Re-invoke `/modify-pi-assets` with the corrected problem statement when ready.
122
167
  ```
123
168
 
124
- ### Step 1: Research (Two Parallel Explorers via Agent Tool — NO docs-researcher)
169
+ ### Step 1: Discovery + Research (Two Parallel Explorers via Agent Tool — NO docs-researcher)
125
170
 
126
- Spawn TWO `explorer-agent` instances via the Agent tool. They are independent and MUST be spawned **in parallel** — issue both Agent tool calls in a SINGLE message. Both write their output files directly to disk.
171
+ Spawn TWO `explorer-agent` instances via the Agent tool. They are independent and MUST be spawned **in parallel** — issue both Agent tool calls in a SINGLE message. Both write their output files directly to disk. Explorer A is the AFFECTED-ASSET DISCOVERY engine — it consumes PROBLEM_INPUT, scans `.pi/` + `.claude/`, and produces the coordinated change-set candidate. Explorer B researches local Pi docs for every asset type Explorer A may name.
127
172
 
128
173
  **Why two explorers and NO docs-researcher**: Pi documentation is NOT a website — it ships inside the installed npm package as version-pinned local files. There is no web page to fetch; a docs-researcher (which web-searches the Claude Code docs site) is the wrong tool. The second research delegation is another `explorer-agent` instance pointed at the on-disk Pi docs via the discovery command and doc-map owned by the `pi-primitives` skill. Do NOT spawn a `docs-researcher-agent` in this command under any circumstances.
129
174
 
130
175
  Note on the explorer prompts: `explorer-agent` has NO `pi-primitives` skill and NO self-arm clause (contrast the three Pi agents). It is a read-only investigator. Therefore the trio-aware tracing rules and the Pi-doc discovery command are given to it **inline in the prompt**, and each explorer is given an explicit `## Output:` disk path (the explorer's default Report returns inline; the disk-handoff loop requires a written file).
131
176
 
132
- #### 1a. Spawn Explorer A Target + Trio Blast Radius (parallel, same message as 1b)
177
+ **Shortcut-shape hint to Explorer A:** if `INTAKE_SHAPE == "single-asset-shortcut"`, the pre-resolved candidate at `AFFECTED_ASSETS[0]` is included in Explorer A's prompt as a seed; Explorer A still scans for additional affected trio consumers from PROBLEM_INPUT and may APPEND to the change set. The pre-resolved entry is preserved unless Explorer A flags it as wrong (in which case the explorer says so explicitly in its findings).
178
+
179
+ #### 1a. Spawn Explorer A — Affected-Asset Discovery + Per-Asset Trio Blast Radius (parallel, same message as 1b)
133
180
 
134
181
  Delegate via Agent tool (`subagent_type: "explorer-agent"`) with this prompt:
135
182
 
136
183
  ```
137
- You are investigating an existing Pi asset and its Subagent-Assembly-trio blast radius, ahead of a targeted modification. Read-only investigation — do not modify anything.
184
+ You are discovering the set of existing Pi assets that a coordinated repair must change, and tracing each one's Subagent-Assembly-trio blast radius. Read-only investigation — do not modify anything.
138
185
 
139
- ## The Asset Being Modified
140
- Path: {RESOLVED_ASSET_PATH}
141
- Type: {ASSET_TYPE} (one of: skill | prompt-template | agent | extension)
142
- Name: {ASSET_NAME}
143
- Action: modify
186
+ ## Problem Statement (free-form from the user)
187
+ {PROBLEM_INPUT}
144
188
 
145
- ## Modification Request
146
- {MOD_REQUEST}
189
+ ## Intake Shape: {INTAKE_SHAPE}
190
+ {If INTAKE_SHAPE == "single-asset-shortcut", append:}
191
+ **Pre-resolved seed candidate** (the user invoked with the legacy single-asset shortcut shape — START with this entry, then scan for ADDITIONAL affected trio consumers; you MAY append, and you MAY flag this seed wrong if the problem description points elsewhere):
192
+ - path: {AFFECTED_ASSETS[0].resolved_path}
193
+ type: {AFFECTED_ASSETS[0].asset_type}
194
+ name: {AFFECTED_ASSETS[0].asset_name}
195
+ proposed modification: {AFFECTED_ASSETS[0].proposed_modification}
147
196
 
148
197
  ## Your Research Tasks
149
- 1. **Read the FULL target file** at {RESOLVED_ASSET_PATH}. If it is an extension, ALSO read every co-imported file in the same directory (e.g. `agents.ts`, helper modules) — note each co-import by exact path.
150
- 2. **Trace trio consumers** (the Subagent Assembly trio is: extension agent `.md` prompt-template preset). Apply the rule for THIS asset's Pi type:
198
+
199
+ 1. **Discover the affected asset set.** From the problem statement above (and the seed candidate if present), identify EVERY Pi asset that the coordinated repair must touch. Cast a wide net:
200
+ - Grep `.pi/` AND `.claude/` for keywords drawn from the problem statement (feature names, command names, tool names, agent names, behavior descriptions).
201
+ - Read candidate Pi assets (`.pi/extensions/*/index.ts`, `.pi/agents/*.md`, `.pi/prompts/*.md`, `.pi/skills/*/SKILL.md`).
202
+ - Apply the **Subagent Assembly trio** rule: if the repair touches one asset in a trio (extension ← agent `.md` ← prompt-template preset), the other two are likely affected too. Inspect each candidate trio.
203
+ - The discovered set is typically 1–4 assets. A single-asset discovery is the trivial N = 1 case and is fully expected.
204
+ 2. **For each discovered asset, derive the asset record:**
205
+ - `resolved_path` — the exact project-relative or absolute path to the asset file (a `.ts`/`index.ts` for an extension; a `.md` for an agent or prompt-template; the containing dir's `SKILL.md` for a skill).
206
+ - `asset_type` — one of: skill | prompt-template | agent | extension (derived from the path location).
207
+ - `asset_name` — the directory name (extensions/skills) or the `.md` stem (agents/prompt-templates).
208
+ - `kebab_slug` — kebab-case of `asset_name` (lowercase, non-alphanumeric → hyphens).
209
+ - `proposed_modification` — a one-paragraph specific description of what THIS asset must change to address the problem statement (drawn from the problem statement and any seed-candidate REMAINDER text).
210
+ 3. **For each discovered asset, read it FULLY and trace its trio consumers.** If it is an extension, ALSO read every co-imported file in the same directory (e.g. `agents.ts`, helper modules). Apply the rule for that asset's Pi type:
151
211
  - **extension** (`.ts`/`index.ts` + co-imported `agents.ts`): trace (a) every agent `.md` whose dispatch path the extension registers (single/parallel/chain consumers of its registered tool); (b) every prompt-template preset that instructs the model to call the extension's registered tool/command; (c) any co-imported helper module (e.g. `agents.ts` → `discoverAgents`) and every `pi.on()` lifecycle consumer.
152
212
  - **agent `.md`**: trace (a) the extension(s) that dispatch it (discovered by `name`/`description`); (b) prompt-template presets that name it in a `subagent` task; (c) chain-mode steps that pass it `{previous}`.
153
213
  - **prompt-template preset**: trace (a) the extension tool/command it instructs the model to call; (b) the agent `.md` files it dispatches via that tool; (c) any sibling preset sharing the same registered tool.
154
214
  - **Pi skill**: trace `.pi/settings.json` `skills` arrays, `--skill` flags, and any prompt/agent body referencing the skill by `/skill:name`.
155
- Use Grep across `.pi/` AND `.claude/` for the asset name and any registered tool/command name to find every consumer. Enumerate each consumer by exact path.
156
- 3. **Size audit**: run `wc -l` on the target file (and each co-import). Flag any file >300 lines as WARNING and >500 lines as CRITICAL (a large file modified in place is a high in-place-modification risk — call this out explicitly).
157
- 4. **Flag high-risk changes**: a registered-tool signature change, a dispatch-`name`/`description` change an extension discovers by, a chain-mode `{previous}` contract change, content removal, or a vendored asset that would diverge from upstream.
215
+ Use Grep across `.pi/` AND `.claude/` for the asset name and any registered tool/command name. Enumerate each consumer by exact path. **A trio consumer that is ITSELF in the change set is also noted as such** — these are the cross-asset coordination links the validator's coordination-consistency check will verify.
216
+ 4. **Per-asset size audit**: run `wc -l` on each discovered asset (and its co-imports). Flag any file >300 lines as WARNING and >500 lines as CRITICAL.
217
+ 5. **Per-asset blast radius**: classify each asset Isolated (target only) / Contained (1–2 trio consumers; change stays within one render/dispatch path) / Broad (3+ trio consumers, OR a registered-tool signature change). Then aggregate a **set-level blast radius**: take the MAX over the per-asset bands (any Broad set is Broad; otherwise any Contained set is Contained; otherwise Isolated).
218
+ 6. **Flag high-risk changes** (per asset and across the set): a registered-tool signature change, a dispatch-`name`/`description` change an extension discovers by, a chain-mode `{previous}` contract change, content removal, or a vendored asset that would diverge from upstream.
219
+ 7. **Coordination notes** (set-level): any cross-asset dependency the design must respect (e.g. "the extension's new dispatch path must match the agent's expected `name`; the prompt-template preset must instruct the model to call the new tool spelling"). These notes are consumed by the validator's coordination-consistency check.
158
220
 
159
221
  ## Output:
160
222
  Write your findings to: {WORK_DIR}/explorer_a_findings.md
161
223
 
162
224
  Use exactly this structure:
163
225
 
164
- ## Direct Changes
165
- {The Pi asset file(s) the modification will change, with the exact sections/lines the request implies}
226
+ ## Discovered Affected Asset Set
227
+ {A numbered list, one entry per discovered Pi asset, in build-order (extensions/skills first as foundations, then agents, then prompt-templates adjust if the dependency graph dictates otherwise). Each entry:}
228
+
229
+ ### Asset {N}: {asset_name}
230
+ - resolved_path: {path}
231
+ - asset_type: {skill | prompt-template | agent | extension}
232
+ - asset_name: {name}
233
+ - kebab_slug: {kebab-slug}
234
+ - proposed_modification: {one paragraph}
235
+ - size: {wc -l result} {WARNING if >300; CRITICAL if >500}
166
236
 
167
- ## Affected Consumers
168
- {Every trio consumer of the modified asset, per the rule for its Pi type above, with a risk note for each — enumerate each by exact path}
237
+ ## Per-Asset Trio Consumers
238
+ {For each asset above, the trio consumers traced under §2.2 of pi-asset-modification-guide, by exact path, with a risk note for each. Mark a consumer "(in change set)" if it is ALSO a discovered asset above these are the coordination links.}
169
239
 
170
- ## Blast Radius
171
- {Isolated (target only) / Contained (1–2 trio consumers; change stays within one render/dispatch path) / Broad (3+ trio consumers OR a registered-tool signature change)}
172
- {Total number of trio dispatch/render paths affected}
173
- {Any high-risk changes flagged, including any >300/>500-line in-place-modification risk}
240
+ ## Per-Asset Blast Radius
241
+ {For each asset: Isolated / Contained / Broad, plus the count of trio dispatch/render paths affected}
242
+
243
+ ## Set-Level Blast Radius
244
+ {Aggregate band: Isolated (all assets Isolated) / Contained / Broad}
245
+ {Total number of distinct trio dispatch/render paths affected across the set}
246
+ {Any high-risk changes flagged across the set, including any >300/>500-line in-place-modification risk}
247
+
248
+ ## Coordination Notes
249
+ {Cross-asset dependencies the coordinated design must respect — bullet list. "None" if the assets are independently modifiable.}
174
250
 
175
251
  ## File Size Audit
176
252
  {Each file read with its line count; WARNING >300, CRITICAL >500}
@@ -183,13 +259,16 @@ Write using the Write tool. Return the file path when done.
183
259
  Delegate via Agent tool (`subagent_type: "explorer-agent"`) with this prompt:
184
260
 
185
261
  ```
186
- You are researching the current LOCAL Pi documentation for a targeted modification of an existing Pi asset. Read-only investigation.
262
+ You are researching the current LOCAL Pi documentation for a coordinated repair of one or more existing Pi assets. Read-only investigation.
263
+
264
+ ## Problem Statement (free-form from the user)
265
+ {PROBLEM_INPUT}
187
266
 
188
- ## What Is Being Modified (a Pi asset)
189
- Type: {ASSET_TYPE} (one of: skill | prompt-template | agent | extension)
267
+ ## Likely Asset Types Involved
268
+ Explorer A (running in parallel) is discovering the affected-asset set. You do not have its findings yet. Cover the asset TYPES that the problem statement most plausibly touches — research the local Pi docs for EACH of those types. Err on the side of breadth: if the problem statement mentions agents, prompts, and a tool, research all three. The four Pi asset types are: skill | prompt-template | agent | extension.
190
269
 
191
- ## Modification Request
192
- {MOD_REQUEST}
270
+ {If INTAKE_SHAPE == "single-asset-shortcut", append:}
271
+ **Hint:** the user named `{AFFECTED_ASSETS[0].asset_type}` "{AFFECTED_ASSETS[0].asset_name}" as the primary candidate; lead with that type's docs, but still cover any other types the problem statement implicates.
193
272
 
194
273
  ## Your Research Tasks
195
274
  1. **Discover the on-disk Pi docs** (NEVER hardcode a version — the path is Node-version-embedded):
@@ -197,8 +276,8 @@ Type: {ASSET_TYPE} (one of: skill | prompt-template | agent | extension)
197
276
  - Fallbacks if that path does not exist: project-local `./node_modules/@earendil-works/pi-coding-agent`; confirm install with `npm ls -g @earendil-works/pi-coding-agent`.
198
277
  - The canonical import/package scope is `@earendil-works/*`. Treat any `@mariozechner/*` reference as stale/defect. The Pi version is informational only — never pin it.
199
278
  2. **Route to the relevant docs** using `.claude/skills/pi-primitives/reference/pi-doc-map.md`:
200
- - Read the doc-map to find which files under `$PKG/docs/` (and `$PKG/examples/`) correspond to the API the modification touches for a {ASSET_TYPE}.
201
- - Read ONLY the doc files relevant to the change. If ANY agent/orchestration/dispatch/rendering is involved, ALWAYS ALSO read the `examples/extensions/subagent/` example (README.md, index.ts, agents.ts, agents/*.md, prompts/*.md).
279
+ - Read the doc-map to find which files under `$PKG/docs/` (and `$PKG/examples/`) correspond to the API(s) the repair touches for each implicated Pi asset type.
280
+ - Read ONLY the doc files relevant to the implicated types. If ANY agent/orchestration/dispatch/rendering is involved, ALWAYS ALSO read the `examples/extensions/subagent/` example (README.md, index.ts, agents.ts, agents/*.md, prompts/*.md).
202
281
  - Note: `$PKG/docs/agents.md` does NOT exist — agent guidance is in the subagent example and the doc-map's routing table.
203
282
 
204
283
  ## Output:
@@ -209,8 +288,11 @@ Use exactly this structure:
209
288
  ## Pi Docs Discovery
210
289
  {The resolved $PKG path, which fallback (if any) was used, npm ls -g confirmation}
211
290
 
212
- ## Relevant Pi Documentation Findings
213
- {What the local Pi docs say about the API/primitive the modification touches confirmed current patterns, APIs, conventions}
291
+ ## Asset Types Covered
292
+ {The bullet list of Pi asset types you researched in this pass, with a one-line rationale linking each back to the problem statement.}
293
+
294
+ ## Per-Type Pi Documentation Findings
295
+ {One subsection per covered type — what the local Pi docs say about the API/primitive the repair touches for that type. Confirmed current patterns, APIs, conventions.}
214
296
 
215
297
  ## Subagent / Orchestration / Rendering Notes
216
298
  {If applicable: findings from examples/extensions/subagent/ and any @earendil-works/pi-tui rendering API the change touches}
@@ -218,43 +300,73 @@ Use exactly this structure:
218
300
  ## Pi Gotchas Confirmed
219
301
  {references/ plural; mandatory description; NO skills: on Pi agents; jiti/no-build; @earendil-works/*; text-only prompt-templates}
220
302
 
221
- ## Recommendations for This Modification
222
- {Specific recommendations for the {ASSET_TYPE} change based on the local Pi docs}
303
+ ## Recommendations for the Coordinated Repair
304
+ {Per-type recommendations the architect can apply to the multi-phase plan. If only one type is plausibly involved, that section will have only one entry — fully valid.}
223
305
 
224
306
  Write using the Write tool. Return the file path when done.
225
307
  ```
226
308
 
227
- #### 1c. Verify Outputs
309
+ #### 1c. Verify Outputs and Populate AFFECTED_ASSETS
310
+
228
311
  After both Agent calls return:
229
312
  1. Read `{WORK_DIR}/explorer_a_findings.md` — verify it exists and has >10 lines.
230
313
  2. Read `{WORK_DIR}/explorer_b_findings.md` — verify it exists and has >10 lines.
231
314
  3. If an agent returned content inline instead of writing, Write that content to the expected path using the Write tool.
232
315
  4. If an output is missing entirely, warn but proceed: `WARNING: {filename} was not produced. Design step will proceed with available findings only.`
233
-
234
- #### 1d. Confirmation Gate B Post-Research Scope
316
+ 5. **Parse the "Discovered Affected Asset Set" section of `explorer_a_findings.md`.** For each numbered entry, build a record `{resolved_path, asset_type, asset_name, kebab_slug, proposed_modification, trio_impact_summary}` (the `trio_impact_summary` is a one-paragraph synthesis of Explorer A's "Per-Asset Trio Consumers" and "Per-Asset Blast Radius" sections for that asset).
317
+ 6. **Reconcile with the shortcut seed (if any).** If `INTAKE_SHAPE == "single-asset-shortcut"` AND `AFFECTED_ASSETS` already contains the seed entry from Step 0b: if Explorer A's discovered set includes that path, KEEP the explorer's enriched record (it has the trio impact). If Explorer A flagged the seed as wrong, REMOVE the seed and adopt the explorer's set. Always REPLACE `AFFECTED_ASSETS` with the final reconciled list.
318
+ 7. **Set `AFFECTED_ASSETS_COUNT = AFFECTED_ASSETS.length`.**
319
+ 8. **Sanity-check the set.** If `AFFECTED_ASSETS_COUNT == 0`, STOP and engage the user:
320
+ ```
321
+ WARNING: Explorer A discovered no affected Pi assets from the problem statement.
322
+
323
+ Problem: {PROBLEM_INPUT}
324
+ Findings: {WORK_DIR}/explorer_a_findings.md
325
+
326
+ Options:
327
+ - Re-invoke /modify-pi-assets with a more specific problem statement (mention an asset name, command, or behaviour).
328
+ - Re-invoke with the legacy single-asset-shortcut shape: /modify-pi-assets <path> "<request>"
329
+ ```
330
+ Do NOT proceed to Step 1d / Step 2 with an empty change set. If `AFFECTED_ASSETS_COUNT >= 1`, proceed to Step 1d.
331
+ 9. **Compute the per-asset artifact suffix policy** (consumed by Step 5c and beyond):
332
+ - If `AFFECTED_ASSETS_COUNT == 1`: `ARTIFACT_SUFFIX_POLICY = "single-pair"` (no per-asset suffix — `functional_run.ndjson` / `functional_run_regression.ndjson` per `reference/pi-asset-modification-guide.md` §3.3 default).
333
+ - If `AFFECTED_ASSETS_COUNT >= 2`: `ARTIFACT_SUFFIX_POLICY = "per-asset-suffix"` (each asset's artifacts use `_{A.kebab_slug}` suffix per `reference/pi-asset-modification-guide.md` §3.4 "Multi-Asset Coordinated Sets").
334
+
335
+ #### 1d. Confirmation Gate B — Post-Research Scope (Coordinated Change Set Confirmation)
235
336
 
236
337
  If `AUTO_CONFIRM == true` (the `--auto-confirm` flag was set in `$ARGUMENTS`), SKIP this gate entirely, set `GATE_B_RESULT = "skipped (--auto-confirm)"`, and proceed to Step 2.
237
338
 
238
339
  Otherwise read both `{WORK_DIR}/explorer_a_findings.md` and `{WORK_DIR}/explorer_b_findings.md` to populate the summary below, then present and WAIT for the user:
239
340
 
240
341
  ```
241
- RESEARCH SUMMARY
342
+ RESEARCH SUMMARY — COORDINATED CHANGE SET
242
343
 
243
- Target: {RESOLVED_ASSET_PATH} ({ASSET_TYPE} — {ASSET_NAME}, modify)
244
- Modification request: {MOD_REQUEST}
344
+ Problem: {PROBLEM_INPUT}
345
+ Intake shape: {INTAKE_SHAPE}
346
+ Affected Pi assets discovered: {AFFECTED_ASSETS_COUNT}
347
+ Artifact convention: {ARTIFACT_SUFFIX_POLICY} (single-pair when N == 1; per-asset-suffix when N >= 2 — per pi-asset-modification-guide §3.3 default / §3.4 multi-asset extension)
245
348
 
246
- Blast radius (from Explorer A): {Isolated | Contained | Broad}
247
- Key consumers identified (from Explorer A): {bulleted list of consumer paths, or "None — Isolated"}
349
+ Per-asset summary:
350
+ {For each A in AFFECTED_ASSETS:}
351
+ - {A.resolved_path} ({A.asset_type} — {A.asset_name}, modify)
352
+ Proposed modification: {A.proposed_modification}
353
+ Trio impact: {A.trio_impact_summary}
354
+
355
+ Set-level blast radius (from Explorer A): {Isolated | Contained | Broad}
356
+ Coordination notes (from Explorer A): {bulleted list, or "None — assets are independently modifiable"}
248
357
  File-size warnings (from either explorer): {list, or "None"}
249
358
 
250
- Local Pi-doc findings (from Explorer B): {one-line summary of the API/primitive the change touches and any gotchas confirmed}
359
+ Local Pi-doc findings (from Explorer B): {one-line summary of the APIs/primitives the change set touches and any gotchas confirmed; cite per-type findings if the set spans multiple types}
251
360
 
252
- Design direction the architect will pursue next: {one-line restatement of the modification approach the architect will encode into the design spec}
361
+ Design direction the architect will pursue next: {one-line restatement of the coordinated change-set approach the architect will encode into the pi-assets-plan — one phase per affected asset, all with action: modify}
253
362
 
254
363
  Findings files:
255
364
  - {WORK_DIR}/explorer_a_findings.md
256
365
  - {WORK_DIR}/explorer_b_findings.md
257
366
 
367
+ {If INTAKE_SHAPE == "single-asset-shortcut" AND AFFECTED_ASSETS_COUNT > 1, prepend a note:}
368
+ NOTE: The change set has grown from N = 1 (the shortcut seed) to N = {AFFECTED_ASSETS_COUNT}. Confirming this gate accepts the expanded set; respond "revise" with a list of asset paths to keep if you want a smaller set.
369
+
258
370
  Does the research match your expectation? (yes / no / revise — provide corrections that the architect should incorporate)
259
371
  ```
260
372
 
@@ -262,100 +374,107 @@ Does the research match your expectation? (yes / no / revise — provide correct
262
374
 
263
375
  Branches:
264
376
  - **yes** → set `GATE_B_RESULT = "confirmed"` and proceed to Step 2.
265
- - **revise** → capture the user's correction text verbatim, store it as `GATE_B_USER_CORRECTION`, and append it to the architect's prompt in Step 2a (after the existing `## Modification Request` block, under a new `## User Correction From Post-Research Gate` heading). Track revisions; on final confirmation set `GATE_B_RESULT = "revised then confirmed ({N} revisions)"`.
377
+ - **revise** → capture the user's correction text verbatim, store it as `GATE_B_USER_CORRECTION`, and append it to the architect's prompt in Step 2a (after the existing `## Coordinated Change Set` block, under a new `## User Correction From Post-Research Gate` heading). The user may also narrow `AFFECTED_ASSETS` by listing the paths to KEEP — if so, filter `AFFECTED_ASSETS` to that subset, recompute `AFFECTED_ASSETS_COUNT` and `ARTIFACT_SUFFIX_POLICY` (per Step 1c §9), then re-present this gate. Track revisions; on final confirmation set `GATE_B_RESULT = "revised then confirmed ({N} revisions)"`.
266
378
  - **no** → set `GATE_B_RESULT = "stopped at gate"`. STOP execution with no design, no build performed. Present:
267
379
  ```
268
380
  STOPPED at post-research gate. Inspect the findings files:
269
381
  - {WORK_DIR}/explorer_a_findings.md
270
382
  - {WORK_DIR}/explorer_b_findings.md
271
- Re-invoke `/modify-pi-assets` with a refined modification request when ready.
383
+ Re-invoke `/modify-pi-assets` with a refined problem statement when ready.
272
384
  ```
273
385
 
274
- ### Step 2: Plan the Modification (Pi Architect via Agent Tool)
386
+ ### Step 2: Plan the Coordinated Change Set (Pi Architect via Agent Tool)
275
387
 
276
- Spawn the Pi architect to produce a complete `action: modify` design spec. It reads the explorer findings from disk and writes a build-ready spec to disk.
388
+ Spawn the Pi architect to produce a complete multi-phase `pi-assets-plan` whose every phase carries `action: modify`. One phase per affected asset. The architect reads the explorer findings from disk and writes a build-ready plan to disk.
277
389
 
278
390
  #### 2a. Spawn pi-architect-agent
279
391
 
280
392
  Delegate via Agent tool (`subagent_type: "pi-architect-agent"`) with this prompt:
281
393
 
282
394
  ```
283
- You are designing a detailed specification for a MODIFICATION to an existing Pi asset. You MUST write the specification directly to disk.
395
+ You are designing a phased coordinated change-set plan for a MODIFICATION across one or more existing Pi assets. You MUST write the plan directly to disk.
284
396
 
285
397
  ## Required First Step (teammate gotcha — do this before designing)
286
398
  Invoke the `pi-primitives` skill using the Skill tool, AND Read `.claude/skills/brainstorm-plan/workflows/pi-primitive-creation.md`. If you were spawned as a team teammate, your `skills:` frontmatter was NOT auto-applied — you MUST self-arm `pi-primitives` via the Skill tool now. (On the normal Agent path your `skills:` is already injected; invoking it again is harmless and simply confirms it is loaded.)
287
399
 
288
400
  ## Save Path
289
- Write the complete specification to: {WORK_DIR}/design_spec.md
290
- Use the Write tool.
291
-
292
- ## What You're Designing (a Pi-asset MODIFICATION)
293
- Type: {ASSET_TYPE} (one of: skill | prompt-template | agent | extension)
294
- Name: {ASSET_NAME}
295
- Action: modify
296
- Target file: {RESOLVED_ASSET_PATH}
297
-
298
- ## Modification Request
299
- {MOD_REQUEST}
401
+ Write the complete plan to: {WORK_DIR}/design_spec.md
402
+ Use the Write tool. (Filename intentionally preserved as `design_spec.md` so downstream validator / builder paths are unchanged — the FILE CONTENT is the `pi-assets-plan` document format defined by `.claude/skills/pi-primitives/templates/pi-assets-plan-template.md`.)
403
+
404
+ ## What You're Designing (a Coordinated Pi Repair)
405
+ Action across every phase: modify (this command NEVER creates).
406
+ Affected-asset count: {AFFECTED_ASSETS_COUNT} (one phase per asset).
407
+ Artifact convention to encode in each phase's Test Scenario: {ARTIFACT_SUFFIX_POLICY}
408
+ - "single-pair" (N == 1): name the regression artifacts `functional_run_regression.ndjson` / `functional_final_message_regression.md` (the pi-asset-modification-guide §3.3 default).
409
+ - "per-asset-suffix" (N >= 2): name each phase's artifacts `functional_run_{kebab_slug}.ndjson` / `functional_final_message_{kebab_slug}.md` and `functional_run_{kebab_slug}_regression.ndjson` / `functional_final_message_{kebab_slug}_regression.md` (the pi-asset-modification-guide §3.4 "Multi-Asset Coordinated Sets" extension).
410
+
411
+ ## Problem Statement (free-form from the user)
412
+ {PROBLEM_INPUT}
413
+
414
+ ## Coordinated Change Set (one entry per affected Pi asset — one phase per entry)
415
+ {For each A in AFFECTED_ASSETS:}
416
+ - resolved_path: {A.resolved_path}
417
+ asset_type: {A.asset_type}
418
+ asset_name: {A.asset_name}
419
+ kebab_slug: {A.kebab_slug}
420
+ proposed_modification: {A.proposed_modification}
421
+ trio_impact_summary: {A.trio_impact_summary}
300
422
 
301
423
  ## Research Findings (Read both before designing)
302
- - Explorer A (target + trio blast radius): {WORK_DIR}/explorer_a_findings.md
303
- - Explorer B (local Pi docs): {WORK_DIR}/explorer_b_findings.md
424
+ - Explorer A (affected-asset discovery + per-asset trio blast radius + coordination notes): {WORK_DIR}/explorer_a_findings.md
425
+ - Explorer B (local Pi docs, per implicated type): {WORK_DIR}/explorer_b_findings.md
304
426
 
305
427
  ## Your Task
306
- Produce a COMPLETE `pi-asset-design-spec` for this MODIFICATION, detailed enough for pi-meta-agent to apply it without further research. You MUST:
428
+ Produce a COMPLETE multi-phase plan using the `pi-assets-plan` template (`.claude/skills/pi-primitives/templates/pi-assets-plan-template.md`) one phase per affected asset, EVERY phase has `action: modify`. The plan must be detailed enough for pi-meta-agent to apply every phase without further research. You MUST:
307
429
 
308
- 1. **Apply the Pi Asset Modification Guide.** Invoke `pi-primitives` (above), then route via its SKILL.md to `reference/pi-asset-modification-guide.md` and apply:
309
- - **§2 Trio Blast-Radius Analysis** — reproduce the `TRIO BLAST-RADIUS ANALYSIS` block (Direct Changes / Affected Consumers / Blast Radius) using Explorer A's traced consumers.
310
- - **§4 Authored-vs-Vendored Preservation** — decide which preservation regime governs (authored byte-for-byte Read-then-Edit/MultiEdit vs vendored byte-parity, where a divergence is a consciously documented fork) and state it in the spec.
311
- - **§5 `action: modify` Design-Spec Conventions** — the spec MUST contain all four modify-specific additions: **Current State**, **Preserved (byte-for-byte)**, **Trio Impact**, **Dual-criterion Test Scenario**.
312
- - **§3 Regression Discipline (the AUTHORITATIVE DEFINER of the dual-criterion Test Scenario rule and the `_regression` artifact convention)** — the Test Scenario MUST carry TWO Success-Criterion groups: a **New-capability criterion** (proves the change does what the request asked) AND a **Regression criterion** (proves the asset's PRESERVED original capability still works, exercised the same headless way it was before). Name the `_regression` capture artifacts: `functional_run_regression.ndjson` / `functional_final_message_regression.md`. Omitting the regression criterion is a planning defect. Do NOT attribute the regression rule or `_regression` artifacts to `pi-testing-validation-guide.md` — that file has NO regression content; it is cross-referenced ONLY for `## Functional Testing` and `## The Five Elements`.
430
+ 1. **Apply the Pi Asset Modification Guide PER PHASE.** Invoke `pi-primitives` (above), then route via its SKILL.md to `reference/pi-asset-modification-guide.md` and apply for EACH phase:
431
+ - **§2 Trio Blast-Radius Analysis** — reproduce the per-asset TRIO BLAST-RADIUS ANALYSIS block (Direct Changes / Affected Consumers / Blast Radius) using Explorer A's traced consumers FOR THAT PHASE'S ASSET. A trio consumer that is itself another phase in this plan is marked "(in change set — see Phase {M})" — these are the coordination links.
432
+ - **§4 Authored-vs-Vendored Preservation** — decide per phase which preservation regime governs (authored byte-for-byte Read-then-Edit/MultiEdit vs vendored byte-parity, where a divergence is a consciously documented fork) and state it in that phase.
433
+ - **§5 `action: modify` Design-Spec Conventions** — every phase MUST contain all four modify-specific additions in its Design Brief: **Current State**, **Preserved (byte-for-byte)**, **Trio Impact**, plus the **Dual-criterion Test Scenario** in the phase's Test Scenario field.
434
+ - **§3 Regression Discipline (the AUTHORITATIVE DEFINER of the dual-criterion Test Scenario rule)** — every phase's Test Scenario MUST carry TWO Success-Criterion groups: a **New-capability criterion** AND a **Regression criterion** (proves THAT phase's asset's PRESERVED original capability still works). Name the `_regression` capture artifacts per the {ARTIFACT_SUFFIX_POLICY} above. Omitting the regression criterion is a planning defect. Do NOT attribute the regression rule or `_regression` artifacts to `pi-testing-validation-guide.md` — that file has NO regression content; it is cross-referenced ONLY for `## Functional Testing` and `## The Five Elements`. The per-asset suffix variant is defined by pi-asset-modification-guide §3.4 "Multi-Asset Coordinated Sets".
313
435
  2. **Apply the Model Portability principle from `pi-primitives` by name** (`## Model Portability`): never introduce or carry over a provider-specific `model:` pin on a Pi agent unless an explicit, justified, declared exception applies.
314
- 3. **Follow the modification request exactly** expand it into full implementation detail without contradicting it. Use Explorer B's local Pi-doc findings for the current API the change touches.
436
+ 3. **Order the phases for dependency safety.** Apply Dependency Ordering (from `pi-primitives` system-design guide): if Phase X's modification depends on Phase Y's modification being in place (e.g. an agent's new dispatch contract assumes the extension's registered tool already accepts the new shape), order Y before X. State each phase's `**Dependencies**:` line accordingly. Single-phase plans always have `**Dependencies**: None`.
437
+ 4. **Encode Explorer A's Coordination Notes** as cross-phase links: any cross-asset dependency the design must respect goes in the relevant phase's Design Brief AND in `## 5. Integration Vision`.
438
+ 5. **Follow the per-phase modification requests exactly** — expand each into full implementation detail without contradicting Explorer A. Use Explorer B's local Pi-doc findings for the current API each phase touches.
439
+ {If GATE_B_USER_CORRECTION is set, append:}
440
+
441
+ ## User Correction From Post-Research Gate
442
+ {GATE_B_USER_CORRECTION}
443
+
444
+ ## Plan Format (pi-assets-plan template — write the full document)
315
445
 
316
- ## Specification Format
317
- Write the spec with this structure:
446
+ Use the format in `.claude/skills/pi-primitives/templates/pi-assets-plan-template.md` VERBATIM. The frontmatter MUST be:
318
447
 
319
448
  ---
320
- type: pi-asset-design-spec
449
+ type: pi-assets-plan
321
450
  task: modify-pi-assets
322
- asset-type: {ASSET_TYPE}
323
- asset-name: {ASSET_NAME}
324
- action: modify
451
+ version: V1
325
452
  status: draft
326
453
  date: {current date}
454
+ phases: {AFFECTED_ASSETS_COUNT}
327
455
  ---
328
456
 
329
- # Design Specification: {ASSET_NAME} (modify)
330
-
331
- ## Overview
332
- [What this modification does and why, 2-3 sentences]
333
-
334
- ## Current State
335
- [The exact target file and the exact sections / line ranges that change]
457
+ Plan-level sections (exact headings, in order): `## 1. Objective`, `## 2. Existing Asset Landscape`, `## 3. Asset Inventory`, `## 4. Phases`, `## 5. Integration Vision`, `## 6. Key Considerations`.
336
458
 
337
- ## Preserved (byte-for-byte)
338
- [The sections explicitly NOT changed, per the §4 governing regime — name the regime: authored byte-for-byte OR vendored byte-parity/documented fork]
459
+ In `## 3. Asset Inventory`, populate the "Modified Assets" table with EVERY entry from AFFECTED_ASSETS; the "New Assets" table is empty (this command NEVER creates).
339
460
 
340
- ## Detailed Design
341
- [Complete change specification: exact content to add/change, where, how it extends the existing code path; what NOT to change]
461
+ Each phase under `## 4. Phases` MUST have, in order:
462
+ - `**Asset**: {asset_type} {asset_name} (modify)` (em-dash separator)
463
+ - `**Dependencies**:` (None, or a comma-separated list of prior phase numbers / asset names)
464
+ - `**Objective**:` (what this phase's modification accomplishes and why)
465
+ - `**Design Brief**:` — a bullet list that MUST contain the FOUR modify-specific subsections from pi-asset-modification-guide §5, clearly labeled:
466
+ - **Current State:** the exact target file and the exact sections / line ranges that change.
467
+ - **Preserved (byte-for-byte):** the sections explicitly NOT changed (per the §4 governing regime — name the regime: authored byte-for-byte OR vendored byte-parity/documented fork).
468
+ - **Detailed Design:** complete change specification — exact content to add/change, where, how it extends the existing code path; what NOT to change.
469
+ - **Trio Impact:** the §2 TRIO BLAST-RADIUS ANALYSIS block (## Direct Changes / ## Affected Consumers / ## Blast Radius). A trio consumer that is itself another phase in this plan is marked "(in change set — see Phase {M})".
470
+ - `**UX/UI Representation**:` — per the Pi `pi-assets-plan-template.md` rule: for an `extension` phase, the concrete in-action UX or the exact waiver string `no UI/UX component to be added, functionality only`; for non-extension phases (skill/prompt-template/agent), `N/A (not an extension)`.
471
+ - `**Test Scenario**:` — the five elements (Setup / Action / Expected) with a **Success Criteria** checkbox list that MUST contain BOTH:
472
+ - `[ ] Criterion A (new capability): {one-line description}` — captured to `functional_run{SUFFIX}.ndjson` / `functional_final_message{SUFFIX}.md` (where SUFFIX is empty under single-pair, `_{kebab_slug}` under per-asset-suffix).
473
+ - `[ ] Criterion B (regression — original capability preserved): {one-line description}` — captured to `functional_run{SUFFIX}_regression.ndjson` / `functional_final_message{SUFFIX}_regression.md`.
342
474
 
343
- ## Trio Impact
344
- [The §2 TRIO BLAST-RADIUS ANALYSIS block: ## Direct Changes / ## Affected Consumers / ## Blast Radius]
475
+ `## 5. Integration Vision`: trace how all phases compose to address the problem statement; cite each Coordination Note from Explorer A.
345
476
 
346
- ## Conventions Applied
347
- [Which Pi patterns this follows and why; the preservation regime; Model Portability]
348
-
349
- ## Research Observations
350
- [Anything from the explorer findings that influenced the design or that the builder should know]
351
-
352
- ## Test Scenario (dual-criterion)
353
- [The five elements (Setup, Action, Input, Expected Output) PLUS a Success Criteria section containing BOTH:
354
- - Criterion A (NEW capability): proves the change works
355
- - Criterion B (REGRESSION): proves the original capability still works, exercised the same headless way, captured to functional_run_regression.ndjson / functional_final_message_regression.md]
356
-
357
- ## Test Readiness
358
- [How this design satisfies each success criterion — both A and B]
477
+ `## 6. Key Considerations`: risks, open questions, declared exceptions (e.g. a vendored fork declaration), and any provider-pin justification.
359
478
 
360
479
  Write using the Write tool. Return the file path when done.
361
480
  ```
@@ -363,10 +482,13 @@ Write using the Write tool. Return the file path when done.
363
482
  #### 2b. Verify Output
364
483
  After the Agent returns:
365
484
  1. Read `{WORK_DIR}/design_spec.md`.
366
- 2. Verify YAML frontmatter has `type: pi-asset-design-spec` AND `action: modify`.
367
- 3. Verify all required sections are present: Overview, Current State, Preserved (byte-for-byte), Detailed Design, Trio Impact, Conventions Applied, Research Observations, Test Scenario (dual-criterion), Test Readiness.
368
- 4. If the architect returned content inline, Write it to the expected path using the Write tool.
369
- 5. If missing entirely, warn: `WARNING: design_spec.md was not produced by the architect. Manual design is required.` (treat as a Step-3 FAIL trigger).
485
+ 2. Verify YAML frontmatter has `type: pi-assets-plan` AND `task: modify-pi-assets` AND `phases: {AFFECTED_ASSETS_COUNT}`.
486
+ 3. Verify the plan-level section headings are present in order: `## 1. Objective`, `## 2. Existing Asset Landscape`, `## 3. Asset Inventory`, `## 4. Phases`, `## 5. Integration Vision`, `## 6. Key Considerations`.
487
+ 4. Verify the `## 3. Asset Inventory` "Modified Assets" table has exactly {AFFECTED_ASSETS_COUNT} rows and the "New Assets" table is empty (this command NEVER creates).
488
+ 5. Verify `## 4. Phases` contains exactly {AFFECTED_ASSETS_COUNT} `### Phase {N}:` headings, in order.
489
+ 6. For EACH phase, verify it contains, in order: `**Asset**:` (with em-dash, `(modify)`), `**Dependencies**:`, `**Objective**:`, `**Design Brief**:`, `**UX/UI Representation**:`, `**Test Scenario**:`. The Design Brief must contain the four modify-specific subsections labeled **Current State:**, **Preserved (byte-for-byte):**, **Detailed Design:**, **Trio Impact:**. The Test Scenario must contain BOTH Criterion A (new capability) AND Criterion B (regression — original capability preserved) checkboxes that name the `_regression` artifact filenames per `ARTIFACT_SUFFIX_POLICY`.
490
+ 7. If the architect returned content inline, Write it to the expected path using the Write tool.
491
+ 8. If missing entirely, or any verification above fails, warn: `WARNING: design_spec.md was not produced correctly by the architect. ({summary of which check failed}) Treating as a Step-3 FAIL trigger.`
370
492
 
371
493
  ### Step 3: Validate the Plan (Pi Validator — Correction Loop)
372
494
 
@@ -374,83 +496,93 @@ Validate the `action: modify` design spec. On FAIL, the pi-architect-agent revis
374
496
 
375
497
  Initialize: `DESIGN_VALIDATION_CYCLE = 1`, `DESIGN_MAX_CYCLES = 3`.
376
498
 
377
- #### 3a. Assemble the Design Validation Checklist
499
+ #### 3a. Assemble the Design Validation Checklist (per-asset multiplied + set-level coordination)
500
+
501
+ Assemble a numbered checklist that multiplies per-asset checks over every entry in `AFFECTED_ASSETS`, plus a single set-level coordination-consistency check. This text is pasted VERBATIM into the validator prompt in 3b.
378
502
 
379
- Assemble a numbered checklist: common checks 1–5 + the type-specific checks 6–8 for ASSET_TYPE + the modification add-on check 9 + the modify-specific dual-criterion check 10. This text is pasted VERBATIM into the validator prompt in 3b.
503
+ **Plan-level common checks (run ONCE for the whole plan):**
380
504
 
381
- **Common checks (all Pi asset types):**
505
+ 1. **Plan format conformance** — The file at `{WORK_DIR}/design_spec.md` is a valid `pi-assets-plan` document: frontmatter `type: pi-assets-plan`, `task: modify-pi-assets`, `phases: {AFFECTED_ASSETS_COUNT}`; plan-level sections `## 1. Objective` … `## 6. Key Considerations` present in order; `## 3. Asset Inventory` has exactly {AFFECTED_ASSETS_COUNT} rows in the "Modified Assets" table and zero rows in "New Assets"; `## 4. Phases` has exactly {AFFECTED_ASSETS_COUNT} `### Phase {N}:` headings. PASS if all hold. FAIL otherwise.
506
+ 2. **Three-layer architecture compliance** — The plan respects the layer model across every phase (knowledge in skills, worker behavior in agents/extensions, workflow orchestration in prompt-templates). PASS if no layer violations across the set. FAIL if any phase violates the layer model.
507
+ 3. **Referenced assets exist** — Every skill, agent, command, extension, or prompt-template referenced in the plan (across all phases AND in `## 5. Integration Vision`) exists in `.claude/` or `.pi/`. Verify each with Glob/Grep. PASS if all resolve. FAIL if any does not exist.
508
+ 4. **Plan satisfies the problem statement** — Read the problem statement: {PROBLEM_INPUT}. Read `## 1. Objective`, every phase's `**Objective**:`, and `## 5. Integration Vision`. PASS if the coordinated change set clearly addresses the problem. FAIL if it diverges or only partially covers it.
509
+ 5. **Set-level dependency ordering** — Phases are ordered such that for every phase X, every phase listed in X's `**Dependencies**:` line appears before X. PASS if dependency ordering is valid. FAIL otherwise.
382
510
 
383
- 1. **Three-layer architecture compliance** — The design spec respects the layer model (knowledge in skills, worker behavior in agents/extensions, workflow orchestration in prompt-templates). Read the design spec's Detailed Design. PASS if no layer violations. FAIL if any layer violation.
384
- 2. **Referenced assets exist** — Every skill, agent, command, extension, or prompt-template referenced in the spec exists in `.claude/` or `.pi/`. Verify each with Glob/Grep. PASS if all resolve. FAIL if any does not exist.
385
- 3. **Design satisfies the modification request** — Read the modification request: {MOD_REQUEST}. Read the spec's Overview and Detailed Design. PASS if the design clearly addresses the request. FAIL if it diverges or only partially covers it.
386
- 4. **Test scenario is achievable** — Read the spec's Test Scenario and Test Readiness. PASS if every success criterion (both the new-capability and regression criteria) has a corresponding explanation in Test Readiness. FAIL if any criterion is unaddressed.
387
- 5. **File structure correctness** — The Current State section names a target file that EXISTS (verify with Glob/Read at {RESOLVED_ASSET_PATH}) and the specified sections are accurate. PASS if the target exists and the sections are accurate. FAIL otherwise.
511
+ **Per-asset checks (RUN FOR EVERY PHASE multiplied across AFFECTED_ASSETS):**
388
512
 
389
- **Pi skill-specific checks (when ASSET_TYPE == "skill"):**
390
- 6. **Progressive disclosure** — SKILL.md detail routed to `references/` (PLURAL), SKILL.md under 500 lines. PASS if so. FAIL otherwise.
391
- 7. **Mandatory description + valid Pi skill frontmatter** — `name` and `description` BOTH present; a missing `description` is a HARD failure. PASS if both present and valid. FAIL otherwise.
392
- 8. **Pi directory-structure conventions** — `references/` (PLURAL) not `reference/`; only recognized subdirs (`references/`, `scripts/`, `assets/`). PASS if so. FAIL otherwise.
513
+ For each entry `A` in AFFECTED_ASSETS (Phase number N, asset_type T, asset_name `A.asset_name`, resolved_path `A.resolved_path`), run the checks numbered 6.N.{1..5}:
393
514
 
394
- **Pi prompt-template-specific checks (when ASSET_TYPE == "prompt-template"):**
395
- 6. **Text-only** A single `.md` with NO orchestration/tool-use language smuggled in. PASS if text-only. FAIL otherwise.
396
- 7. **Valid substitution tokens** `$1`, `$@`, `$ARGUMENTS`, `${@:N}`, `${@:N:L}` well-formed; optional `description`/`argument-hint` well-formed. PASS if valid. FAIL otherwise.
397
- 8. **Single-file, valid command name** Single `.md`, valid slash-command name, discoverable. PASS if valid. FAIL otherwise.
515
+ - **6.N.1 Target file exists.** Read `A.resolved_path`. PASS if the file exists. FAIL otherwise.
516
+ - **6.N.2Phase satisfies its proposed modification.** Read the phase's `**Objective**:` and `**Design Brief**:` `Detailed Design:` subsection. PASS if the design clearly addresses `A.proposed_modification` from the problem statement and Explorer A. FAIL otherwise.
517
+ - **6.N.3 Type-specific structural design check (T-dispatched).** Run the type-specific check below for `T`. PASS / FAIL accordingly.
518
+ - **6.N.4 Modification safety per asset.** Grep for `A.asset_name` (and any registered tool/command name the phase exposes) across `.claude/` and `.pi/`. The phase's Trio Impact section identifies these consumers; the Preserved section delineates unchanged sections; modifications do not break consumer interfaces. PASS if consumer analysis is present and modifications preserve existing interfaces. FAIL otherwise.
519
+ - **6.N.5 — Per-phase dual-criterion Test Scenario** (per `reference/pi-asset-modification-guide.md` §3, the AUTHORITATIVE DEFINER). The phase's `**Test Scenario**:` MUST contain BOTH a Criterion A (new capability) checkbox AND a Criterion B (regression) checkbox, with the regression-capture artifact filenames named per `ARTIFACT_SUFFIX_POLICY`:
520
+ - If `ARTIFACT_SUFFIX_POLICY == "single-pair"`: `functional_run_regression.ndjson` / `functional_final_message_regression.md` (§3.3 default).
521
+ - If `ARTIFACT_SUFFIX_POLICY == "per-asset-suffix"`: `functional_run_{A.kebab_slug}_regression.ndjson` / `functional_final_message_{A.kebab_slug}_regression.md` (§3.4 "Multi-Asset Coordinated Sets").
522
+ An absent regression criterion is a PLANNING DEFECT per §3.1. PASS if BOTH criteria are present and the correctly-named regression artifacts appear. FAIL otherwise.
398
523
 
399
- **Pi agent-specific checks (when ASSET_TYPE == "agent"):**
400
- 6. **Full-prompt body, NO `skills:` field** — A FULL system-prompt body (a ~5-line body is a red flag) and NO `skills:` field in frontmatter. PASS if both. FAIL otherwise.
401
- 7. **Valid Pi agent frontmatter** — `name` AND `description` required; `tools` (if present) comma-separated lowercase Pi names (`read, write, edit, bash, grep, find, ls`); `model` (if present) a valid model ID string. PASS if valid. FAIL otherwise.
402
- 8. **No knowledge-layer leakage via skills** — Required knowledge inlined in the body (Pi agents have no `skills:` mechanism). PASS if inlined. FAIL if it relies on a non-existent Pi `skills:` field.
524
+ **Type-specific design check dispatched by 6.N.3** (apply the bundle for `T`):
403
525
 
404
- **Pi extension-specific checks (when ASSET_TYPE == "extension"):**
405
- 6. **jiti / no-build, correct scope**A raw `.ts` shipped as-is (NO build/`tsc`/bundle), importing from `@earendil-works/pi-coding-agent` (any `@mariozechner/*` is a stale defect FAIL). PASS if jiti/no-build and `@earendil-works/*`. FAIL otherwise.
406
- 7. **Preservation regime correctly declared**The spec correctly states whether the asset is authored (byte-for-byte Read-then-Edit/MultiEdit) or vendored (byte-parity vs `$PKG`; a divergence MUST be declared a conscious documented fork and the byte-parity `diff` must NOT then be expected). PASS if the regime is correctly declared per `reference/pi-asset-modification-guide.md` §4. FAIL otherwise.
407
- 8. **Valid extension API usage**Uses `export default function(pi)` factory + `pi.register*` / `pi.on` APIs; any rendering API the change introduces is current per the local Pi docs. PASS if valid. FAIL otherwise.
526
+ - T == **"skill"**: (a) Progressive disclosure — SKILL.md detail routed to `references/` (PLURAL), SKILL.md under 500 lines; (b) Mandatory description + valid Pi skill frontmatter — `name` and `description` BOTH present (missing `description` is a HARD failure); (c) Pi directory-structure conventions — `references/` (PLURAL) not `reference/`; only recognized subdirs (`references/`, `scripts/`, `assets/`). PASS if all three. FAIL otherwise.
527
+ - T == **"prompt-template"**: (a) Text-onlya single `.md` with NO orchestration/tool-use language smuggled in; (b) Valid substitution tokens — `$1`, `$@`, `$ARGUMENTS`, `${@:N}`, `${@:N:L}` well-formed; optional `description`/`argument-hint` well-formed; (c) Single-file, valid command name single `.md`, valid slash-command name, discoverable. PASS if all three. FAIL otherwise.
528
+ - T == **"agent"**: (a) Full-prompt bodya FULL system-prompt body (a ~5-line body is a red flag); (b) NO `skills:` field in frontmatter; (c) Valid Pi agent frontmatter `name` AND `description` required; `tools` (if present) comma-separated lowercase Pi names (`read, write, edit, bash, grep, find, ls`); `model` (if present) a valid model ID string; (d) No knowledge-layer leakage via skills — required knowledge inlined in the body. PASS if all four. FAIL otherwise.
529
+ - T == **"extension"**: (a) jiti / no-build, correct scope — a raw `.ts` shipped as-is (NO build/`tsc`/bundle), importing from `@earendil-works/pi-coding-agent` (any `@mariozechner/*` is a stale defect → FAIL); (b) Preservation regime correctly declared — the phase correctly states authored byte-for-byte vs vendored byte-parity / documented fork per `reference/pi-asset-modification-guide.md` §4; (c) Valid extension API usage — `export default function(pi)` factory + `pi.register*` / `pi.on` APIs; any rendering API the change introduces is current per the local Pi docs. PASS if all three. FAIL otherwise.
408
530
 
409
- **Modification add-on (always ASSET_ACTION == "modify"):**
410
- 9. **Modification safety** — Grep for {ASSET_NAME} (and any registered tool/command name) across `.claude/` and `.pi/` to identify consumers. The spec's Trio Impact section identifies these consumers and the Preserved section delineates unchanged sections. Modifications do not break interfaces consumers depend on. PASS if consumer analysis is present and modifications preserve existing interfaces. FAIL otherwise.
531
+ **Set-level coordination-consistency check (run ONCE for the whole plan):**
411
532
 
412
- **Modify-specific dual-criterion check (alwaysper `reference/pi-asset-modification-guide.md` §3, the AUTHORITATIVE DEFINER):**
413
- 10. **Dual-criterion Test Scenario present** — The spec's Test Scenario contains BOTH a New-capability Success criterion AND a Regression Success criterion for the asset's original capability, with the `_regression` capture artifacts named (`functional_run_regression.ndjson` / `functional_final_message_regression.md`). An absent regression criterion is a PLANNING DEFECT per `reference/pi-asset-modification-guide.md` §3.1. PASS if BOTH criteria are present and the `_regression` artifacts are named. FAIL if the regression criterion is absent or the `_regression` artifacts are not named.
533
+ 7. **Coordination consistency across the change set** — Cross-asset coordination must be internally consistent. Read Explorer A's "Coordination Notes" (`{WORK_DIR}/explorer_a_findings.md`). For each coordination link the explorer flagged AND for each "(in change set see Phase {M})" cross-reference in any phase's Trio Impact: verify the design on both sides of the link matches (e.g. if an extension's new dispatch path is named `do-foo`, the agent's expected name and the prompt-template's tool-invocation must also be `do-foo`; if an extension's `{previous}` chain contract gains a field, the consuming agent's expected input shape must match). PASS if every cross-asset link is internally consistent. FAIL if any link mismatches. For single-asset plans (`AFFECTED_ASSETS_COUNT == 1`), this check is N/A and recorded "PASS (N/A — single-asset plan)".
414
534
 
415
- Store `DESIGN_CHECK_COUNT = 10`.
535
+ Store `DESIGN_CHECK_COUNT`:
536
+ - Plan-level: 5 checks (1..5).
537
+ - Per-asset: 5 checks (6.N.1..5) × {AFFECTED_ASSETS_COUNT} phases.
538
+ - Set-level coordination: 1 check (7).
539
+ - `DESIGN_CHECK_COUNT = 5 + 5 * AFFECTED_ASSETS_COUNT + 1`. For the single-asset case (N == 1): `DESIGN_CHECK_COUNT = 11` (5 plan + 5 per-asset + 1 coordination(N/A)). For N == 2: 16. For N == 3: 21. Etc.
416
540
 
417
541
  #### 3b. Spawn Design Validator
418
542
 
419
543
  Delegate via Agent tool (`subagent_type: "pi-validator-agent"`) with this prompt:
420
544
 
421
545
  ```
422
- You are validating the design specification for a Pi-asset MODIFICATION: {ASSET_TYPE} "{ASSET_NAME}" (modify).
546
+ You are validating a phased coordinated-change-set plan for a Pi-asset repair across {AFFECTED_ASSETS_COUNT} affected asset(s). Each phase carries action: modify.
423
547
 
424
548
  ## Required First Step (teammate gotcha)
425
- Invoke the `pi-primitives` skill using the Skill tool before validating. If you were spawned as a team teammate, your `skills:` frontmatter was NOT auto-applied — self-arm now. (On the normal Agent path this is already loaded; re-invoking is harmless.) Once `pi-primitives` is loaded, route via its SKILL.md to `reference/pi-asset-modification-guide.md` — §3 is the AUTHORITATIVE DEFINER of the dual-criterion Test Scenario rule (do NOT attribute it to `pi-testing-validation-guide.md`); §2 owns consumer-regression.
549
+ Invoke the `pi-primitives` skill using the Skill tool before validating. If you were spawned as a team teammate, your `skills:` frontmatter was NOT auto-applied — self-arm now. (On the normal Agent path this is already loaded; re-invoking is harmless.) Once `pi-primitives` is loaded, route via its SKILL.md to `reference/pi-asset-modification-guide.md` — §3 (incl. §3.4 "Multi-Asset Coordinated Sets") is the AUTHORITATIVE DEFINER of the dual-criterion Test Scenario rule and BOTH the single-pair AND per-asset-suffix `_regression` artifact conventions (do NOT attribute either to `pi-testing-validation-guide.md`); §2 owns consumer-regression and the per-asset trio blast radius.
426
550
 
427
- ## Design Spec to Validate
428
- Read the design specification at: {WORK_DIR}/design_spec.md
551
+ ## Plan to Validate
552
+ Read the plan at: {WORK_DIR}/design_spec.md (frontmatter `type: pi-assets-plan`, `task: modify-pi-assets`, `phases: {AFFECTED_ASSETS_COUNT}`)
429
553
 
430
554
  ## Research Artifacts (for cross-referencing)
431
- - Explorer A (target + blast radius): {WORK_DIR}/explorer_a_findings.md
432
- - Explorer B (local Pi docs): {WORK_DIR}/explorer_b_findings.md
555
+ - Explorer A (discovered affected-asset set + per-asset trio blast radius + coordination notes): {WORK_DIR}/explorer_a_findings.md
556
+ - Explorer B (local Pi docs, per implicated type): {WORK_DIR}/explorer_b_findings.md
433
557
 
434
- ## Modification Request
435
- {MOD_REQUEST}
558
+ ## Problem Statement (from the user)
559
+ {PROBLEM_INPUT}
436
560
 
437
- ## Command self-exception note (carry for safety; relevant only if the spec being validated itself describes a CC-style command Pi asset)
438
- A documented, deliberate `disable-model-invocation: false` (cited against the `/build-pi-assets-phases` precedent and documented in the spec) is a recognized exception, NOT a defect. When enumerating valid CC tool names in any command-type check, use the CURRENT canonical names: `Read, Write, Edit, MultiEdit, Grep, Glob, Bash, Agent` (the `Task` tool was renamed to **Agent** in v2.1.63; `Task` still works as an alias), plus `Skill, WebFetch, WebSearch, NotebookEdit, TeamCreate, SendMessage, TaskCreate, TaskUpdate, TaskList, TaskGet, EnterWorktree, EnterPlanMode, ExitPlanMode`, plus the `mcp__` prefix pattern. For Pi-agent frontmatter use lowercase Pi tool names (`read, write, edit, bash, grep, find, ls`). Do NOT inherit any stale hardcoded tool list.
561
+ ## Coordinated Change Set Summary (for context full per-phase content is in design_spec.md)
562
+ - Affected-asset count: {AFFECTED_ASSETS_COUNT}
563
+ - Artifact convention: {ARTIFACT_SUFFIX_POLICY}
564
+ - Per-asset (one phase per entry):
565
+ {For each A in AFFECTED_ASSETS:}
566
+ - Phase {N}: {A.asset_type} — {A.asset_name} ({A.resolved_path})
439
567
 
440
- ## Validation Checks (10 total run ALL of these)
568
+ ## Command self-exception note (carry for safety; relevant only if any phase being validated itself describes a CC-style command Pi asset)
569
+ A documented, deliberate `disable-model-invocation: false` (cited against the `/build-pi-assets-phases` precedent and documented in the phase's Design Brief) is a recognized exception, NOT a defect. When enumerating valid CC tool names in any command-type check, use the CURRENT canonical names: `Read, Write, Edit, MultiEdit, Grep, Glob, Bash, Agent` (the `Task` tool was renamed to **Agent** in v2.1.63; `Task` still works as an alias), plus `Skill, WebFetch, WebSearch, NotebookEdit, TeamCreate, SendMessage, TaskCreate, TaskUpdate, TaskList, TaskGet, EnterWorktree, EnterPlanMode, ExitPlanMode`, plus the `mcp__` prefix pattern. For Pi-agent frontmatter use lowercase Pi tool names (`read, write, edit, bash, grep, find, ls`). Do NOT inherit any stale hardcoded tool list.
441
570
 
442
- {Paste the assembled numbered checklist from 3a HERE VERBATIM common checks 1–5, the type-specific checks 6–8 for this ASSET_TYPE, check 9 (Modification safety), and check 10 (Dual-criterion Test Scenario present). Do NOT abbreviate, do NOT replace with "see the guide" — paste the full numbered text. You hard-error "No validation checks provided." if the checklist is absent.}
571
+ ## Validation Checks ({DESIGN_CHECK_COUNT} totalrun ALL of these)
572
+
573
+ {Paste the assembled checklist from 3a HERE VERBATIM — plan-level checks 1..5, per-asset checks 6.N.1..5 multiplied across every phase N, and set-level coordination-consistency check 7. Do NOT abbreviate, do NOT replace with "see the guide" — paste the full numbered text. You hard-error "No validation checks provided." if the checklist is absent.}
443
574
 
444
575
  ## Validation Parameters
445
576
  - task: modify-pi-assets
446
577
  - phase: 2
447
578
  - phase-name: Modify Pi Assets Command
448
579
  - cycle: {DESIGN_VALIDATION_CYCLE}
580
+ - affected-asset-count: {AFFECTED_ASSETS_COUNT}
581
+ - artifact-suffix-policy: {ARTIFACT_SUFFIX_POLICY}
449
582
 
450
583
  ## Output
451
584
  Write your validation report to: {WORK_DIR}/design_validation_report.md
452
- Use YAML frontmatter with the parameters above plus `result: pass` or `result: fail` and `checks-passed: X/10`.
453
- Write using the Write tool. Return the file path AND the overall result (pass or fail).
585
+ Use YAML frontmatter with the parameters above plus `result: pass` or `result: fail` and `checks-passed: X/{DESIGN_CHECK_COUNT}`. In the Checks table, tag each check by scope: "Plan", "Phase {N}", or "Set". Write using the Write tool. Return the file path AND the overall result (pass or fail).
454
586
  ```
455
587
 
456
588
  #### 3c. Read Validation Result
@@ -468,45 +600,50 @@ The architect is a fresh sub-agent with no memory of Step 2. The prompt MUST be
468
600
  Delegate via Agent tool (`subagent_type: "pi-architect-agent"`) with this prompt:
469
601
 
470
602
  ```
471
- You are REVISING the design specification for a Pi-asset MODIFICATION. You MUST write the revised spec directly to disk.
603
+ You are REVISING a phased coordinated-change-set plan for a Pi-asset repair across {AFFECTED_ASSETS_COUNT} affected asset(s). Every phase carries action: modify. You MUST write the revised plan directly to disk.
472
604
 
473
605
  ## Required First Step (teammate gotcha)
474
- Invoke the `pi-primitives` skill using the Skill tool, AND Read `.claude/skills/brainstorm-plan/workflows/pi-primitive-creation.md` before revising. If you were spawned as a team teammate, your `skills:` frontmatter was NOT auto-applied — self-arm now. (On the normal Agent path this is already loaded; re-invoking is harmless.) Route via the `pi-primitives` SKILL.md to `reference/pi-asset-modification-guide.md` (§2/§4/§5 + §3 for the dual-criterion Test Scenario — §3 is its authoritative definer).
606
+ Invoke the `pi-primitives` skill using the Skill tool, AND Read `.claude/skills/brainstorm-plan/workflows/pi-primitive-creation.md` before revising. If you were spawned as a team teammate, your `skills:` frontmatter was NOT auto-applied — self-arm now. (On the normal Agent path this is already loaded; re-invoking is harmless.) Route via the `pi-primitives` SKILL.md to `reference/pi-asset-modification-guide.md` (§2/§4/§5 + §3 incl. §3.4 for the dual-criterion Test Scenario and BOTH artifact conventions — §3 is its authoritative definer).
475
607
 
476
608
  ## Save Path
477
- Write the revised specification to: {WORK_DIR}/design_spec.md (overwrite the existing file)
478
- Use the Write tool.
609
+ Write the revised plan to: {WORK_DIR}/design_spec.md (overwrite the existing file)
610
+ Use the Write tool. (Filename is intentionally `design_spec.md` — the FILE CONTENT is the `pi-assets-plan` document defined by `.claude/skills/pi-primitives/templates/pi-assets-plan-template.md`.)
479
611
 
480
- ## What You're Revising (a Pi-asset MODIFICATION)
481
- Type: {ASSET_TYPE} Name: {ASSET_NAME} Action: modify
482
- Target file: {RESOLVED_ASSET_PATH}
612
+ ## What You're Revising
613
+ - Affected-asset count: {AFFECTED_ASSETS_COUNT}
614
+ - Artifact convention: {ARTIFACT_SUFFIX_POLICY}
615
+ - Per-asset (one phase per entry):
616
+ {For each A in AFFECTED_ASSETS:}
617
+ - Phase {N}: {A.asset_type} — {A.asset_name} ({A.resolved_path})
618
+ proposed modification: {A.proposed_modification}
483
619
 
484
- ## Modification Request
485
- {MOD_REQUEST}
620
+ ## Problem Statement
621
+ {PROBLEM_INPUT}
486
622
 
487
623
  ## Research Findings (Read both)
488
624
  - Explorer A: {WORK_DIR}/explorer_a_findings.md
489
625
  - Explorer B: {WORK_DIR}/explorer_b_findings.md
490
626
 
491
- ## Current Design Spec (to revise)
492
- Read the current spec at: {WORK_DIR}/design_spec.md
627
+ ## Current Plan (to revise)
628
+ Read the current plan at: {WORK_DIR}/design_spec.md
493
629
 
494
630
  ## Validation Report (failures to fix)
495
631
  Read the validation report at: {WORK_DIR}/design_validation_report.md
496
632
 
497
633
  ## Correction Instructions
498
- - Read both the current spec and the validation report before changing anything.
499
- - Fix EVERY issue listed under "Issues Found" in the validation report.
634
+ - Read both the current plan and the validation report before changing anything.
635
+ - Fix EVERY issue listed under "Issues Found" in the validation report (each issue is tagged Plan / Phase {N} / Set — fix the corresponding scope).
500
636
  - Do NOT remove or weaken sections that passed validation — check "Verified Claims".
501
- - Keep all four modify-specific sections (Current State, Preserved (byte-for-byte), Trio Impact, dual-criterion Test Scenario). An absent regression criterion is a planning defect.
502
- - Keep the YAML frontmatter `type: pi-asset-design-spec` and `action: modify`; set `status: revised` and `date: {current date}`.
637
+ - Every phase must retain the four modify-specific subsections in its Design Brief (Current State, Preserved (byte-for-byte), Detailed Design, Trio Impact) AND the dual-criterion Test Scenario (Criterion A + Criterion B with `_regression` artifact filenames per {ARTIFACT_SUFFIX_POLICY}). An absent regression criterion is a planning defect.
638
+ - Preserve the plan's frontmatter `type: pi-assets-plan`, `task: modify-pi-assets`, `phases: {AFFECTED_ASSETS_COUNT}`; set `status: revised` and `date: {current date}`.
503
639
  - Apply the Model Portability principle from `pi-primitives` by name.
640
+ - If a coordination-consistency issue is reported (check 7), revise the affected phases on BOTH sides of the cross-asset link.
504
641
 
505
642
  Write using the Write tool. Return the file path when done.
506
643
  ```
507
644
 
508
645
  After the Agent returns:
509
- 1. Read `{WORK_DIR}/design_spec.md`. Verify it still has `type: pi-asset-design-spec` and `action: modify`.
646
+ 1. Read `{WORK_DIR}/design_spec.md`. Verify it still has `type: pi-assets-plan`, `task: modify-pi-assets`, `phases: {AFFECTED_ASSETS_COUNT}`, and that `## 4. Phases` still has exactly {AFFECTED_ASSETS_COUNT} `### Phase {N}:` headings.
510
647
  2. If returned inline, Write it to the expected path.
511
648
 
512
649
  #### 3e. Re-validate
@@ -520,8 +657,11 @@ If validation failed 3 times, present:
520
657
  ```
521
658
  DESIGN VALIDATION FAILED after 3 cycles. Aborting.
522
659
 
523
- Target: {RESOLVED_ASSET_PATH} ({ASSET_TYPE} — {ASSET_NAME}, modify)
524
- Checks passed: {X}/10 (cycle 3)
660
+ Problem: {PROBLEM_INPUT}
661
+ Affected assets ({AFFECTED_ASSETS_COUNT}, all action: modify):
662
+ {For each A in AFFECTED_ASSETS:}
663
+ - Phase {N}: {A.resolved_path} ({A.asset_type} — {A.asset_name})
664
+ Checks passed: {X}/{DESIGN_CHECK_COUNT} (cycle 3)
525
665
 
526
666
  Remaining failures:
527
667
  - {check name — problem summary}
@@ -539,14 +679,14 @@ If `AUTO_CONFIRM == true` (the `--auto-confirm` flag was set in `$ARGUMENTS`), S
539
679
 
540
680
  Otherwise:
541
681
 
542
- **3g.1 Render the build-approval HTML.** Read `{WORK_DIR}/design_spec.md` to extract the Trio Impact, Detailed Design, Preserved, and Test Scenario sections. Ensure the output directory exists: `mkdir -p .claude/specs/modify-pi-assets/` via Bash. Define `APPROVAL_HTML_PATH = .claude/specs/modify-pi-assets/{KEBAB_TARGET}-build-approval.html`. Write a self-contained HTML file to `APPROVAL_HTML_PATH` using the Write tool, with this exact template (substitute each `{token}` with the resolved value; leave the embedded `<style>` block intact and unedited):
682
+ **3g.1 Render the build-approval HTML.** Read `{WORK_DIR}/design_spec.md` to extract per-phase Trio Impact / Detailed Design / Preserved / Test Scenario, plus the plan-level Integration Vision. Ensure the output directory exists: `mkdir -p .claude/specs/modify-pi-assets/` via Bash. Define `APPROVAL_HTML_PATH = .claude/specs/modify-pi-assets/{KEBAB_PROBLEM_SLUG}-build-approval.html`. Write a self-contained HTML file to `APPROVAL_HTML_PATH` using the Write tool, with this exact template (substitute each `{token}` with the resolved value; leave the embedded `<style>` block intact and unedited; for the `{s}` plural marker, substitute `""` when `AFFECTED_ASSETS_COUNT == 1` and `"s"` when `AFFECTED_ASSETS_COUNT >= 2`):
543
683
 
544
684
  ```html
545
685
  <!DOCTYPE html>
546
686
  <html lang="en">
547
687
  <head>
548
688
  <meta charset="utf-8">
549
- <title>Build Approval — {ASSET_NAME} (modify)</title>
689
+ <title>Build Approval — Coordinated Repair ({AFFECTED_ASSETS_COUNT} asset{s})</title>
550
690
  <style>
551
691
  body { font: 15px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; max-width: 880px; margin: 2rem auto; padding: 0 1.5rem; color: #1a1a1a; }
552
692
  h1 { font-size: 1.6rem; margin-bottom: 0.25rem; }
@@ -563,47 +703,62 @@ ul { padding-left: 1.25rem; margin: 0.25rem 0; }
563
703
  .criterion { margin: 0.5rem 0; }
564
704
  .criterion strong { display: inline-block; min-width: 11rem; }
565
705
  .meta { color: #666; font-size: 0.9rem; font-style: italic; }
706
+ .phase { border: 1px solid #ddd; border-radius: 6px; padding: 0.75rem 1rem; margin: 1rem 0; background: #fafafa; }
707
+ .phase h3 { margin-top: 0; }
566
708
  </style>
567
709
  </head>
568
710
  <body>
569
- <h1>Build Approval — {ASSET_NAME} <span style="color:#888;">(modify)</span></h1>
711
+ <h1>Build Approval — Coordinated Repair <span style="color:#888;">({AFFECTED_ASSETS_COUNT} asset{s})</span></h1>
570
712
  <p class="meta">Generated {current date YYYY-MM-DD HH:MM} • Review this plan in your browser, then respond in the terminal.</p>
571
713
 
572
- <h2>Target</h2>
714
+ <h2>Problem</h2>
573
715
  <dl>
574
- <dt>File to be edited</dt><dd><code>{RESOLVED_ASSET_PATH}</code></dd>
575
- <dt>Type / Name</dt><dd>{ASSET_TYPE} — {ASSET_NAME}</dd>
576
- <dt>Action</dt><dd>modify</dd>
577
- <dt>Modification request</dt><dd>{MOD_REQUEST}</dd>
716
+ <dt>Problem statement</dt><dd>{PROBLEM_INPUT}</dd>
717
+ <dt>Intake shape</dt><dd>{INTAKE_SHAPE}</dd>
718
+ <dt>Action across phases</dt><dd>modify (every phase)</dd>
719
+ <dt>Affected-asset count</dt><dd>{AFFECTED_ASSETS_COUNT}</dd>
720
+ <dt>Artifact convention</dt><dd>{ARTIFACT_SUFFIX_POLICY}</dd>
578
721
  </dl>
579
722
 
580
- <h2>Trio Impact / Blast Radius</h2>
581
- <div class="callout"><strong>Blast radius:</strong> {Isolated | Contained | Broad}</div>
582
- <h3>Direct Changes</h3>
583
- <ul>{<li> items from the design spec's Trio Impact > Direct Changes section, one <li> per file}</ul>
584
- <h3>Affected Consumers</h3>
585
- <ul>{<li> items from Trio Impact > Affected Consumers, OR <li>None — Isolated</li> if Isolated}</ul>
586
-
587
- <h2>Detailed Design (summary)</h2>
588
- <p>{2-4 sentence summary of the exact change, drawn from the design spec's Detailed Design section}</p>
723
+ <h2>Set-Level Blast Radius</h2>
724
+ <div class="callout"><strong>Set-level blast radius:</strong> {Isolated | Contained | Broad} (aggregated from per-asset bands)</div>
725
+
726
+ <h2>Affected Assets (one phase per asset)</h2>
727
+ {For each A in AFFECTED_ASSETS, emit one <div class="phase"> block, with SUFFIX = "" when ARTIFACT_SUFFIX_POLICY == "single-pair" else "_{A.kebab_slug}":}
728
+ <div class="phase">
729
+ <h3>Phase {N}: {A.asset_type} — {A.asset_name}</h3>
730
+ <dl>
731
+ <dt>File to be edited</dt><dd><code>{A.resolved_path}</code></dd>
732
+ <dt>Proposed modification</dt><dd>{A.proposed_modification}</dd>
733
+ <dt>Per-asset blast radius</dt><dd>{Isolated | Contained | Broad}</dd>
734
+ <dt>Preservation regime</dt><dd>{authored byte-for-byte | vendored byte-parity | documented fork}</dd>
735
+ </dl>
736
+ <h4>Direct Changes</h4>
737
+ <ul>{<li> items from this phase's Trio Impact > Direct Changes}</ul>
738
+ <h4>Affected Consumers</h4>
739
+ <ul>{<li> items from this phase's Trio Impact > Affected Consumers, OR <li>None — Isolated</li> if Isolated. Mark any consumer that is itself another phase in this plan with "(in change set — see Phase {M})".}</ul>
740
+ <h4>Detailed Design (summary)</h4>
741
+ <p>{2-4 sentence summary of this phase's exact change, drawn from its Detailed Design subsection}</p>
742
+ <h4>Preserved (byte-for-byte)</h4>
743
+ <p>{one-line summary of what will be left byte-identical in this phase}</p>
744
+ <h4>Test Scenario (dual-criterion)</h4>
745
+ <div class="criterion"><strong>Criterion A (new):</strong> {one-line restatement of this phase's new-capability criterion} → <code>functional_run{SUFFIX}.ndjson</code></div>
746
+ <div class="criterion"><strong>Criterion B (regression):</strong> {one-line restatement of this phase's regression criterion that protects the original capability} → <code>functional_run{SUFFIX}_regression.ndjson</code></div>
747
+ </div>
589
748
 
590
- <h2>Preserved (byte-for-byte)</h2>
591
- <p>{one-line summary of what will be left byte-identical}</p>
592
- <p><strong>Preservation regime declared:</strong> {authored byte-for-byte | vendored byte-parity | documented fork}</p>
749
+ <h2>Integration Vision (cross-phase coordination)</h2>
750
+ <p>{2-5 sentence summary of how the phases compose to address the problem statement, drawn from the plan's `## 5. Integration Vision` section. Cite each coordination link.}</p>
593
751
 
594
752
  <h2>Design Validation</h2>
595
753
  <dl>
596
754
  <dt>Cycles consumed</dt><dd>{DESIGN_VALIDATION_CYCLE_FINAL} / 3</dd>
597
755
  <dt>Result</dt><dd>PASS</dd>
756
+ <dt>Checks passed</dt><dd>{X}/{DESIGN_CHECK_COUNT} (plan: 5; per-asset: 5 × {AFFECTED_ASSETS_COUNT}; set coordination: 1)</dd>
598
757
  </dl>
599
758
 
600
- <h2>Test Scenario (dual-criterion)</h2>
601
- <div class="criterion"><strong>Criterion A (new):</strong> {one-line restatement of the new-capability criterion}</div>
602
- <div class="criterion"><strong>Criterion B (regression):</strong> {one-line restatement of the regression criterion that protects the original capability}</div>
603
-
604
759
  <h2>Artifacts</h2>
605
760
  <ul>
606
- <li>Design spec: <code>{WORK_DIR}/design_spec.md</code></li>
761
+ <li>Plan (pi-assets-plan): <code>{WORK_DIR}/design_spec.md</code></li>
607
762
  <li>Design validation report: <code>{WORK_DIR}/design_validation_report.md</code></li>
608
763
  <li>Explorer A findings: <code>{WORK_DIR}/explorer_a_findings.md</code></li>
609
764
  <li>Explorer B findings: <code>{WORK_DIR}/explorer_b_findings.md</code></li>
@@ -611,7 +766,7 @@ ul { padding-left: 1.25rem; margin: 0.25rem 0; }
611
766
 
612
767
  <h2>Next Step</h2>
613
768
  <div class="callout warn">
614
- Respond in your terminal: <strong>yes</strong> (approve and build), <strong>no</strong> (abort with no file changes), or <strong>revise</strong> (provide feedback for the architect to redesign).
769
+ Respond in your terminal: <strong>yes</strong> (approve and build the FULL change set), <strong>no</strong> (abort no file changes), or <strong>revise</strong> (provide feedback for the architect to redesign).
615
770
  </div>
616
771
  </body>
617
772
  </html>
@@ -620,11 +775,15 @@ ul { padding-left: 1.25rem; margin: 0.25rem 0; }
620
775
  **3g.2 Present the gate prompt in the terminal and WAIT for the user:**
621
776
 
622
777
  ```
623
- BUILD APPROVAL
778
+ BUILD APPROVAL — COORDINATED CHANGE SET ({AFFECTED_ASSETS_COUNT} ASSET{S})
779
+
780
+ Problem: {PROBLEM_INPUT}
781
+ Affected assets (one phase each):
782
+ {For each A in AFFECTED_ASSETS:}
783
+ - Phase {N}: {A.resolved_path} ({A.asset_type} — {A.asset_name}, modify)
624
784
 
625
- Target: {RESOLVED_ASSET_PATH} ({ASSET_TYPE} {ASSET_NAME}, modify)
626
- Design spec: {WORK_DIR}/design_spec.md
627
- Design validation: PASS (cycle {DESIGN_VALIDATION_CYCLE_FINAL} / 3)
785
+ Plan: {WORK_DIR}/design_spec.md (pi-assets-plan, {AFFECTED_ASSETS_COUNT} phase{s})
786
+ Design validation: PASS (cycle {DESIGN_VALIDATION_CYCLE_FINAL} / 3 — {X}/{DESIGN_CHECK_COUNT} checks)
628
787
 
629
788
  Full build-approval plan rendered to (open in browser for easy review):
630
789
  {APPROVAL_HTML_PATH}
@@ -636,85 +795,98 @@ Approve the build? (yes / no / revise — provide feedback for the architect to
636
795
 
637
796
  Branches:
638
797
  - **yes** → set `GATE_C_RESULT = "confirmed"` and proceed to Step 4.
639
- - **revise** → capture the user's feedback verbatim, store it as `GATE_C_USER_FEEDBACK`, and RETURN to Step 2 with that feedback appended to the architect's prompt under a new `## User Feedback From Pre-Build Gate` heading (after the `## Modification Request` block). Re-run Step 2 → Step 3 (validation loop). Track revisions; on final approval set `GATE_C_RESULT = "revised then confirmed ({N} revisions)"`. **On re-entry to this gate, RE-RENDER the HTML at the same `APPROVAL_HTML_PATH` (overwrite) so the user always sees the latest plan.**
798
+ - **revise** → capture the user's feedback verbatim, store it as `GATE_C_USER_FEEDBACK`, and RETURN to Step 2 with that feedback appended to the architect's prompt under a new `## User Feedback From Pre-Build Gate` heading (after the `## Coordinated Change Set` block). Re-run Step 2 → Step 3 (validation loop). Track revisions; on final approval set `GATE_C_RESULT = "revised then confirmed ({N} revisions)"`. **On re-entry to this gate, RE-RENDER the HTML at the same `APPROVAL_HTML_PATH` (overwrite) so the user always sees the latest plan.** The HTML filename uses `KEBAB_PROBLEM_SLUG` (not a per-asset slug) so a single file represents the whole coordinated set.
640
799
  - **no** → set `GATE_C_RESULT = "stopped at gate"`. STOP execution with NO build performed. Present:
641
800
  ```
642
- STOPPED at pre-build approval gate. No file changes have been made to {RESOLVED_ASSET_PATH}.
643
- Inspect the design spec at: {WORK_DIR}/design_spec.md
801
+ STOPPED at pre-build approval gate. No file changes have been made to ANY of the {AFFECTED_ASSETS_COUNT} affected asset(s).
802
+ Inspect the plan at: {WORK_DIR}/design_spec.md
644
803
  Build-approval HTML (still on disk for reference): {APPROVAL_HTML_PATH}
645
- You may manually edit the spec and re-invoke `/modify-pi-assets`, or re-invoke with a different modification request.
804
+ You may manually edit the plan and re-invoke `/modify-pi-assets`, or re-invoke with a different problem statement.
646
805
  ```
647
806
 
648
- ### Step 4: Build (pi-meta-agent via Agent Tool)
807
+ ### Step 4: Build (pi-meta-agent via Agent Tool — iterates over the full change set in one invocation)
649
808
 
650
- Spawn pi-meta-agent to apply the validated modification. It reads the existing target FIRST and applies ONLY the spec's changes via Read-then-Edit/MultiEdit, preserving every Preserved section byte-for-byte. `pi-meta-agent` is a LEAF builder — it never spawns sub-agents. It is reused BYTE-FOR-BYTE — no agent edits.
809
+ Spawn pi-meta-agent to apply the validated coordinated change set across every phase. It reads the existing target FIRST per phase and applies ONLY each phase's changes via Read-then-Edit/MultiEdit, preserving every Preserved section byte-for-byte. `pi-meta-agent` is a LEAF builder — it never spawns sub-agents. It is reused BYTE-FOR-BYTE — no agent edits.
651
810
 
652
811
  #### 4a. Spawn pi-meta-agent Builder
653
812
 
654
813
  Delegate via Agent tool (`subagent_type: "pi-meta-agent"`) with this prompt:
655
814
 
656
815
  ```
657
- You are applying a validated MODIFICATION to an existing Pi asset. You MUST write all changes directly to disk.
816
+ You are applying a validated coordinated change set across {AFFECTED_ASSETS_COUNT} existing Pi asset(s). Every phase has action: modify. You MUST write all changes directly to disk and you MUST iterate through every phase in this single invocation — do not stop after one phase.
658
817
 
659
818
  ## Required First Step (teammate gotcha)
660
- Invoke the `pi-primitives` skill using the Skill tool before building. If you were spawned as a team teammate, your `skills:` frontmatter was NOT auto-applied — self-arm now. (On the normal Agent path this is already injected; re-invoking is harmless.) Once `pi-primitives` is loaded, route via its SKILL.md to `reference/pi-asset-modification-guide.md` §4 — it governs which preservation regime applies to your Read-then-Edit/MultiEdit.
819
+ Invoke the `pi-primitives` skill using the Skill tool before building. If you were spawned as a team teammate, your `skills:` frontmatter was NOT auto-applied — self-arm now. (On the normal Agent path this is already injected; re-invoking is harmless.) Once `pi-primitives` is loaded, route via its SKILL.md to `reference/pi-asset-modification-guide.md` §4 — it governs which preservation regime applies to your Read-then-Edit/MultiEdit (apply PER PHASE).
661
820
 
662
- ## What You're Modifying (a Pi asset)
663
- Type: {ASSET_TYPE} Name: {ASSET_NAME} Action: modify
664
- Target file: {RESOLVED_ASSET_PATH}
821
+ ## What You're Building (a Coordinated Repair)
822
+ - Affected-asset count: {AFFECTED_ASSETS_COUNT}
823
+ - Action across every phase: modify
824
+ - Phases (build in the dependency order encoded in the plan — the plan's `**Dependencies**:` lines and the order of `### Phase N:` headings):
825
+ {For each A in AFFECTED_ASSETS:}
826
+ - Phase {N}: {A.asset_type} — {A.asset_name} ({A.resolved_path})
665
827
 
666
- ## Design Specification
667
- Read the complete validated design spec at: {WORK_DIR}/design_spec.md
668
- It carries `action: modify`. It has been validated. Follow it faithfully — do not redesign or deviate.
828
+ ## Plan (read FIRST — every phase)
829
+ Read the complete validated plan at: {WORK_DIR}/design_spec.md (frontmatter `type: pi-assets-plan`, `task: modify-pi-assets`). It has been validated. Follow it faithfully — do not redesign or deviate.
669
830
 
670
831
  ## Research Findings (for reference if needed)
671
832
  - Explorer A: {WORK_DIR}/explorer_a_findings.md
672
833
  - Explorer B: {WORK_DIR}/explorer_b_findings.md
673
834
 
674
- ## Build Instructions (MODIFY — byte-for-byte preservation)
675
- 1. Read the design spec completely before touching any file.
676
- 2. Read the EXISTING target file at {RESOLVED_ASSET_PATH} FIRST (and any co-imported files the spec names).
677
- 3. Apply ONLY the changes the spec's "Detailed Design" / "Current State" sections specify, via Edit/MultiEdit. Preserve every section the spec's "Preserved (byte-for-byte)" section marks Preserved — byte-for-byte. NEVER rewrite the whole file.
678
- 4. Honor the preservation regime the spec declares (per `reference/pi-asset-modification-guide.md` §4): authored → byte-for-byte Read-then-Edit/MultiEdit; vendored byte-parity vs `$PKG`, and if the spec declares a conscious documented fork, the byte-parity `diff` no longer applies (note this in the build report).
679
- 5. You are a LEAF builder you NEVER spawn sub-agents. Do all work yourself with Bash and file tools.
680
- 6. The only acceptable deviations: fixing obvious typos; adjusting relative→absolute paths where needed. A genuine spec-vs-reality conflict is reported in the build report, not improvised around.
835
+ ## Build Instructions (PER PHASE iterate over EVERY phase; byte-for-byte preservation per asset)
836
+ For each phase in the plan, in the order they appear (which respects dependencies):
837
+ 1. Read the phase's `**Design Brief**:` FULLY (including its Current State, Preserved (byte-for-byte), Detailed Design, Trio Impact subsections) before touching any file.
838
+ 2. Read the EXISTING target file for that phase (and any co-imported files the phase names) FIRST.
839
+ 3. Apply ONLY the changes the phase's Detailed Design subsection specifies, via Edit/MultiEdit. Preserve every section the phase's Preserved (byte-for-byte) subsection marks Preserved byte-for-byte. NEVER rewrite the whole file.
840
+ 4. Honor the preservation regime the phase declares (per `reference/pi-asset-modification-guide.md` §4): authored byte-for-byte Read-then-Edit/MultiEdit; vendored → byte-parity vs `$PKG`, and if the phase declares a conscious documented fork, the byte-parity `diff` no longer applies (note this in the build report).
841
+ 5. Move to the next phase. Do NOT stop after one phase every phase must be applied in this single invocation.
842
+ 6. You are a LEAF builder — you NEVER spawn sub-agents. Do all work yourself with Bash and file tools.
843
+ 7. The only acceptable deviations: fixing obvious typos; adjusting relative→absolute paths where needed. A genuine spec-vs-reality conflict is reported in the build report under that phase, not improvised around.
681
844
 
682
845
  ## Output
683
- Write a build report to: {WORK_DIR}/build_report.md
846
+ Write a single build report covering ALL phases to: {WORK_DIR}/build_report.md
684
847
 
685
848
  ---
686
849
  task: modify-pi-assets
687
850
  phase: 2
688
851
  phase-name: Modify Pi Assets Command
689
- asset-type: {ASSET_TYPE}
690
- asset-name: {ASSET_NAME}
691
- action: modify
692
852
  type: pi-asset-build-report
853
+ affected-asset-count: {AFFECTED_ASSETS_COUNT}
854
+ action: modify
693
855
  status: built
694
856
  date: {current date}
695
857
  ---
696
858
 
697
- # Build Report: {ASSET_NAME} (modify)
859
+ # Build Report: Coordinated Repair ({AFFECTED_ASSETS_COUNT} asset{s})
698
860
 
699
861
  ## Files Created/Modified
700
- - {file path} modified
701
- - ...
862
+ {For each A in AFFECTED_ASSETS, one entry:}
863
+ - Phase {N} ({A.asset_type} — {A.asset_name}): {A.resolved_path} — modified
864
+
865
+ ## Per-Phase Build Notes
866
+ {One subsection per phase:}
867
+
868
+ ### Phase {N}: {A.asset_name}
869
+ - Preservation regime applied: {authored byte-for-byte | vendored byte-parity | documented fork}
870
+ - Sections preserved byte-for-byte: {brief summary}
871
+ - Edits applied: {brief summary of the edits applied via Edit/MultiEdit}
702
872
 
703
873
  ## Key Decisions
704
- - {minor decisions, or "None — followed spec exactly"; note the preservation regime applied and whether a documented fork was declared}
874
+ - {minor decisions across phases, or "None — followed plan exactly"}
705
875
 
706
876
  ## Issues Encountered
707
- - {conflicts/problems, or "None"}
877
+ - {conflicts/problems per phase, or "None"}
708
878
 
709
879
  Write the report using the Write tool. Return the file path in your response.
710
880
  ```
711
881
 
712
882
  #### 4b. Verify Builder Output
883
+
713
884
  After the Agent returns:
714
885
  1. Read `{WORK_DIR}/build_report.md`. If returned inline, Write it to the expected path.
715
- 2. Extract `## Files Created/Modified`. For each file listed, verify it exists on disk via Glob/Read. If any is missing, warn: `WARNING: {file path} listed in build report but not found on disk.`
716
- 3. Extract `## Issues Encountered`. If not "None", present: `BUILDER ISSUES DETECTED: {issue summary}. Proceeding to validation.`
717
- 4. Store `FILES_CREATED_MODIFIED` (the file list) and `BUILD_ISSUES`.
886
+ 2. Verify the "Files Created/Modified" section lists EXACTLY {AFFECTED_ASSETS_COUNT} entries (one per phase) and that each entry's path matches an entry in `AFFECTED_ASSETS`. If any phase's file is missing or mismatched, warn: `WARNING: Phase {N} ({A.asset_name}) file mismatch expected {A.resolved_path}, got {what the builder reported}.`
887
+ 3. For each path listed, verify it exists on disk via Glob/Read. If any is missing, warn: `WARNING: {file path} listed in build report but not found on disk.`
888
+ 4. Extract `## Issues Encountered`. If not "None", present: `BUILDER ISSUES DETECTED across {N} phase(s): {issue summary}. Proceeding to validation.`
889
+ 5. Store `FILES_CREATED_MODIFIED` (the file list keyed by phase) and `BUILD_ISSUES`.
718
890
  Proceed to Step 5.
719
891
 
720
892
  ### Step 5: Validate & Test the Build (Correction Loop)
@@ -736,142 +908,163 @@ Record the bounded-execution environment:
736
908
 
737
909
  Record `PI_AVAILABLE`, `TIMEOUT_TOOL`, `PI_FUNCTIONAL_ALARM`, `PROVIDER_SUBSTITUTION`.
738
910
 
739
- #### 5b. Assemble the Unified Checklist
740
-
741
- Assemble structural + functional checks for ASSET_TYPE, sourced from `.claude/skills/pi-primitives/reference/pi-testing-validation-guide.md` `## Structural Validation` and `## Functional Testing`, PLUS the two modification add-ons whose definitions come from `reference/pi-asset-modification-guide.md` (NOT from `pi-testing-validation-guide.md`, which has NO regression content).
742
-
743
- **Structural checks when ASSET_TYPE == "skill":** (1) SKILL.md exists; (2) valid frontmatter, MANDATORY description; (3) name format (≤64, lowercase/0-9/hyphens); (4) `references/` PLURAL not `reference/`; (5) recognized subdirs only (`references/`,`scripts/`,`assets/`); (6) relative links resolve.
911
+ #### 5b. Assemble the Unified Checklist (per-asset multiplication + per-asset modify add-ons)
744
912
 
745
- **Structural checks when ASSET_TYPE == "prompt-template":** (1) single `.md`, no accompanying dir; (2) valid slash-command name; (3) well-formed optional frontmatter; (4) valid substitution tokens; (5) text-only (no orchestration leakage); (6) discovery location.
913
+ Assemble structural + functional checks PER AFFECTED ASSET, sourced from `.claude/skills/pi-primitives/reference/pi-testing-validation-guide.md` `## Structural Validation` and `## Functional Testing`, PLUS the two per-asset modification add-ons whose definitions come from `reference/pi-asset-modification-guide.md` (NOT from `pi-testing-validation-guide.md`, which has NO regression content).
746
914
 
747
- **Structural checks when ASSET_TYPE == "agent":** (1) `.md`, valid YAML frontmatter; (2) `name` + `description` present; (3) valid `tools` (lowercase Pi names) or absent; (4) valid `model` ID (structural only pinned model NOT exercised at runtime; the 5c run uses the configured default provider); (5) NO `skills:` field; (6) full-prompt body (not thin).
915
+ **Per-asset checks — iterate over every A in AFFECTED_ASSETS (Phase N, type T):**
748
916
 
749
- **Structural checks when ASSET_TYPE == "extension":** (1) `.ts`, `@earendil-works/pi-coding-agent` import (any `@mariozechner/*` is a stale defect → FAIL); (2) `export default function(pi)` factory; (3) uses `pi.register*` / `pi.on` APIs; (4) raw `.ts`, no build artefacts; (5) vendored byte-parity IF the spec declares the asset vendored AND NOT a documented fork `diff` against `$(npm root -g)/@earendil-works/pi-coding-agent`; if the spec's §4 regime declares a conscious documented fork, this check is N/A (do NOT expect the diff).
917
+ For each A, append the structural-check bundle for T (mark each "Phase {N}Structural"):
918
+ - T == **"skill"** (6 structural): (1) SKILL.md exists; (2) valid frontmatter, MANDATORY description; (3) name format (≤64, lowercase/0-9/hyphens); (4) `references/` PLURAL not `reference/`; (5) recognized subdirs only (`references/`,`scripts/`,`assets/`); (6) relative links resolve.
919
+ - T == **"prompt-template"** (6 structural): (1) single `.md`, no accompanying dir; (2) valid slash-command name; (3) well-formed optional frontmatter; (4) valid substitution tokens; (5) text-only (no orchestration leakage); (6) discovery location.
920
+ - T == **"agent"** (6 structural): (1) `.md`, valid YAML frontmatter; (2) `name` + `description` present; (3) valid `tools` (lowercase Pi names) or absent; (4) valid `model` ID (structural only — pinned model NOT exercised at runtime; the 5c run for A uses the configured default provider); (5) NO `skills:` field; (6) full-prompt body (not thin).
921
+ - T == **"extension"** (5 structural): (1) `.ts`, `@earendil-works/pi-coding-agent` import (any `@mariozechner/*` is a stale defect → FAIL); (2) `export default function(pi)` factory; (3) uses `pi.register*` / `pi.on` APIs; (4) raw `.ts`, no build artefacts; (5) vendored byte-parity IF that phase declares the asset vendored AND NOT a documented fork — `diff` against `$(npm root -g)/@earendil-works/pi-coding-agent`; if the phase's §4 regime declares a conscious documented fork, this check is N/A for that asset (do NOT expect the diff).
750
922
 
751
- **Modification add-on structural check (ALWAYS — defined by `reference/pi-asset-modification-guide.md` §2, append after the type-specific structural checks):**
752
- - **Consumer regression** — Grep for {ASSET_NAME} (and any registered tool/command name) across `.claude/` and `.pi/` to find every trio consumer (the consumers Explorer A enumerated). For each, verify its reference to the modified asset still resolves correctly. PASS if all consumer references still resolve. FAIL if any reference is broken.
923
+ **Per-asset structural add-on (ALWAYS, per asset — defined by `reference/pi-asset-modification-guide.md` §2, append after that asset's type-specific structural checks):**
924
+ - **Consumer regression (Phase {N})** — Grep for `A.asset_name` (and any registered tool/command name A exposes) across `.claude/` and `.pi/` to find every trio consumer (the consumers Explorer A enumerated for A). For each, verify its reference to the modified asset still resolves correctly. PASS if all consumer references still resolve. FAIL if any reference is broken. A cross-set consumer (a consumer that is itself another phase in this plan) is verified against THAT phase's modified state.
753
925
 
754
- Store `STRUCTURAL_CHECK_COUNT`.
926
+ Sum across all phases to set `STRUCTURAL_CHECK_COUNT = sum over A of (per-type-structural-count(T) + 1)`. (`+1` per phase for the Consumer-regression add-on.)
755
927
 
756
- > **FUNCTIONAL VERDICT RULE — applies to every functional check below for ALL asset types. Read first.** Outcomes are exactly PASS, FAIL, or BLOCKED.
928
+ > **FUNCTIONAL VERDICT RULE — applies to every functional check below for ALL asset types and EVERY phase. Read first.** Outcomes are exactly PASS, FAIL, or BLOCKED.
757
929
  > - **FAIL** if the run errored, timed out (exit 124 from `timeout` / 142 from the perl-alarm wrapper), the output does not meet the criteria, **OR the asset (or any subprocess it dispatches) errored due to its OWN configured model/provider/credentials** (`No API key found`, auth/login error, `Parallel: N/0 succeeded`). An asset-own-config failure is an ASSET defect and MUST NEVER be recorded as an "environment substitution" or scored PASS.
758
- > - **BLOCKED** (not PASS, not silently absorbed — escalated in 5e) only if the check could not be verified for a reason that is NOT an asset defect and NOT the asset's own configuration: Pi not installed, a genuinely external/host unavailability (e.g. no Anthropic API key / no `timeout` binary on this host), an interactive-only verification, OR a provider pin the user explicitly accepted during planning.
930
+ > - **BLOCKED** (not PASS, not silently absorbed — escalated in 5e) only if the check could not be verified for a reason that is NOT an asset defect and NOT the asset's own configuration: Pi not installed, a genuinely external/host unavailability, an interactive-only verification, OR a provider pin the user explicitly accepted during planning.
759
931
  > - **PASS** only if the criteria are met AND backed by an existing on-disk artifact (path + exact command line + exit code + quoted excerpt). Skill load-and-verify checks legitimately have no runtime artifact and PASS on their stated load-and-verify conditions.
760
932
  > When in doubt between FAIL and BLOCKED, choose FAIL. Never PASS on a narrative assertion.
761
933
 
762
- **Functional checks when ASSET_TYPE == "agent"** (append after structural): (7) Headless invocation reflects the role — evaluate `{WORK_DIR}/functional_run.ndjson` + `{WORK_DIR}/functional_final_message.md` (orchestrator ran it in 5c); PASS only if the run completed within the bound (NOT 124/142), the artifact exists with its run header, and the final assistant message reflects the role and the new-capability criterion. If `PI_AVAILABLE == "no"`: BLOCKED (resolved in 5e). (8) Output meets the new-capability criterion from the spec's Test Scenario.
934
+ For each A, append the functional-check bundle for T (mark each "Phase {N} Functional"); per-asset SUFFIX_A = `""` when `ARTIFACT_SUFFIX_POLICY == "single-pair"` else `"_{A.kebab_slug}"`:
935
+ - T == **"agent"** (2 functional): (7) Headless invocation reflects the role — evaluate `{WORK_DIR}/functional_run{SUFFIX_A}.ndjson` + `{WORK_DIR}/functional_final_message{SUFFIX_A}.md` (orchestrator ran it in 5c); PASS only if the run completed within the bound (NOT 124/142), the artifact exists with its run header, and the final assistant message reflects the role and the new-capability criterion. If `PI_AVAILABLE == "no"`: BLOCKED (resolved in 5e). (8) Output meets the new-capability criterion from the phase's Test Scenario.
936
+ - T == **"prompt-template"** (2 functional): (7) Expanded-text invocation — evaluate `{WORK_DIR}/functional_run{SUFFIX_A}.ndjson` + `functional_final_message{SUFFIX_A}.md`; PASS only if completed within bound and output reflects intended behaviour. `/name` registration is interactive-only → that sub-verification is BLOCKED until 5e. (8) Output meets the new-capability criterion.
937
+ - T == **"extension"** (2 functional): (7) jiti load — evaluate `{WORK_DIR}/functional_run{SUFFIX_A}.ndjson` (orchestrator ran `pi -e ./{A.resolved_path}` in 5c — jiti load, NO compile); PASS only if it loaded with no error within the bound and the registered tools/commands appear. Interactive-only verifications (e.g. `/reload`) → BLOCKED until 5e. (8) Output reflects the new-capability criterion.
938
+ - T == **"skill"** (1 functional): (7) Load-and-verify — NO headless `pi`. Verify the skill loads, its `references/` are readable, the knowledge is reflected when the skill is active (invoke via the Skill tool and confirm). PASS if all hold.
763
939
 
764
- **Functional checks when ASSET_TYPE == "prompt-template"** (append): (7) Expanded-text invocation evaluate `{WORK_DIR}/functional_run.ndjson` + `functional_final_message.md`; PASS only if completed within bound and output reflects intended behaviour. `/name` registration is interactive-only → that sub-verification is BLOCKED until 5e. (8) Output meets the new-capability criterion.
940
+ **Per-asset functional add-on (ALWAYS, per assetthe dual-criterion regression rule and the `_regression` artifact convention are DEFINED by `reference/pi-asset-modification-guide.md` §3 (incl. §3.3 single-pair default AND §3.4 per-asset-suffix extension); append after that asset's type-specific functional checks):**
941
+ - **Regression check (Phase {N})** — Re-verify A's ORIGINAL capability. For agent/prompt-template/extension phases: evaluate the SECOND captured artifact `{WORK_DIR}/functional_run{SUFFIX_A}_regression.ndjson` + `{WORK_DIR}/functional_final_message{SUFFIX_A}_regression.md` (the orchestrator ran that second bounded exercise in 5c). For skill phases: re-invoke the skill and confirm the original knowledge still loads. PASS only if the captured regression artifact shows the original capability still works (subject to the same Functional Verdict Rule and the artifact precondition). FAIL if the original capability is broken.
765
942
 
766
- **Functional checks when ASSET_TYPE == "extension"** (append): (7) jiti load evaluate `{WORK_DIR}/functional_run.ndjson` (orchestrator ran `pi -e ./{ext.ts}` in 5c — jiti load, NO compile); PASS only if it loaded with no error within the bound and the registered tools/commands appear. Interactive-only verifications (e.g. `/reload`) BLOCKED until 5e. (8) Output reflects the new-capability criterion (the new behaviour the modification adds).
943
+ Sum across all phases to set `FUNCTIONAL_CHECK_COUNT = sum over A of (per-type-functional-count(T) + 1)` (`+1` per phase for the Regression add-on).
767
944
 
768
- **Functional checks when ASSET_TYPE == "skill"** (append): (7) Load-and-verify NO headless `pi`. Verify the skill loads, its `references/` are readable, the knowledge is reflected when the skill is active (invoke via the Skill tool and confirm). PASS if all hold.
945
+ Store `BUILD_CHECK_COUNT = STRUCTURAL_CHECK_COUNT + FUNCTIONAL_CHECK_COUNT`. For the trivial single-asset case the counts match the pre-repair behavior exactly (e.g. an agent phase: 6 + 1 structural and 2 + 1 functional = 10 checks total symmetric with the original).
769
946
 
770
- **Modification add-on functional check (ALWAYS — the dual-criterion regression rule and the `_regression` artifact convention are DEFINED by `reference/pi-asset-modification-guide.md` §3, NOT by `pi-testing-validation-guide.md`; append after the type-specific functional checks):**
771
- - **Regression check** — Re-verify the asset's ORIGINAL capability. For agent/prompt-template/extension: evaluate the SECOND captured artifact `{WORK_DIR}/functional_run_regression.ndjson` + `{WORK_DIR}/functional_final_message_regression.md` (the orchestrator ran that second bounded exercise in 5c). For skill: re-invoke the skill and confirm the original knowledge still loads. PASS only if the captured regression artifact shows the original capability still works (subject to the same Functional Verdict Rule and the artifact precondition). FAIL if the original capability is broken.
947
+ #### 5c. Run the Bounded Functional + Regression Exercises (Orchestrator-Run, Inline PER ASSET)
772
948
 
773
- Store `FUNCTIONAL_CHECK_COUNT` and `BUILD_CHECK_COUNT = STRUCTURAL_CHECK_COUNT + FUNCTIONAL_CHECK_COUNT`.
949
+ The orchestrator (you — you have Bash) runs the headless `pi` exercises HERE, inline, bounded and stdin-guarded, **once per affected asset**. The unbounded `pi` run is NEVER delegated to a sub-agent. The exercises iterate over every entry in `AFFECTED_ASSETS`; their captured artifacts are named per `ARTIFACT_SUFFIX_POLICY`.
774
950
 
775
- #### 5c. Run the Bounded Functional + Regression Exercises (Orchestrator-Run, Inline)
951
+ **Per-asset SUFFIX convention (read first, applied to EVERY filename below):**
952
+ - If `ARTIFACT_SUFFIX_POLICY == "single-pair"` (`AFFECTED_ASSETS_COUNT == 1`): `SUFFIX = ""` (empty — preserves the original single-pair convention, the §3.3 default).
953
+ - If `ARTIFACT_SUFFIX_POLICY == "per-asset-suffix"` (`AFFECTED_ASSETS_COUNT >= 2`): for each asset A, `SUFFIX_A = "_{A.kebab_slug}"` (per §3.4 "Multi-Asset Coordinated Sets").
954
+ The four artifact filenames per asset A are therefore:
955
+ - New-capability: `functional_run{SUFFIX_A}.ndjson` and `functional_final_message{SUFFIX_A}.md`
956
+ - Regression: `functional_run{SUFFIX_A}_regression.ndjson` and `functional_final_message{SUFFIX_A}_regression.md`
776
957
 
777
- The orchestrator (you you have Bash) runs the headless `pi` exercises HERE, inline, bounded and stdin-guarded. The unbounded `pi` run is NEVER delegated to a sub-agent.
778
-
779
- **Skip conditions:**
780
- - `ASSET_TYPE == "skill"` SKIP the `pi` run entirely (load-and-verify only). Set `FUNCTIONAL_EXERCISE_RAN = "no (skill no runtime)"`; `FUNCTIONAL_ARTIFACT_OK = "n/a (skill load-and-verify)"`. Proceed to 5d.
781
- - `PI_AVAILABLE == "no"` → SKIP the `pi` run. Write `{WORK_DIR}/manual_test_instructions.md` (manual fallback format below). Set `FUNCTIONAL_EXERCISE_RAN = "no (Pi not installed — manual fallback)"`. Proceed to 5d.
782
- - If the only outstanding verification is interactive-only (prompt-template `/name` registration, extension `/reload`): write `{WORK_DIR}/manual_test_instructions.md` for that sub-verification; still run the headless portion below for any non-interactive part.
958
+ **Skip conditions (apply PER ASSET):**
959
+ - For an asset A where `A.asset_type == "skill"` → SKIP the `pi` run for that asset entirely (load-and-verify only). Record per-asset: `FUNCTIONAL_EXERCISE_RAN[A] = "no (skill — no runtime)"`; `FUNCTIONAL_ARTIFACT_OK[A] = "n/a (skill — load-and-verify)"`.
960
+ - `PI_AVAILABLE == "no"` → SKIP the `pi` runs for ALL assets. Write `{WORK_DIR}/manual_test_instructions.md` (manual fallback format below) enumerating every phase. Set per-asset `FUNCTIONAL_EXERCISE_RAN[A] = "no (Pi not installed — manual fallback)"`. Proceed to 5d.
961
+ - If the only outstanding verification for a given asset A is interactive-only (prompt-template `/name` registration, extension `/reload`): write the manual-fallback section for that sub-verification of A; still run the headless portion for any non-interactive part of A.
783
962
 
784
963
  **Bounded-execution wrapper.** Every `pi` invocation below MUST run through this wrapper, chosen by `TIMEOUT_TOOL`:
785
964
  - If `TIMEOUT_TOOL` is a `timeout`/`gtimeout` path: `{TIMEOUT_TOOL} {PI_FUNCTIONAL_ALARM} pi <args…> </dev/null` (a timed-out run exits 124).
786
965
  - If `TIMEOUT_TOOL == "perl-alarm"`: `perl -e 'alarm shift; exec @ARGV' {PI_FUNCTIONAL_ALARM} pi <args…> </dev/null` (a timed-out run is killed by SIGALRM; shell reports exit 142 = 128+14).
787
966
 
788
- `</dev/null` is MANDATORY on every form — it removes the interactive `/login` / TTY block. `--model` is NEVER passed (5a model-pinning policy).
967
+ `</dev/null` is MANDATORY on every form. `--model` is NEVER passed (5a model-pinning policy).
968
+
969
+ **Iteration loop.** For each A in AFFECTED_ASSETS (in plan order):
789
970
 
790
- **Primary (new-capability) exercise — per-asset-type bounded command** (stream stdout to `{WORK_DIR}/functional_run.ndjson`; capture wrapper exit code as `FUNCTIONAL_EXIT`):
791
- - **agent**: `BODY="$(mktemp)"`; write the agent body (everything after the closing frontmatter `---`) to `$BODY`; `<wrapper> pi --mode json -p --no-session --append-system-prompt "$BODY" "Task: {a task derived from the spec's Test Scenario new-capability criterion}" </dev/null` → `{WORK_DIR}/functional_run.ndjson`; then `rm -f "$BODY"` UNCONDITIONALLY (even on timeout).
792
- - **prompt-template**: expand the template with substitution from the Test Scenario; `<wrapper> pi --mode json -p --no-session "<expanded text>" </dev/null` → `{WORK_DIR}/functional_run.ndjson`.
793
- - **extension**: `<wrapper> pi -e ./{built extension .ts path from build_report.md} </dev/null` → `{WORK_DIR}/functional_run.ndjson` (jiti load; no compile step).
971
+ **Primary (new-capability) exercise — per-asset-type bounded command** (stream stdout to `{WORK_DIR}/functional_run{SUFFIX_A}.ndjson`; capture wrapper exit code as `FUNCTIONAL_EXIT[A]`):
972
+ - A.asset_type == **agent**: `BODY="$(mktemp)"`; write A's agent body (everything after the closing frontmatter `---` of `A.resolved_path`) to `$BODY`; `<wrapper> pi --mode json -p --no-session --append-system-prompt "$BODY" "Task: {a task derived from this phase's Test Scenario new-capability criterion (Criterion A)}" </dev/null` → `{WORK_DIR}/functional_run{SUFFIX_A}.ndjson`; then `rm -f "$BODY"` UNCONDITIONALLY (even on timeout).
973
+ - A.asset_type == **prompt-template**: expand A's template with substitution from THIS phase's Test Scenario; `<wrapper> pi --mode json -p --no-session "<expanded text>" </dev/null` → `{WORK_DIR}/functional_run{SUFFIX_A}.ndjson`.
974
+ - A.asset_type == **extension**: `<wrapper> pi -e ./{A.resolved_path} </dev/null` → `{WORK_DIR}/functional_run{SUFFIX_A}.ndjson` (jiti load; no compile step).
975
+ - A.asset_type == **skill**: SKIPPED per the per-asset skip condition above.
794
976
 
795
- **Capture & artifact contract:**
796
- 1. Stream stdout to `{WORK_DIR}/functional_run.ndjson`.
797
- 2. Record `FUNCTIONAL_EXIT`. 124 (timeout) / 142 (perl-alarm) ⇒ TIMED OUT — record it; the run is bounded, NOT hung.
798
- 3. Extract the final assistant message and write `{WORK_DIR}/functional_final_message.md` with a header line: exact command (with wrapper), `FUNCTIONAL_EXIT`, `TIMEOUT_TOOL`, `PROVIDER_SUBSTITUTION`, `PI_FUNCTIONAL_ALARM`. On timeout/no parseable message, write the timeout/error note + captured tail.
799
- 4. Set `FUNCTIONAL_EXERCISE_RAN = "yes — {command summary}, exit {FUNCTIONAL_EXIT}, provider-substitution: {PROVIDER_SUBSTITUTION}"`.
977
+ **Capture & artifact contract per asset A:**
978
+ 1. Stream stdout to `{WORK_DIR}/functional_run{SUFFIX_A}.ndjson`.
979
+ 2. Record `FUNCTIONAL_EXIT[A]`. 124 (timeout) / 142 (perl-alarm) ⇒ TIMED OUT — record it; the run is bounded, NOT hung.
980
+ 3. Extract the final assistant message and write `{WORK_DIR}/functional_final_message{SUFFIX_A}.md` with a header line: exact command (with wrapper), `FUNCTIONAL_EXIT[A]`, `TIMEOUT_TOOL`, `PROVIDER_SUBSTITUTION`, `PI_FUNCTIONAL_ALARM`. On timeout/no parseable message, write the timeout/error note + captured tail.
981
+ 4. Set `FUNCTIONAL_EXERCISE_RAN[A] = "yes — {command summary}, exit {FUNCTIONAL_EXIT[A]}, provider-substitution: {PROVIDER_SUBSTITUTION}"`.
800
982
 
801
- **SECOND (regression) exercise — ALWAYS run (ASSET_ACTION is always "modify"; the `_regression` artifact convention is DEFINED by `reference/pi-asset-modification-guide.md` §3.3):** with the SAME wrapper, run the asset's ORIGINAL capability (for an extension, the original tool dispatch the spec's regression criterion names; for an agent, the original role task; for a prompt-template, the original expansion). Stream stdout to `{WORK_DIR}/functional_run_regression.ndjson`; extract the final assistant message to `{WORK_DIR}/functional_final_message_regression.md` with the same header line shape.
983
+ **SECOND (regression) exercise per asset A — ALWAYS run** (every phase is action: modify; the `_regression` artifact convention is DEFINED by `reference/pi-asset-modification-guide.md` §3 — single-pair under §3.3 default, per-asset-suffix under §3.4 "Multi-Asset Coordinated Sets"): with the SAME wrapper, run A's ORIGINAL capability (for an extension, the original tool dispatch the phase's regression criterion names; for an agent, the original role task; for a prompt-template, the original expansion). Stream stdout to `{WORK_DIR}/functional_run{SUFFIX_A}_regression.ndjson`; extract the final assistant message to `{WORK_DIR}/functional_final_message{SUFFIX_A}_regression.md` with the same header line shape.
802
984
 
803
- **Artifact-existence assertion (orchestrator, fast).** Confirm `{WORK_DIR}/functional_run.ndjson` is non-empty and `{WORK_DIR}/functional_final_message.md` exists with its header, AND `{WORK_DIR}/functional_run_regression.ndjson` is non-empty and `{WORK_DIR}/functional_final_message_regression.md` exists with its header. If a `pi` run was attempted but any required artifact is absent/empty/headerless, set `FUNCTIONAL_ARTIFACT_OK = "no — <which file> missing/empty"`; else `FUNCTIONAL_ARTIFACT_OK = "yes"`. (Skill: `FUNCTIONAL_ARTIFACT_OK = "n/a (skill — load-and-verify)"`.) Thread `FUNCTIONAL_ARTIFACT_OK` into the 5d validator prompt.
985
+ **Artifact-existence assertion per asset** (orchestrator, fast). For each A, confirm `{WORK_DIR}/functional_run{SUFFIX_A}.ndjson` is non-empty and `{WORK_DIR}/functional_final_message{SUFFIX_A}.md` exists with its header, AND `{WORK_DIR}/functional_run{SUFFIX_A}_regression.ndjson` is non-empty and `{WORK_DIR}/functional_final_message{SUFFIX_A}_regression.md` exists with its header. If a `pi` run was attempted for A but any required artifact for A is absent/empty/headerless, set `FUNCTIONAL_ARTIFACT_OK[A] = "no — <which file> missing/empty"`; else `FUNCTIONAL_ARTIFACT_OK[A] = "yes"`. (Skill phases: `FUNCTIONAL_ARTIFACT_OK[A] = "n/a (skill — load-and-verify)"`.) Thread the full per-asset map into the 5d validator prompt.
804
986
 
805
987
  Proceed to 5d.
806
988
 
807
989
  **Manual fallback format** (written to `{WORK_DIR}/manual_test_instructions.md` ONLY when an interactive-only verification is required, OR `PI_AVAILABLE == "no"`):
808
990
  ```
809
- # Manual Test: {ASSET_NAME} ({ASSET_TYPE}, modify)
991
+ # Manual Test: Coordinated Repair ({AFFECTED_ASSETS_COUNT} asset{s}, modify)
810
992
 
811
993
  ## Why Manual
812
- {"Pi is not installed in this environment (npm ls -g @earendil-works/pi-coding-agent / command -v pi did not resolve)." | "This verification is interactive-only."}
994
+ {"Pi is not installed in this environment (npm ls -g @earendil-works/pi-coding-agent / command -v pi did not resolve)." | "One or more verifications are interactive-only."}
995
+
996
+ {For each A in AFFECTED_ASSETS, one section:}
813
997
 
814
- ## Setup
815
- {Extract setup from the spec's Test Scenario}
998
+ ## Phase {N}: {A.asset_type} — {A.asset_name}
816
999
 
817
- ## Run (new capability)
818
- {The exact headless command that would have run}
819
- ## Run (regression — original capability)
820
- {The exact headless regression command that would have run}
1000
+ ### Setup
1001
+ {Extract setup from this phase's Test Scenario}
821
1002
 
822
- ## Expected Behavior
823
- {Extract expected behaviour from the Test Scenario, numbered include BOTH the new-capability and regression criteria}
1003
+ ### Run (new capability)
1004
+ {The exact headless command that would have run for A}
824
1005
 
825
- ## Success Criteria
826
- {The dual-criterion checkboxes from the spec's Test Scenario: Criterion A (new) AND Criterion B (regression)}
1006
+ ### Run (regression — original capability)
1007
+ {The exact headless regression command that would have run for A}
1008
+
1009
+ ### Expected Behavior
1010
+ {Extract expected behavior from this phase's Test Scenario, numbered — include BOTH the new-capability and regression criteria}
1011
+
1012
+ ### Success Criteria
1013
+ {The dual-criterion checkboxes from this phase's Test Scenario: Criterion A (new) AND Criterion B (regression) — name the per-asset-suffixed `_regression` artifact filenames per ARTIFACT_SUFFIX_POLICY}
827
1014
  ```
828
1015
 
829
- #### 5d. Spawn Build Validator (Structural + Captured-Artifact Evaluation)
1016
+ #### 5d. Spawn Build Validator (Structural + Captured-Artifact Evaluation — per-asset iteration)
830
1017
 
831
1018
  Delegate via Agent tool (`subagent_type: "pi-validator-agent"`) with this prompt:
832
1019
 
833
1020
  ```
834
- You are validating a MODIFIED Pi asset: {ASSET_TYPE} "{ASSET_NAME}" (modify).
1021
+ You are validating a built coordinated repair across {AFFECTED_ASSETS_COUNT} Pi asset(s). Every phase carries action: modify.
835
1022
 
836
1023
  ## Required First Step (teammate gotcha)
837
- Invoke the `pi-primitives` skill using the Skill tool before validating. If you were spawned as a team teammate, your `skills:` frontmatter was NOT auto-applied — self-arm now. (On the normal Agent path this is already loaded; re-invoking is harmless.) Route via the `pi-primitives` SKILL.md to `reference/pi-asset-modification-guide.md`: §3 mandates the Regression check for `action == modify` and DEFINES the `_regression` artifact convention (do NOT attribute it to `pi-testing-validation-guide.md`); §2 owns the Consumer-regression check.
1024
+ Invoke the `pi-primitives` skill using the Skill tool before validating. If you were spawned as a team teammate, your `skills:` frontmatter was NOT auto-applied — self-arm now. (On the normal Agent path this is already loaded; re-invoking is harmless.) Route via the `pi-primitives` SKILL.md to `reference/pi-asset-modification-guide.md`: §3 (incl. §3.4 — single-pair AND per-asset-suffix conventions) mandates the Regression check for every action: modify phase and DEFINES both `_regression` artifact conventions (do NOT attribute either to `pi-testing-validation-guide.md`); §2 owns the Consumer-regression check per phase.
838
1025
 
839
1026
  ## Context
840
- The orchestrator ran the bounded, stdin-guarded headless `pi` exercises INLINE in 5c and captured the output. Your job is to EVALUATE the captured artifacts (including the `_regression` variants), NOT to run `pi`. **You MUST NOT spawn any `pi` subprocess.** PI_AVAILABLE = {PI_AVAILABLE}.
1027
+ The orchestrator ran the bounded, stdin-guarded headless `pi` exercises INLINE in 5c and captured the output PER ASSET. Your job is to EVALUATE the captured artifacts (including the `_regression` variants) PER ASSET, NOT to run `pi`. **You MUST NOT spawn any `pi` subprocess.** PI_AVAILABLE = {PI_AVAILABLE}; ARTIFACT_SUFFIX_POLICY = {ARTIFACT_SUFFIX_POLICY}; AFFECTED_ASSETS_COUNT = {AFFECTED_ASSETS_COUNT}.
1028
+
1029
+ ## Per-Asset Functional Artifacts (already captured — DO NOT run `pi`)
1030
+ {For each A in AFFECTED_ASSETS, with SUFFIX_A = "" if ARTIFACT_SUFFIX_POLICY == "single-pair" else "_{A.kebab_slug}":}
1031
+ Phase {N} — {A.asset_type} {A.asset_name} ({A.resolved_path}):
1032
+ - New-capability run: {WORK_DIR}/functional_run{SUFFIX_A}.ndjson + {WORK_DIR}/functional_final_message{SUFFIX_A}.md
1033
+ - Regression run (original capability): {WORK_DIR}/functional_run{SUFFIX_A}_regression.ndjson + {WORK_DIR}/functional_final_message{SUFFIX_A}_regression.md
1034
+ - FUNCTIONAL_EXERCISE_RAN[A] = {FUNCTIONAL_EXERCISE_RAN[A]}; FUNCTIONAL_ARTIFACT_OK[A] = {FUNCTIONAL_ARTIFACT_OK[A]}
1035
+ PROVIDER_SUBSTITUTION = {PROVIDER_SUBSTITUTION}
841
1036
 
842
- ## Functional artifacts (already captured DO NOT run `pi`)
843
- - New-capability run: {WORK_DIR}/functional_run.ndjson + {WORK_DIR}/functional_final_message.md
844
- - Regression run (original capability): {WORK_DIR}/functional_run_regression.ndjson + {WORK_DIR}/functional_final_message_regression.md
845
- - FUNCTIONAL_EXERCISE_RAN = {FUNCTIONAL_EXERCISE_RAN}; PROVIDER_SUBSTITUTION = {PROVIDER_SUBSTITUTION}; FUNCTIONAL_ARTIFACT_OK = {FUNCTIONAL_ARTIFACT_OK}
846
- - **ARTIFACT PRECONDITION (every Functional check, incl. the Regression check): Read/Glob the cited artifact FIRST. A Functional check is PASS ONLY if it cites an existing on-disk artifact with path + exact command line + exit code + a quoted output excerpt. If `FUNCTIONAL_ARTIFACT_OK` is not "yes"/"n/a", or the artifact is absent/empty/headerless, the check is FAIL (or BLOCKED only if Pi was not installed) — NEVER PASS on a narrative assertion.** (Skill load-and-verify has no runtime artifact.)
847
- You DO still run these with Bash: structural Grep/Glob/Read checks and (if applicable) the vendored-extension byte-parity `diff` against `$(npm root -g)/@earendil-works/pi-coding-agent` — UNLESS the design spec's §4 regime declares a conscious documented fork, in which case do NOT expect the diff.
1037
+ - **ARTIFACT PRECONDITION (per asset, every Functional check incl. the Regression check): Read/Glob the cited artifact FIRST. A Functional check is PASS ONLY if it cites an existing on-disk artifact with path + exact command line + exit code + a quoted output excerpt. If `FUNCTIONAL_ARTIFACT_OK[A]` is not "yes"/"n/a", or the artifact is absent/empty/headerless, the check is FAIL for that asset (or BLOCKED only if Pi was not installed) — NEVER PASS on a narrative assertion.** (Skill phases have no runtime artifact.)
1038
+ You DO still run these with Bash: structural Grep/Glob/Read checks PER ASSET and (per asset, if applicable) the vendored-extension byte-parity `diff` against `$(npm root -g)/@earendil-works/pi-coding-agent` — UNLESS that phase's §4 regime declares a conscious documented fork, in which case do NOT expect the diff for that asset.
848
1039
 
849
- ## Design Specification (intended behavior)
850
- Read the design spec at: {WORK_DIR}/design_spec.md (frontmatter `action: modify`)
1040
+ ## Plan (intended behavior)
1041
+ Read the plan at: {WORK_DIR}/design_spec.md (frontmatter `type: pi-assets-plan`, `task: modify-pi-assets`, action: modify across every phase)
851
1042
 
852
1043
  ## Build Report (what was built)
853
1044
  Read the build report at: {WORK_DIR}/build_report.md
854
1045
 
855
1046
  ## Validation Checks ({BUILD_CHECK_COUNT} total — run ALL of these)
856
1047
 
857
- {Paste the assembled unified checklist from 5b HERE VERBATIM — all structural checks for this ASSET_TYPE, the Consumer-regression structural add-on, all functional checks for this ASSET_TYPE, and the Regression functional add-on. Do NOT abbreviate, do NOT replace with "see the guide". You hard-error "No validation checks provided." if the checklist is absent.}
1048
+ {Paste the assembled unified checklist from 5b HERE VERBATIM — per-asset structural checks (multiplied across every phase), the per-asset Consumer-regression structural add-on, per-asset functional checks (multiplied), the per-asset Regression functional add-on. Do NOT abbreviate, do NOT replace with "see the guide". You hard-error "No validation checks provided." if the checklist is absent.}
858
1049
 
859
1050
  ## Validation Parameters
860
1051
  - task: modify-pi-assets
861
1052
  - phase: 2
862
1053
  - phase-name: Modify Pi Assets Command
863
1054
  - cycle: {BUILD_VALIDATION_CYCLE}
1055
+ - affected-asset-count: {AFFECTED_ASSETS_COUNT}
1056
+ - artifact-suffix-policy: {ARTIFACT_SUFFIX_POLICY}
864
1057
 
865
- ## Verdict Rules (read before scoring)
1058
+ ## Verdict Rules (read before scoring — apply PER ASSET)
866
1059
  - A Functional check is PASS ONLY if it cites an EXISTING on-disk artifact: path + the exact command line + exit code + a quoted output excerpt. Verify artifact existence Read/Glob FIRST. Absent/headerless ⇒ never PASS (FAIL, or BLOCKED only if Pi was not installed).
867
- - The **Regression check** PASSes ONLY if the captured `{WORK_DIR}/functional_run_regression.ndjson` / `functional_final_message_regression.md` artifact shows the original capability still works.
1060
+ - The **Regression check for each phase** PASSes ONLY if THAT phase's `functional_run{SUFFIX_A}_regression.ndjson` / `functional_final_message{SUFFIX_A}_regression.md` shows the original capability still works.
868
1061
  - NEVER record an error originating from the asset's OWN configured model/provider/credentials (`No API key found`, auth/login, `Parallel: N/0 succeeded`) as an environment substitution. That is an ASSET defect → FAIL (or BLOCKED ONLY for an explicitly user-accepted pin).
869
1062
  - Allowed verdicts: PASS, FAIL, BLOCKED. BLOCKED is never PASS and is surfaced to the user. When in doubt between FAIL and BLOCKED, choose FAIL.
870
1063
 
871
1064
  ## Output
872
1065
  Write your validation report to: {WORK_DIR}/build_validation_report.md
873
- YAML frontmatter with the parameters above plus: `result: pass|fail|blocked`, `checks-passed: X/{BUILD_CHECK_COUNT}`, `structural-passed: X/{STRUCTURAL_CHECK_COUNT}`, `functional-passed: X/{FUNCTIONAL_CHECK_COUNT}`, `blocked-checks: X/{BUILD_CHECK_COUNT}`.
874
- In the Checks table mark each check Type = "Structural" or "Functional"; mark any manual-fallback check "Functional (manual fallback — Pi not installed / interactive-only)".
1066
+ YAML frontmatter with the parameters above plus: `result: pass|fail|blocked` (overall — pass requires every phase pass), `checks-passed: X/{BUILD_CHECK_COUNT}`, `structural-passed: X/{STRUCTURAL_CHECK_COUNT}`, `functional-passed: X/{FUNCTIONAL_CHECK_COUNT}`, `blocked-checks: X/{BUILD_CHECK_COUNT}`.
1067
+ In the Checks table, tag each check with scope "Phase {N}" or "Plan"/"Set" and Type ("Structural" or "Functional"). Mark any manual-fallback check "Functional (manual fallback — Pi not installed / interactive-only)".
875
1068
  Write using the Write tool. Return the file path AND the overall result.
876
1069
  ```
877
1070
 
@@ -879,8 +1072,9 @@ After the Agent returns:
879
1072
  1. Read `{WORK_DIR}/build_validation_report.md`. Extract `result`, `structural-passed`, `functional-passed`. If returned inline, Write it. If missing entirely, warn and treat as FAIL.
880
1073
  2. Store `STRUCTURAL_CHECKS_PASSED`, `FUNCTIONAL_CHECKS_PASSED`.
881
1074
 
882
- #### 5d-cross. Orchestrator Verdict Cross-Check
883
- If `{WORK_DIR}/functional_run.ndjson` exists, Grep it AND `{WORK_DIR}/functional_run_regression.ndjson` for asset-own-failure signatures: `No API key found`, `Parallel: [0-9]+/0 succeeded`, `Parallel: 0/[0-9]+ succeeded`, `"exitCode":1`, `auth`/`login` error lines, `not authenticated`. If ANY match AND the validator scored that portion `pass`, OVERRIDE: set `BUILD_VALIDATION_RESULT = "fail"` (or `"blocked"` ONLY if the design spec / Key Considerations records an explicitly user-accepted provider pin). Record `VERDICT_CROSSCHECK = "override: validator PASS contradicted by <matched signature> in <which ndjson>"`. If no match, `VERDICT_CROSSCHECK = "N/A (no contradicting signal)"` and accept the validator's result. Literal-string grep only — not a re-validation.
1075
+ #### 5d-cross. Orchestrator Verdict Cross-Check (per-asset iteration)
1076
+
1077
+ For each A in AFFECTED_ASSETS (with SUFFIX_A computed per `ARTIFACT_SUFFIX_POLICY`: `""` when single-pair, `"_{A.kebab_slug}"` when per-asset-suffix): if `{WORK_DIR}/functional_run{SUFFIX_A}.ndjson` exists, Grep it AND `{WORK_DIR}/functional_run{SUFFIX_A}_regression.ndjson` for asset-own-failure signatures: `No API key found`, `Parallel: [0-9]+/0 succeeded`, `Parallel: 0/[0-9]+ succeeded`, `"exitCode":1`, `auth`/`login` error lines, `not authenticated`. If ANY match AND the validator scored that phase's portion `pass`, OVERRIDE for that phase: set the phase's verdict to `fail` (or `blocked` ONLY if the plan's `## 6. Key Considerations` records an explicitly user-accepted provider pin). Aggregate: if ANY phase's verdict becomes `fail` post-override, set `BUILD_VALIDATION_RESULT = "fail"`; else if any phase becomes `blocked`, set `BUILD_VALIDATION_RESULT = "blocked"`; else accept the validator's overall result. Record `VERDICT_CROSSCHECK = "override: validator PASS contradicted by <matched signature> in <which ndjson> for Phase {N} ({A.asset_name})"` (one entry per overridden phase), or `VERDICT_CROSSCHECK = "N/A (no contradicting signal across any phase)"` if no match anywhere. Literal-string grep only — not a re-validation.
884
1078
 
885
1079
  #### 5e. Handle Result
886
1080
 
@@ -898,8 +1092,11 @@ Present and WAIT:
898
1092
  ```
899
1093
  BLOCKED — cannot auto-complete (functional verification could not be honestly established)
900
1094
 
901
- Target: {RESOLVED_ASSET_PATH} ({ASSET_TYPE} — {ASSET_NAME}, modify)
902
- Reason: {the BLOCKED reason — non-asset/external, or a user-accepted provider pin}
1095
+ Problem: {PROBLEM_INPUT}
1096
+ Affected assets ({AFFECTED_ASSETS_COUNT}, all action: modify):
1097
+ {For each A in AFFECTED_ASSETS:}
1098
+ - Phase {N}: {A.resolved_path} ({A.asset_type} — {A.asset_name})
1099
+ Reason: {the BLOCKED reason — non-asset/external, or a user-accepted provider pin; identify which phase(s) the BLOCKED applies to}
903
1100
  Blocked checks: {list from the validation report's "Blocked Checks" section}
904
1101
  {If VERDICT_CROSSCHECK is an override: "Orchestrator cross-check: {VERDICT_CROSSCHECK}"}
905
1102
 
@@ -921,37 +1118,42 @@ If any failure is design-level, go directly to 5g.
921
1118
  **Spawn Fix-Builder** — Delegate via Agent tool (`subagent_type: "pi-meta-agent"`) with this prompt:
922
1119
 
923
1120
  ```
924
- You are FIXING build issues for the MODIFIED Pi asset: {ASSET_TYPE} "{ASSET_NAME}" (modify).
925
- This is fix cycle {BUILD_VALIDATION_CYCLE}.
1121
+ You are FIXING build issues for a coordinated repair across {AFFECTED_ASSETS_COUNT} Pi asset(s). Every phase carries action: modify. This is fix cycle {BUILD_VALIDATION_CYCLE}.
926
1122
 
927
1123
  ## Required First Step (teammate gotcha)
928
- Invoke the `pi-primitives` skill using the Skill tool before fixing. If you were spawned as a team teammate, your `skills:` frontmatter was NOT auto-applied — self-arm now. (On the normal Agent path this is already injected; re-invoking is harmless.) Route via the `pi-primitives` SKILL.md to `reference/pi-asset-modification-guide.md` §4 — it governs the preservation regime for your Read-then-Edit/MultiEdit.
1124
+ Invoke the `pi-primitives` skill using the Skill tool before fixing. If you were spawned as a team teammate, your `skills:` frontmatter was NOT auto-applied — self-arm now. (On the normal Agent path this is already injected; re-invoking is harmless.) Route via the `pi-primitives` SKILL.md to `reference/pi-asset-modification-guide.md` §4 — it governs the preservation regime for your Read-then-Edit/MultiEdit (apply PER PHASE).
929
1125
 
930
- ## Design Specification (intended behavior)
931
- Read the design spec at: {WORK_DIR}/design_spec.md (action: modify)
1126
+ ## Plan (intended behavior)
1127
+ Read the plan at: {WORK_DIR}/design_spec.md (frontmatter `type: pi-assets-plan`, `task: modify-pi-assets`, `phases: {AFFECTED_ASSETS_COUNT}`)
932
1128
 
933
1129
  ## Build Validation Report
934
1130
  Read the validation report at: {WORK_DIR}/build_validation_report.md
935
- Focus on "Issues Found" — both structural and functional failures.
1131
+ Focus on "Issues Found" — each issue is tagged Plan / Phase {N} / Set. Fix EVERY issue, in the scope tagged.
1132
+
1133
+ ## Affected Assets (one phase per entry — iterate in plan order)
1134
+ {For each A in AFFECTED_ASSETS:}
1135
+ - Phase {N}: {A.asset_type} — {A.asset_name} ({A.resolved_path})
936
1136
 
937
1137
  ## Fix Instructions
938
- - Read the design spec and validation report before changing anything.
939
- - Fix EVERY issue listed under "Issues Found" structural and functional.
940
- - Do NOT break things currently passing — check "Verified Claims".
941
- - Preserve byte-for-byte the sections the spec's "Preserved (byte-for-byte)" section marks Preserved. NEVER rewrite the whole file — Read-then-Edit/MultiEdit only.
942
- - Honor the §4 preservation regime the spec declares.
943
- {If COMMAND_USER_TEST == "fail": "- User-reported manual-fallback failure: {user's failure description}. Fix the asset to address this."}
1138
+ - Read the plan and validation report before changing anything.
1139
+ - For each issue, identify which phase / scope it belongs to and apply the fix in that scope.
1140
+ - Do NOT break things currently passing — check "Verified Claims" per phase.
1141
+ - Preserve byte-for-byte the sections each phase's Preserved (byte-for-byte) subsection marks Preserved. NEVER rewrite the whole file — Read-then-Edit/MultiEdit only, per phase.
1142
+ - Honor each phase's §4 preservation regime.
1143
+ - A Set-scope issue (e.g. coordination consistency) is fixed by editing the affected phase(s) on both sides of the cross-asset link.
1144
+ {If COMMAND_USER_TEST == "fail": "- User-reported manual-fallback failure: {user's failure description}. Fix the relevant phase(s)."}
944
1145
 
945
1146
  ## Output
946
- Write a fix report to: {WORK_DIR}/fix_report_cycle{BUILD_VALIDATION_CYCLE}.md
1147
+ Write a single fix report covering ALL phases to: {WORK_DIR}/fix_report_cycle{BUILD_VALIDATION_CYCLE}.md
947
1148
 
948
- ## Fix Report: {ASSET_NAME} (Cycle {BUILD_VALIDATION_CYCLE})
1149
+ ## Fix Report: Coordinated Repair (Cycle {BUILD_VALIDATION_CYCLE}) — {AFFECTED_ASSETS_COUNT} asset(s)
949
1150
 
950
1151
  ### Issues Fixed
951
- - {check/test name}: {what changed and why}
1152
+ - {check/test name (scope: Plan / Phase {N} / Set)}: {what changed and why}
952
1153
 
953
- ### Files Modified
954
- - {file path} {what changed}
1154
+ ### Files Modified (per phase)
1155
+ {For each phase touched in this fix cycle:}
1156
+ - Phase {N} ({A.asset_name}): {file path} — {what changed}
955
1157
 
956
1158
  ### Unresolved Issues
957
1159
  - {any unfixable issues, or "None"}
@@ -969,10 +1171,13 @@ If validation failed 3 times OR a design-level failure was detected, present:
969
1171
  ```
970
1172
  BUILD VALIDATION FAILED{" after 3 cycles" | " — design-level issue detected"}.
971
1173
 
972
- Target: {RESOLVED_ASSET_PATH} ({ASSET_TYPE} — {ASSET_NAME}, modify)
1174
+ Problem: {PROBLEM_INPUT}
1175
+ Affected assets ({AFFECTED_ASSETS_COUNT}, all action: modify):
1176
+ {For each A in AFFECTED_ASSETS:}
1177
+ - Phase {N}: {A.resolved_path} ({A.asset_type} — {A.asset_name})
973
1178
  Structural: {STRUCTURAL_CHECKS_PASSED}/{STRUCTURAL_CHECK_COUNT} passed
974
1179
  Functional: {FUNCTIONAL_CHECKS_PASSED}/{FUNCTIONAL_CHECK_COUNT} passed
975
- {If FUNCTIONAL_EXIT in (124,142): "Functional exercise: TIMED OUT (bounded at {PI_FUNCTIONAL_ALARM}s by {TIMEOUT_TOOL}) — bounded, not hung"}
1180
+ {If any A has FUNCTIONAL_EXIT[A] in (124,142): "Functional exercise(s) TIMED OUT (bounded at {PI_FUNCTIONAL_ALARM}s by {TIMEOUT_TOOL}) on phase(s): {list of phase numbers} — bounded, not hung"}
976
1181
 
977
1182
  Remaining failures:
978
1183
  - {check/test name — problem summary}
@@ -988,69 +1193,80 @@ Fix reports: {list any fix_report_cycle*.md paths}
988
1193
 
989
1194
  Compile a terminal report from all {WORK_DIR} artifacts and present a console summary.
990
1195
 
991
- #### 6a. Read Source Artifacts
992
- Read: `{WORK_DIR}/design_spec.md` (check `status: revised`), `{WORK_DIR}/build_report.md`, `{WORK_DIR}/design_validation_report.md` (cycle), `{WORK_DIR}/build_validation_report.md` (result, counts, cycle), any `{WORK_DIR}/fix_report_cycle*.md`, `{WORK_DIR}/functional_run.ndjson` + `functional_final_message.md` AND `{WORK_DIR}/functional_run_regression.ndjson` + `functional_final_message_regression.md` (note `FUNCTIONAL_EXIT`, `TIMEOUT_TOOL`, `PROVIDER_SUBSTITUTION` from the headers). Count lines with `wc -l {WORK_DIR}/*` via Bash.
1196
+ #### 6a. Read Source Artifacts (per asset)
1197
+ Read: `{WORK_DIR}/design_spec.md` (check `status: revised`, verify `type: pi-assets-plan` and `phases: {AFFECTED_ASSETS_COUNT}`), `{WORK_DIR}/build_report.md`, `{WORK_DIR}/design_validation_report.md` (cycle), `{WORK_DIR}/build_validation_report.md` (result, counts, cycle), any `{WORK_DIR}/fix_report_cycle*.md`. For each A in AFFECTED_ASSETS, with SUFFIX_A computed per `ARTIFACT_SUFFIX_POLICY`, read (if they exist): `{WORK_DIR}/functional_run{SUFFIX_A}.ndjson` + `functional_final_message{SUFFIX_A}.md` AND `{WORK_DIR}/functional_run{SUFFIX_A}_regression.ndjson` + `functional_final_message{SUFFIX_A}_regression.md`, noting `FUNCTIONAL_EXIT[A]`, `TIMEOUT_TOOL`, `PROVIDER_SUBSTITUTION` from each header. Count lines with `wc -l {WORK_DIR}/*` via Bash.
993
1198
 
994
1199
  #### 6b. Compile Report Data
995
- - **What Was Built:** files modified from build_report.md, plus any fix-cycle modifications (note "(modified in fix cycle N)"), with the byte-preservation note (which Preserved sections were left byte-identical).
996
- - **Test Results:** every check from the final build_validation_report.md Checks table + the functional + regression checks, with Type (Structural/Functional) and result.
997
- - **Regression Result:** original capability re-verified (PASS) / BLOCKED / FAIL.
998
- - **Gate outcomes:** `GATE_A_RESULT`, `GATE_B_RESULT`, `GATE_C_RESULT` (each is `"confirmed"`, `"skipped (--auto-confirm)"`, `"revised then confirmed (N revisions)"`, or `"stopped at gate"`). Any value containing `"revised then confirmed"` counts as a deviation. A `"skipped (--auto-confirm)"` value is NOT a deviation (it is the documented headless behavior).
999
- - **Deviations:** design revision (design_validation_report cycle > 1); build issues (non-"None"); each fix cycle; manual-fallback substitution (Pi not installed / interactive-only); provider/timeout substitution (`PROVIDER_SUBSTITUTION != "N/A"` or `FUNCTIONAL_EXIT` in 124/142); a BLOCKED outcome; a 5d-cross override; any gate result containing `"revised then confirmed"`.
1000
- - Set `REPORT_STATUS`: `"completed"` if clean pass with no deviations and no BLOCKED checks; `"completed-with-deviations"` if any deviation or BLOCKED check or a 5d-cross override; `"FAILED"` only if Step 5g was reached (in which case execution already stopped — this status is for the terminal report only if a partial report is still produced).
1200
+ - **What Was Built (per phase):** for each A, the file(s) modified from build_report.md (Phase {N}), plus any fix-cycle modifications (note "(modified in fix cycle M)"), with the per-phase byte-preservation note (which Preserved sections were left byte-identical).
1201
+ - **Test Results (per phase):** every check from the final build_validation_report.md Checks table, tagged by scope (Plan / Phase {N} / Set) and Type (Structural/Functional) with its result.
1202
+ - **Per-asset Regression Results:** for each A, original capability re-verified (PASS) / BLOCKED / FAIL — drawn from the validator's per-phase Regression check verdict.
1203
+ - **Gate outcomes:** `GATE_A_RESULT`, `GATE_B_RESULT`, `GATE_C_RESULT` (each is `"confirmed"`, `"skipped (--auto-confirm)"`, `"revised then confirmed (N revisions)"`, or `"stopped at gate"`). Any value containing `"revised then confirmed"` counts as a deviation. A `"skipped (--auto-confirm)"` value is NOT a deviation.
1204
+ - **Deviations:** design revision (design_validation_report cycle > 1); build issues (non-"None") per phase; each fix cycle; manual-fallback substitution (Pi not installed / interactive-only) per phase; provider/timeout substitution (`PROVIDER_SUBSTITUTION != "N/A"` or any `FUNCTIONAL_EXIT[A]` in 124/142); any BLOCKED outcome per phase; a 5d-cross override per phase; any gate result containing `"revised then confirmed"`.
1205
+ - Set `REPORT_STATUS`: `"completed"` if clean pass across every phase with no deviations and no BLOCKED checks; `"completed-with-deviations"` if any deviation or BLOCKED check or a 5d-cross override on any phase; `"FAILED"` only if Step 5g was reached.
1001
1206
 
1002
1207
  #### 6c. Present Terminal Report
1003
1208
  ```
1004
- MODIFY PI ASSET COMPLETE
1209
+ MODIFY PI ASSETS COMPLETE — COORDINATED CHANGE SET ({AFFECTED_ASSETS_COUNT} ASSET{S})
1005
1210
 
1006
- Modification request: {MOD_REQUEST}
1007
- Target: {RESOLVED_ASSET_PATH} ({ASSET_TYPE} — {ASSET_NAME}, modify)
1008
- Blast radius: {Isolated|Contained|Broad — from explorer_a_findings.md / design_spec Trio Impact}
1211
+ Problem: {PROBLEM_INPUT}
1212
+ Intake shape: {INTAKE_SHAPE}
1213
+ Affected-asset count: {AFFECTED_ASSETS_COUNT}
1214
+ Artifact convention: {ARTIFACT_SUFFIX_POLICY}
1215
+ Set-level blast radius: {Isolated|Contained|Broad — from explorer_a_findings.md set-level aggregation}
1009
1216
  Working directory: {WORK_DIR}
1010
1217
 
1011
- Files modified (byte-preservation): {list; note Preserved sections left byte-identical}
1012
-
1013
- Design validation: {DESIGN_VALIDATION_RESULT} (cycle {DESIGN_VALIDATION_CYCLE_FINAL}) — {X}/10
1014
- Build validation: {BUILD_VALIDATION_RESULT} (cycle {BUILD_VALIDATION_CYCLE})
1218
+ Per-asset (one block per phase):
1219
+ {For each A in AFFECTED_ASSETS, with SUFFIX_A computed per ARTIFACT_SUFFIX_POLICY:}
1220
+ ─── Phase {N}: {A.asset_type} — {A.asset_name} ───────────────────────────
1221
+ Target: {A.resolved_path}
1222
+ Proposed modification: {A.proposed_modification}
1223
+ Files modified (byte-preservation): {A.resolved_path} — {Preserved sections left byte-identical}
1224
+ Per-phase blast radius: {Isolated|Contained|Broad}
1225
+ Functional mode: {"automated headless pi (inline, bounded by {TIMEOUT_TOOL} @ {PI_FUNCTIONAL_ALARM}s; provider-substitution: {PROVIDER_SUBSTITUTION})" | "manual fallback (Pi not installed)" | "manual fallback (interactive-only)" | "BLOCKED (Pi not runnable here)" | "n/a (skill — load-and-verify)"}
1226
+ New-capability result: {PASS | FAIL | BLOCKED} (artifact: functional_run{SUFFIX_A}.ndjson)
1227
+ Regression result: {original capability re-verified PASS | BLOCKED | FAIL} (artifact: functional_run{SUFFIX_A}_regression.ndjson)
1228
+
1229
+ Design validation: {DESIGN_VALIDATION_RESULT} (cycle {DESIGN_VALIDATION_CYCLE_FINAL}) — {X}/{DESIGN_CHECK_COUNT} (plan: 5; per-asset: 5 × {AFFECTED_ASSETS_COUNT}; set coordination: 1)
1230
+ Build validation: {BUILD_VALIDATION_RESULT} (cycle {BUILD_VALIDATION_CYCLE}) — {X}/{BUILD_CHECK_COUNT}
1015
1231
  - Structural: {STRUCTURAL_CHECKS_PASSED}/{STRUCTURAL_CHECK_COUNT}
1016
1232
  - Functional: {FUNCTIONAL_CHECKS_PASSED}/{FUNCTIONAL_CHECK_COUNT}
1017
- - Functional mode: {"automated headless pi (inline, bounded by {TIMEOUT_TOOL} @ {PI_FUNCTIONAL_ALARM}s; provider-substitution: {PROVIDER_SUBSTITUTION})" | "manual fallback (Pi not installed)" | "manual fallback (interactive-only)" | "BLOCKED (Pi not runnable here)"}
1018
- - Regression result: {original capability re-verified PASS | BLOCKED (Pi not runnable here) | FAIL}
1019
1233
  - Fix cycles: {BUILD_VALIDATION_CYCLE - 1} {or "None (passed first try)"}
1020
1234
 
1021
1235
  Gates: intake={GATE_A_RESULT}; post-research={GATE_B_RESULT}; build-approval={GATE_C_RESULT}
1022
- Recorded substitutions / BLOCKED deviations: {PROVIDER_SUBSTITUTION / timeout / Pi-not-installed / VERDICT_CROSSCHECK, or "None"}
1236
+ Recorded substitutions / BLOCKED deviations: {PROVIDER_SUBSTITUTION / per-phase timeouts / Pi-not-installed / VERDICT_CROSSCHECK overrides, or "None"}
1023
1237
 
1024
1238
  Artifacts (absolute paths):
1025
1239
  - {WORK_DIR}/explorer_a_findings.md, explorer_b_findings.md
1026
- - {WORK_DIR}/design_spec.md, design_validation_report.md
1240
+ - {WORK_DIR}/design_spec.md (pi-assets-plan), design_validation_report.md
1027
1241
  - {WORK_DIR}/build_report.md, build_validation_report.md
1028
1242
  {- {WORK_DIR}/fix_report_cycle{N}.md — per fix cycle, if any}
1029
- {- {WORK_DIR}/functional_run.ndjson / functional_final_message.md — if the exercise ran}
1030
- {- {WORK_DIR}/functional_run_regression.ndjson / functional_final_message_regression.md — always for modify, if the exercise ran}
1243
+ {For each A in AFFECTED_ASSETS:}
1244
+ {- {WORK_DIR}/functional_run{SUFFIX_A}.ndjson / functional_final_message{SUFFIX_A}.md — if A's new-capability exercise ran}
1245
+ {- {WORK_DIR}/functional_run{SUFFIX_A}_regression.ndjson / functional_final_message{SUFFIX_A}_regression.md — always for modify, if A's regression exercise ran}
1031
1246
  {- {WORK_DIR}/manual_test_instructions.md — only if the manual fallback applied}
1032
1247
 
1033
1248
  Final status: {completed | completed-with-deviations | FAILED}
1034
1249
 
1035
- {If REPORT_STATUS == "completed-with-deviations" AND the ONLY deviations are substitutions/BLOCKED/a verdict-override (0 fix cycles AND no genuine asset FAIL):
1250
+ {If REPORT_STATUS == "completed-with-deviations" AND the ONLY deviations are substitutions/BLOCKED/verdict-overrides (0 fix cycles AND no genuine asset FAIL on any phase):
1036
1251
  =====================================================================
1037
1252
  ⚠ FALSE-CLEAN REVIEW REQUIRED — read before trusting this result
1038
- This run reports clean metrics but its ONLY deviations are
1039
- substitutions / BLOCKED / a verdict-cross-check override — the known
1040
- signature of a MASKED functional failure. Do NOT treat this as verified
1041
- until you have read {WORK_DIR}/functional_run.ndjson,
1042
- {WORK_DIR}/functional_run_regression.ndjson, and
1043
- {WORK_DIR}/build_validation_report.md, and confirmed each
1044
- substitution/BLOCKED is genuinely non-asset (not the asset's own
1045
- pinned model/provider failing) and any provider pin was an explicit,
1046
- justified, user-accepted decision.
1253
+ This run reports clean metrics but its ONLY deviations across the
1254
+ {AFFECTED_ASSETS_COUNT}-asset coordinated repair are substitutions /
1255
+ BLOCKED / verdict-cross-check overrides the known signature of a
1256
+ MASKED functional failure. Do NOT treat this as verified until you have
1257
+ read each phase's `functional_run{SUFFIX_A}.ndjson` and
1258
+ `functional_run{SUFFIX_A}_regression.ndjson` (per the artifact list
1259
+ above) plus {WORK_DIR}/build_validation_report.md, and confirmed each
1260
+ substitution/BLOCKED is genuinely non-asset (not the asset's own pinned
1261
+ model/provider failing) and any provider pin was an explicit, justified,
1262
+ user-accepted decision.
1047
1263
  Type "ACK false-clean reviewed" to acknowledge before this run is considered complete.
1048
1264
  =====================================================================}
1049
1265
  ```
1050
1266
 
1051
1267
  ## Report
1052
1268
 
1053
- The terminal report is presented inline by Step 6c above. After presenting it, return to the caller a concise summary containing: the modification request, the resolved target (path, type, name), the blast-radius classification, the working directory, the files modified with the byte-preservation note, the design-validation result and cycle, the build-validation result with structural/functional counts and the functional mode, the regression result, any recorded substitutions / BLOCKED deviations / verdict-override, and the final status (`completed` | `completed-with-deviations` | `FAILED`). Surface every BLOCKED outcome and every deviation explicitly — never silently absorb one. If the FALSE-CLEAN REVIEW banner was shown, state that acknowledgement is required before the run is considered complete.
1269
+ The terminal report is presented inline by Step 6c above. After presenting it, return to the caller a concise summary containing: the problem statement, the intake shape, the discovered affected-asset count and artifact convention, the per-asset block list (one entry per phase: target path, type, name, blast radius, new-capability result, regression result, functional mode), the working directory, the design-validation result and cycle, the build-validation result with structural/functional counts and the per-phase verdicts, any recorded substitutions / BLOCKED deviations / verdict-override across phases, and the final status (`completed` | `completed-with-deviations` | `FAILED`). Surface every BLOCKED outcome and every deviation per-phase explicitly — never silently absorb one. If the FALSE-CLEAN REVIEW banner was shown, state that acknowledgement is required before the run is considered complete.
1054
1270
 
1055
1271
  ---
1056
1272