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.
- package/.agents/README.md +46 -5
- package/.agents/docs/SDLC.md +97 -82
- package/.agents/docs/agentrc-reference.json +10 -2
- package/.agents/docs/configuration.md +4 -1
- package/.agents/docs/execution-reference.md +52 -0
- package/.agents/docs/workflows.md +1 -1
- package/.agents/instructions.md +85 -45
- package/.agents/personas/architect.md +8 -5
- package/.agents/personas/engineer-mobile.md +3 -2
- package/.agents/personas/engineer-web.md +3 -2
- package/.agents/personas/engineer.md +6 -5
- package/.agents/personas/product.md +19 -13
- package/.agents/personas/project-manager.md +9 -8
- package/.agents/personas/qa-engineer.md +10 -6
- package/.agents/personas/refactorer.md +3 -2
- package/.agents/personas/technical-writer.md +2 -1
- package/.agents/personas/ux-designer.md +2 -2
- package/.agents/schemas/agentrc.schema.json +41 -3
- package/.agents/schemas/qa-ledger.schema.json +2 -2
- package/.agents/scripts/acceptance-spec-reconciler.js +143 -59
- package/.agents/scripts/epic-deliver-prepare.js +40 -31
- package/.agents/scripts/epic-plan-decompose.js +2 -5
- package/.agents/scripts/epic-plan-spec.js +16 -19
- package/.agents/scripts/hierarchy-gate.js +11 -11
- package/.agents/scripts/lib/ITicketingProvider.js +4 -3
- package/.agents/scripts/lib/bdd-runner-detect.js +1 -1
- package/.agents/scripts/lib/bdd-scenario-scanner.js +1 -1
- package/.agents/scripts/lib/cli-args.js +1 -5
- package/.agents/scripts/lib/codebase-snapshot.js +1 -1
- package/.agents/scripts/lib/config/explain.js +4 -1
- package/.agents/scripts/lib/config/temp-paths.js +1 -4
- package/.agents/scripts/lib/config-settings-schema.js +30 -1
- package/.agents/scripts/lib/epic-body-sections.js +310 -0
- package/.agents/scripts/lib/epic-plan-clarity.js +38 -1
- package/.agents/scripts/lib/epic-plan-ideation.js +15 -3
- package/.agents/scripts/lib/findings/promote-finding.js +3 -3
- package/.agents/scripts/lib/findings/severity.js +5 -6
- package/.agents/scripts/lib/label-constants.js +7 -17
- package/.agents/scripts/lib/label-taxonomy.js +4 -21
- package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +65 -2
- package/.agents/scripts/lib/orchestration/context-hydration-engine.js +105 -9
- package/.agents/scripts/lib/orchestration/doc-reader.js +29 -0
- package/.agents/scripts/lib/orchestration/docs-digest.js +134 -0
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/context.js +23 -22
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +7 -10
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +4 -38
- package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +8 -9
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/authoring-context.js +11 -5
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/cli-args.js +26 -5
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +102 -304
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/prompts.js +32 -29
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +19 -20
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-authoring-grounding.js +1 -1
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-freshness.js +6 -9
- package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +3 -4
- package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +1 -1
- package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +20 -27
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +11 -5
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +22 -59
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +1 -1
- package/.agents/scripts/lib/orchestration/planning-context-budget.js +1 -1
- package/.agents/scripts/lib/orchestration/preflight-cache.js +1 -1
- package/.agents/scripts/lib/orchestration/spec-freshness.js +3 -3
- package/.agents/scripts/lib/orchestration/spec-section-validator.js +1 -1
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +15 -1
- package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +122 -1
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +5 -8
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +2 -2
- package/.agents/scripts/lib/plan-phase-cleanup.js +1 -2
- package/.agents/scripts/lib/qa/console-allowlist.js +5 -4
- package/.agents/scripts/lib/qa/qa-context-hydrator.js +6 -85
- package/.agents/scripts/lib/qa/resolve-qa-contract.js +144 -8
- package/.agents/scripts/lib/templates/decomposer-prompts.js +14 -8
- package/.agents/scripts/lifecycle-emit.js +1 -1
- package/.agents/scripts/lint-label-vocabulary.js +2 -3
- package/.agents/scripts/providers/github/mappers.js +0 -3
- package/.agents/scripts/providers/github/tickets.js +7 -18
- package/.agents/scripts/single-story-init.js +0 -1
- package/.agents/scripts/story-init.js +1 -29
- package/.agents/skills/core/epic-plan-consolidate/SKILL.md +43 -22
- package/.agents/skills/core/epic-plan-consolidate/examples.md +51 -0
- package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +27 -40
- package/.agents/skills/core/epic-plan-decompose-author/examples.md +47 -0
- package/.agents/skills/core/epic-plan-premortem/SKILL.md +15 -13
- package/.agents/skills/core/epic-plan-premortem/examples.md +53 -0
- package/.agents/skills/core/epic-plan-spec-author/SKILL.md +143 -151
- package/.agents/skills/core/epic-plan-spec-author/examples.md +91 -0
- package/.agents/skills/core/hydrate-context/SKILL.md +10 -5
- package/.agents/skills/core/knowledge-transfer/SKILL.md +3 -2
- package/.agents/skills/core/scope-triage/SKILL.md +2 -1
- package/.agents/skills/skills.index.json +8 -8
- package/.agents/skills/stack/qa/qa-explore-driving/SKILL.md +52 -38
- package/.agents/templates/epic-from-idea.md +4 -0
- package/.agents/workflows/audit-to-stories.md +2 -2
- package/.agents/workflows/helpers/code-review.md +11 -9
- package/.agents/workflows/helpers/deliver-epic-reference.md +514 -0
- package/.agents/workflows/helpers/deliver-epic.md +173 -490
- package/.agents/workflows/helpers/epic-audit.md +11 -8
- package/.agents/workflows/helpers/epic-deliver-story.md +45 -27
- package/.agents/workflows/helpers/epic-plan-decompose.md +17 -12
- package/.agents/workflows/helpers/epic-plan-spec.md +68 -68
- package/.agents/workflows/helpers/parallel-tooling.md +2 -1
- package/.agents/workflows/helpers/plan-epic-reference.md +136 -0
- package/.agents/workflows/helpers/plan-epic.md +141 -256
- package/.agents/workflows/helpers/plan-story.md +31 -61
- package/.agents/workflows/helpers/qa-run-scenario.md +194 -0
- package/.agents/workflows/helpers/scope-triage-gate.md +97 -0
- package/.agents/workflows/helpers/single-story-deliver-reference.md +423 -0
- package/.agents/workflows/helpers/single-story-deliver.md +129 -393
- package/.agents/workflows/helpers/worktree-lifecycle.md +1 -1
- package/.agents/workflows/plan.md +8 -8
- package/.agents/workflows/qa-assist.md +2 -1
- package/.agents/workflows/qa-explore.md +63 -32
- package/.agents/workflows/qa-run.md +293 -130
- package/docs/CHANGELOG.md +35 -0
- package/package.json +1 -1
- package/.agents/schemas/qa-finding.schema.json +0 -133
- package/.agents/scripts/lib/issue-link-parser.js +0 -74
- package/.agents/scripts/lib/orchestration/finalize/close-planning-tickets.js +0 -116
- package/.agents/scripts/lib/orchestration/planning-state-manager.js +0 -318
- 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
|
|
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
|
|
8
|
-
|
|
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
|
|
21
|
-
- Start each markdown artifact at the correct `##` heading (
|
|
22
|
-
-
|
|
23
|
-
-
|
|
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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
the
|
|
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
|
|
46
|
-
workflow
|
|
47
|
-
|
|
48
|
-
`temp/epic-<Epic_ID>/
|
|
49
|
-
|
|
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.
|
|
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
|
|
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
|
|
110
|
-
|
|
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
|
-
`##
|
|
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
|
|
140
|
+
starting with `## Acceptance Table` (no `<h1>`).
|
|
126
141
|
|
|
127
|
-
All
|
|
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> --
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
-
|
|
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
|
|
182
|
+
#### Delivery Slicing section (authoritative ceiling for Phase 8 consolidation)
|
|
188
183
|
|
|
189
|
-
The Tech Spec MUST carry a `## Delivery Slicing` section
|
|
190
|
-
|
|
191
|
-
|
|
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
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
**
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
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
|
|
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.
|
|
252
|
-
2.
|
|
253
|
-
3.
|
|
254
|
-
4.
|
|
255
|
-
5.
|
|
256
|
-
6.
|
|
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.
|
|
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
|
-
-
|
|
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
|
|
229
|
+
### Step 3 — Author the risk verdict (Risk Assessor persona)
|
|
266
230
|
|
|
267
|
-
Judge the change described by the
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
276
|
+
### Step 4 — Author the Acceptance Spec (Acceptance Engineer persona)
|
|
313
277
|
|
|
314
|
-
Apply the Acceptance Spec system prompt below to the
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
374
|
+
### Step 5 — Hand back to `/plan`
|
|
385
375
|
|
|
386
|
-
All
|
|
387
|
-
`node .agents/scripts/epic-plan-spec.js --epic <Epic_ID>
|
|
388
|
-
|
|
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-
|
|
391
|
-
the risk verdict, derives the planningRisk envelope,
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
`
|
|
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.
|