mandrel 1.81.0 → 1.83.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 (121) hide show
  1. package/.agents/README.md +46 -5
  2. package/.agents/docs/SDLC.md +97 -82
  3. package/.agents/docs/agentrc-reference.json +10 -2
  4. package/.agents/docs/configuration.md +4 -1
  5. package/.agents/docs/execution-reference.md +52 -0
  6. package/.agents/docs/workflows.md +1 -1
  7. package/.agents/instructions.md +85 -45
  8. package/.agents/personas/architect.md +8 -5
  9. package/.agents/personas/engineer-mobile.md +3 -2
  10. package/.agents/personas/engineer-web.md +3 -2
  11. package/.agents/personas/engineer.md +6 -5
  12. package/.agents/personas/product.md +19 -13
  13. package/.agents/personas/project-manager.md +9 -8
  14. package/.agents/personas/qa-engineer.md +10 -6
  15. package/.agents/personas/refactorer.md +3 -2
  16. package/.agents/personas/technical-writer.md +2 -1
  17. package/.agents/personas/ux-designer.md +2 -2
  18. package/.agents/schemas/agentrc.schema.json +41 -3
  19. package/.agents/schemas/qa-ledger.schema.json +2 -2
  20. package/.agents/scripts/acceptance-spec-reconciler.js +143 -59
  21. package/.agents/scripts/epic-deliver-prepare.js +40 -31
  22. package/.agents/scripts/epic-plan-decompose.js +2 -5
  23. package/.agents/scripts/epic-plan-spec.js +16 -19
  24. package/.agents/scripts/hierarchy-gate.js +11 -11
  25. package/.agents/scripts/lib/ITicketingProvider.js +4 -3
  26. package/.agents/scripts/lib/bdd-runner-detect.js +1 -1
  27. package/.agents/scripts/lib/bdd-scenario-scanner.js +1 -1
  28. package/.agents/scripts/lib/cli-args.js +1 -5
  29. package/.agents/scripts/lib/codebase-snapshot.js +1 -1
  30. package/.agents/scripts/lib/config/explain.js +4 -1
  31. package/.agents/scripts/lib/config/temp-paths.js +1 -4
  32. package/.agents/scripts/lib/config-settings-schema.js +30 -1
  33. package/.agents/scripts/lib/epic-body-sections.js +310 -0
  34. package/.agents/scripts/lib/epic-plan-clarity.js +38 -1
  35. package/.agents/scripts/lib/epic-plan-ideation.js +15 -3
  36. package/.agents/scripts/lib/findings/promote-finding.js +3 -3
  37. package/.agents/scripts/lib/findings/severity.js +5 -6
  38. package/.agents/scripts/lib/label-constants.js +7 -17
  39. package/.agents/scripts/lib/label-taxonomy.js +4 -21
  40. package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +65 -2
  41. package/.agents/scripts/lib/orchestration/context-hydration-engine.js +105 -9
  42. package/.agents/scripts/lib/orchestration/doc-reader.js +29 -0
  43. package/.agents/scripts/lib/orchestration/docs-digest.js +134 -0
  44. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/context.js +23 -22
  45. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +7 -10
  46. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +4 -38
  47. package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +8 -9
  48. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/authoring-context.js +11 -5
  49. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/cli-args.js +26 -5
  50. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +102 -304
  51. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/prompts.js +32 -29
  52. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +19 -20
  53. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-authoring-grounding.js +1 -1
  54. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-freshness.js +6 -9
  55. package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +3 -4
  56. package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +1 -1
  57. package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +20 -27
  58. package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +11 -5
  59. package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +22 -59
  60. package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +1 -1
  61. package/.agents/scripts/lib/orchestration/planning-context-budget.js +1 -1
  62. package/.agents/scripts/lib/orchestration/preflight-cache.js +1 -1
  63. package/.agents/scripts/lib/orchestration/spec-freshness.js +3 -3
  64. package/.agents/scripts/lib/orchestration/spec-section-validator.js +1 -1
  65. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +15 -1
  66. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +122 -1
  67. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +5 -8
  68. package/.agents/scripts/lib/orchestration/ticketing/reads.js +2 -2
  69. package/.agents/scripts/lib/plan-phase-cleanup.js +1 -2
  70. package/.agents/scripts/lib/qa/console-allowlist.js +5 -4
  71. package/.agents/scripts/lib/qa/qa-context-hydrator.js +6 -85
  72. package/.agents/scripts/lib/qa/resolve-qa-contract.js +144 -8
  73. package/.agents/scripts/lib/templates/decomposer-prompts.js +14 -8
  74. package/.agents/scripts/lifecycle-emit.js +1 -1
  75. package/.agents/scripts/lint-label-vocabulary.js +2 -3
  76. package/.agents/scripts/providers/github/mappers.js +0 -3
  77. package/.agents/scripts/providers/github/tickets.js +7 -18
  78. package/.agents/scripts/single-story-init.js +0 -1
  79. package/.agents/scripts/story-init.js +1 -29
  80. package/.agents/skills/core/epic-plan-consolidate/SKILL.md +43 -22
  81. package/.agents/skills/core/epic-plan-consolidate/examples.md +51 -0
  82. package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +27 -40
  83. package/.agents/skills/core/epic-plan-decompose-author/examples.md +47 -0
  84. package/.agents/skills/core/epic-plan-premortem/SKILL.md +15 -13
  85. package/.agents/skills/core/epic-plan-premortem/examples.md +53 -0
  86. package/.agents/skills/core/epic-plan-spec-author/SKILL.md +143 -151
  87. package/.agents/skills/core/epic-plan-spec-author/examples.md +91 -0
  88. package/.agents/skills/core/hydrate-context/SKILL.md +10 -5
  89. package/.agents/skills/core/knowledge-transfer/SKILL.md +3 -2
  90. package/.agents/skills/core/scope-triage/SKILL.md +2 -1
  91. package/.agents/skills/skills.index.json +8 -8
  92. package/.agents/skills/stack/qa/qa-explore-driving/SKILL.md +52 -38
  93. package/.agents/templates/epic-from-idea.md +4 -0
  94. package/.agents/workflows/audit-to-stories.md +2 -2
  95. package/.agents/workflows/helpers/code-review.md +11 -9
  96. package/.agents/workflows/helpers/deliver-epic-reference.md +514 -0
  97. package/.agents/workflows/helpers/deliver-epic.md +173 -490
  98. package/.agents/workflows/helpers/epic-audit.md +11 -8
  99. package/.agents/workflows/helpers/epic-deliver-story.md +45 -27
  100. package/.agents/workflows/helpers/epic-plan-decompose.md +17 -12
  101. package/.agents/workflows/helpers/epic-plan-spec.md +68 -68
  102. package/.agents/workflows/helpers/parallel-tooling.md +2 -1
  103. package/.agents/workflows/helpers/plan-epic-reference.md +136 -0
  104. package/.agents/workflows/helpers/plan-epic.md +141 -256
  105. package/.agents/workflows/helpers/plan-story.md +31 -61
  106. package/.agents/workflows/helpers/qa-run-scenario.md +194 -0
  107. package/.agents/workflows/helpers/scope-triage-gate.md +97 -0
  108. package/.agents/workflows/helpers/single-story-deliver-reference.md +423 -0
  109. package/.agents/workflows/helpers/single-story-deliver.md +129 -393
  110. package/.agents/workflows/helpers/worktree-lifecycle.md +1 -1
  111. package/.agents/workflows/plan.md +8 -8
  112. package/.agents/workflows/qa-assist.md +2 -1
  113. package/.agents/workflows/qa-explore.md +63 -32
  114. package/.agents/workflows/qa-run.md +293 -130
  115. package/docs/CHANGELOG.md +35 -0
  116. package/package.json +1 -1
  117. package/.agents/schemas/qa-finding.schema.json +0 -133
  118. package/.agents/scripts/lib/issue-link-parser.js +0 -74
  119. package/.agents/scripts/lib/orchestration/finalize/close-planning-tickets.js +0 -116
  120. package/.agents/scripts/lib/orchestration/planning-state-manager.js +0 -318
  121. package/.agents/scripts/lib/story-init/hierarchy-tracer.js +0 -57
@@ -0,0 +1,53 @@
1
+ # epic-plan-premortem — examples & extended rationale
2
+
3
+ Read this file on demand. The SKILL.md carries the operating contract (Policy
4
+ Capsule, Inputs / Outputs, Procedure, Constraints); this file carries the
5
+ extended rationale behind the pre-mortem critic — why it is a separate,
6
+ fresh-context, code-reading pass and how its three predicted-rework finding
7
+ classes differ from the structural gates.
8
+
9
+ ## Why a separate fresh-context code-reading critic
10
+
11
+ This Skill acts as a Senior Engineer + Architect in the role of a
12
+ **fresh-context pre-mortem critic**. It is deliberately *separate* from
13
+ `epic-plan-decompose-author` (the generator) and from `epic-plan-consolidate`
14
+ (the scope-preserving merge critic): a same-pass self-critique is the weak mode
15
+ this is built to escape. The generator maps Epic capabilities to Stories
16
+ against the spec text; this critic opens the **actual cited code** and asks "if
17
+ I tried to deliver this exact backlog, where would it rework?" — before any
18
+ GitHub write makes the rework expensive.
19
+
20
+ **You MUST read the actual cited code surfaces.** This is the load-bearing
21
+ difference between this critic and the structural file-assumption gate: that
22
+ gate proves a path **exists** (or does not); this critic reads what the file
23
+ actually **contains**. A pre-mortem that did not open the cited files has not
24
+ run.
25
+
26
+ ## Not scope-preserving (unlike consolidation)
27
+
28
+ Unlike `epic-plan-consolidate` (merge-and-rewire only), this critic MAY
29
+ recommend splitting an under-specified Story, tightening or rewording an
30
+ acceptance criterion, or flagging an over-specified Story — because it only
31
+ *recommends* in a report; it never applies the change itself. The conservation
32
+ invariant belongs to consolidation; this pass is deliberately a separate,
33
+ additive-recommendation lens. It never writes to GitHub, never persists
34
+ `tickets.json`, and never flips a label — re-authoring on its findings is the
35
+ author skill's job (the workflow re-runs `epic-plan-decompose-author` on the
36
+ report before the persist call).
37
+
38
+ ## The three predicted-rework finding classes
39
+
40
+ Hunt for the three classes the structural gates cannot catch:
41
+
42
+ 1. **Unverifiable acceptance criteria** — an AC no `verify[]` command or
43
+ readable code state can prove. Recommend a concrete verify command or a
44
+ reworded, checkable AC.
45
+ 2. **Over- or under-specified Stories** — a Story whose `acceptance[]` is far
46
+ broader or narrower than its `changes[]` footprint and the cited code
47
+ support. Recommend a split (under-specified: one Story doing the work of
48
+ several) or a tightening.
49
+ 3. **Semantically-wrong assumptions** — the cited file exists (so the
50
+ file-assumption gate passes) but does not contain the seam / export /
51
+ function / data shape the Story assumes — the file-assumption gate passes,
52
+ the work would still rework. Recommend the corrected target or an explicit
53
+ "create the seam first" Story.
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: epic-plan-spec-author
3
3
  description: >-
4
- Author the PRD, Tech Spec, Acceptance Spec markdown, and risk-verdict JSON
4
+ Author the Tech Spec, Acceptance Table markdown, and risk-verdict JSON
5
5
  for an Epic from the planner authoring context emitted by
6
6
  `epic-plan-spec.js --emit-context`. Use during Phase 7 of `/plan` when
7
- the host LLM needs to write the four artifacts before `epic-plan-spec.js`
8
- persists them.
7
+ the host LLM needs to write the three artifacts before `epic-plan-spec.js`
8
+ folds them into the Epic body's managed sections.
9
9
  allowed_tools:
10
10
  - Read
11
11
  - Write
@@ -14,13 +14,30 @@ allowed_tools:
14
14
 
15
15
  # epic-plan-spec-author
16
16
 
17
+ > **PRD retired (Story #4314).** The `context::prd` PRD artifact class was
18
+ > retired; this Skill no longer authors `prd.md`. Its one novel section —
19
+ > User Stories — now lives inline in the Epic body under a `## User Stories`
20
+ > heading, which is the requirements input. Both the Tech Spec and the
21
+ > Acceptance Spec now consume the Epic body directly (Context / Goal / Scope /
22
+ > User Stories) rather than a paraphrased PRD.
23
+ >
24
+ > **Context tickets retired (Story #4324).** The `context::tech-spec` /
25
+ > `context::acceptance-spec` ticket classes are retired too. The artifacts
26
+ > this Skill authors still land in `temp/epic-<Epic_ID>/` under the same
27
+ > filenames, but the persist half folds them into **managed sections of the
28
+ > Epic body** — the `## Delivery Slicing`-led Tech Spec sections and the
29
+ > `## Acceptance Table` AC-ID table — instead of creating separate tickets.
30
+ > On a re-plan, the Epic body's existing sections are the previous-spec
31
+ > input (that is how AC IDs stay stable across re-plans).
32
+
17
33
  ## Policy Capsule
18
34
 
19
35
  - Run only during `/plan` Phase 7, after `epic-plan-spec.js --emit-context` has written `temp/epic-<Epic_ID>/planner-context.json`; fail loudly if the file is missing rather than fabricating context.
20
- - Write exactly four artifacts and only inside `temp/epic-<Epic_ID>/`: `prd.md`, `techspec.md`, `risk-verdict.json`, `acceptance-spec.md`. All four MUST exist on disk before returning.
21
- - Start each markdown artifact at the correct `##` heading (PRD → `## Overview`, Tech Spec → `## Technical Overview`, Acceptance Spec → `## Acceptance Criteria`) — never emit a top-level `#` heading. `risk-verdict.json` is raw JSON conforming to `.agents/schemas/risk-verdict.schema.json`.
22
- - Judge risk from what the change *does* (the PRD / Tech Spec you just wrote), never from keyword presence — "out of scope: billing" is not a billing change; "rotate the credential vault" is high-risk even without a security keyword.
23
- - The Tech Spec MUST carry a `## Delivery Slicing` section proposing how the PRD's enumerated capabilities cluster into N shippable Stories — the intentional target the Phase 8 consolidation pass (`epic-plan-consolidate`) reconciles the decomposer draft against. Do NOT coarsen the PRD enumeration to produce it; the grouping recommendation is the granularity lever.
36
+ - Write exactly three artifacts and only inside `temp/epic-<Epic_ID>/`: `techspec.md`, `risk-verdict.json`, `acceptance-spec.md`. All three MUST exist on disk before returning.
37
+ - Start each markdown artifact at the correct `##` heading (Tech Spec → `## Delivery Slicing`, Acceptance Spec → `## Acceptance Table` — never the Epic's own `## Acceptance Criteria` heading, which stays the ideation bullets) — never emit a top-level `#` heading. `risk-verdict.json` is raw JSON conforming to `.agents/schemas/risk-verdict.schema.json`.
38
+ - The Tech Spec MUST open with `## Delivery Slicing` and MUST NOT restate the Epic's Context, Goal, or Scope — your output lands as sections of the same Epic body, which travels into every downstream story agent's prompt, so any restatement is duplication and a drift risk. A `## Technical Overview` section is optional and, when present, is a 2–3 sentence orientation of the *technical approach* only (which subsystems are touched and reused), never a re-narration of the problem statement, goals, or scope.
39
+ - Judge risk from what the change *does* (the Epic body / Tech Spec you just wrote), never from keyword presence — "out of scope: billing" is not a billing change; "rotate the credential vault" is high-risk even without a security keyword.
40
+ - The Tech Spec MUST carry a `## Delivery Slicing` section proposing how the Epic's enumerated capabilities cluster into N shippable Stories — the intentional grouping the Phase 8 consolidation pass (`epic-plan-consolidate`) reconciles the decomposer draft against. The proposed count is a **ceiling, not a target**: consolidation may merge below it when slices form dependent single-consumer chains, but never splits above it. Mark a slice "Independent? No" only with a one-line justification (parallelism, risk isolation, or delivery-envelope pressure); an unjustified dependent single-consumer slice folds into its consumer. Do NOT coarsen the Epic enumeration to produce it; the grouping recommendation is the granularity lever.
24
41
  - Cite real module / file names from `codebaseSnapshot.files` and `codebaseSnapshot.signatures` before citing docs-only names; flag any cited path that is missing from the snapshot with a `<!-- DRIFT -->` callout.
25
42
  - Assign stable AC IDs of the form `AC-<n>` in document order; reuse existing IDs across re-plans when Outcome wording is materially unchanged and tag every row's `Disposition` with one of `new | updated | unchanged`.
26
43
  - Render the AC table with the canonical columns `AC ID | Outcome | Feature File | Scenario | Disposition`; when `bddScenarios` is non-empty, run `findBestScenarioMatch` per AC and annotate matched rows with `<file>:L<line>` (never tag a covered outcome as `new`).
@@ -31,22 +48,21 @@ allowed_tools:
31
48
 
32
49
  ## Role
33
50
 
34
- Technical Product Manager + Engineering Architect + Risk Assessor +
35
- Acceptance Engineer (four personas, one Skill — the PRD persona produces the
36
- requirements; the Architect persona consumes the PRD to produce the Tech
37
- Spec; the Risk Assessor judges the change the two specs describe to produce
38
- the risk verdict; the Acceptance Engineer consumes all of them to produce
39
- the Acceptance Spec).
51
+ Engineering Architect + Risk Assessor + Acceptance Engineer (three authoring
52
+ roles, one Skill — the Architect persona consumes the Epic body to produce the
53
+ Tech Spec; the Risk Assessor judges the change the Epic and Tech Spec describe
54
+ to produce the risk verdict; the Acceptance Engineer consumes the Epic body and
55
+ the Tech Spec to produce the Acceptance Spec).
40
56
 
41
57
  ## When to use
42
58
 
43
59
  `/plan` Phase 7, immediately after `epic-plan-spec.js --emit-context`
44
60
  writes `temp/epic-<Epic_ID>/planner-context.json`. This Skill replaces the
45
- inline "Author the PRD" / "Author the Tech Spec" steps from the legacy
46
- workflow body — the calling workflow dispatches this Skill via the `Skill`
47
- tool, supplies the Epic ID, and on completion has `temp/epic-<Epic_ID>/prd.md`,
48
- `temp/epic-<Epic_ID>/techspec.md`, `temp/epic-<Epic_ID>/risk-verdict.json`,
49
- and `temp/epic-<Epic_ID>/acceptance-spec.md` ready for the persist half of
61
+ inline "Author the Tech Spec" step from the legacy workflow body — the calling
62
+ workflow dispatches this Skill via the `Skill` tool, supplies the Epic ID, and
63
+ on completion has `temp/epic-<Epic_ID>/techspec.md`,
64
+ `temp/epic-<Epic_ID>/risk-verdict.json`, and
65
+ `temp/epic-<Epic_ID>/acceptance-spec.md` ready for the persist half of
50
66
  the script.
51
67
 
52
68
  ## Inputs
@@ -87,7 +103,7 @@ reads:
87
103
  Treat each as a likely drift signal: confirm the path exists (it may
88
104
  have been dropped by truncation) or mark it net-new explicitly in
89
105
  the spec so the post-author freshness gate does not flag it.
90
- - `systemPrompts.prd`, `systemPrompts.techSpec`, and
106
+ - `systemPrompts.techSpec` and
91
107
  `systemPrompts.acceptanceSpec` — left in the envelope as a backstop;
92
108
  this Skill's own body below carries the authoritative versions and is
93
109
  the source of truth going forward
@@ -104,29 +120,28 @@ reads:
104
120
  means the project has not adopted BDD; degrade silently and proceed
105
121
  as before. Non-empty means the Acceptance Engineer step MUST run
106
122
  `findBestScenarioMatch` for each planned AC and annotate the
107
- Disposition column accordingly (see Step 5).
123
+ Disposition column accordingly (see Step 4).
108
124
  Planning risk is **not** an input — this Skill authors it. The risk
109
- verdict (`risk-verdict.json`, Step 4 below) is the fourth planning
110
- artifact; the persist half validates it against
125
+ verdict (`risk-verdict.json`, Step 3 below) is one of the three planning
126
+ artifacts; the persist half validates it against
111
127
  `.agents/schemas/risk-verdict.schema.json` and derives the deterministic
112
128
  `planningRisk` envelope (`deriveRiskEnvelope`) that drives gate routing
113
129
  and the acceptance disposition (Epic #3865).
114
130
 
115
131
  ## Outputs
116
132
 
117
- - `temp/epic-<Epic_ID>/prd.md` — PRD markdown starting with `## Overview`
118
- (no `<h1>`).
119
133
  - `temp/epic-<Epic_ID>/techspec.md` — Tech Spec markdown starting with
120
- `## Technical Overview` (no `<h1>`).
134
+ `## Delivery Slicing` (no `<h1>`; an optional 2–3 sentence
135
+ `## Technical Overview` may follow, never restating Epic context).
121
136
  - `temp/epic-<Epic_ID>/risk-verdict.json` — planner risk verdict JSON
122
137
  conforming to `.agents/schemas/risk-verdict.schema.json`:
123
138
  `{ axes: [{ axis, level, rationale }], summary }`.
124
139
  - `temp/epic-<Epic_ID>/acceptance-spec.md` — Acceptance Spec markdown
125
- starting with `## Acceptance Criteria` (no `<h1>`).
140
+ starting with `## Acceptance Table` (no `<h1>`).
126
141
 
127
- All four files MUST exist on disk before this Skill returns control. The
142
+ All three files MUST exist on disk before this Skill returns control. The
128
143
  caller will invoke
129
- `epic-plan-spec.js --epic <Epic_ID> --prd ... --techspec ... --risk-verdict ... --acceptance-spec ...`
144
+ `epic-plan-spec.js --epic <Epic_ID> --tech-spec ... --risk-verdict ... --acceptance-table ...`
130
145
  next, and the persist half will fail loudly if any file is missing, empty,
131
146
  or (for the verdict) schema-invalid.
132
147
 
@@ -135,136 +150,85 @@ or (for the verdict) schema-invalid.
135
150
  ### Step 1 — Load the context
136
151
 
137
152
  Read `temp/epic-<Epic_ID>/planner-context.json` with the `Read` tool. Pull
138
- the Epic title, body (or body summary), the `docsContext` items, and (for
139
- reference) the two system prompts.
140
-
141
- ### Step 2 — Author the PRD (Technical Product Manager persona)
142
-
143
- Apply the PRD system prompt below to the Epic title + body. Write the PRD
144
- to `temp/epic-<Epic_ID>/prd.md` using the `Write` tool. The PRD MUST:
153
+ the Epic title, body (or body summary, including the Epic's `## User Stories`
154
+ section), the `docsContext` items, and (for reference) the two system prompts.
145
155
 
146
- - Start with `## Overview` — never a top-level `#` heading.
147
- - Contain four sections: **Context & Goals**, **User Stories**,
148
- **Acceptance Criteria**, **Out of Scope**.
149
- - Be valid Markdown — no fenced code blocks of prose, no smart quotes that
150
- break the issue body renderer.
156
+ ### Step 2 — Author the Tech Spec (Engineering Architect persona)
151
157
 
152
- #### PRD system prompt (authoritative)
153
-
154
- ```text
155
- You are an expert Technical Product Manager.
156
- Your job is to convert a high-level Epic description into a structured Product Requirements Document (PRD).
157
-
158
- The PRD should outline:
159
- 1. Context & Goals
160
- 2. User Stories
161
- 3. Acceptance Criteria
162
- 4. Out of Scope
163
-
164
- CRITICAL REQUIREMENTS:
165
- - Respond ONLY with valid Markdown.
166
- - Do not use top-level <h1> (# ) tags. Start with ## Overview.
167
- - Format requirements clearly with bullet points and bold text where appropriate.
168
- ```
169
-
170
- ### Step 3 — Author the Tech Spec (Engineering Architect persona)
171
-
172
- Apply the Tech Spec system prompt below to the PRD just written, the
158
+ Apply the Tech Spec system prompt below to the Epic body (Context / Goal /
159
+ Scope / User Stories), the
173
160
  `docsContext` items, and the `codebaseSnapshot` envelope (so the spec is
174
161
  grounded in the actual codebase, not hallucinated patterns). Cite module
175
162
  and file names from `codebaseSnapshot.files` / `codebaseSnapshot.signatures`
176
163
  before reaching for names that appear only in the documentation. Write to
177
164
  `temp/epic-<Epic_ID>/techspec.md`. The Tech Spec MUST:
178
165
 
179
- - Start with `## Technical Overview` — never a top-level `#` heading.
166
+ - **Open with `## Delivery Slicing`** (see below) — never a top-level `#`
167
+ heading, and never an Epic-context recap. The Delivery Slicing section is
168
+ the primary input to Phase 8 consolidation, so author it first and hang the
169
+ rest of the spec off it.
170
+ - **Do NOT restate the Epic's Context, Goal, or Scope.** The Epic body always
171
+ travels alongside the Tech Spec into every downstream story agent's prompt,
172
+ so restating the problem statement, goals, or scope is pure duplication
173
+ (~300–500 tokens per Epic) and a drift risk. A `## Technical Overview`
174
+ section is **optional**; when you include one, cap it at 2–3 sentences that
175
+ orient the reader on the *technical approach* only (which subsystems are
176
+ touched and reused) — never re-narrate the problem, goals, or scope.
180
177
  - Cover Architecture & Design, Data Models (if any), API Changes (if any),
181
178
  Core Components, Security & Privacy Considerations.
182
- - Include a **`## Delivery Slicing`** section (see below) proposing how the
183
- PRD's enumerated capabilities cluster into N shippable Stories.
184
179
  - Cite the source files / modules it touches by relative path. Avoid
185
180
  pseudocode — name real symbols when proposing edits.
186
181
 
187
- #### Delivery Slicing section (authoritative target for Phase 8 consolidation)
182
+ #### Delivery Slicing section (authoritative ceiling for Phase 8 consolidation)
188
183
 
189
- The Tech Spec MUST carry a `## Delivery Slicing` section in which the Architect
190
- — who holds the full design — proposes how the PRD's enumerated capabilities
191
- **cluster into N shippable Stories**. This section is the intentional target
192
- grouping the Phase 8 consolidation pass
184
+ The Tech Spec MUST carry a `## Delivery Slicing` section proposing how the
185
+ Epic's enumerated capabilities **cluster into N shippable Stories** — the
186
+ intentional grouping the Phase 8 consolidation pass
193
187
  ([`epic-plan-consolidate`](../epic-plan-consolidate/SKILL.md)) reconciles the
194
- decomposer's draft against before any GitHub write. Without it, the decompose
195
- phase maps PRD capabilities to Stories ~1:1 and cannot produce a coarser,
196
- holistic plan; with it, the consolidation critic has a well-defined target
197
- instead of a guess.
198
-
199
- **Write the Delivery Slicing section before any other section — it is the
200
- primary input to Phase 8 consolidation.** Author it first so the rest of the
201
- spec (Core Components, API Changes, Data Models) hangs off a deliberate
202
- slicing decision rather than being reverse-engineered into one at the end.
203
- Drafting it last is exactly how the model omits it under the weight of the
204
- other sections.
205
-
206
- Author the section as a table — one row per proposed slice — naming the
207
- capability cluster each slice would deliver, what ships in it, and whether it
208
- can ship independently. Use **noun phrases** for slice names ("Foundation",
209
- "Transport seam", "Send helper") so they map cleanly onto Feature titles in the
210
- resulting decomposition — never verb phrases ("Add transport") or file names
211
- ("`sender.ts`"). Do **not** coarsen the PRD's capability enumeration to produce
212
- the slicing: the granularity lever is *this* grouping recommendation, not a
213
- dumbed-down PRD.
214
-
215
- **What "Independent?" means:** can this slice ship to production and provide
216
- value *without the next slice landing*? A `Yes` slice is releasable on its own;
217
- a `No` slice only becomes valuable once a later slice lands on top of it.
218
-
219
- Worked example:
220
-
221
- ```text
222
- ## Delivery Slicing
223
-
224
- Proposed shippable slices (consolidation target for Phase 8):
225
-
226
- | Slice | What ships | Independent? |
227
- | -------------- | ------------------------------------------------------ | ------------ |
228
- | Foundation | Config schema, types, and the no-op default path | Yes |
229
- | Transport seam | The pluggable transport interface + in-memory adapter | Yes |
230
- | Send helper | The send() helper built on the transport seam | No |
231
-
232
- - **Foundation** folds PRD capabilities "config surface" + "type model" — they
233
- share a reason to exist and ship as one reviewable PR.
234
- - **Transport seam** is the pluggable boundary; it provides value on its own
235
- (in-memory adapter is usable for tests) so it is independently shippable.
236
- - **Send helper** depends on the transport seam landing first, so it is *not*
237
- independent — it is valuable only once Transport seam ships.
238
- ```
239
-
240
- The consolidation pass degrades gracefully when this section is absent (it
241
- falls back to cohesion + single-Story-Feature rules only), so authoring it is
242
- how the Architect steers the decomposition toward fewer, right-sized Stories.
188
+ decomposer draft against before any GitHub write. Author it as a table (one row
189
+ per slice: `Slice | What ships | Independent?`), using **noun-phrase** slice
190
+ names, and **write it before any other section** — it is the primary input to
191
+ consolidation and the section the model most often omits when it drafts it last.
192
+
193
+ - **The count is a ceiling, not a target.** Consolidation may merge below it
194
+ (dependent single-consumer chains) but never splits above it.
195
+ - **"Independent?"** answers: can this slice ship to production and provide
196
+ value without the next slice landing? Mark a slice `No` only with a one-line
197
+ justification (parallelism, risk isolation, or delivery-envelope pressure);
198
+ an unjustified dependent single-consumer slice folds into its consumer.
199
+ - Do **not** coarsen the Epic's capability enumeration to produce the slicing;
200
+ the grouping recommendation is the granularity lever.
201
+
202
+ > **Read [`examples.md`](./examples.md) on demand** for the worked Delivery
203
+ > Slicing table and the extended rationale behind these rules (what
204
+ > "Independent?" means, why an unjustified `No` slice is a smell, and how the
205
+ > consolidation pass degrades gracefully when the section is absent).
243
206
 
244
207
  #### Tech Spec system prompt (authoritative)
245
208
 
246
209
  ```text
247
210
  You are an expert Engineering Architect.
248
- Your job is to convert a PRD into a Technical Specification for implementation.
211
+ Your job is to convert an Epic into a Technical Specification for implementation.
249
212
 
250
213
  The Tech Spec should outline:
251
- 1. Architecture & Design
252
- 2. Data Models (if any)
253
- 3. API Changes (if any)
254
- 4. Core Components
255
- 5. Security & Privacy Considerations
256
- 6. Delivery Slicing — propose how the PRD's enumerated capabilities cluster into N shippable Stories (the consolidation target for Phase 8). One bullet per proposed Story, naming the capability cluster it delivers. Do NOT coarsen the PRD enumeration to produce this; the grouping recommendation is the granularity lever.
214
+ 1. Delivery Slicing — propose how the Epic's enumerated capabilities cluster into shippable Stories. This count is a CEILING, not a target: the Phase 8 consolidation pass may merge below your proposed count when slices form dependent single-consumer chains, but never splits above it. Do NOT coarsen the Epic enumeration to produce this; the grouping recommendation is the granularity lever.
215
+ 2. Architecture & Design
216
+ 3. Data Models (if any)
217
+ 4. API Changes (if any)
218
+ 5. Core Components
219
+ 6. Security & Privacy Considerations
257
220
 
258
221
  CRITICAL REQUIREMENTS:
259
222
  - Respond ONLY with valid Markdown.
260
- - Do not use top-level <h1> (# ) tags. Start with ## Technical Overview.
223
+ - Do not use top-level <h1> (# ) tags. Open the document with the `## Delivery Slicing` section — it is the primary input to Phase 8 consolidation, so author it first and hang the rest of the spec off it.
224
+ - Do NOT restate the Epic's Context, Goal, or Scope — your output lands as sections of the same Epic body, which travels into every downstream story agent's prompt, so any restatement is pure duplication and a drift risk. If a brief technical orientation is genuinely useful, add an optional `## Technical Overview` of no more than 2–3 sentences that names the *technical approach* only (which subsystems are touched and reused); never re-narrate the problem statement, goals, or scope.
261
225
  - Format architectural decisions clearly with bullet points.
262
- - Include a `## Delivery Slicing` section proposing the shippable-Story grouping. Write the Delivery Slicing section before any other section — it is the primary input to Phase 8 consolidation. Author it as a markdown table with columns `Slice | What ships | Independent?`, using noun-phrase slice names (e.g. "Foundation", "Transport seam", "Send helper") that map onto Feature titles. "Independent?" answers: can this slice ship to production and provide value without the next slice landing?
226
+ - Author the `## Delivery Slicing` section as a markdown table with columns `Slice | What ships | Independent?`, using noun-phrase slice names (e.g. "Foundation", "Transport seam", "Send helper") that map onto Feature titles. "Independent?" answers: can this slice ship to production and provide value without the next slice landing? A slice you mark "Independent? No" MUST carry a one-line justification (parallelism, risk isolation, or delivery-envelope pressure); an unjustified dependent single-consumer slice folds into its consumer by default rather than shipping as its own Story.
263
227
  ```
264
228
 
265
- ### Step 4 — Author the risk verdict (Risk Assessor persona)
229
+ ### Step 3 — Author the risk verdict (Risk Assessor persona)
266
230
 
267
- Judge the change described by the PRD and Tech Spec you just wrote —
231
+ Judge the change described by the Epic body and Tech Spec you just wrote —
268
232
  grounded in `codebaseSnapshot` where it helps — and write
269
233
  `temp/epic-<Epic_ID>/risk-verdict.json` with the `Write` tool. The file
270
234
  MUST be valid JSON conforming to
@@ -290,11 +254,11 @@ Axis vocabulary (fixed — the schema rejects anything else):
290
254
  Authoring rules:
291
255
 
292
256
  - Include an axis only when the change **genuinely exercises it** — judge
293
- what the Epic *does*, not which words appear in it. A PRD that says
257
+ what the Epic *does*, not which words appear in it. An Epic that says
294
258
  "out of scope: billing" carries no `billing` axis; an Epic that rotates
295
259
  a credential vault carries `security` even if the word never appears.
296
260
  - `level` reflects blast radius and reversibility of *this* change on
297
- *that* axis. `rationale` cites the PRD / Tech Spec section or code
261
+ *that* axis. `rationale` cites the Epic / Tech Spec section or code
298
262
  surface that justifies the entry — never an empty self-attestation.
299
263
  - An empty `axes` array is a deliberate assertion that no recognized risk
300
264
  axis applies (derives an all-low, auto-proceed envelope) — use it only
@@ -305,13 +269,13 @@ Authoring rules:
305
269
  judgment, not control flow.
306
270
 
307
271
  The derivation rules you are feeding (so you can anticipate the
308
- disposition Step 5 must honor): any required axis ⇒ acceptance spec
272
+ disposition Step 4 must honor): any required axis ⇒ acceptance spec
309
273
  `required`; otherwise any `medium` level ⇒ `recommended`; otherwise
310
274
  only not-applicable axes (or no axes) ⇒ `not-applicable` (waived).
311
275
 
312
- ### Step 5 — Author the Acceptance Spec (Acceptance Engineer persona)
276
+ ### Step 4 — Author the Acceptance Spec (Acceptance Engineer persona)
313
277
 
314
- Apply the Acceptance Spec system prompt below to the PRD + Tech Spec just
278
+ Apply the Acceptance Spec system prompt below to the Epic body + Tech Spec just
315
279
  written, plus the **existing BDD scenario index** from
316
280
  `bddScenarios` on the planner-context envelope (Story #2637). The
317
281
  scenario index is the output of
@@ -327,20 +291,42 @@ behaviour) — never `new` for an AC whose outcome is already proven by
327
291
  an existing scenario. When `bddScenarios` is empty (the project has not
328
292
  adopted BDD), proceed exactly as before with no annotation.
329
293
 
330
- Branch on the acceptance disposition your Step 4 verdict derives (see the
294
+ Branch on the acceptance disposition your Step 3 verdict derives (see the
331
295
  derivation rules there): `required` and `recommended` author the spec
332
296
  normally per the rules below. `not-applicable` authorizes the persist half
333
297
  to apply `acceptance::n-a` on the Epic; in that case write a one-paragraph
334
298
  waiver rationale to `temp/epic-<Epic_ID>/acceptance-spec.md` instead of
335
299
  the AC table so the audit trail still exists, and start the file with
336
- `## Acceptance Criteria — waived (planner-selected)`.
300
+ `## Acceptance Table — waived (planner-selected)`.
337
301
 
338
302
  Write to `temp/epic-<Epic_ID>/acceptance-spec.md`. The Acceptance Spec
339
303
  MUST:
340
304
 
341
- - Start with `## Acceptance Criteria` — never a top-level `#` heading.
305
+ - Start with `## Acceptance Table` — never a top-level `#` heading, and
306
+ never the Epic's own `## Acceptance Criteria` heading (the table lands
307
+ as a section of the same Epic body).
342
308
  - Render the AC table with the canonical column shape documented in Tech
343
309
  Spec #2083: `| AC ID | Outcome | Feature File | Scenario | Disposition |`.
310
+ - **Key each `Outcome` off a specific Epic `## Acceptance Criteria`
311
+ bullet** — the Epic body's AC bullets are the single source of truth, so
312
+ the `Outcome` column is a **terse restatement anchored to one Epic
313
+ bullet**, not an independent re-elaboration. Lead each `Outcome` with its
314
+ anchor (the bullet's quoted lead phrase or an explicit `Epic AC N` index),
315
+ then state the single user-visible behaviour. A free-standing `Outcome`
316
+ that paraphrases a criterion in new words without naming the Epic bullet
317
+ it verifies is the drift this rule exists to prevent — it decouples the
318
+ spec from the Epic silently.
319
+ - **Split case (one Epic AC → several rows).** When one Epic AC bullet
320
+ genuinely expands into several user-visible outcomes, emit one row per
321
+ outcome and **declare the split on each** row (e.g. lead with
322
+ `splits Epic AC 3`) so the fan-out is explicit, not hidden.
323
+ - **Flag divergence, do not absorb it.** Anchor coverage MUST be complete
324
+ and auditable: every Epic AC bullet is covered by at least one row and
325
+ every row anchors to an Epic bullet. Call out any Epic AC bullet with
326
+ **no** corresponding row, and any AC row with **no** Epic anchor, in a
327
+ note directly beneath the AC table — surfacing spec/Epic divergence at
328
+ authoring time. Never silently drop an uncovered Epic bullet or emit an
329
+ unanchored row.
344
330
  - Use **stable AC IDs** of the form `AC-1`, `AC-2`, … assigned in document
345
331
  order. On re-plan, reuse the ID for any AC whose Outcome text is
346
332
  materially unchanged; new ACs receive fresh sequential IDs (existing
@@ -364,34 +350,40 @@ MUST:
364
350
 
365
351
  ```text
366
352
  You are an expert Acceptance Engineer.
367
- Your job is to convert a PRD and a Tech Spec into a structured Acceptance Specification that drives features-first BDD authoring.
353
+ Your job is to convert an Epic and a Tech Spec into a structured Acceptance Specification that drives features-first BDD authoring.
368
354
 
369
355
  The Acceptance Spec should outline:
370
- 1. Acceptance Criteria — one row per user-visible outcome, expressed as a Markdown table with columns: AC ID | Outcome | Feature File | Scenario | Disposition
356
+ 1. Acceptance Table — one row per user-visible outcome, expressed as a Markdown table with columns: AC ID | Outcome | Feature File | Scenario | Disposition
371
357
  2. Stable AC IDs — assign AC-1, AC-2, ... in document order; reuse the same ID across re-plans when an Outcome is materially unchanged so scenario tags (@ac-N) stay aligned
372
358
  3. Disposition — tag each row with one of: new | updated | unchanged
373
359
 
360
+ The Epic body's `## Acceptance Criteria` bullets are the single source of truth for what the spec verifies. Your table does not re-invent criteria — it anchors each one to a specific Epic AC bullet.
361
+
374
362
  CRITICAL REQUIREMENTS:
375
363
  - Respond ONLY with valid Markdown.
376
- - Do not use top-level <h1> (# ) tags. Start with ## Acceptance Criteria.
364
+ - Do not use top-level <h1> (# ) tags. Start with ## Acceptance Table — the table lands as a section of the Epic body, so it must NOT reuse the Epic's own ## Acceptance Criteria heading.
377
365
  - Every AC row MUST have a stable AC ID of the form AC-<n> (AC-1, AC-2, ...) — do not reorder IDs across re-plans; new ACs get fresh sequential IDs.
378
- - Every AC row MUST carry a Disposition value from the enum: new | updated | unchanged.
379
- - Each Outcome MUST be a single user-visible behaviour — no DB assertions, no HTTP status codes, no internal implementation details.
366
+ - Every AC row MUST carry a Disposition value from the enum: new | updated | unchanged. (At Epic close, the acceptance reconciler overwrites Disposition with the verification outcome — satisfied | pending | missing — inside this section only; on re-plan, reset each row to the authoring enum.)
367
+ - Each Outcome MUST be a **terse restatement keyed to a specific Epic `## Acceptance Criteria` bullet** — lead the Outcome with the bullet's anchor (its quoted lead phrase or an explicit "Epic AC N" index) and keep the rest to a single user-visible behaviour. Do NOT re-elaborate the Epic bullet in independent words: a free-standing Outcome that paraphrases the criterion without naming the bullet it verifies is forbidden, because it drifts from the Epic silently. No DB assertions, no HTTP status codes, no internal implementation details.
368
+ - Where one Epic AC bullet genuinely expands into several user-visible outcomes, emit one row per outcome and declare the split on each — e.g. lead with "splits Epic AC 3" — so the fan-out is explicit rather than hidden.
369
+ - Anchor coverage MUST be complete and auditable: every Epic AC bullet MUST be covered by at least one row, and every row MUST anchor to an Epic AC bullet. Flag divergence in the authored spec instead of dropping it — if an Epic AC bullet has no corresponding row, or a row has no Epic anchor, call it out explicitly (a note beneath the table) rather than silently omitting the bullet or emitting an unanchored row.
380
370
  - Cite proposed feature file paths under tests/features/** so Phase 8 can scaffold matching scenarios.
381
371
  - Acceptance Outcomes MUST NOT prescribe a commit subject that begins with a non-Conventional-Commits prefix (allowed leading types: feat|fix|chore|refactor|perf|docs|style|test|build|ci|revert). The legacy `baseline-refresh` token used as a leading subject prescription is forbidden — commitlint will reject it at commit time, and the decompose-time validator (`ticket-validator.js` → `validateAcceptanceSubjectPrefix`) will reject the decompose with `code: 'forbidden-subject-prefix'`. Use a Conventional-Commits subject (e.g. `chore(baselines): refresh ...`) and a body trailer (e.g. `baseline-refresh: true` — trailer with a value, not a subject prefix) when a machine-readable marker is needed. See Epic #2501 for rationale.
382
372
  ```
383
373
 
384
- ### Step 6 — Hand back to `/plan`
374
+ ### Step 5 — Hand back to `/plan`
385
375
 
386
- All four files exist; return. The caller will run
387
- `node .agents/scripts/epic-plan-spec.js --epic <Epic_ID> --prd
388
- temp/epic-<Epic_ID>/prd.md --techspec temp/epic-<Epic_ID>/techspec.md
376
+ All three files exist; return. The caller will run
377
+ `node .agents/scripts/epic-plan-spec.js --epic <Epic_ID>
378
+ --tech-spec temp/epic-<Epic_ID>/techspec.md
389
379
  --risk-verdict temp/epic-<Epic_ID>/risk-verdict.json
390
- --acceptance-spec temp/epic-<Epic_ID>/acceptance-spec.md`, which validates
391
- the risk verdict, derives the planningRisk envelope, persists the
392
- artifacts, records the `risk-verdict` structured comment, appends the
393
- `## Planning Artifacts` section to the Epic body, flips the Epic to
394
- `agent::review-spec`, and cleans up the temp files.
380
+ --acceptance-table temp/epic-<Epic_ID>/acceptance-spec.md`, which validates
381
+ the risk verdict, derives the planningRisk envelope, folds the authored
382
+ content into the Epic body's managed sections (`## Delivery Slicing`-led
383
+ Tech Spec sections + the `## Acceptance Table`), records the
384
+ `risk-verdict` structured comment, flips the Epic to
385
+ `agent::review-spec`, and cleans up the temp files. No context tickets
386
+ are created (Story #4324).
395
387
 
396
388
  ## Constraints
397
389
 
@@ -0,0 +1,91 @@
1
+ # epic-plan-spec-author — examples & extended rationale
2
+
3
+ Read this file on demand while authoring the Tech Spec. The SKILL.md carries
4
+ the operating contract (Policy Capsule, Inputs / Outputs, Procedure, the two
5
+ authoritative system prompts, and Constraints); this file carries the worked
6
+ Delivery Slicing example and the extended rationale behind the slicing rules.
7
+
8
+ ## Delivery Slicing — extended rationale
9
+
10
+ The Tech Spec MUST carry a `## Delivery Slicing` section in which the Architect
11
+ — who holds the full design — proposes how the Epic's enumerated capabilities
12
+ **cluster into N shippable Stories**. This section is the intentional grouping
13
+ the Phase 8 consolidation pass
14
+ ([`epic-plan-consolidate`](../epic-plan-consolidate/SKILL.md)) reconciles the
15
+ decomposer's draft against before any GitHub write. Without it, the decompose
16
+ phase maps Epic capabilities to Stories ~1:1 and cannot produce a coarser,
17
+ holistic plan; with it, the consolidation critic has a well-defined reference
18
+ instead of a guess.
19
+
20
+ **The proposed count is a ceiling, not a target.** Consolidation reconciles
21
+ the draft *toward* your grouping, but it treats the count as an upper bound: it
22
+ may **merge below** your proposed count when slices form dependent
23
+ single-consumer chains, and it **never splits above** it. Over-slicing here
24
+ therefore locks in fragmentation only when the extra slices are genuinely
25
+ independent — so keep a slice separate only when it earns its own delivery
26
+ session.
27
+
28
+ **Write the Delivery Slicing section before any other section — it is the
29
+ primary input to Phase 8 consolidation.** Author it first so the rest of the
30
+ spec (Core Components, API Changes, Data Models) hangs off a deliberate
31
+ slicing decision rather than being reverse-engineered into one at the end.
32
+ Drafting it last is exactly how the model omits it under the weight of the
33
+ other sections.
34
+
35
+ Author the section as a table — one row per proposed slice — naming the
36
+ capability cluster each slice would deliver, what ships in it, and whether it
37
+ can ship independently. Use **noun phrases** for slice names ("Foundation",
38
+ "Transport seam", "Send helper") so they map cleanly onto Feature titles in the
39
+ resulting decomposition — never verb phrases ("Add transport") or file names
40
+ ("`sender.ts`"). Do **not** coarsen the Epic's capability enumeration to produce
41
+ the slicing: the granularity lever is *this* grouping recommendation, not a
42
+ dumbed-down Epic enumeration.
43
+
44
+ **What "Independent?" means:** can this slice ship to production and provide
45
+ value *without the next slice landing*? A `Yes` slice is releasable on its own;
46
+ a `No` slice only becomes valuable once a later slice lands on top of it.
47
+
48
+ **"Independent? No" is a smell that must be justified.** A dependent,
49
+ single-consumer slice (one that only feeds the next slice) folds into its
50
+ consumer by default — it is not worth its own delivery session's hydration,
51
+ branch, PR, and CI ceremony. Mark a slice `No` only when you can name a
52
+ one-line reason to keep it separate anyway: **parallelism** (two `No` slices
53
+ that can be delivered concurrently by different sessions), **risk isolation**
54
+ (a blast-radius or reviewability reason to land it as its own reviewable PR),
55
+ or **delivery-envelope pressure** (folding it in would push the consumer past a
56
+ single-session sizing envelope). Absent such a justification, do not author the
57
+ slice as its own row — fold it into its consumer and let the merged slice carry
58
+ the combined capability.
59
+
60
+ ### Worked example
61
+
62
+ ```text
63
+ ## Delivery Slicing
64
+
65
+ Proposed shippable slices (consolidation ceiling for Phase 8):
66
+
67
+ | Slice | What ships | Independent? |
68
+ | -------------- | ------------------------------------------------------ | ------------ |
69
+ | Foundation | Config schema, types, and the no-op default path | Yes |
70
+ | Transport seam | The pluggable transport interface + in-memory adapter | Yes |
71
+ | Send helper | The send() helper + retries, built on the transport | No (justified: risk isolation) |
72
+
73
+ - **Foundation** folds Epic capabilities "config surface" + "type model" — they
74
+ share a reason to exist and ship as one reviewable PR.
75
+ - **Transport seam** is the pluggable boundary; it provides value on its own
76
+ (in-memory adapter is usable for tests) so it is independently shippable.
77
+ - **Send helper** depends on the transport seam landing first, so it is *not*
78
+ independent. It stays its own slice only because the retry/backoff logic is a
79
+ large, high-blast-radius surface worth isolating in its own reviewable PR
80
+ (risk isolation). Absent that justification it would fold into Transport
81
+ seam — a bare "depends on the previous slice" is not a reason to keep it
82
+ separate.
83
+ ```
84
+
85
+ The consolidation pass degrades gracefully when this section is absent (it
86
+ falls back to cohesion + single-Story-Feature rules only), so authoring it is
87
+ how the Architect steers the decomposition toward fewer, right-sized Stories.
88
+ Because the count is a **ceiling**, an over-sliced table is coarsened back
89
+ during consolidation — but only where the extra slices are dependent
90
+ single-consumer chains, so an unjustified `No` slice is the one you should fold
91
+ in yourself rather than leaning on the consolidator to catch.