mandrel 1.59.0 → 1.61.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 (267) hide show
  1. package/.agents/README.md +86 -44
  2. package/.agents/docs/SDLC.md +135 -141
  3. package/.agents/docs/configuration.md +77 -20
  4. package/.agents/docs/quality-gates.md +796 -0
  5. package/.agents/docs/workflows.md +6 -9
  6. package/.agents/instructions.md +12 -11
  7. package/.agents/personas/architect.md +1 -1
  8. package/.agents/personas/product.md +1 -1
  9. package/.agents/personas/project-manager.md +14 -14
  10. package/.agents/personas/technical-writer.md +1 -1
  11. package/.agents/rules/changelog-style.md +5 -5
  12. package/.agents/rules/git-conventions.md +3 -3
  13. package/.agents/runtime-deps.json +2 -2
  14. package/.agents/schemas/agentrc.schema.json +3 -3
  15. package/.agents/schemas/dispatch-manifest.json +4 -4
  16. package/.agents/schemas/epic-spec.schema.json +15 -45
  17. package/.agents/schemas/lifecycle/README.md +1 -1
  18. package/.agents/schemas/lifecycle/story.dispatch.end.schema.json +1 -1
  19. package/.agents/schemas/lifecycle/story.dispatch.start.schema.json +1 -1
  20. package/.agents/schemas/lifecycle/story.heartbeat.schema.json +1 -1
  21. package/.agents/schemas/validation-evidence.schema.json +1 -1
  22. package/.agents/scripts/README.md +2 -2
  23. package/.agents/scripts/acceptance-eval.js +1 -1
  24. package/.agents/scripts/acceptance-spec-reconciler.js +2 -2
  25. package/.agents/scripts/agents-bootstrap-github.js +23 -119
  26. package/.agents/scripts/analyze-execution.js +2 -2
  27. package/.agents/scripts/audit-to-stories.js +1 -1
  28. package/.agents/scripts/check-doc-links.js +2 -3
  29. package/.agents/scripts/diagnose-friction.js +1 -1
  30. package/.agents/scripts/dispatcher.js +2 -2
  31. package/.agents/scripts/drain-pending-cleanup.js +1 -1
  32. package/.agents/scripts/epic-audit-prepare.js +3 -3
  33. package/.agents/scripts/epic-deliver-note-intervention.js +2 -2
  34. package/.agents/scripts/epic-deliver-preflight.js +6 -6
  35. package/.agents/scripts/epic-deliver-prepare.js +1 -1
  36. package/.agents/scripts/epic-execute-record-wave.js +4 -4
  37. package/.agents/scripts/epic-plan-healthcheck.js +6 -10
  38. package/.agents/scripts/epic-plan-spec-validate.js +1 -1
  39. package/.agents/scripts/epic-reconcile.js +11 -29
  40. package/.agents/scripts/evidence-gate.js +1 -1
  41. package/.agents/scripts/generate-workflows-doc.js +1 -1
  42. package/.agents/scripts/hierarchy-gate.js +7 -11
  43. package/.agents/scripts/lib/ITicketingProvider.js +1 -1
  44. package/.agents/scripts/lib/audit-suite/selector.js +1 -1
  45. package/.agents/scripts/lib/audit-to-stories/seed-epic-from-findings.js +2 -2
  46. package/.agents/scripts/lib/baseline-snapshot.js +7 -7
  47. package/.agents/scripts/lib/bdd-runner-detect.js +1 -1
  48. package/.agents/scripts/lib/bdd-scenario-scanner.js +3 -3
  49. package/.agents/scripts/lib/bootstrap/baselines-layout-migration.js +1 -1
  50. package/.agents/scripts/lib/bootstrap/branch-protection.js +1 -1
  51. package/.agents/scripts/lib/bootstrap/ci-workflow-template.js +47 -1
  52. package/.agents/scripts/lib/bootstrap/commit-push.js +2 -2
  53. package/.agents/scripts/lib/bootstrap/gh-preflight.js +7 -9
  54. package/.agents/scripts/lib/bootstrap/manifest.js +21 -1
  55. package/.agents/scripts/lib/bootstrap/merge-methods.js +31 -16
  56. package/.agents/scripts/lib/bootstrap/project-bootstrap.js +32 -11
  57. package/.agents/scripts/lib/codebase-snapshot.js +1 -1
  58. package/.agents/scripts/lib/config/explain.js +1 -1
  59. package/.agents/scripts/lib/config/runners.js +2 -2
  60. package/.agents/scripts/lib/config/runtime.js +1 -1
  61. package/.agents/scripts/lib/config/sync-agentrc.js +1 -1
  62. package/.agents/scripts/lib/config/temp-paths.js +2 -2
  63. package/.agents/scripts/lib/config-settings-schema-delivery.js +2 -2
  64. package/.agents/scripts/lib/config-settings-schema-quality.js +1 -1
  65. package/.agents/scripts/lib/config-settings-schema.js +3 -3
  66. package/.agents/scripts/lib/detect-package-manager.js +72 -0
  67. package/.agents/scripts/lib/duplicate-search.js +1 -1
  68. package/.agents/scripts/lib/dynamic-workflow/capability.js +1 -1
  69. package/.agents/scripts/lib/epic-plan-clarity.js +1 -1
  70. package/.agents/scripts/lib/epic-plan-ideation.js +1 -1
  71. package/.agents/scripts/lib/errors/index.js +4 -4
  72. package/.agents/scripts/lib/feedback-loop/memory-freshness.js +1 -1
  73. package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +1 -1
  74. package/.agents/scripts/lib/findings/classify-finding.js +1 -1
  75. package/.agents/scripts/lib/findings/promote-finding.js +10 -10
  76. package/.agents/scripts/lib/label-constants.js +3 -4
  77. package/.agents/scripts/lib/label-taxonomy.js +5 -10
  78. package/.agents/scripts/lib/onboard/detect-stack.js +10 -10
  79. package/.agents/scripts/lib/onboard/init-tail.js +218 -0
  80. package/.agents/scripts/lib/onboard/scaffold-docs.js +18 -3
  81. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +1 -1
  82. package/.agents/scripts/lib/orchestration/code-review.js +5 -5
  83. package/.agents/scripts/lib/orchestration/context-hydration-engine.js +8 -9
  84. package/.agents/scripts/lib/orchestration/dependency-analyzer.js +3 -3
  85. package/.agents/scripts/lib/orchestration/detectors-phase.js +2 -2
  86. package/.agents/scripts/lib/orchestration/dispatch-engine.js +30 -38
  87. package/.agents/scripts/lib/orchestration/dispatch-pipeline.js +9 -25
  88. package/.agents/scripts/lib/orchestration/epic-cleanup.js +1 -1
  89. package/.agents/scripts/lib/orchestration/epic-deliver-lease-guard.js +8 -8
  90. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/creation.js +1 -1
  91. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/dag.js +7 -21
  92. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/diagnostics.js +3 -3
  93. package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +26 -13
  94. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +1 -1
  95. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/prompts.js +1 -1
  96. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +2 -2
  97. package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +1 -1
  98. package/.agents/scripts/lib/orchestration/epic-run-state-store.js +3 -3
  99. package/.agents/scripts/lib/orchestration/epic-runner/concurrency-gate.js +4 -4
  100. package/.agents/scripts/lib/orchestration/epic-runner/deliver-phases.js +3 -3
  101. package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +6 -21
  102. package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +7 -7
  103. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/composition.js +1 -1
  104. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/signals.js +2 -2
  105. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/transport.js +4 -4
  106. package/.agents/scripts/lib/orchestration/epic-runner/story-launcher.js +4 -4
  107. package/.agents/scripts/lib/orchestration/epic-runner/story-run-progress-writer.js +8 -8
  108. package/.agents/scripts/lib/orchestration/epic-runner/sub-agent-return.js +4 -4
  109. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-apply.js +7 -15
  110. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +72 -41
  111. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-ops.js +2 -4
  112. package/.agents/scripts/lib/orchestration/file-assumptions.js +2 -2
  113. package/.agents/scripts/lib/orchestration/finalize/close-planning-tickets.js +1 -1
  114. package/.agents/scripts/lib/orchestration/finalize/open-or-locate-pr.js +2 -2
  115. package/.agents/scripts/lib/orchestration/finalize/sanitize-skip-ci.js +1 -1
  116. package/.agents/scripts/lib/orchestration/lease-guard-shared.js +3 -3
  117. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-dispatch-end.js +1 -1
  118. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +1 -1
  119. package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +1 -1
  120. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +1 -1
  121. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +1 -1
  122. package/.agents/scripts/lib/orchestration/lifecycle/listeners/branch-cleaner.js +1 -1
  123. package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +1 -1
  124. package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +1 -1
  125. package/.agents/scripts/lib/orchestration/lifecycle/listeners/merge-watcher.js +1 -1
  126. package/.agents/scripts/lib/orchestration/lifecycle/listeners/notify-dispatcher.js +1 -1
  127. package/.agents/scripts/lib/orchestration/lifecycle/listeners/watcher.js +1 -1
  128. package/.agents/scripts/lib/orchestration/manifest-builder.js +5 -5
  129. package/.agents/scripts/lib/orchestration/parked-follow-ons.js +2 -2
  130. package/.agents/scripts/lib/orchestration/plan-runner/plan-router.js +5 -5
  131. package/.agents/scripts/lib/orchestration/post-merge/phases/ticket-closure.js +3 -3
  132. package/.agents/scripts/lib/orchestration/preflight-cache.js +1 -1
  133. package/.agents/scripts/lib/orchestration/recurring-failure-detector.js +1 -1
  134. package/.agents/scripts/lib/orchestration/retro/phases/compose-body.js +1 -1
  135. package/.agents/scripts/lib/orchestration/retro/phases/gather-signals.js +2 -2
  136. package/.agents/scripts/lib/orchestration/retro-runner.js +3 -3
  137. package/.agents/scripts/lib/orchestration/review-depth.js +1 -1
  138. package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +1 -1
  139. package/.agents/scripts/lib/orchestration/spec-freshness.js +1 -1
  140. package/.agents/scripts/lib/orchestration/spec-renderer.js +36 -73
  141. package/.agents/scripts/lib/orchestration/spec-section-validator.js +1 -1
  142. package/.agents/scripts/lib/orchestration/story-close/baseline-friction-body.js +1 -1
  143. package/.agents/scripts/lib/orchestration/story-close/phases/locked-pipeline.js +2 -2
  144. package/.agents/scripts/lib/orchestration/task-body-validator.js +6 -6
  145. package/.agents/scripts/lib/orchestration/ticket-lease.js +1 -1
  146. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +2 -2
  147. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +1 -10
  148. package/.agents/scripts/lib/orchestration/ticket-validator.js +25 -70
  149. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +5 -12
  150. package/.agents/scripts/lib/orchestration/ticketing/reads.js +8 -8
  151. package/.agents/scripts/lib/orchestration/ticketing/state.js +3 -3
  152. package/.agents/scripts/lib/orchestration/wave-record-notifications.js +2 -2
  153. package/.agents/scripts/lib/orchestration/wave-record-projection.js +1 -1
  154. package/.agents/scripts/lib/plan-phase-cleanup.js +1 -1
  155. package/.agents/scripts/lib/preflight-runner.js +1 -1
  156. package/.agents/scripts/lib/presentation/dispatch-manifest-render.js +4 -5
  157. package/.agents/scripts/lib/presentation/manifest-builder.js +28 -34
  158. package/.agents/scripts/lib/presentation/manifest-formatter.js +3 -4
  159. package/.agents/scripts/lib/presentation/manifest-helpers.js +1 -1
  160. package/.agents/scripts/lib/presentation/manifest-procedures.js +4 -4
  161. package/.agents/scripts/lib/presentation/manifest-render-waves.js +4 -23
  162. package/.agents/scripts/lib/presentation/manifest-renderer.js +1 -1
  163. package/.agents/scripts/lib/presentation/manifest-story-views.js +2 -11
  164. package/.agents/scripts/lib/runtime-deps/preflight.js +6 -6
  165. package/.agents/scripts/lib/signals/schema.js +1 -1
  166. package/.agents/scripts/lib/spec/index.js +1 -1
  167. package/.agents/scripts/lib/spec/loader.js +2 -2
  168. package/.agents/scripts/lib/spec/state.js +7 -16
  169. package/.agents/scripts/lib/story-init/context-resolver.js +3 -3
  170. package/.agents/scripts/lib/story-init/state-transitioner.js +2 -2
  171. package/.agents/scripts/lib/story-init/task-graph-builder.js +7 -7
  172. package/.agents/scripts/lib/story-lifecycle.js +8 -8
  173. package/.agents/scripts/lib/story-plan.js +1 -1
  174. package/.agents/scripts/lib/templates/decomposer-prompts.js +59 -52
  175. package/.agents/scripts/lib/wave-runner/tick.js +1 -1
  176. package/.agents/scripts/lib/worktree/node-modules-strategy.js +5 -2
  177. package/.agents/scripts/lifecycle-emit-story-dispatch.js +1 -1
  178. package/.agents/scripts/lifecycle-emit.js +1 -1
  179. package/.agents/scripts/providers/github/board-add.js +1 -1
  180. package/.agents/scripts/providers/github/errors.js +1 -1
  181. package/.agents/scripts/providers/github/mappers.js +2 -2
  182. package/.agents/scripts/providers/github/tickets.js +4 -4
  183. package/.agents/scripts/resync-status-column.js +1 -1
  184. package/.agents/scripts/retro-run.js +2 -2
  185. package/.agents/scripts/run-lint.js +1 -1
  186. package/.agents/scripts/single-story-init.js +1 -1
  187. package/.agents/scripts/stories-wave-tick.js +5 -5
  188. package/.agents/scripts/story-close.js +1 -1
  189. package/.agents/scripts/story-init.js +13 -16
  190. package/.agents/scripts/story-phase.js +5 -5
  191. package/.agents/scripts/story-plan.js +3 -3
  192. package/.agents/scripts/sync-branch-from-base.js +1 -1
  193. package/.agents/scripts/validate-docs-freshness.js +1 -1
  194. package/.agents/scripts/wave-tick.js +1 -1
  195. package/.agents/skills/core/analyze-execution/SKILL.md +2 -2
  196. package/.agents/skills/core/epic-plan-consolidate/SKILL.md +21 -26
  197. package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +23 -56
  198. package/.agents/skills/core/epic-plan-spec-author/SKILL.md +4 -4
  199. package/.agents/skills/core/hydrate-context/SKILL.md +2 -2
  200. package/.agents/skills/core/idea-refinement/SKILL.md +4 -4
  201. package/.agents/skills/core/knowledge-transfer/SKILL.md +2 -2
  202. package/.agents/skills/core/planning-and-task-breakdown/SKILL.md +1 -1
  203. package/.agents/skills/core/scope-triage/SKILL.md +9 -10
  204. package/.agents/skills/core/using-agent-skills/SKILL.md +1 -1
  205. package/.agents/skills/skills.index.json +7 -7
  206. package/.agents/templates/agent-protocol.md +2 -2
  207. package/.agents/workflows/agents-update.md +16 -31
  208. package/.agents/workflows/audit-architecture.md +2 -2
  209. package/.agents/workflows/audit-clean-code.md +2 -2
  210. package/.agents/workflows/audit-dependencies.md +1 -1
  211. package/.agents/workflows/audit-devops.md +1 -1
  212. package/.agents/workflows/audit-documentation.md +2 -2
  213. package/.agents/workflows/audit-lighthouse.md +1 -1
  214. package/.agents/workflows/audit-performance.md +2 -2
  215. package/.agents/workflows/audit-privacy.md +1 -1
  216. package/.agents/workflows/audit-quality.md +2 -2
  217. package/.agents/workflows/audit-security.md +2 -2
  218. package/.agents/workflows/audit-seo.md +1 -1
  219. package/.agents/workflows/audit-sre.md +1 -1
  220. package/.agents/workflows/audit-to-stories.md +10 -10
  221. package/.agents/workflows/audit-ux-ui.md +1 -1
  222. package/.agents/workflows/deliver.md +85 -0
  223. package/.agents/workflows/explain.md +3 -3
  224. package/.agents/workflows/git-merge-pr.md +1 -1
  225. package/.agents/workflows/git-pr-all.md +13 -10
  226. package/.agents/workflows/git-push.md +6 -3
  227. package/.agents/workflows/helpers/_merge-conflict-template.md +1 -1
  228. package/.agents/workflows/helpers/acceptance-self-eval.md +1 -1
  229. package/.agents/workflows/helpers/agents-sync-config.md +3 -2
  230. package/.agents/workflows/helpers/code-review.md +5 -5
  231. package/.agents/workflows/{epic-deliver.md → helpers/deliver-epic.md} +43 -43
  232. package/.agents/workflows/{story-deliver.md → helpers/deliver-stories.md} +25 -25
  233. package/.agents/workflows/helpers/diagnose.md +1 -1
  234. package/.agents/workflows/helpers/epic-audit.md +6 -6
  235. package/.agents/workflows/helpers/epic-deliver-story.md +13 -13
  236. package/.agents/workflows/helpers/epic-plan-decompose.md +23 -23
  237. package/.agents/workflows/helpers/epic-plan-spec.md +6 -6
  238. package/.agents/workflows/helpers/epic-testing.md +3 -3
  239. package/.agents/workflows/helpers/parallel-tooling.md +1 -1
  240. package/.agents/workflows/{epic-plan.md → helpers/plan-epic.md} +84 -84
  241. package/.agents/workflows/{story-plan.md → helpers/plan-story.md} +43 -43
  242. package/.agents/workflows/helpers/signals.md +1 -1
  243. package/.agents/workflows/helpers/single-story-deliver.md +11 -11
  244. package/.agents/workflows/helpers/worktree-lifecycle.md +18 -18
  245. package/.agents/workflows/plan.md +131 -0
  246. package/.agents/workflows/qa-explore.md +1 -1
  247. package/.agents/workflows/qa-run-harness.md +1 -1
  248. package/README.md +19 -39
  249. package/bin/mandrel.js +235 -16
  250. package/docs/CHANGELOG.md +1173 -0
  251. package/lib/cli/doctor.js +45 -3
  252. package/lib/cli/init.js +97 -36
  253. package/lib/cli/registry.js +41 -145
  254. package/lib/cli/sync.js +122 -23
  255. package/lib/cli/uninstall.js +42 -7
  256. package/lib/cli/update.js +524 -210
  257. package/lib/cli/version-helpers.js +59 -0
  258. package/package.json +7 -6
  259. package/.agents/scripts/lib/orchestration/reconciler.js +0 -137
  260. package/.agents/workflows/onboard.md +0 -208
  261. package/lib/cli/__tests__/migrate.test.js +0 -268
  262. package/lib/cli/__tests__/sync-local-zone.test.js +0 -247
  263. package/lib/cli/__tests__/sync.test.js +0 -372
  264. package/lib/cli/__tests__/update-major.test.js +0 -217
  265. package/lib/cli/__tests__/update.test.js +0 -696
  266. package/lib/cli/__tests__/version-check.test.js +0 -398
  267. package/lib/migrations/__tests__/index.test.js +0 -216
@@ -4,7 +4,7 @@ description: >-
4
4
  Aggregate per-Story or per-Epic execution signals into a structured
5
5
  perf-summary or perf-report and upsert it onto the corresponding GitHub
6
6
  ticket. Use after a Story closes (Story mode) or as part of
7
- `/epic-deliver` Phase 6 (Epic mode). Reads NDJSON via
7
+ `/deliver` Phase 6 (Epic mode). Reads NDJSON via
8
8
  `lib/signals/read` and writes a single structured comment.
9
9
  allowed_tools:
10
10
  - Read
@@ -36,7 +36,7 @@ into the Epic dashboard.
36
36
  pipeline dispatches this Skill (or the wrapping script) to roll up the
37
37
  Story's NDJSON signals into a single `<!-- structured:story-perf-summary -->`
38
38
  marker comment on the Story ticket.
39
- - **Epic mode** — during `/epic-deliver` Phase 6.0 (or the retro
39
+ - **Epic mode** — during `/deliver` Phase 6.0 (or the retro
40
40
  composer), the Skill fans out across every Story under the Epic,
41
41
  reads each Story's structured perf summary, and posts a single
42
42
  `<!-- structured:epic-perf-report -->` marker on the Epic ticket.
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  name: epic-plan-consolidate
3
3
  description: >-
4
- Run a holistic, pre-persist consolidation pass over the draft Feature/Story
4
+ Run a holistic, pre-persist consolidation pass over the draft Story
5
5
  ticket array an Epic's decompose phase produced. Use during Phase 8 of
6
- `/epic-plan`, after `epic-plan-decompose-author` writes
6
+ `/plan`, after `epic-plan-decompose-author` writes
7
7
  `temp/epic-<Epic_ID>/tickets.json` and before `epic-plan-decompose.js`
8
8
  validates and persists it. Reconciles the draft against the Tech Spec
9
9
  "Delivery Slicing" target via scope-preserving operations only.
@@ -19,13 +19,12 @@ allowed_tools:
19
19
 
20
20
  - Run only after `epic-plan-decompose-author` has written `temp/epic-<Epic_ID>/tickets.json`; fail loudly if the draft array is missing. Read the PRD / Tech Spec from `temp/epic-<Epic_ID>/decomposer-context.json` (the same envelope the author skill consumed) — never re-fetch from GitHub, and never call the GitHub API from this Skill.
21
21
  - Emit exactly two artifacts inside `temp/epic-<Epic_ID>/`: the **consolidated** `tickets.json` (overwriting the draft array in place) and a human-readable `consolidation-report.md` (the rationale + before/after diff the operator reviews at the HITL gate). Both MUST exist before returning.
22
- - **Scope conservation is the load-bearing invariant.** You are a *critic*, not a second author: you MUST NOT add scope, invent tickets, or drop acceptance criteria. Every acceptance item and every `verify` entry present in the draft MUST survive into the consolidated array (possibly re-homed onto a merged Story). **This is your contract, not a machine guarantee:** there is **no runtime acceptance-union diff** on your output. The only deterministic runtime backstop the validator applies after you run is `assertNoSingleStoryFeature` (Story #3777) plus the standard ticket-structure validation — neither re-derives the pre-consolidation acceptance/verify union, so a critic that silently dropped an acceptance item would **not** be caught downstream. (The repo's unit test exercises a *pure model* of the merge over an over-fragmented fixture to document the intended invariant; it does not inspect this Skill's actual output.) Conserve scope yourself, deliberately, on every merge.
23
- - Your operations are constrained to exactly four shapes: **(1) merge two or more Stories** into one (union their `changes`/`acceptance`/`verify`/`references`, keep one coherent `goal`); **(2) collapse a single-Story Feature** into a sibling Feature (re-parent its lone Story, drop the empty Feature) — **never** by manufacturing a second Story; **(3) re-parent** a Story to a different sibling Feature; **(4) rewire `depends_on`** so the edges still reference surviving sibling-Story slugs. No other mutation is permitted.
24
- - Consume the Tech Spec **"Delivery Slicing"** section as the authoritative target grouping when one is present: cluster the draft's Stories toward the N shippable Stories the Architect proposed. When the section is **absent**, degrade gracefully — apply only the cohesion + single-Story-Feature rules below and leave the rest of the draft shape intact.
25
- - Implement rec #2: resolve every single-Story Feature by **collapsing** it into a sibling (operation 2), not by splitting its lone Story into two. The `assertNoSingleStoryFeature` validator from Story #3777 stays as the post-consolidation backstop — your output must already satisfy it.
22
+ - **Scope conservation is the load-bearing invariant.** You are a *critic*, not a second author: you MUST NOT add scope, invent tickets, or drop acceptance criteria. Every acceptance item and every `verify` entry present in the draft MUST survive into the consolidated array (possibly re-homed onto a merged Story). **This is your contract, not a machine guarantee:** there is **no runtime acceptance-union diff** on your output. The only deterministic runtime backstop the validator applies after you run is the standard ticket-structure validation — it does not re-derive the pre-consolidation acceptance/verify union, so a critic that silently dropped an acceptance item would **not** be caught downstream. (The repo's unit test exercises a *pure model* of the merge over an over-fragmented fixture to document the intended invariant; it does not inspect this Skill's actual output.) Conserve scope yourself, deliberately, on every merge.
23
+ - Your operations are constrained to exactly two shapes: **(1) merge two or more Stories** into one (union their `changes`/`acceptance`/`verify`/`references`, keep one coherent `goal`); **(2) rewire `depends_on`** so the edges still reference surviving sibling-Story slugs. No other mutation is permitted.
24
+ - Consume the Tech Spec **"Delivery Slicing"** section as the authoritative target grouping when one is present: cluster the draft's Stories toward the N shippable Stories the Architect proposed. When the section is **absent**, degrade gracefully — apply only the cohesion rules below and leave the rest of the draft shape intact.
26
25
  - Apply the same cohesion heuristic the author skill leads with: **one Story = one coherent change with one reason to exist**, and the **single-consumer merge rule** (a Story whose only consumer is one sibling Story is merged into that sibling). Lead every merge decision with the change's reason, not its file count.
27
- - After every merge / collapse / re-parent, **rewire `depends_on`**: drop self-edges, collapse edges that now point at the absorbing Story onto itself, and re-point any edge that named a now-deleted slug at its surviving successor. Never leave a `depends_on` referencing a slug absent from the consolidated array — the validator HARD-rejects unknown deps.
28
- - The consolidation report MUST name each operation applied (merged slugs → surviving slug, collapsed Feature → sibling, re-parented Story, rewired edges) with a one-line reason, plus a before/after Story-count line, so the operator can approve or reject at the HITL diff gate before the persist call.
26
+ - After every merge, **rewire `depends_on`**: drop self-edges, collapse edges that now point at the absorbing Story onto itself, and re-point any edge that named a now-deleted slug at its surviving successor. Never leave a `depends_on` referencing a slug absent from the consolidated array — the validator HARD-rejects unknown deps.
27
+ - The consolidation report MUST name each operation applied (merged slugs → surviving slug, rewired edges) with a one-line reason, plus a before/after Story-count line, so the operator can approve or reject at the HITL diff gate before the persist call.
29
28
 
30
29
  ## Role
31
30
 
@@ -38,7 +37,7 @@ against the Tech Spec's intentional grouping before any GitHub write.
38
37
 
39
38
  ## When to use
40
39
 
41
- `/epic-plan` Phase 8, as the **8.3 — Holistic Consolidation** sub-step:
40
+ `/plan` Phase 8, as the **8.3 — Holistic Consolidation** sub-step:
42
41
  immediately after `epic-plan-decompose-author` writes
43
42
  `temp/epic-<Epic_ID>/tickets.json` and **before**
44
43
  `epic-plan-decompose.js --tickets …` validates and persists. The pass operates
@@ -51,7 +50,7 @@ emit a plan the validator would reject.
51
50
  The dispatcher passes the Epic ID as the Skill argument. The Skill itself
52
51
  reads:
53
52
 
54
- - `temp/epic-<Epic_ID>/tickets.json` — the **draft** Feature/Story array the
53
+ - `temp/epic-<Epic_ID>/tickets.json` — the **draft** Story array the
55
54
  `epic-plan-decompose-author` Skill wrote. This is the consolidation input.
56
55
  - `temp/epic-<Epic_ID>/decomposer-context.json` — the authoring envelope
57
56
  emitted by `epic-plan-decompose.js --emit-context`. Read `prd.body` /
@@ -62,7 +61,7 @@ reads:
62
61
  ## Outputs
63
62
 
64
63
  - `temp/epic-<Epic_ID>/tickets.json` — the **consolidated** array, overwriting
65
- the draft. Same schema as the author skill emits (Feature Story; Stories
64
+ the draft. Same schema as the author skill emits (flat Story array; Stories
66
65
  carry top-level `acceptance[]` / `verify[]`; `body` is a serialized string).
67
66
  The downstream `epic-plan-decompose.js --tickets …` validator is the final
68
67
  gate — author for its rules, not for "looks right."
@@ -83,21 +82,18 @@ anything:
83
82
 
84
83
  1. The **target grouping** — the N shippable Stories the Architect proposed in
85
84
  Delivery Slicing, or `null` when the section is absent (graceful-degrade
86
- mode: cohesion + single-Story-Feature rules only).
87
- 2. The **draft Story count per Feature** — so you can spot single-Story
88
- Features and over-fragmented capability clusters.
85
+ mode: cohesion rules only).
86
+ 2. The **draft Story count** — so you can spot over-fragmented capability
87
+ clusters.
89
88
 
90
89
  ### Step 2 — Plan the consolidation
91
90
 
92
- For each Feature, decide which Stories merge, which collapse, which re-parent:
91
+ Across the draft Story array, decide which Stories merge:
93
92
 
94
- - **Single-Story Feature** → collapse its lone Story into a sibling Feature
95
- whose capability is closest (Delivery-Slicing target, else thematic
96
- proximity). Drop the now-empty Feature. Never split the lone Story.
97
93
  - **Over-fragmented capability** → when several draft Stories map to one
98
94
  Delivery-Slicing target (or one coherent reason to exist), merge them into a
99
95
  single Story: union their `changes` / `acceptance` / `verify` / `references`,
100
- write one `goal` naming the parent Feature, and keep the union of labels.
96
+ write one coherent `goal`, and keep the union of labels.
101
97
  - **Single-consumer Story** → merge into the one sibling that consumes it.
102
98
 
103
99
  Record each decision with its one-line reason for the report.
@@ -120,7 +116,7 @@ Write the consolidated array to `temp/epic-<Epic_ID>/tickets.json` (2-space
120
116
  indent, machine-consumed) and the rationale + before/after diff to
121
117
  `temp/epic-<Epic_ID>/consolidation-report.md`.
122
118
 
123
- ### Step 5 — Hand back to `/epic-plan`
119
+ ### Step 5 — Hand back to `/plan`
124
120
 
125
121
  Return control. The workflow shows the operator the consolidation report at the
126
122
  HITL diff gate; on approval it runs
@@ -133,13 +129,12 @@ persists the hierarchy, and flips the Epic to `agent::ready`.
133
129
  - Do **not** call the GitHub API from this Skill. It reads two temp artifacts
134
130
  and writes two temp artifacts; persistence belongs to the script.
135
131
  - Do **not** write outside `temp/epic-<Epic_ID>/`.
136
- - Do **not** add scope or invent tickets. The four permitted operations (merge
137
- Stories, collapse single-Story Features, re-parent, rewire `depends_on`) are
138
- exhaustive — anything else is out of contract.
132
+ - Do **not** add scope or invent tickets. The two permitted operations (merge
133
+ Stories, rewire `depends_on`) are exhaustive — anything else is out of
134
+ contract.
139
135
  - If `temp/epic-<Epic_ID>/tickets.json` is missing, fail loudly and instruct
140
136
  the caller to run the `epic-plan-decompose-author` Skill first.
141
137
  - The validator
142
138
  ([`lib/orchestration/ticket-validator.js`](../../../scripts/lib/orchestration/ticket-validator.js))
143
- is the authoritative post-consolidation gate including
144
- `assertNoSingleStoryFeature`. Re-consolidate when it rejects rather than
145
- patching tickets by hand.
139
+ is the authoritative post-consolidation gate. Re-consolidate when it
140
+ rejects rather than patching tickets by hand.
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  name: epic-plan-decompose-author
3
3
  description: >-
4
- Author the Feature/Story ticket JSON for an Epic from the decomposer
4
+ Author the Story ticket JSON for an Epic from the decomposer
5
5
  authoring context emitted by `epic-plan-decompose.js --emit-context`. Use
6
- during Phase 8 of `/epic-plan` when the host LLM needs to write the ticket
6
+ during Phase 8 of `/plan` when the host LLM needs to write the ticket
7
7
  array before `epic-plan-decompose.js` validates and persists it.
8
8
  allowed_tools:
9
9
  - Read
@@ -18,10 +18,10 @@ allowed_tools:
18
18
  - Run only after `epic-plan-decompose.js --emit-context` has written `temp/epic-<Epic_ID>/decomposer-context.json`; fail loudly if the file is missing.
19
19
  - Emit exactly one artifact: `temp/epic-<Epic_ID>/tickets.json` (a JSON array). Do not write anywhere else, and never call the GitHub API from this Skill — persistence belongs to the script.
20
20
  - Output is JSON only — no prose, no Markdown fence. The downstream validator (`lib/orchestration/ticket-validator.js`) is the authoritative gate; re-author rather than hand-patching when it rejects.
21
- - Treat **`maxTickets`** from the context envelope as a **reviewability budget**, not a hard authoring cap (Story #2798). Merge narrow, single-module Stories into their capability first; if the plan genuinely needs more, emit the full plan and add a compact `over_budget_rationale` field at the top of the first Feature's `body` explaining why the plan exceeds the budget. Operator persistence then requires the explicit `--allow-over-budget` override on `epic-plan-decompose.js`; without it the persist step rejects the over-budget array. Never truncate the JSON array to fit.
22
- - Honour the two-level hierarchy under each Epic: **Feature Story**. Stories carry the implementation scope inline; no lower ticket tier exists.
23
- - **Decompose at deliverable granularity, not module/task level.** A Story is a capability slice a frontier model delivers and self-verifies in one pass — a shippable slice a reviewer would accept as a single PR — not a single module or file. Every Feature MUST decompose into at least TWO Stories; the validator HARD-rejects a single-Story Feature. See the STORY SIZING section for the full guidance and the single-consumer merge rule.
24
- - Every ticket carries `type::[feature|story]` and `persona::*` labels. Every Story ticket object MUST carry top-level `acceptance: string[]` and `verify: string[]` arrays (read by `hasInlineAcceptanceAndVerify` in the validator) and `body` MUST be a **string** produced by `serialize()` from `lib/story-body/story-body.js` — an object body causes `createOp` in `epic-spec-reconciler-ops.js` to throw `StoryBodyParseError` (Story #3302), and is also silently discarded by `composeStoryBody` in the GitHub provider, producing an empty issue body.
21
+ - Treat **`maxTickets`** from the context envelope as a **reviewability budget**, not a hard authoring cap (Story #2798). Merge narrow, single-module Stories into their capability first; if the plan genuinely needs more, emit the full plan and add a compact `over_budget_rationale` note inside the first Story's `## Goal` section explaining why the plan exceeds the budget. Operator persistence then requires the explicit `--allow-over-budget` override on `epic-plan-decompose.js`; without it the persist step rejects the over-budget array. Never truncate the JSON array to fit.
22
+ - Honour the 2-tier hierarchy: every ticket is a **Story** attached directly to the Epic. Stories carry the implementation scope inline; no Feature and no lower ticket tier exists. Thematic grouping is prose in the Epic body / Tech Spec, never a ticket.
23
+ - **Decompose at deliverable granularity, not module/task level.** A Story is a capability slice a frontier model delivers and self-verifies in one pass — a shippable slice a reviewer would accept as a single PR — not a single module or file. See the STORY SIZING section for the full guidance and the single-consumer merge rule.
24
+ - Every ticket carries `type::story` and `persona::*` labels. Every Story ticket object MUST carry top-level `acceptance: string[]` and `verify: string[]` arrays (read by `hasInlineAcceptanceAndVerify` in the validator) and `body` MUST be a **string** produced by `serialize()` from `lib/story-body/story-body.js` — an object body causes `createOp` in `epic-spec-reconciler-ops.js` to throw `StoryBodyParseError` (Story #3302), and is also silently discarded by `composeStoryBody` in the GitHub provider, producing an empty issue body.
25
25
  - **New-File Contract**: any path referenced in `goal`, `acceptance`, or `verify` that does not exist on `main` MUST appear in the Story's `changes[]` with `assumption: "creates"`; otherwise the freshness validator rejects the decompose.
26
26
  - Acceptance items MUST be **observable from outside the agent** (command exits 0, file exists, snapshot matches, testid resolves). Items like "verify by reading the diff" or "looks good" are forbidden — push them into `verify` commands instead.
27
27
  - Acceptance MUST NOT prescribe a commit subject starting with a non-Conventional-Commits prefix; the literal `baseline-refresh:` leading token is forbidden (use a body trailer instead — see Epic #2501).
@@ -31,12 +31,12 @@ allowed_tools:
31
31
  ## Role
32
32
 
33
33
  Senior Project Manager + Orchestrator. The Skill's job is to take a PRD plus
34
- a Tech Spec and emit a Feature Story ticket hierarchy the orchestrator
35
- can execute autonomously.
34
+ a Tech Spec and emit a flat Story backlog the orchestrator can execute
35
+ autonomously.
36
36
 
37
37
  ## When to use
38
38
 
39
- `/epic-plan` Phase 8, immediately after
39
+ `/plan` Phase 8, immediately after
40
40
  `epic-plan-decompose.js --emit-context` writes
41
41
  `temp/epic-<Epic_ID>/decomposer-context.json`. The Skill replaces the
42
42
  inline "Author the Ticket Array" step in the legacy workflow body —
@@ -74,7 +74,7 @@ Skill's body below is the authoritative version going forward.
74
74
 
75
75
  ## Outputs
76
76
 
77
- - `temp/epic-<Epic_ID>/tickets.json` — JSON array of Feature/Story
77
+ - `temp/epic-<Epic_ID>/tickets.json` — JSON array of Story
78
78
  objects conforming to the schema in this Skill's body.
79
79
 
80
80
  The file MUST exist before the Skill returns. The caller will then run
@@ -116,7 +116,7 @@ Write the final JSON array to `temp/epic-<Epic_ID>/tickets.json` with
116
116
  the `Write` tool. Do not pretty-print past 2-space indent — the file is
117
117
  machine-consumed.
118
118
 
119
- ### Step 4 — Hand back to `/epic-plan`
119
+ ### Step 4 — Hand back to `/plan`
120
120
 
121
121
  Return control. The caller invokes
122
122
  `node .agents/scripts/epic-plan-decompose.js --epic <Epic_ID> --tickets
@@ -132,17 +132,16 @@ budget (Story #2798) — stay under by default; over-budget plans need an
132
132
 
133
133
  ```text
134
134
  You are an expert Senior Project Manager and Orchestrator.
135
- Your job is to take a Product Requirements Document (PRD) and a Technical Specification and decompose them into a Feature Story ticket hierarchy for an AI Agent to execute.
135
+ Your job is to take a Product Requirements Document (PRD) and a Technical Specification and decompose them into a flat list of Story tickets for an AI Agent to execute.
136
136
 
137
137
  ### HIERARCHY RULES:
138
- 1. **Features**: Large functional milestones (e.g., "Authentication Provider Integration"). Features are navigational containers — no implementation work hangs off the Feature body itself.
139
- 2. **Stories**: Capability-sized, verifiable units of work (e.g., "Implement JWT Token Exchange").
140
- - MUST be nested under a Feature via `parent_slug`.
138
+ 1. **Stories**: Capability-sized, verifiable units of work (e.g., "Implement JWT Token Exchange").
139
+ - Attach directly to the Epic there is NO Feature tier; thematic grouping is prose in the Epic body / Tech Spec.
141
140
  - **Story-Level Execution**: Each Story is executed on a single Story branch (`story-<storyId>`), implemented in one Story-implementation phase, then merged into the Epic branch. The Story body carries the full execution contract (goal, changes, acceptance, verify).
142
- - Do NOT emit a lower ticket tier — the validator only accepts `type::feature` and `type::story`.
141
+ - Do NOT emit any other ticket tier — the validator only accepts `type::story`.
143
142
 
144
143
  ### LABEL CONVENTIONS:
145
- - Every ticket must have a `type::[feature|story]` label.
144
+ - Every ticket must have the `type::story` label.
146
145
  - Every ticket must have a `persona::[engineer|architect|qa-engineer|engineer-web|etc]` label indicating WHO should execute it.
147
146
 
148
147
  ### OUTPUT FORMAT:
@@ -152,48 +151,18 @@ You MUST respond ONLY with a valid JSON array of objects. No prose, no markdown
152
151
  [
153
152
  {
154
153
  "slug": "hyphen-case-id",
155
- "type": "feature" | "story",
154
+ "type": "story",
156
155
  "title": "Short descriptive title",
157
156
  "body": <string — see BODY RULES below>,
158
157
  "acceptance": ["<testable criterion>", ...], // STORIES ONLY — top-level, read by validator
159
158
  "verify": ["<exact command> (<tier>)", ...], // STORIES ONLY — top-level, read by validator
160
- "labels": ["type::...", "persona::..."],
161
- "parent_slug": "slug_of_parent_ticket" (leave empty for features to nest under epic; required for stories — must point at a sibling Feature),
159
+ "labels": ["type::story", "persona::..."],
162
160
  "depends_on": ["slug_of_blocking_dependency"] (optional array of Story slugs that block execution)
163
161
  }
164
162
  ]
165
163
 
166
164
  **Slug format**: `^[a-z0-9][a-z0-9-]*$` — hyphen-case only. Underscores are rejected by the validator.
167
165
 
168
- ### FEATURE BODY:
169
- For Features, `body` is a brief string under 2 sentences. Features are navigational — the work happens at the Story level — so dense bodies waste output budget.
170
-
171
- FEATURE GROUPING — CAPABILITY/STAKEHOLDER, NOT EXECUTION SHAPE:
172
-
173
- - Do not group Stories by technical execution shape (cron jobs, middleware, scripts). Group by the capability or stakeholder they serve. Two Stories that happen to share a delivery mechanism — both are cron sweeps, both are Express middleware, both are CLI scripts — do NOT belong in the same Feature just because of that shared shape. The Feature axis is the user-facing capability or the stakeholder served, never the implementation vehicle.
174
- - Operational/compliance work gets its own Feature. Retention purges, audit-log sweeps, scheduled cleanups, observability emitters, and other operational/compliance chores serve operators and compliance, not end users. Place them in a dedicated `compliance-and-observability` or `data-retention` Feature — do NOT fold them into a user-facing Feature (e.g. notification flows) merely because they share a cron/scheduled execution shape with user-facing Stories.
175
-
176
- ANTI-PATTERN (based on Epic #18 -> Feature #1446):
177
-
178
- A decomposition produced a Feature "Notification flows: reminders, schedule-change, retention" grouping three Stories. WRONG — grouped by execution shape (all three are cron sweeps):
179
-
180
- Feature: notification-flows ("Notification flows: reminders, schedule-change, retention")
181
- [X] Story: send-appointment-reminders (user-facing: emails patients)
182
- [X] Story: send-schedule-change-notices (user-facing: emails patients)
183
- [X] Story: purge-email-audit-log-retention (compliance: deletes audit rows past retention)
184
-
185
- The email audit-log retention purge was folded in only because all three run as scheduled cron jobs — a shared execution shape, not a shared capability. The purge serves compliance/operators, not the patients the other two Stories notify. CORRECT — regroup by capability/stakeholder:
186
-
187
- Feature: notification-flows ("Patient notification flows")
188
- Story: send-appointment-reminders (user-facing)
189
- Story: send-schedule-change-notices (user-facing)
190
- Feature: compliance-and-observability ("Data-retention and audit-log compliance")
191
- Story: purge-email-audit-log-retention (compliance)
192
-
193
- The cron shape is the false grouping signal. Once the retention purge has a sibling under a dedicated compliance Feature it ceases to be a lone-Story Feature (which the validator would reject); pair it with other operational/compliance sweeps (e.g. a session-token cleanup or a metrics-rollup job) under the same `compliance-and-observability` Feature.
194
-
195
- - Smell test: if the only thing two Stories have in common is how they run (a scheduled job, a request interceptor, a build step) rather than whom they serve or what capability they deliver, they are mis-grouped. Re-home the operational/compliance Story into its own capability Feature.
196
-
197
166
  ### STORY BODY SCHEMA (REQUIRED FOR EVERY STORY):
198
167
  For Stories, `body` MUST be a **string** — the serialized markdown produced by calling `serialize()` from `lib/story-body/story-body.js`. Do NOT emit `body` as a JSON object: `createOp` in `epic-spec-reconciler-ops.js` will throw `StoryBodyParseError` when it receives an object body (Story #3302 serialize-or-throw contract), and `composeStoryBody` in the GitHub provider also discards non-string bodies producing an empty issue. The canonical pipeline requires a serialized string body end-to-end. The freshness gate (`collectTaskChangesPaths`) and the assumption gate (`collectStoryAssumptionEntries`) both parse the string body via `story-body.js#parse` to recover `changes[]`/`references[]` — they operate correctly only on the serialized string form.
199
168
 
@@ -202,7 +171,7 @@ The `acceptance[]` and `verify[]` arrays live at the **top level** of the Story
202
171
  The serialized `body` string renders these markdown sections (in order):
203
172
 
204
173
  ## Goal
205
- <one sentence — why this Story exists; tie it to the parent Feature slug>
174
+ <one sentence — why this Story exists within the Epic>
206
175
 
207
176
  ## Changes
208
177
  - {"path": "<file path>", "assumption": "creates" | "refactors-existing" | "deletes"}
@@ -225,7 +194,7 @@ Fields `wide` and `estimated_test_files` are encoded as a `<!-- meta: {...} -->`
225
194
  #### STORY BODY RULES:
226
195
 
227
196
  - **slug**: MUST be hyphen-case (`^[a-z0-9][a-z0-9-]*$`). Do not use underscores.
228
- - **goal** (in body string): One sentence stating WHY this Story exists. SHOULD name the parent Feature slug.
197
+ - **goal** (in body string): One sentence stating WHY this Story exists within the Epic.
229
198
  - **changes** (in body string): Each entry is an object `{ path, assumption }` where `assumption` is one of `creates | refactors-existing | deletes`. The Phase 8 validator probes the base branch for every declared path and rejects the decompose when the declared assumption contradicts reality: `creates` against an existing path is an error, `refactors-existing` / `deletes` against a missing path is an error. Use `refactors-existing` for in-place edits to a file already on `main`; `creates` for net-new files; `deletes` for removals. Acceptable path shapes include explicit files (`src/components/Foo.tsx`), glob patterns (`tests/e2e/*.spec.ts`, `**/*.astro`), and module identifiers that resolve to files.
230
199
  - **references** (in body string, optional): Object-form entries `{ path, assumption: "exists" }` for paths the Story **reads** but does not modify (test fixtures it relies on, sibling modules it imports, feature files it scans). The validator probes these like `changes` and rejects the decompose when an `exists` path is absent on the base branch. Use this list to make read-dependencies explicit so a hallucinated or stale assumption surfaces at planning time rather than execution time.
231
200
  - **NEW-FILE CONTRACT (must-follow)**: Any path the Story references in `goal`, `acceptance`, or `verify` that does **not** already exist on `main` MUST also appear in the same Story's `changes` array with `assumption: "creates"`. The freshness validator probes `main` for every referenced code path and rejects the decompose when a missing path is absent from `changes` — even when the Story is the one authoring the file. Example: a Story creating `tests/lib/foo.test.js` whose `verify` runs `node --test tests/lib/foo.test.js` MUST include `{ "path": "tests/lib/foo.test.js", "assumption": "creates" }` in `changes`, otherwise the validator emits a freshness miss and the decompose round trips for a re-emit.
@@ -245,9 +214,8 @@ The first question is **cohesion, not count**: *is this one coherent change with
245
214
 
246
215
  - **One Story = one coherent change with one reason to exist.** If you cannot state that reason in a sentence, the Story is probably two Stories.
247
216
  - **Single-consumer merge rule.** A Story whose only consumer is one sibling Story should be **merged into that sibling** rather than emitted separately — a single-consumer downstream slice is not its own unit of work.
248
- - **Split independent, parallelizable work** into sibling Stories under the same Feature — but only when the pieces genuinely have separate reasons to exist.
217
+ - **Split independent, parallelizable work** into sibling Stories — but only when the pieces genuinely have separate reasons to exist.
249
218
  - **Declare `wide` with a one-line reason when a change is legitimately broad** (a cohesive cutover that spans many files for one reason).
250
- - **Every Feature MUST decompose into at least TWO Stories.** A Feature with a single Story is the work of a Story, not a Feature. **Resolve it by COLLAPSING, not splitting** — drop the Feature wrapper and attach its lone Story to a sibling Feature (or merge the Feature into another). Do NOT manufacture a second Story to satisfy the rule; splitting a lone Story into two inflates ticket count and defeats the "fewer, right-sized Stories" goal. The validator (`ticket-validator.js` → `assertNoSingleStoryFeature`) HARD-rejects a decomposition containing a Feature with fewer than two Stories, naming the offending Feature; the Phase 8 consolidation pass (`epic-plan-consolidate`) performs the collapse holistically before the validator runs.
251
219
 
252
220
  **Numeric backstop.** The thresholds are defined **once**, in the `DEFAULT_TASK_SIZING` constant in `ticket-validator-sizing.js` (operator-overridable via `agentSettings.planning.taskSizing`). They are a backstop, not the primary rule — do not restate divergent numbers anywhere else. The defaults:
253
221
 
@@ -291,7 +259,7 @@ The Acceptance Spec's AC table (columns `AC ID | Outcome | Feature File | Scenar
291
259
 
292
260
  When the Acceptance Spec contains **one or more `Disposition: new` rows**, you MUST emit **exactly one** dedicated wave-0 scaffold Story whose sole job is to create those `.feature` files with `@skip`-tagged scenarios BEFORE any implementation Story runs:
293
261
 
294
- - **goal** (in body string): contains the literal token `bdd-scaffold` and names the parent Feature slug.
262
+ - **goal** (in body string): contains the literal token `bdd-scaffold`.
295
263
  - **depends_on**: EMPTY (`[]`) — the scaffold runs first, in wave 0.
296
264
  - **changes** (in body string): one `{ path, assumption: "creates" }` entry per distinct `.feature` file named in a `new` row.
297
265
  - **acceptance** (top-level array): MUST assert (a) every new `.feature` file exists, and (b) every new scenario within them carries an `@skip` tag. Keep items observable (a command exits 0; a file exists at a path).
@@ -306,7 +274,6 @@ When the Acceptance Spec contains **zero `new`-disposition rows** (every row is
306
274
  "slug": "scaffold-billing-feature-files",
307
275
  "type": "story",
308
276
  "title": "Scaffold @skip-tagged billing feature files",
309
- "parent_slug": "billing-flows",
310
277
  "depends_on": [],
311
278
  "labels": ["type::story", "persona::qa-engineer"],
312
279
  "acceptance": [
@@ -398,7 +365,7 @@ Do NOT silently allow two Stories to write the same root configuration
398
365
  file in the same wave; parallel dispatch would produce a merge conflict
399
366
  on every Story-to-Epic close after the first.
400
367
 
401
- CRITICAL: Dependencies should follow execution blockers. For hierarchical grouping, strongly strictly use 'parent_slug' (Story parent MUST be a Feature). Features should have no 'parent_slug' (they attach to Epic).
368
+ CRITICAL: Dependencies should follow execution blockers. Stories attach directly to the Epic never emit a 'parent_slug' field.
402
369
  IMPORTANT DEPENDENCY RULE: A Story's `depends_on` MUST only reference other Stories within the SAME Epic. If two Stories have a logical ordering requirement, express it via Story-level `depends_on`.
403
370
  WARNING: You MUST conserve your output limit. Do NOT generate more than ${maxTickets} tickets in total. Merge narrow work into cohesive capability Stories. Do NOT cut off the JSON array prematurely!
404
371
 
@@ -3,7 +3,7 @@ name: epic-plan-spec-author
3
3
  description: >-
4
4
  Author the PRD, Tech Spec, Acceptance Spec markdown, and risk-verdict JSON
5
5
  for an Epic from the planner authoring context emitted by
6
- `epic-plan-spec.js --emit-context`. Use during Phase 7 of `/epic-plan` when
6
+ `epic-plan-spec.js --emit-context`. Use during Phase 7 of `/plan` when
7
7
  the host LLM needs to write the four artifacts before `epic-plan-spec.js`
8
8
  persists them.
9
9
  allowed_tools:
@@ -16,7 +16,7 @@ allowed_tools:
16
16
 
17
17
  ## Policy Capsule
18
18
 
19
- - Run only during `/epic-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.
19
+ - 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
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
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
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.
@@ -40,7 +40,7 @@ the Acceptance Spec).
40
40
 
41
41
  ## When to use
42
42
 
43
- `/epic-plan` Phase 7, immediately after `epic-plan-spec.js --emit-context`
43
+ `/plan` Phase 7, immediately after `epic-plan-spec.js --emit-context`
44
44
  writes `temp/epic-<Epic_ID>/planner-context.json`. This Skill replaces the
45
45
  inline "Author the PRD" / "Author the Tech Spec" steps from the legacy
46
46
  workflow body — the calling workflow dispatches this Skill via the `Skill`
@@ -366,7 +366,7 @@ CRITICAL REQUIREMENTS:
366
366
  - 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.
367
367
  ```
368
368
 
369
- ### Step 6 — Hand back to `/epic-plan`
369
+ ### Step 6 — Hand back to `/plan`
370
370
 
371
371
  All four files exist; return. The caller will run
372
372
  `node .agents/scripts/epic-plan-spec.js --epic <Epic_ID> --prd
@@ -25,8 +25,8 @@ allowed_tools:
25
25
 
26
26
  ## Role
27
27
 
28
- Context aggregator. Resolves a ticket's hierarchy (TaskStory →
29
- Feature → Epic) and stitches the linked planning artifacts into a
28
+ Context aggregator. Resolves a ticket's hierarchy (StoryEpic)
29
+ and stitches the linked planning artifacts into a
30
30
  single prompt the executor consumes.
31
31
 
32
32
  ## When to use
@@ -13,7 +13,7 @@ description:
13
13
  - Phase 1 MUST restate the idea as a "How Might We" statement, ask 3–5 sharpening questions via `AskUserQuestion`, and generate 5–8 variations (not 20+ shallow ones); do not proceed until target user and success criteria are explicit.
14
14
  - Phase 2 grill loop poses **one** question at a time, each with a recommended answer + one-line rationale grounded in user input / codebase / first principles; never batch questions and never omit the recommendation.
15
15
  - Re-enumerate open branches after every grill answer; stop only when no unresolved decisions remain. Take the off-ramp directly to Phase 3 when the idea is already crisply scoped.
16
- - Phase 3 emits a markdown one-pager with the canonical five Epic headings exactly: `## Context`, `## Goal`, `## Non-Goals`, `## Scope`, `## Acceptance Criteria` (plus optional `## Open Questions`). No alternate heading text — the `/epic-plan` clarity gate depends on this verbatim.
16
+ - Phase 3 emits a markdown one-pager with the canonical five Epic headings exactly: `## Context`, `## Goal`, `## Non-Goals`, `## Scope`, `## Acceptance Criteria` (plus optional `## Open Questions`). No alternate heading text — the `/plan` clarity gate depends on this verbatim.
17
17
  - Surface every key assumption inside `## Context` (or `## Scope`); assumptions do not get their own heading. Unresolved decisions MUST NOT carry into the one-pager.
18
18
  - The `## Non-Goals` list is mandatory and each entry includes a reason — focus is created by explicit exclusion.
19
19
  - Be honest, not supportive: push back on weak ideas with kindness; never function as a yes-machine.
@@ -35,7 +35,7 @@ structured divergent and convergent thinking.
35
35
 
36
36
  ## Activation
37
37
 
38
- Called from `/epic-plan` Phase 1 (ideation entry, when no `<epic#>` is
38
+ Called from `/plan` Phase 1 (ideation entry, when no `<epic#>` is
39
39
  supplied or `--idea "<seed>"` is passed) and Phase 6 (Epic Clarity Gate,
40
40
  when an existing Epic body fails the section-presence rubric). In Phase 6
41
41
  the skill is seeded from the **current Epic body** — not a blank seed —
@@ -73,7 +73,7 @@ The final output is a markdown one-pager saved to `docs/ideas/[idea-name].md`
73
73
 
74
74
  Assumptions and open questions are recorded in the body of the relevant
75
75
  section (typically under Context or Scope) rather than carved into their
76
- own headings — the canonical five drive the `/epic-plan` clarity gate.
76
+ own headings — the canonical five drive the `/plan` clarity gate.
77
77
 
78
78
  ## Detailed Instructions
79
79
 
@@ -213,7 +213,7 @@ it inside the grill loop, not after the one-pager is already written.
213
213
 
214
214
  Produce a concrete artifact — a markdown one-pager that moves work forward.
215
215
  The five canonical headings below match `.agents/templates/epic-from-idea.md`
216
- and the `/epic-plan` clarity gate; emit them verbatim so the renderer can
216
+ and the `/plan` clarity gate; emit them verbatim so the renderer can
217
217
  substitute the body into a new Epic without translation.
218
218
 
219
219
  ```markdown
@@ -152,9 +152,9 @@ This skill is the engine behind two operator-facing entry points:
152
152
 
153
153
  - [`/explain`](../../../workflows/explain.md) — runs the loop over a realized
154
154
  change (a PR, branch, or diff).
155
- - [`/epic-plan`](../../../workflows/epic-plan.md) **Phase 11 — Plan
155
+ - [`/plan`](../../../workflows/helpers/plan-epic.md) **Phase 11 — Plan
156
156
  Comprehension Gate** — runs the loop over a freshly planned backlog before
157
- the operator hands off to `/epic-deliver`. That phase decides *whether* to
157
+ the operator hands off to `/deliver`. That phase decides *whether* to
158
158
  run via an LM-judgment predicate; this skill owns *how* it runs once
159
159
  invoked.
160
160
 
@@ -13,7 +13,7 @@ description:
13
13
  > teaches how to slice and order work into verifiable units, independent
14
14
  > of any particular ticket hierarchy. The word "task" below refers to a
15
15
  > generic unit of work, not specifically to a Mandrel ticket. Under
16
- > Mandrel's 3-tier hierarchy (Epic → Feature → Story), these units map
16
+ > Mandrel's 2-tier hierarchy (Epic → Story), these units map
17
17
  > onto acceptance/verification bullets inlined on the Story body, or
18
18
  > onto sequential sibling Stories. The principles — vertical slicing,
19
19
  > dependency ordering, sizing caps, explicit acceptance and
@@ -4,7 +4,7 @@ description:
4
4
  Judge whether a piece of planned work is epic-sized or story-sized before the
5
5
  planning ceremony is paid for. Emits one of three verdicts —
6
6
  `epic` | `story` | `borderline` — over any planning artifact (a one-pager, an
7
- Epic body, or a Story draft). Use from `/epic-plan` Phase 1.5 and any other
7
+ Epic body, or a Story draft). Use from `/plan` Phase 1.5 and any other
8
8
  planning gate that needs the canonical story-vs-epic rubric.
9
9
  ---
10
10
 
@@ -32,9 +32,8 @@ description:
32
32
  wrong in the `epic` direction is cheap — the Phase 8.3 consolidation pass and
33
33
  the sizing validator catch an over-planned Story later. Being wrong in the
34
34
  `story` direction is expensive — a story-sized scope pushed through the full
35
- Epic ceremony pays a PRD + Tech Spec + Acceptance Spec + Feature/Story tree +
36
- `epic/<id>` integration-branch tax for a degenerate one-Feature-one-Story
37
- output.
35
+ Epic ceremony pays a PRD + Tech Spec + Acceptance Spec + Story backlog +
36
+ `epic/<id>` integration-branch tax for a degenerate one-Story output.
38
37
  - Keep the rubric prose **artifact-agnostic**. The thing under judgment may be a
39
38
  sharpened one-pager, an existing Epic body, or a draft Story — the rubric
40
39
  reads the same against all three so every consumer reuses it verbatim.
@@ -62,7 +61,7 @@ The work is a single shippable capability. Signals:
62
61
  architectural decision and matches none of the `planning.riskHeuristics` in
63
62
  `.agentrc.json` (destructive/irreversible changes, shared auth/security,
64
63
  CI/CD gate changes, monorepo-wide rewrites, destructive migrations).
65
- - **Decomposition would degenerate.** Running it through `/epic-plan` would
64
+ - **Decomposition would degenerate.** Running it through `/plan` would
66
65
  plausibly yield exactly **one Feature with one Story** — the shape the Phase
67
66
  8.3 consolidation skill flags only after all the spec authoring is already
68
67
  sunk cost.
@@ -90,18 +89,18 @@ option; a borderline scope surfaced as borderline is the correct output.
90
89
  A workflow entered via a scope-triage **handoff** MUST NOT re-triage. A handoff
91
90
  *is* a triage decision already made — re-running this gate on the receiving side
92
91
  would re-litigate a settled call and risk a ping-pong between two planning
93
- workflows. Handoff invocations identify themselves as such (e.g. `/epic-plan`
94
- entered via a `/story-plan` scope-triage escalation, or `/story-plan` entered
95
- via an `/epic-plan` Phase 1.5 handoff), and the receiving workflow skips its own
92
+ workflows. Handoff invocations identify themselves as such (e.g. `/plan`
93
+ entered via a `/plan` scope-triage escalation, or `/plan` entered
94
+ via an `/plan` Phase 1.5 handoff), and the receiving workflow skips its own
96
95
  scope-triage gate when it detects the handoff marker.
97
96
 
98
97
  ## When to use
99
98
 
100
- - **`/epic-plan` Phase 1.5** (ideation path only) — judge the sharpened
99
+ - **`/plan` Phase 1.5** (ideation path only) — judge the sharpened
101
100
  one-pager Phase 1 produced before the Epic ceremony is paid for. The verdict
102
101
  folds into the existing Phase 1 HITL stop; on a `story` / `borderline`
103
102
  verdict the operator may hand off to
104
- [`/story-plan --from-notes`](../../../workflows/story-plan.md).
103
+ [`/plan --from-notes`](../../../workflows/helpers/plan-story.md).
105
104
  - Any other planning gate that needs the canonical story-vs-epic rubric. Keep
106
105
  the rubric here as the SSOT; consumers reference this file rather than
107
106
  forking the prose.
@@ -101,7 +101,7 @@ In that context:
101
101
  2. If you genuinely cannot proceed, transition to `agent::blocked`, post a
102
102
  `friction` structured comment naming the decision required and the
103
103
  default assumption you would have made, and exit non-zero. The parent
104
- `/epic-deliver` aggregator will surface the block.
104
+ `/deliver` aggregator will surface the block.
105
105
  3. **Never** stall waiting for input that will never arrive.
106
106
 
107
107
  This is the only documented exception to the "Manage Confusion Actively"
@@ -1,5 +1,5 @@
1
1
  {
2
- "generatedAt": "2026-06-10T15:27:53.874Z",
2
+ "generatedAt": "2026-06-11T19:47:29.752Z",
3
3
  "generator": "generate-skills-index.js@1",
4
4
  "skills": [
5
5
  {
@@ -7,7 +7,7 @@
7
7
  "tier": "core",
8
8
  "category": "core",
9
9
  "path": ".agents/skills/core/analyze-execution/SKILL.md",
10
- "description": "Aggregate per-Story or per-Epic execution signals into a structured perf-summary or perf-report and upsert it onto the corresponding GitHub ticket. Use after a Story closes (Story mode) or as part of `/epic-deliver` Phase 6 (Epic mode). Reads NDJSON via `lib/signals/read` and writes a single structured comment.",
10
+ "description": "Aggregate per-Story or per-Epic execution signals into a structured perf-summary or perf-report and upsert it onto the corresponding GitHub ticket. Use after a Story closes (Story mode) or as part of `/deliver` Phase 6 (Epic mode). Reads NDJSON via `lib/signals/read` and writes a single structured comment.",
11
11
  "policyCapsuleBullets": 8,
12
12
  "allowedTools": ["Read", "Bash"],
13
13
  "vendor": null
@@ -127,8 +127,8 @@
127
127
  "tier": "core",
128
128
  "category": "core",
129
129
  "path": ".agents/skills/core/epic-plan-consolidate/SKILL.md",
130
- "description": "Run a holistic, pre-persist consolidation pass over the draft Feature/Story ticket array an Epic's decompose phase produced. Use during Phase 8 of `/epic-plan`, after `epic-plan-decompose-author` writes `temp/epic-<Epic_ID>/tickets.json` and before `epic-plan-decompose.js` validates and persists it. Reconciles the draft against the Tech Spec \"Delivery Slicing\" target via scope-preserving operations only.",
131
- "policyCapsuleBullets": 9,
130
+ "description": "Run a holistic, pre-persist consolidation pass over the draft Story ticket array an Epic's decompose phase produced. Use during Phase 8 of `/plan`, after `epic-plan-decompose-author` writes `temp/epic-<Epic_ID>/tickets.json` and before `epic-plan-decompose.js` validates and persists it. Reconciles the draft against the Tech Spec \"Delivery Slicing\" target via scope-preserving operations only.",
131
+ "policyCapsuleBullets": 8,
132
132
  "allowedTools": ["Read", "Write", "Bash"],
133
133
  "vendor": null
134
134
  },
@@ -137,7 +137,7 @@
137
137
  "tier": "core",
138
138
  "category": "core",
139
139
  "path": ".agents/skills/core/epic-plan-decompose-author/SKILL.md",
140
- "description": "Author the Feature/Story ticket JSON for an Epic from the decomposer authoring context emitted by `epic-plan-decompose.js --emit-context`. Use during Phase 8 of `/epic-plan` when the host LLM needs to write the ticket array before `epic-plan-decompose.js` validates and persists it.",
140
+ "description": "Author the Story ticket JSON for an Epic from the decomposer authoring context emitted by `epic-plan-decompose.js --emit-context`. Use during Phase 8 of `/plan` when the host LLM needs to write the ticket array before `epic-plan-decompose.js` validates and persists it.",
141
141
  "policyCapsuleBullets": 12,
142
142
  "allowedTools": ["Read", "Write", "Bash"],
143
143
  "vendor": null
@@ -147,7 +147,7 @@
147
147
  "tier": "core",
148
148
  "category": "core",
149
149
  "path": ".agents/skills/core/epic-plan-spec-author/SKILL.md",
150
- "description": "Author the PRD, Tech Spec, Acceptance Spec markdown, and risk-verdict JSON for an Epic from the planner authoring context emitted by `epic-plan-spec.js --emit-context`. Use during Phase 7 of `/epic-plan` when the host LLM needs to write the four artifacts before `epic-plan-spec.js` persists them.",
150
+ "description": "Author the PRD, Tech Spec, Acceptance Spec markdown, and risk-verdict JSON for an Epic from the planner authoring context emitted by `epic-plan-spec.js --emit-context`. Use during Phase 7 of `/plan` when the host LLM needs to write the four artifacts before `epic-plan-spec.js` persists them.",
151
151
  "policyCapsuleBullets": 12,
152
152
  "allowedTools": ["Read", "Write", "Bash"],
153
153
  "vendor": null
@@ -287,7 +287,7 @@
287
287
  "tier": "core",
288
288
  "category": "core",
289
289
  "path": ".agents/skills/core/scope-triage/SKILL.md",
290
- "description": "Judge whether a piece of planned work is epic-sized or story-sized before the planning ceremony is paid for. Emits one of three verdicts — `epic` | `story` | `borderline` — over any planning artifact (a one-pager, an Epic body, or a Story draft). Use from `/epic-plan` Phase 1.5 and any other planning gate that needs the canonical story-vs-epic rubric.",
290
+ "description": "Judge whether a piece of planned work is epic-sized or story-sized before the planning ceremony is paid for. Emits one of three verdicts — `epic` | `story` | `borderline` — over any planning artifact (a one-pager, an Epic body, or a Story draft). Use from `/plan` Phase 1.5 and any other planning gate that needs the canonical story-vs-epic rubric.",
291
291
  "policyCapsuleBullets": 1,
292
292
  "allowedTools": null,
293
293
  "vendor": null
@@ -5,8 +5,8 @@ Version: {{PROTOCOL_VERSION}}
5
5
  You are an AI coding assistant. This protocol governs your execution of the
6
6
  current work unit. You must follow these rules strictly.
7
7
 
8
- > **Hierarchy shape.** Mandrel uses a **3-tier hierarchy**
9
- > (Epic → Feature → Story). The work unit is the `type::story` issue
8
+ > **Hierarchy shape.** Mandrel uses a **2-tier hierarchy**
9
+ > (Epic → Story). The work unit is the `type::story` issue
10
10
  > itself, with acceptance criteria and verification inlined on the
11
11
  > Story body. There is no per-Task sub-loop; the agent authors commit
12
12
  > subjects directly per `.agents/rules/git-conventions.md` and