mandrel 1.80.0 → 1.82.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 (101) hide show
  1. package/.agents/README.md +5 -5
  2. package/.agents/docs/SDLC.md +93 -80
  3. package/.agents/docs/configuration.md +11 -1
  4. package/.agents/docs/quality-gates.md +61 -0
  5. package/.agents/docs/workflows.md +1 -1
  6. package/.agents/instructions.md +9 -7
  7. package/.agents/personas/architect.md +8 -5
  8. package/.agents/personas/engineer-mobile.md +3 -2
  9. package/.agents/personas/engineer-web.md +3 -2
  10. package/.agents/personas/engineer.md +6 -5
  11. package/.agents/personas/product.md +19 -13
  12. package/.agents/personas/project-manager.md +9 -8
  13. package/.agents/personas/qa-engineer.md +10 -6
  14. package/.agents/personas/refactorer.md +3 -2
  15. package/.agents/personas/technical-writer.md +2 -1
  16. package/.agents/personas/ux-designer.md +2 -2
  17. package/.agents/schemas/agentrc.schema.json +10 -0
  18. package/.agents/scripts/acceptance-spec-reconciler.js +143 -59
  19. package/.agents/scripts/epic-deliver-prepare.js +0 -31
  20. package/.agents/scripts/epic-plan-decompose.js +2 -5
  21. package/.agents/scripts/epic-plan-spec.js +16 -19
  22. package/.agents/scripts/hierarchy-gate.js +11 -11
  23. package/.agents/scripts/lib/ITicketingProvider.js +4 -3
  24. package/.agents/scripts/lib/baselines/env-overrides.js +35 -0
  25. package/.agents/scripts/lib/bdd-runner-detect.js +1 -1
  26. package/.agents/scripts/lib/bdd-scenario-scanner.js +1 -1
  27. package/.agents/scripts/lib/cli-args.js +1 -5
  28. package/.agents/scripts/lib/codebase-snapshot.js +1 -1
  29. package/.agents/scripts/lib/config/temp-paths.js +1 -4
  30. package/.agents/scripts/lib/config-settings-schema.js +5 -0
  31. package/.agents/scripts/lib/epic-body-sections.js +222 -0
  32. package/.agents/scripts/lib/epic-plan-clarity.js +38 -1
  33. package/.agents/scripts/lib/epic-plan-ideation.js +15 -3
  34. package/.agents/scripts/lib/label-constants.js +7 -17
  35. package/.agents/scripts/lib/label-taxonomy.js +4 -21
  36. package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +47 -1
  37. package/.agents/scripts/lib/orchestration/check-baselines/phases/parse-args.js +7 -0
  38. package/.agents/scripts/lib/orchestration/check-baselines/phases/pipeline.js +1 -1
  39. package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +2 -1
  40. package/.agents/scripts/lib/orchestration/context-hydration-engine.js +19 -8
  41. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/context.js +23 -22
  42. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +7 -10
  43. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +4 -38
  44. package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +8 -9
  45. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/authoring-context.js +11 -5
  46. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/cli-args.js +26 -5
  47. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +102 -304
  48. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/prompts.js +32 -29
  49. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +19 -20
  50. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-authoring-grounding.js +1 -1
  51. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-freshness.js +6 -9
  52. package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +3 -4
  53. package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +1 -1
  54. package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +20 -27
  55. package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +11 -5
  56. package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +22 -59
  57. package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +1 -1
  58. package/.agents/scripts/lib/orchestration/planning-context-budget.js +1 -1
  59. package/.agents/scripts/lib/orchestration/preflight-cache.js +1 -1
  60. package/.agents/scripts/lib/orchestration/spec-freshness.js +3 -3
  61. package/.agents/scripts/lib/orchestration/spec-section-validator.js +1 -1
  62. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +122 -1
  63. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +5 -8
  64. package/.agents/scripts/lib/orchestration/ticketing/reads.js +2 -2
  65. package/.agents/scripts/lib/plan-phase-cleanup.js +1 -2
  66. package/.agents/scripts/lib/qa/qa-context-hydrator.js +6 -85
  67. package/.agents/scripts/lib/templates/decomposer-prompts.js +14 -8
  68. package/.agents/scripts/lifecycle-emit.js +1 -1
  69. package/.agents/scripts/lint-label-vocabulary.js +2 -3
  70. package/.agents/scripts/providers/github/mappers.js +0 -3
  71. package/.agents/scripts/providers/github/tickets.js +7 -18
  72. package/.agents/scripts/single-story-init.js +0 -1
  73. package/.agents/scripts/story-init.js +1 -29
  74. package/.agents/skills/core/epic-plan-consolidate/SKILL.md +37 -18
  75. package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +23 -18
  76. package/.agents/skills/core/epic-plan-premortem/SKILL.md +7 -6
  77. package/.agents/skills/core/epic-plan-spec-author/SKILL.md +161 -109
  78. package/.agents/skills/core/hydrate-context/SKILL.md +10 -5
  79. package/.agents/skills/core/knowledge-transfer/SKILL.md +3 -2
  80. package/.agents/skills/core/scope-triage/SKILL.md +2 -1
  81. package/.agents/skills/skills.index.json +6 -6
  82. package/.agents/templates/epic-from-idea.md +4 -0
  83. package/.agents/workflows/audit-to-stories.md +2 -2
  84. package/.agents/workflows/helpers/code-review.md +11 -9
  85. package/.agents/workflows/helpers/deliver-epic.md +32 -44
  86. package/.agents/workflows/helpers/epic-audit.md +11 -8
  87. package/.agents/workflows/helpers/epic-deliver-story.md +10 -16
  88. package/.agents/workflows/helpers/epic-plan-decompose.md +17 -12
  89. package/.agents/workflows/helpers/epic-plan-spec.md +68 -68
  90. package/.agents/workflows/helpers/parallel-tooling.md +2 -1
  91. package/.agents/workflows/helpers/plan-epic.md +114 -99
  92. package/.agents/workflows/helpers/single-story-deliver.md +1 -1
  93. package/.agents/workflows/helpers/worktree-lifecycle.md +1 -1
  94. package/.agents/workflows/plan.md +8 -8
  95. package/.agents/workflows/qa-assist.md +2 -1
  96. package/docs/CHANGELOG.md +28 -0
  97. package/package.json +1 -1
  98. package/.agents/scripts/lib/issue-link-parser.js +0 -74
  99. package/.agents/scripts/lib/orchestration/finalize/close-planning-tickets.js +0 -116
  100. package/.agents/scripts/lib/orchestration/planning-state-manager.js +0 -318
  101. package/.agents/scripts/lib/story-init/hierarchy-tracer.js +0 -57
@@ -79,13 +79,15 @@ review yourself, honor the `depth` semantics above directly.
79
79
 
80
80
  1. Resolve `[TICKET_ID]` from `ticketId` (Story or Epic depending on `scope`).
81
81
  2. Resolve `[BASE_REF]` from `baseRef` and `[HEAD_REF]` from `headRef`.
82
- 3. Fetch the `[TICKET_ID]` ticket and identify linked context tickets:
82
+ 3. Fetch the `[TICKET_ID]` ticket and resolve the planning context:
83
83
  - **Story scope** — read the parent Epic from the Story body, then load
84
- the Epic's `context::prd` (PRD) and `context::tech-spec` (Tech Spec).
85
- - **Epic scope** — load the Epic's `context::prd` (PRD) and
86
- `context::tech-spec` (Tech Spec) directly from the Epic body.
87
- 4. Read both the PRD and Tech Spec fully to understand the intended scope,
88
- architectural decisions, and acceptance criteria.
84
+ the Epic body (including its `## User Stories` section and its folded
85
+ Tech Spec sections).
86
+ - **Epic scope** read the Epic body directly; its managed sections
87
+ carry the Tech Spec.
88
+ 4. Read the Epic body fully (including its Tech Spec sections) to
89
+ understand the intended
90
+ scope, architectural decisions, and acceptance criteria.
89
91
 
90
92
  ## Step 1 — Automated Audit (Pre-Review)
91
93
 
@@ -120,7 +122,7 @@ before finalizing findings.
120
122
 
121
123
  ### Pillar 1: Spec Adherence
122
124
 
123
- Does the implementation match the PRD requirements and Tech Spec architecture?
125
+ Does the implementation match the Epic's requirements and Tech Spec architecture?
124
126
 
125
127
  - Compare each completed Story/Task against its stated acceptance criteria.
126
128
  - Flag any undocumented deviations, missing features, or scope creep.
@@ -251,7 +253,7 @@ anything not fixed in-place.
251
253
  structured comment for the operator to triage in Step 5.
252
254
  2. **Leave the finding on the structured comment for Step 5.** Required
253
255
  when the finding falls into any of the following classes:
254
- - `spec-deviation` — the change diverges from the PRD/Tech Spec.
256
+ - `spec-deviation` — the change diverges from the Epic/Tech Spec.
255
257
  - `secrets` — credentials, tokens, or PII surfaced in the diff.
256
258
  - `test-deletion` — coverage was removed without an explicit
257
259
  decision in the spec.
@@ -359,7 +361,7 @@ to the next phase of the parent workflow.
359
361
  the scope is set by the caller, and reviewing against the wrong base
360
362
  produces either a hollow review (too small a diff) or noise (too large a
361
363
  diff that includes unrelated history).
362
- - **Always** read the PRD and Tech Spec before reviewing code. Findings without
364
+ - **Always** read the Epic body and Tech Spec before reviewing code. Findings without
363
365
  spec context are noise.
364
366
  - **Never** implement fixes unless the operator explicitly requests it. The
365
367
  default mode is read-only audit.
@@ -167,24 +167,17 @@ Validates `type::epic`, enumerates `type::story` descendants, parses
167
167
  (to enumerate the open Story set), and upserts the `epic-run-state`
168
168
  checkpoint in the per-Story-status shape (a flat `stories` map seeded at
169
169
  `pending`, plus the global `concurrencyCap`). Treat the printed JSON as
170
- `state`: `{ epicId, storyCount, concurrencyCap, stories, prdId, techSpecId, checkpointInitializedAt }`.
170
+ `state`: `{ epicId, storyCount, concurrencyCap, stories, checkpointInitializedAt }`.
171
171
  `stories` is the flat dispatch hint (`{ storyId, worktree, title }` per open
172
172
  Story); the ready-set `tick` (Phase 2) decides which to dispatch on each
173
173
  beat. Flip the Epic to `agent::executing` (idempotent) after the CLI returns.
174
174
 
175
- **Epic linkages resolved once (Story #4253).** The envelope also carries
176
- `prdId` and `techSpecId` the Epic's linked PRD / Tech-Spec issue ids,
177
- resolved a **single** time here from the Epic snapshot prepare already
178
- holds (no extra fetch). Capture both and thread them into **every**
179
- per-Story `story-init.js` invocation 2b `epic-deliver-story` Step 0)
180
- as `--prd <prdId> --tech-spec <techSpecId>`. This collapses the N
181
- per-Story `getEpic` round-trips (one per child, each in its own process
182
- with its own provider cache) to this one parent-side resolution — the
183
- immutable Epic issue is invariant for the lifetime of a delivery run.
184
- When a linkage is `null` (the Epic links no PRD or Tech Spec), omit the
185
- corresponding flag; the child's `story-init.js` then falls back to its
186
- own `getEpic` resolution for the missing id, preserving graceful
187
- degradation.
175
+ **No spec-ticket linkage to resolve (Story #4324).** The Tech Spec lives
176
+ as managed sections of the Epic body itself there is no separate
177
+ Tech-Spec issue id in the envelope and no `--tech-spec` flag to thread
178
+ into the per-Story `story-init.js` invocations. Story agents receive the
179
+ Tech Spec via context hydration, which embeds the Epic body (with the
180
+ `## Acceptance Table` section stripped) directly into each Story prompt.
188
181
 
189
182
  > **Preflight guards (Story #3482 / F-workflow-guards).** Before the
190
183
  > snapshot phase runs — and before any worktree is created — prepare runs
@@ -218,19 +211,19 @@ degradation.
218
211
 
219
212
  Once the preflight guards pass, the snapshot phase applies one more gate:
220
213
 
221
- > **Acceptance-spec start gate.** Before the wave loop fans out, the
214
+ > **Acceptance-table start gate.** Before the wave loop fans out, the
222
215
  > snapshot phase
223
216
  > ([`lib/orchestration/epic-runner/phases/snapshot.js`](../../scripts/lib/orchestration/epic-runner/phases/snapshot.js))
224
217
  > asserts that the Epic either carries the `acceptance::n-a` waiver
225
- > label **or** has a linked `context::acceptance-spec` ticket. The
226
- > ticket's GitHub state (open / closed) is **not** checked —
227
- > presence is sufficient, matching the PRD and Tech Spec contract.
218
+ > label **or** has a `## Acceptance Table` managed section in its
219
+ > body section presence is sufficient.
228
220
  > The reviewer's OK during `/plan` Phase 7 is the approval
229
- > signal, not a manual ticket-close action. Neither condition met →
221
+ > signal. Neither condition met →
230
222
  > the snapshot throws a clear error
231
- > (`[epic-deliver] Epic #<id> cannot launch: …`) and `runAsCli`
223
+ > (`[epic-deliver] Epic #<id> cannot launch: …` naming the missing
224
+ > `## Acceptance Table` section and the absent waiver) and `runAsCli`
232
225
  > maps it to `process.exit(1)`. Operator remediation: either run
233
- > `/plan` Phase 7 to author the spec, or apply the
226
+ > `/plan` Phase 7 to author the acceptance table, or apply the
234
227
  > `acceptance::n-a` label to opt out.
235
228
 
236
229
  ---
@@ -348,10 +341,7 @@ matching `story.dispatch.end` record is appended later by
348
341
  `epic-execute-record-wave.js` (via `emit-story-dispatch-end.js`, Story #3900)
349
342
  after the Agent return is recorded in § 2c.
350
343
 
351
- Each Agent call's prompt must (1) name the Story + Epic ids **and the
352
- `prdId` / `techSpecId` from the Phase 1 prepare envelope** (Story #4253) so
353
- the child can thread `--prd <prdId> --tech-spec <techSpecId>` into its
354
- `story-init.js` Step 0 — omit whichever flag is `null`, (2)
344
+ Each Agent call's prompt must (1) name the Story + Epic ids, (2)
355
345
  instruct the child to invoke `helpers/epic-deliver-story <storyId>`
356
346
  (whose Step 4 defines the child's return shape), (3) remind the child
357
347
  of the **non-interactive contract** (no clarifying questions;
@@ -765,19 +755,22 @@ bus-owned finalize) composes three helpers under
765
755
  chain.** Treat this section as a runtime contract — `/deliver`
766
756
  just fires the emit and reads the resulting ledger.
767
757
 
768
- 1. **Acceptance-spec reconciliation — bus-driven.** The
758
+ 1. **Acceptance-table reconciliation — bus-driven.** The
769
759
  `AcceptanceReconciler` listener invokes
770
760
  [`acceptance-spec-reconciler.js`](../../scripts/acceptance-spec-reconciler.js)
771
- to diff the AC IDs declared in the linked `context::acceptance-spec`
772
- body against `@ac-*` / `@pending` tags in `tests/features/**`. A
761
+ to diff the AC IDs declared in the Epic body's `## Acceptance Table`
762
+ section against `@ac-*` / `@pending` tags in `tests/features/**`,
763
+ recording each row's verification outcome
764
+ (`satisfied` / `pending` / `missing`) into the table's Disposition
765
+ column via a section-scoped upsert of the Epic body. A
773
766
  non-OK reconciliation throws (per
774
767
  [`rules/orchestration-error-handling.md`](../../rules/orchestration-error-handling.md)),
775
- aborting finalize **before** any PR is opened or planning artifacts
776
- are closed — so the PRD, Tech Spec, and Acceptance Spec stay open
777
- until the AC coverage gap is fixed. The reconciler returns
768
+ aborting finalize **before** any PR is opened so the Epic stays
769
+ unfinalized until the AC coverage gap is fixed. The reconciler returns
778
770
  `status: 'waived'` without scanning features when the Epic carries
779
771
  `acceptance::n-a`, and defends against direct CLI invocation by
780
- refusing to run when no spec is linked and no waiver is set (the
772
+ refusing to run when the body has no `## Acceptance Table` section
773
+ and no waiver is set (the
781
774
  start gate in Phase 1 would normally catch that first).
782
775
  2. **PR open — bus-driven (Story #2894).** On
783
776
  `acceptance.reconcile.ok` the `Finalizer` listener invokes
@@ -800,21 +793,16 @@ just fires the emit and reads the resulting ledger.
800
793
  in [`check-lifecycle-lint.js`](../../scripts/check-lifecycle-lint.js)
801
794
  keeps `gh pr merge --auto --squash --delete-branch` confined to
802
795
  `AutomergeArmer` — Phase 7 never shells the merge command.
803
- 3. **Planning-artifact close + hand-off — bus-driven (Story
804
- #2894).** After `openOrLocatePr` returns, the `Finalizer` chains
805
- [`closePlanningTickets`](../../scripts/lib/orchestration/finalize/close-planning-tickets.js)
806
- to close the three planning context tickets
807
- (`context::prd`, `context::tech-spec`, `context::acceptance-spec`)
808
- so the Epic's `Closes #<id>` auto-close path is not blocked by
809
- open sub-issues, then
796
+ 3. **Hand-off — bus-driven (Story #2894).** After `openOrLocatePr`
797
+ returns, the `Finalizer` chains
810
798
  [`postHandoffComment`](../../scripts/lib/orchestration/finalize/post-handoff-comment.js)
811
799
  to upsert the canonical `epic-handoff` structured comment naming
812
- the PR URL. Both helpers are idempotent — already-closed tickets
813
- are counted under `alreadyClosed`, and the handoff comment is
800
+ the PR URL. The helper is idempotent — the handoff comment is
814
801
  edited in place via `upsertStructuredComment` rather than
815
- appending a duplicate. When the `acceptance::n-a` waiver is set
816
- and no Acceptance Spec ticket was ever opened, the third
817
- planning-ticket close is recorded as `skipped`.
802
+ appending a duplicate. There is **no planning-ticket close sweep**
803
+ (Story #4324): the planning artifacts live as sections of the Epic
804
+ body itself, so there are no context tickets to close and nothing
805
+ blocks the Epic's `Closes #<id>` auto-close path.
818
806
 
819
807
  Branch cleanup is out-of-band (Phase 9 reaps local refs after merge; the
820
808
  rare "scrap and reset" case for an unmerged Epic is handled manually).
@@ -44,12 +44,15 @@ change-set selection. Both lens sources fire through the **same**
44
44
  2. Resolve `[EPIC_BRANCH]` — `epic/<epicId>`.
45
45
  3. Resolve `[BASE_BRANCH]` from `baseBranch` in `.agentrc.json` (default:
46
46
  `main`).
47
- 4. Fetch the Epic ticket and identify linked context tickets:
48
- - **PRD** — the `context::prd` ticket linked in the Epic body.
49
- - **Tech Spec** — the `context::tech-spec` ticket linked in the Epic
50
- body.
51
- 5. Read both the PRD and Tech Spec fully to understand the intended scope,
52
- selected lenses, and acceptance criteria.
47
+ 4. Fetch the Epic ticket the Epic body is the single planning
48
+ document:
49
+ - **Narrative sections** — Context / Goal / Scope / User Stories /
50
+ Acceptance Criteria.
51
+ - **Tech Spec** the folded Tech Spec sections (opening with
52
+ `## Delivery Slicing`) inside the body's managed region.
53
+ 5. Read the Epic body fully (including its Tech Spec sections) to
54
+ understand the intended
55
+ scope, selected lenses, and acceptance criteria.
53
56
 
54
57
  ## Step 1 — Prepare (`epic-audit-prepare.js`)
55
58
 
@@ -226,7 +229,7 @@ For each 🔴 / 🟠 finding, the host LLM MUST decide between two paths:
226
229
  (path 2) and record the attempt context in Step 4.
227
230
  2. **Escalate to the operator via Step 4.** Required when the finding
228
231
  falls into any of the following classes:
229
- - `spec-deviation` — the change diverges from the PRD/Tech Spec.
232
+ - `spec-deviation` — the change diverges from the Epic/Tech Spec.
230
233
  - `secrets` — credentials, tokens, or PII surfaced in the diff.
231
234
  - `test-deletion` — coverage was removed without an explicit
232
235
  decision in the spec.
@@ -282,7 +285,7 @@ The body MUST include:
282
285
 
283
286
  - **Always** diff against `[BASE_BRANCH]`, not against individual Story
284
287
  branches. The audit examines the cumulative effect of the entire Epic.
285
- - **Always** read the PRD and Tech Spec before walking lenses. Findings
288
+ - **Always** read the Epic body and Tech Spec before walking lenses. Findings
286
289
  without spec context are noise.
287
290
  - **Always** cap focused fixes at one attempt per finding (Step 3). The
288
291
  host LLM is the executor; there is no shared retry/anti-thrash module
@@ -77,21 +77,15 @@ the parent's permissions but have **no input channel** mid-run.
77
77
  Run from the **main checkout** (the worktree does not exist yet):
78
78
 
79
79
  ```bash
80
- node .agents/scripts/story-init.js --story <storyId> \
81
- --prd <prdId> --tech-spec <techSpecId>
80
+ node .agents/scripts/story-init.js --story <storyId>
82
81
  ```
83
82
 
84
- **Thread the Epic linkages (Story #4253).** The parent `/deliver` resolved
85
- the Epic's `prdId` / `techSpecId` **once** in its Phase 1 prepare and passed
86
- them into your dispatch prompt. Forward them as `--prd` / `--tech-spec` so
87
- this `story-init.js` run **skips** the per-Story `getEpic` round-trip the
88
- two ids are invariant for the whole delivery run, so re-fetching the
89
- immutable Epic per Story is pure waste (and secondary-rate-limit pressure
90
- during wide fan-out). **Omit** whichever flag the prompt reported as `null`;
91
- `story-init.js` then falls back to its own `getEpic` resolution for the
92
- missing id (graceful degradation on a missing Epic linkage). When dispatched
93
- interactively with neither flag, drop both — the legacy single-fetch path is
94
- unchanged.
83
+ **No spec-ticket threading (Story #4324).** The Tech Spec lives as managed
84
+ sections of the Epic body there is no separate Tech-Spec issue, no
85
+ `--tech-spec` flag, and no per-Story hierarchy trace to a spec ticket.
86
+ Your hydrated prompt already embeds the Epic body (with the
87
+ `## Acceptance Table` section stripped), which carries the folded Tech
88
+ Spec sections; do not fetch a Tech Spec issue.
95
89
 
96
90
  > **Execution mode (sub-agents must read).** This command typically takes
97
91
  > 3–6 minutes when the worktree's per-tree install runs. Invoke it
@@ -105,15 +99,15 @@ unchanged.
105
99
  > partial state, so the recovery is to re-run it synchronously, but
106
100
  > prevention is cheaper: just give Bash the 10-minute timeout and block.
107
101
 
108
- The script validates `type::story`, checks blockers, traces the
109
- Epic → PRD/Tech-Spec hierarchy, seeds `story-<id>` from the
102
+ The script validates `type::story`, checks blockers, resolves the parent
103
+ Epic id, seeds `story-<id>` from the
110
104
  Epic branch, and (when worktree isolation is on) runs `git worktree add`
111
105
  at `.worktrees/story-<id>/`. The Story flips to `agent::executing`. A
112
106
  `story-init` structured comment is upserted with the Story's inline
113
107
  `acceptance[]` and `verify[]` arrays from the body.
114
108
 
115
109
  Capture `workCwd`, `dependenciesInstalled` (tri-state), and
116
- `context.{prdId,techSpecId,acceptance,verify}`. Add `--dry-run` to check
110
+ `context.parentId`. Add `--dry-run` to check
117
111
  status without git or ticket changes.
118
112
 
119
113
  ### Step 0.5 — `cd` into the workCwd
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  description: >-
3
- Phase 8 of sprint planning — decompose an Epic's PRD and Tech Spec into a
3
+ Phase 8 of sprint planning — decompose an Epic's sectioned body (which
4
+ carries the folded Tech Spec) into a
4
5
  backlog of child Stories, persist the backlog, and flip the Epic to
5
6
  `agent::ready`. Host-LLM authored; no external API calls.
6
7
  ---
@@ -18,8 +19,9 @@ Director / Architect
18
19
  ## Context
19
20
 
20
21
  This helper is the **decompose phase** of the split planning pipeline. It
21
- reads the PRD and Tech Spec previously produced by the spec phase helper
22
- ([`epic-plan-spec.md`](epic-plan-spec.md)), generates the Epic's child
22
+ reads the Epic body whose managed sections carry the Tech Spec previously
23
+ produced by the spec phase
24
+ helper ([`epic-plan-spec.md`](epic-plan-spec.md)) — generates the Epic's child
23
25
  Story tickets, persists them to GitHub, and flips the Epic to
24
26
  `agent::ready` (parking) so a human can run `/deliver` when
25
27
  execution should begin.
@@ -38,9 +40,9 @@ skill.
38
40
 
39
41
  ## Constraint
40
42
 
41
- - **Do not** run this skill until the spec phase is complete. The Epic must
42
- have linked `context::prd` and `context::tech-spec` issues; the script will
43
- refuse to proceed otherwise.
43
+ - **Do not** run this skill until the spec phase is complete. The Epic body
44
+ must carry Tech Spec content (the managed section or a `## Delivery
45
+ Slicing` heading); the script will refuse to proceed otherwise.
44
46
  - **Do not** restructure the Story set after the decomposition
45
47
  writes — the `epic-plan-state` checkpoint records the structure as
46
48
  committed. Use `--force` to rebuild from scratch.
@@ -52,7 +54,7 @@ skill.
52
54
  ## Prerequisites
53
55
 
54
56
  1. **Epic is on `agent::review-spec`** — i.e. the spec phase has already run
55
- and the PRD / Tech Spec exist.
57
+ and the Epic body carries the Tech Spec sections.
56
58
  2. **API keys** — `GITHUB_TOKEN` set in `.env`.
57
59
 
58
60
  ## Step 1 — Gather decomposition context
@@ -62,7 +64,8 @@ node .agents/scripts/epic-plan-decompose.js --epic [Epic_ID] --emit-context \
62
64
  > temp/epic-[Epic_ID]/decomposer-context.json
63
65
  ```
64
66
 
65
- The emitted JSON contains the PRD body, Tech Spec body, risk heuristics, the
67
+ The emitted JSON contains the Epic body (`epicBody` the spec sections and
68
+ acceptance table travel inside it), risk heuristics, the
66
69
  decomposer system prompt, and the `maxTickets` **reviewability budget**
67
70
  (Story #2798 — not a hard cap; over-budget plans require an explicit
68
71
  `--allow-over-budget` override at persist time).
@@ -74,7 +77,7 @@ Story objects that conforms to the schema in the system prompt
74
77
  and write it to `temp/epic-[Epic_ID]/tickets.json`.
75
78
 
76
79
  When the Tech Spec carries a `## Delivery Slicing` section, author toward the
77
- Architect's proposed shippable-Story clusters rather than mapping PRD
80
+ Architect's proposed shippable-Story clusters rather than mapping Epic
78
81
  capabilities 1:1; degrade gracefully (current behaviour) when it is absent.
79
82
 
80
83
  ## Step 2.5 — Phase 8.3: Holistic Consolidation (HITL diff gate)
@@ -87,7 +90,8 @@ deterministic validator and **before** the GitHub write.
87
90
  Activate the
88
91
  [`epic-plan-consolidate`](../../skills/core/epic-plan-consolidate/SKILL.md)
89
92
  skill with `[Epic_ID]` as input. It reads the draft
90
- `temp/epic-[Epic_ID]/tickets.json` plus the PRD / Tech Spec from
93
+ `temp/epic-[Epic_ID]/tickets.json` plus the Epic body (with its folded
94
+ Tech Spec sections) from
91
95
  `decomposer-context.json`, reconciles the draft against the Tech Spec
92
96
  `## Delivery Slicing` target (degrading gracefully when absent), and emits:
93
97
 
@@ -187,8 +191,9 @@ is the single source of truth for which temp paths this phase owns.
187
191
 
188
192
  ## Troubleshooting
189
193
 
190
- - "Epic #N is missing a linked PRD or Tech Spec" — run `/plan [Epic_ID]`
191
- first (it will run the spec phase if the PRD / Tech Spec are missing).
194
+ - "Epic #N body carries no Tech Spec sections (no ## Delivery Slicing)" —
195
+ run `/plan [Epic_ID]`
196
+ first (it will run the spec phase if the Tech Spec sections are missing).
192
197
  - Validator rejects the tickets file — the most common causes are a
193
198
  Story whose `parent_slug` does not point at a Feature, a missing
194
199
  `acceptance[]` / `verify[]` array on a Story body, or a Story
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  description: >-
3
- Phase 7 of sprint planning — generate the PRD and Tech Spec for an Epic,
4
- persist them as linked GitHub issues, and flip the Epic to
5
- `agent::review-spec`. Host-LLM authored; no external API calls.
3
+ Phase 7 of sprint planning — generate the Tech Spec and Acceptance Table for
4
+ an Epic, persist them as managed sections of the Epic body, and flip the
5
+ Epic to `agent::review-spec`. Host-LLM authored; no external API calls.
6
6
  ---
7
7
 
8
8
  # Sprint Plan — Spec Phase (helper)
@@ -18,22 +18,28 @@ Director / Architect
18
18
  ## Context
19
19
 
20
20
  This helper is the **spec phase** of the split planning pipeline. It produces
21
- **three** planning artifacts for an Epic — a Product Requirements Document, a
22
- Technical Specification, and an Acceptance Spec — persists them as
23
- `context::prd`, `context::tech-spec`, and `context::acceptance-spec` issues
24
- under the Epic, and flips the Epic to `agent::review-spec` (parking) so a human
25
- reviewer can read the artifacts on GitHub before decomposition.
21
+ two planning artifacts for an Epic — a Technical Specification and an
22
+ Acceptance Table — persists them as **marker-delimited managed sections of
23
+ the Epic body** (`<!-- mandrel:tech-spec:start/end -->` and
24
+ `<!-- mandrel:acceptance-table:start/end -->`), and flips the Epic to
25
+ `agent::review-spec` (parking) so a human reviewer can read the updated Epic
26
+ body on GitHub before decomposition. A `/plan` Epic run creates exactly
27
+ **one** issue — the Epic. The PRD artifact class was retired (Story #4314);
28
+ its one novel section, **User Stories**, lives inline in the Epic body.
29
+ Story #4324 retired the `context::tech-spec` / `context::acceptance-spec`
30
+ ticket classes the same way — the content semantics are unchanged, only
31
+ where the output lives moved.
26
32
 
27
33
  > **Single prose home.** The canonical, full-detail spec-phase contract
28
- > (idempotent context tickets, the three-ticket rationale, the
34
+ > (idempotent managed sections, the fold rationale, the
29
35
  > `acceptance::n-a` waiver, the Epic-lease preflight) lives in
30
36
  > [`epic-plan.md` § Phase 7](plan-epic.md). This helper carries only the
31
37
  > operational step list; when the two disagree, `epic-plan.md` wins.
32
38
 
33
- The PRD and Tech Spec are authored **directly by you, the host LLM**.
34
- `epic-plan-spec.js` is a deterministic wrapper that (a) emits the authoring
35
- context you need and (b) persists the artifacts and transitions the Epic
36
- lifecycle state.
39
+ The Tech Spec and Acceptance Table are authored **directly by you, the host
40
+ LLM**. `epic-plan-spec.js` is a deterministic wrapper that (a) emits the
41
+ authoring context you need and (b) persists the sections and transitions the
42
+ Epic lifecycle state.
37
43
 
38
44
  The complementary Phase 8 helper is
39
45
  [`epic-plan-decompose.md`](epic-plan-decompose.md). The `/plan`
@@ -41,14 +47,14 @@ wrapper chains both helpers with a confirmation gate in between.
41
47
 
42
48
  ## Constraint
43
49
 
44
- - **Do not** create or modify tickets outside the `context::prd` /
45
- `context::tech-spec` / `context::acceptance-spec` contract
50
+ - **Do not** create any tickets from this phase — the only GitHub write is
51
+ the section-scoped Epic body update (plus structured comments);
46
52
  decomposition belongs to
47
53
  [`epic-plan-decompose.md`](epic-plan-decompose.md).
48
54
  - **Do not** flip the Epic to `agent::ready` from this skill. The terminal
49
55
  label for the spec phase is `agent::review-spec`.
50
56
  - **Every** temp file must include the Epic ID in its name. Multiple Epics may
51
- be planned concurrently; bare names like `temp/prd.md` will collide.
57
+ be planned concurrently; bare names like `temp/techspec.md` will collide.
52
58
  - **Stop and hand back to the operator** after Step 4 when
53
59
  `planningRisk.requiresReview` is true or the operator passed
54
60
  `--force-review` — do not chain into decomposition. Low-risk Epics
@@ -58,7 +64,8 @@ wrapper chains both helpers with a confirmation gate in between.
58
64
  ## Prerequisites
59
65
 
60
66
  1. **GitHub Epic** — an open issue with the `type::epic` label. The Epic's
61
- body should contain enough narrative context to seed the PRD.
67
+ body should contain enough narrative context (including its `## User
68
+ Stories` section) to seed the Tech Spec.
62
69
  2. **API keys** — `GITHUB_TOKEN` set in `.env`.
63
70
 
64
71
  ## Step 1 — Gather authoring context
@@ -71,23 +78,18 @@ node .agents/scripts/epic-plan-spec.js --epic [Epic_ID] --emit-context \
71
78
  > temp/epic-[Epic_ID]/planner-context.json
72
79
  ```
73
80
 
74
- ## Step 2 — Author the PRD
81
+ ## Step 2 — Author the Tech Spec
75
82
 
76
- Read `temp/epic-[Epic_ID]/planner-context.json`. Using `systemPrompts.prd`
77
- combined with the Epic title/body, write the PRD markdown to
78
- `temp/epic-[Epic_ID]/prd.md`. Use the four-section structure (Context & Goals,
79
- User Stories, Acceptance Criteria, Out of Scope) and start the document with
80
- `## Overview` (no `<h1>`).
83
+ Read `temp/epic-[Epic_ID]/planner-context.json`. Using
84
+ `systemPrompts.techSpec`, the Epic body (its Context / Goal / Scope / User
85
+ Stories sections), and `docsContext`, write the Tech Spec to
86
+ `temp/epic-[Epic_ID]/techspec.md`. Open the document with the
87
+ `## Delivery Slicing` section (no `<h1>`); do not restate the Epic's
88
+ Context / Goal / Scope — the output lands as sections of the same Epic body.
81
89
 
82
- ## Step 3 — Author the Tech Spec
90
+ ## Step 2.5 — Author the risk verdict
83
91
 
84
- Using `systemPrompts.techSpec`, the PRD you just wrote, and `docsContext`,
85
- write the Tech Spec to `temp/epic-[Epic_ID]/techspec.md`. Start with
86
- `## Technical Overview` (no `<h1>`).
87
-
88
- ## Step 3.5 — Author the risk verdict
89
-
90
- Judge the change described by the PRD and Tech Spec you just wrote and
92
+ Judge the change described by the Epic body and Tech Spec you just wrote and
91
93
  write `temp/epic-[Epic_ID]/risk-verdict.json` conforming to
92
94
  [`risk-verdict.schema.json`](../../schemas/risk-verdict.schema.json):
93
95
  `{ axes: [{ axis, level, rationale }], summary }`. The authoritative
@@ -95,39 +97,36 @@ authoring rules (axis vocabulary, judgment-not-keywords, derivation
95
97
  preview) live in the
96
98
  [`epic-plan-spec-author` Skill, Step 4](../../skills/core/epic-plan-spec-author/SKILL.md).
97
99
 
98
- ## Step 3.6 — Author the Acceptance Spec
100
+ ## Step 2.6 — Author the Acceptance Table
99
101
 
100
- Using `systemPrompts.acceptanceSpec`, the PRD, and the Tech Spec, write the
101
- Acceptance Spec to `temp/epic-[Epic_ID]/acceptance-spec.md`. It captures the
102
- stable-ID acceptance criteria table
103
- (`| AC ID | Outcome | Feature File | Scenario | Disposition |`) that drives
104
- close-time reconciliation in `/deliver` Phase 6.
102
+ Using `systemPrompts.acceptanceSpec`, the Epic body, and the Tech Spec, write
103
+ the Acceptance Spec to `temp/epic-[Epic_ID]/acceptance-spec.md`. It opens
104
+ with `## Acceptance Table` and captures the stable-ID acceptance criteria
105
+ table (`| AC ID | Outcome | Feature File | Scenario | Disposition |`) that
106
+ drives close-time reconciliation in `/deliver` Phase 6.
105
107
 
106
108
  **Skip this step only** when the Epic carries the `acceptance::n-a` waiver
107
- label (refactor-only or docs-only Epics); in that case omit `--acceptance-spec`
108
- from Step 4.
109
+ label (refactor-only or docs-only Epics); in that case omit
110
+ `--acceptance-table` from Step 3.
109
111
 
110
- ## Step 4 — Persist and transition
112
+ ## Step 3 — Persist and transition
111
113
 
112
114
  ```bash
113
- # Normal flow (three context tickets)
115
+ # Normal flow (both managed sections)
114
116
  node .agents/scripts/epic-plan-spec.js --epic [Epic_ID] \
115
- --prd temp/epic-[Epic_ID]/prd.md \
116
- --techspec temp/epic-[Epic_ID]/techspec.md \
117
+ --tech-spec temp/epic-[Epic_ID]/techspec.md \
117
118
  --risk-verdict temp/epic-[Epic_ID]/risk-verdict.json \
118
- --acceptance-spec temp/epic-[Epic_ID]/acceptance-spec.md
119
+ --acceptance-table temp/epic-[Epic_ID]/acceptance-spec.md
119
120
 
120
- # Re-plan (--force overwrites the three context tickets in place)
121
+ # Re-plan (--force overwrites the managed sections in place)
121
122
  node .agents/scripts/epic-plan-spec.js --epic [Epic_ID] \
122
- --prd temp/epic-[Epic_ID]/prd.md \
123
- --techspec temp/epic-[Epic_ID]/techspec.md \
123
+ --tech-spec temp/epic-[Epic_ID]/techspec.md \
124
124
  --risk-verdict temp/epic-[Epic_ID]/risk-verdict.json \
125
- --acceptance-spec temp/epic-[Epic_ID]/acceptance-spec.md --force
125
+ --acceptance-table temp/epic-[Epic_ID]/acceptance-spec.md --force
126
126
 
127
- # Waived (acceptance::n-a label on Epic — no Acceptance Spec authored)
127
+ # Waived (acceptance::n-a label on Epic — no Acceptance Table authored)
128
128
  node .agents/scripts/epic-plan-spec.js --epic [Epic_ID] \
129
- --prd temp/epic-[Epic_ID]/prd.md \
130
- --techspec temp/epic-[Epic_ID]/techspec.md \
129
+ --tech-spec temp/epic-[Epic_ID]/techspec.md \
131
130
  --risk-verdict temp/epic-[Epic_ID]/risk-verdict.json
132
131
  ```
133
132
 
@@ -136,22 +135,21 @@ On success the script:
136
135
  - Validates the risk verdict against `risk-verdict.schema.json` (a
137
136
  malformed verdict fails closed before any GitHub mutation) and derives
138
137
  the `planningRisk` envelope from it.
139
- - Creates `[PRD]`, `[Tech Spec]`, and `[Acceptance Spec]` child issues
140
- (`context::prd` / `context::tech-spec` / `context::acceptance-spec`
141
- labels). The Acceptance Spec is skipped when `--acceptance-spec` is
142
- omitted under the `acceptance::n-a` waiver.
143
- - Appends a `## Planning Artifacts` section to the Epic body.
138
+ - Upserts the Tech Spec content and (unless waived) the `## Acceptance
139
+ Table` as managed sections of the Epic body, stripping any legacy
140
+ `## Planning Artifacts` section. The Acceptance Table is skipped when
141
+ `--acceptance-table` is omitted under the `acceptance::n-a` waiver.
144
142
  - Upserts the `risk-verdict` structured comment recording the verdict and
145
143
  the derived envelope.
146
144
  - Upserts the `epic-plan-state` structured comment with the current phase,
147
- PRD / Tech Spec / Acceptance Spec IDs, the `riskVerdict` field, and
148
- timestamps.
145
+ the persisted-section flags (`techSpecPersisted`, `acceptanceTable`),
146
+ the `riskVerdict` field, and timestamps.
149
147
  - Flips the Epic to `agent::review-spec`.
150
148
 
151
- ## Step 5 — Cleanup
149
+ ## Step 4 — Cleanup
152
150
 
153
151
  The wrapper script deletes the phase-scoped temp files automatically when
154
- Step 4 succeeds — no operator action required. The cleanup contract lives in
152
+ Step 3 succeeds — no operator action required. The cleanup contract lives in
155
153
  [`lib/plan-phase-cleanup.js`](../../scripts/lib/plan-phase-cleanup.js), which
156
154
  is the single source of truth for which temp paths this phase owns. If you
157
155
  need to inspect the temp artefacts after the fact, re-run
@@ -162,12 +160,13 @@ need to inspect the temp artefacts after the fact, re-run
162
160
  Branch on the shared planning risk decision surfaced in the persist stdout
163
161
  JSON (`planningRisk`, `reviewRouting`):
164
162
 
165
- - **High risk or `--force-review` — STOP.** Surface the PRD and Tech Spec
166
- URLs to the operator:
163
+ - **High risk or `--force-review` — STOP.** Surface the Epic URL to the
164
+ operator:
167
165
 
168
- > "Spec phase complete for Epic #[ID]. Review PRD (#XX) and Tech Spec (#YY)
169
- > on GitHub. When you're ready, re-run `/plan [Epic_ID]` — the wrapper
170
- > will pick up where it left off and run the decompose phase."
166
+ > "Spec phase complete for Epic #[ID]. Review the updated Epic body
167
+ > (Tech Spec sections + `## Acceptance Table`) on GitHub. When you're
168
+ > ready, re-run `/plan [Epic_ID]` the wrapper will pick up where it
169
+ > left off and run the decompose phase."
171
170
 
172
171
  - **Low risk — auto-proceed.** Relay `reviewRouting.operatorMessage` and
173
172
  continue directly to Phase 8 decomposition without waiting for verbal
@@ -177,8 +176,9 @@ JSON (`planningRisk`, `reviewRouting`):
177
176
 
178
177
  - If `--emit-context` fails with "Epic not found", confirm the ID matches the
179
178
  GitHub issue number and the token has `issues:read`.
180
- - If the persist call fails after creating the PRD but before the Tech Spec,
181
- re-run with `--force` (the script reuses the existing PRD when appropriate).
179
+ - If the persist call fails after writing the Tech Spec section but before
180
+ the Acceptance Table, re-run with `--force` (the section upsert is
181
+ idempotent — it replaces the managed regions in place).
182
182
  - If the Epic does not flip to `agent::review-spec` after the script claims
183
183
  success, the label write likely races with a concurrent mutation — re-run the
184
- persist step; it's idempotent against the existing PRD/Tech Spec.
184
+ persist step; it's idempotent against the already-persisted sections.
@@ -20,7 +20,8 @@ them in one assistant turn rather than serially. The host runtime executes
20
20
  the batch in parallel; serial calls cost N round-trips for no gain.
21
21
 
22
22
  - **Tool primitives:** `Read`, `Grep`, `Glob`, MCP `list_*` / `get_*` calls.
23
- - **When:** reading the PRD, Tech Spec, and Story body up front; grepping
23
+ - **When:** reading the Epic body (with its folded Tech Spec sections)
24
+ and Story body up front; grepping
24
25
  for multiple unrelated patterns; globbing several directory trees;
25
26
  fetching independent GitHub tickets.
26
27
  - **Anti-pattern:** sequential `Read` → wait → `Read` → wait → `Grep` chains