mandrel 1.58.0 → 1.60.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 (319) hide show
  1. package/.agents/README.md +100 -98
  2. package/.agents/docs/SDLC.md +140 -141
  3. package/.agents/docs/configuration.md +16 -16
  4. package/.agents/docs/workflows.md +7 -8
  5. package/.agents/instructions.md +12 -11
  6. package/.agents/personas/architect.md +1 -1
  7. package/.agents/personas/product.md +1 -1
  8. package/.agents/personas/project-manager.md +14 -14
  9. package/.agents/personas/technical-writer.md +1 -1
  10. package/.agents/rules/changelog-style.md +5 -5
  11. package/.agents/rules/git-conventions.md +3 -3
  12. package/.agents/schemas/agentrc.schema.json +3 -3
  13. package/.agents/schemas/audit-rules.json +20 -0
  14. package/.agents/schemas/dispatch-manifest.json +4 -4
  15. package/.agents/schemas/epic-spec.schema.json +15 -45
  16. package/.agents/schemas/lifecycle/README.md +1 -1
  17. package/.agents/schemas/lifecycle/story.dispatch.end.schema.json +1 -1
  18. package/.agents/schemas/lifecycle/story.dispatch.start.schema.json +1 -1
  19. package/.agents/schemas/lifecycle/story.heartbeat.schema.json +1 -1
  20. package/.agents/schemas/validation-evidence.schema.json +1 -1
  21. package/.agents/scripts/README.md +1 -1
  22. package/.agents/scripts/acceptance-eval.js +21 -4
  23. package/.agents/scripts/acceptance-spec-reconciler.js +2 -2
  24. package/.agents/scripts/analyze-execution.js +2 -2
  25. package/.agents/scripts/assert-branch.js +1 -3
  26. package/.agents/scripts/audit-to-stories.js +1 -1
  27. package/.agents/scripts/bootstrap.js +1 -1
  28. package/.agents/scripts/check-arch-cycles.js +360 -0
  29. package/.agents/scripts/check-doc-links.js +2 -3
  30. package/.agents/scripts/coverage-capture.js +24 -3
  31. package/.agents/scripts/diagnose-friction.js +1 -1
  32. package/.agents/scripts/dispatcher.js +2 -2
  33. package/.agents/scripts/drain-pending-cleanup.js +1 -1
  34. package/.agents/scripts/epic-audit-prepare.js +3 -3
  35. package/.agents/scripts/epic-deliver-note-intervention.js +2 -2
  36. package/.agents/scripts/epic-deliver-preflight.js +11 -9
  37. package/.agents/scripts/epic-deliver-prepare.js +13 -5
  38. package/.agents/scripts/epic-execute-record-wave.js +5 -5
  39. package/.agents/scripts/epic-plan-healthcheck.js +6 -10
  40. package/.agents/scripts/epic-plan-spec-validate.js +1 -1
  41. package/.agents/scripts/epic-reconcile.js +11 -29
  42. package/.agents/scripts/evidence-gate.js +2 -2
  43. package/.agents/scripts/generate-workflows-doc.js +1 -1
  44. package/.agents/scripts/git-rebase-and-resolve.js +1 -1
  45. package/.agents/scripts/hierarchy-gate.js +40 -24
  46. package/.agents/scripts/lib/ITicketingProvider.js +1 -1
  47. package/.agents/scripts/lib/audit-suite/selector.js +1 -1
  48. package/.agents/scripts/lib/audit-to-stories/seed-epic-from-findings.js +2 -2
  49. package/.agents/scripts/lib/baseline-snapshot.js +7 -7
  50. package/.agents/scripts/lib/baselines/kinds/coverage.js +33 -149
  51. package/.agents/scripts/lib/baselines/kinds/duplication.js +27 -116
  52. package/.agents/scripts/lib/baselines/kinds/kind-factory.js +192 -0
  53. package/.agents/scripts/lib/baselines/kinds/lighthouse.js +34 -133
  54. package/.agents/scripts/lib/baselines/kinds/maintainability.js +31 -124
  55. package/.agents/scripts/lib/baselines/kinds/mutation.js +25 -111
  56. package/.agents/scripts/lib/baselines/maintainability-baseline-io.js +59 -0
  57. package/.agents/scripts/lib/baselines/maintainability-baseline-save.js +37 -0
  58. package/.agents/scripts/lib/baselines/writer.js +1 -1
  59. package/.agents/scripts/lib/bdd-runner-detect.js +1 -1
  60. package/.agents/scripts/lib/bdd-scenario-scanner.js +3 -3
  61. package/.agents/scripts/lib/bootstrap/baselines-layout-migration.js +1 -1
  62. package/.agents/scripts/lib/bootstrap/branch-protection.js +1 -1
  63. package/.agents/scripts/lib/bootstrap/ci-workflow-template.js +1 -1
  64. package/.agents/scripts/lib/bootstrap/commit-push.js +2 -2
  65. package/.agents/scripts/lib/close-validation/commands.js +188 -0
  66. package/.agents/scripts/lib/close-validation/gates.js +235 -0
  67. package/.agents/scripts/lib/close-validation/process.js +101 -0
  68. package/.agents/scripts/lib/close-validation/projections/maintainability.js +1 -1
  69. package/.agents/scripts/lib/close-validation/runner.js +325 -0
  70. package/.agents/scripts/lib/close-validation/telemetry.js +70 -0
  71. package/.agents/scripts/lib/codebase-snapshot.js +1 -1
  72. package/.agents/scripts/lib/config/explain.js +1 -1
  73. package/.agents/scripts/lib/config/quality.js +6 -6
  74. package/.agents/scripts/lib/config/runners.js +2 -2
  75. package/.agents/scripts/lib/config/runtime.js +1 -1
  76. package/.agents/scripts/lib/config/temp-paths.js +2 -2
  77. package/.agents/scripts/lib/config-resolver.js +2 -5
  78. package/.agents/scripts/lib/config-settings-schema-delivery.js +2 -2
  79. package/.agents/scripts/lib/config-settings-schema-quality.js +1 -1
  80. package/.agents/scripts/lib/config-settings-schema.js +3 -3
  81. package/.agents/scripts/lib/coverage-capture.js +147 -4
  82. package/.agents/scripts/lib/cpu-pool.js +14 -0
  83. package/.agents/scripts/lib/crap-utils.js +6 -11
  84. package/.agents/scripts/lib/duplicate-search.js +1 -1
  85. package/.agents/scripts/lib/dynamic-workflow/capability.js +1 -1
  86. package/.agents/scripts/lib/dynamic-workflow/documentation-report-contract.js +87 -0
  87. package/.agents/scripts/lib/epic-plan-clarity.js +1 -1
  88. package/.agents/scripts/lib/epic-plan-ideation.js +1 -1
  89. package/.agents/scripts/lib/feedback-loop/memory-freshness.js +1 -1
  90. package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +1 -1
  91. package/.agents/scripts/lib/findings/classify-finding.js +1 -1
  92. package/.agents/scripts/lib/findings/promote-finding.js +10 -10
  93. package/.agents/scripts/lib/git-utils.js +24 -22
  94. package/.agents/scripts/lib/label-constants.js +3 -4
  95. package/.agents/scripts/lib/label-taxonomy.js +3 -8
  96. package/.agents/scripts/lib/maintainability-engine.js +1 -1
  97. package/.agents/scripts/lib/maintainability-utils.js +4 -187
  98. package/.agents/scripts/lib/observability/perf-report-readers.js +32 -23
  99. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +81 -7
  100. package/.agents/scripts/lib/orchestration/code-review.js +95 -82
  101. package/.agents/scripts/lib/orchestration/context-hydration-engine.js +8 -9
  102. package/.agents/scripts/lib/orchestration/dependency-analyzer.js +3 -3
  103. package/.agents/scripts/lib/orchestration/detectors-phase.js +2 -2
  104. package/.agents/scripts/lib/orchestration/dispatch-engine.js +30 -38
  105. package/.agents/scripts/lib/orchestration/dispatch-pipeline.js +14 -37
  106. package/.agents/scripts/lib/orchestration/epic-cleanup.js +1 -1
  107. package/.agents/scripts/lib/orchestration/epic-deliver-lease-guard.js +22 -22
  108. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/creation.js +1 -1
  109. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/dag.js +7 -21
  110. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/diagnostics.js +3 -3
  111. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +2 -2
  112. package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +206 -58
  113. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/drain.js +1 -1
  114. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +27 -3
  115. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/prompts.js +1 -1
  116. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +28 -8
  117. package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +1 -1
  118. package/.agents/scripts/lib/orchestration/epic-run-state-store.js +3 -3
  119. package/.agents/scripts/lib/orchestration/epic-runner/concurrency-gate.js +4 -4
  120. package/.agents/scripts/lib/orchestration/epic-runner/deliver-phases.js +3 -3
  121. package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +13 -41
  122. package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +7 -7
  123. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/composition.js +2 -3
  124. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/signals.js +2 -8
  125. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/transport.js +4 -4
  126. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/component-drift.js +103 -0
  127. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/crap-drift.js +22 -64
  128. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/maintainability-drift.js +38 -76
  129. package/.agents/scripts/lib/orchestration/epic-runner/story-launcher.js +4 -4
  130. package/.agents/scripts/lib/orchestration/epic-runner/story-run-progress-writer.js +10 -10
  131. package/.agents/scripts/lib/orchestration/epic-runner/sub-agent-return.js +8 -20
  132. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-apply.js +7 -15
  133. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +72 -41
  134. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-ops.js +2 -4
  135. package/.agents/scripts/lib/orchestration/file-assumptions.js +6 -5
  136. package/.agents/scripts/lib/orchestration/finalize/close-planning-tickets.js +1 -1
  137. package/.agents/scripts/lib/orchestration/finalize/open-or-locate-pr.js +2 -2
  138. package/.agents/scripts/lib/orchestration/finalize/sanitize-skip-ci.js +1 -1
  139. package/.agents/scripts/lib/orchestration/lease-guard-shared.js +144 -0
  140. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-dispatch-end.js +1 -1
  141. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +3 -3
  142. package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +1 -1
  143. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +1 -1
  144. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +1 -1
  145. package/.agents/scripts/lib/orchestration/lifecycle/listeners/branch-cleaner.js +1 -1
  146. package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +1 -1
  147. package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +1 -1
  148. package/.agents/scripts/lib/orchestration/lifecycle/listeners/merge-watcher.js +1 -1
  149. package/.agents/scripts/lib/orchestration/lifecycle/listeners/notify-dispatcher.js +1 -1
  150. package/.agents/scripts/lib/orchestration/lifecycle/listeners/watcher.js +8 -8
  151. package/.agents/scripts/lib/orchestration/manifest-builder.js +5 -5
  152. package/.agents/scripts/lib/orchestration/parked-follow-ons.js +2 -2
  153. package/.agents/scripts/lib/orchestration/plan-runner/plan-router.js +5 -5
  154. package/.agents/scripts/lib/orchestration/post-merge/phases/notification.js +3 -3
  155. package/.agents/scripts/lib/orchestration/post-merge/phases/ticket-closure.js +3 -3
  156. package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +7 -7
  157. package/.agents/scripts/lib/orchestration/preflight-cache.js +36 -13
  158. package/.agents/scripts/lib/orchestration/recurring-failure-detector.js +1 -1
  159. package/.agents/scripts/lib/orchestration/retro/phases/compose-body.js +1 -1
  160. package/.agents/scripts/lib/orchestration/retro/phases/gather-signals.js +2 -2
  161. package/.agents/scripts/lib/orchestration/retro-runner.js +3 -3
  162. package/.agents/scripts/lib/orchestration/review-depth.js +1 -1
  163. package/.agents/scripts/lib/orchestration/review-providers/codex.js +5 -60
  164. package/.agents/scripts/lib/orchestration/review-providers/native.js +7 -6
  165. package/.agents/scripts/lib/orchestration/review-providers/parse-findings.js +105 -0
  166. package/.agents/scripts/lib/orchestration/review-providers/security-review.js +7 -59
  167. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +2 -4
  168. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +1 -1
  169. package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +1 -1
  170. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +2 -4
  171. package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +32 -35
  172. package/.agents/scripts/lib/orchestration/skill-capsule-loader.js +1 -2
  173. package/.agents/scripts/lib/orchestration/spec-freshness.js +1 -1
  174. package/.agents/scripts/lib/orchestration/spec-renderer.js +36 -73
  175. package/.agents/scripts/lib/orchestration/spec-section-validator.js +1 -1
  176. package/.agents/scripts/lib/orchestration/story-close/auto-refresh-runner.js +451 -503
  177. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/pre-merge-attribution.js +8 -2
  178. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +47 -2
  179. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/regression-projection.js +2 -2
  180. package/.agents/scripts/lib/orchestration/story-close/baseline-friction-body.js +1 -1
  181. package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +358 -54
  182. package/.agents/scripts/lib/orchestration/story-close/phases/close.js +1 -1
  183. package/.agents/scripts/lib/orchestration/story-close/phases/gates.js +3 -2
  184. package/.agents/scripts/lib/orchestration/story-close/phases/locked-pipeline.js +32 -5
  185. package/.agents/scripts/lib/orchestration/story-close/post-merge-close.js +5 -18
  186. package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +3 -3
  187. package/.agents/scripts/lib/orchestration/story-close-recovery.js +33 -16
  188. package/.agents/scripts/lib/orchestration/story-reachability.js +47 -0
  189. package/.agents/scripts/lib/orchestration/task-body-validator.js +6 -6
  190. package/.agents/scripts/lib/orchestration/ticket-lease.js +1 -1
  191. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +4 -35
  192. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +1 -10
  193. package/.agents/scripts/lib/orchestration/ticket-validator.js +25 -70
  194. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +44 -73
  195. package/.agents/scripts/lib/orchestration/ticketing/reads.js +16 -7
  196. package/.agents/scripts/lib/orchestration/ticketing/state.js +53 -439
  197. package/.agents/scripts/lib/orchestration/ticketing/transition.js +471 -0
  198. package/.agents/scripts/lib/orchestration/ticketing.js +0 -1
  199. package/.agents/scripts/lib/orchestration/wave-record-notifications.js +3 -3
  200. package/.agents/scripts/lib/orchestration/wave-record-projection.js +2 -8
  201. package/.agents/scripts/lib/plan-phase-cleanup.js +1 -1
  202. package/.agents/scripts/lib/preflight-runner.js +1 -1
  203. package/.agents/scripts/lib/presentation/dispatch-manifest-render.js +4 -5
  204. package/.agents/scripts/lib/presentation/manifest-builder.js +28 -34
  205. package/.agents/scripts/lib/presentation/manifest-formatter.js +3 -4
  206. package/.agents/scripts/lib/presentation/manifest-helpers.js +1 -1
  207. package/.agents/scripts/lib/presentation/manifest-procedures.js +4 -4
  208. package/.agents/scripts/lib/presentation/manifest-render-waves.js +4 -23
  209. package/.agents/scripts/lib/presentation/manifest-renderer.js +1 -1
  210. package/.agents/scripts/lib/presentation/manifest-story-views.js +2 -11
  211. package/.agents/scripts/lib/project-root.js +17 -0
  212. package/.agents/scripts/lib/signals/schema.js +1 -1
  213. package/.agents/scripts/lib/spec/index.js +1 -1
  214. package/.agents/scripts/lib/spec/loader.js +2 -2
  215. package/.agents/scripts/lib/spec/state.js +7 -16
  216. package/.agents/scripts/lib/story-adjacency.js +76 -0
  217. package/.agents/scripts/lib/story-init/context-resolver.js +3 -3
  218. package/.agents/scripts/lib/story-init/state-transitioner.js +2 -2
  219. package/.agents/scripts/lib/story-init/task-graph-builder.js +7 -7
  220. package/.agents/scripts/lib/story-lifecycle.js +9 -9
  221. package/.agents/scripts/lib/story-plan.js +1 -1
  222. package/.agents/scripts/lib/templates/decomposer-prompts.js +59 -52
  223. package/.agents/scripts/lib/transpile.js +93 -0
  224. package/.agents/scripts/lib/wave-runner/tick.js +4 -153
  225. package/.agents/scripts/lib/workers/crap-worker.js +1 -1
  226. package/.agents/scripts/lib/workers/maintainability-report-worker.js +1 -1
  227. package/.agents/scripts/lib/worktree/lifecycle/creation.js +20 -2
  228. package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +90 -0
  229. package/.agents/scripts/lib/worktree/lifecycle/reap.js +26 -8
  230. package/.agents/scripts/lib/worktree/node-modules-strategy.js +74 -0
  231. package/.agents/scripts/lifecycle-emit-story-dispatch.js +1 -1
  232. package/.agents/scripts/lifecycle-emit.js +1 -1
  233. package/.agents/scripts/providers/github/board-add.js +1 -1
  234. package/.agents/scripts/providers/github/errors.js +1 -1
  235. package/.agents/scripts/providers/github/mappers.js +2 -2
  236. package/.agents/scripts/providers/github/tickets.js +114 -10
  237. package/.agents/scripts/resync-status-column.js +1 -1
  238. package/.agents/scripts/retro-run.js +2 -2
  239. package/.agents/scripts/run-lint.js +10 -1
  240. package/.agents/scripts/run-tests.js +24 -4
  241. package/.agents/scripts/single-story-init.js +1 -1
  242. package/.agents/scripts/stories-wave-tick.js +13 -10
  243. package/.agents/scripts/story-close.js +1 -1
  244. package/.agents/scripts/story-init.js +162 -26
  245. package/.agents/scripts/story-phase.js +5 -5
  246. package/.agents/scripts/story-plan.js +3 -3
  247. package/.agents/scripts/sync-branch-from-base.js +2 -2
  248. package/.agents/scripts/validate-docs-freshness.js +1 -1
  249. package/.agents/scripts/wave-tick.js +1 -1
  250. package/.agents/skills/core/analyze-execution/SKILL.md +2 -2
  251. package/.agents/skills/core/epic-plan-consolidate/SKILL.md +21 -26
  252. package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +23 -56
  253. package/.agents/skills/core/epic-plan-spec-author/SKILL.md +4 -4
  254. package/.agents/skills/core/hydrate-context/SKILL.md +2 -2
  255. package/.agents/skills/core/idea-refinement/SKILL.md +4 -4
  256. package/.agents/skills/core/knowledge-transfer/SKILL.md +2 -2
  257. package/.agents/skills/core/planning-and-task-breakdown/SKILL.md +1 -1
  258. package/.agents/skills/core/scope-triage/SKILL.md +9 -10
  259. package/.agents/skills/core/using-agent-skills/SKILL.md +1 -1
  260. package/.agents/skills/skills.index.json +7 -7
  261. package/.agents/skills/stack/qa/lighthouse-baseline/SKILL.md +1 -1
  262. package/.agents/templates/agent-protocol.md +2 -2
  263. package/.agents/workflows/agents-update.md +2 -2
  264. package/.agents/workflows/audit-architecture.md +2 -2
  265. package/.agents/workflows/audit-clean-code.md +2 -2
  266. package/.agents/workflows/audit-dependencies.md +1 -1
  267. package/.agents/workflows/audit-devops.md +1 -1
  268. package/.agents/workflows/audit-documentation.md +226 -0
  269. package/.agents/workflows/audit-lighthouse.md +1 -1
  270. package/.agents/workflows/audit-performance.md +2 -2
  271. package/.agents/workflows/audit-privacy.md +1 -1
  272. package/.agents/workflows/audit-quality.md +2 -2
  273. package/.agents/workflows/audit-security.md +2 -2
  274. package/.agents/workflows/audit-seo.md +1 -1
  275. package/.agents/workflows/audit-sre.md +1 -1
  276. package/.agents/workflows/audit-to-stories.md +10 -10
  277. package/.agents/workflows/audit-ux-ui.md +1 -1
  278. package/.agents/workflows/deliver.md +85 -0
  279. package/.agents/workflows/explain.md +3 -3
  280. package/.agents/workflows/git-merge-pr.md +1 -1
  281. package/.agents/workflows/git-pr-all.md +13 -10
  282. package/.agents/workflows/git-push.md +6 -3
  283. package/.agents/workflows/helpers/_merge-conflict-template.md +1 -1
  284. package/.agents/workflows/helpers/acceptance-self-eval.md +1 -1
  285. package/.agents/workflows/helpers/code-review.md +5 -5
  286. package/.agents/workflows/{epic-deliver.md → helpers/deliver-epic.md} +59 -66
  287. package/.agents/workflows/{story-deliver.md → helpers/deliver-stories.md} +25 -25
  288. package/.agents/workflows/helpers/diagnose.md +1 -1
  289. package/.agents/workflows/helpers/epic-audit.md +6 -6
  290. package/.agents/workflows/helpers/epic-deliver-story.md +28 -39
  291. package/.agents/workflows/helpers/epic-plan-decompose.md +23 -23
  292. package/.agents/workflows/helpers/epic-plan-spec.md +6 -6
  293. package/.agents/workflows/helpers/epic-testing.md +3 -3
  294. package/.agents/workflows/helpers/parallel-tooling.md +1 -1
  295. package/.agents/workflows/{epic-plan.md → helpers/plan-epic.md} +84 -84
  296. package/.agents/workflows/{story-plan.md → helpers/plan-story.md} +43 -43
  297. package/.agents/workflows/helpers/signals.md +1 -1
  298. package/.agents/workflows/helpers/single-story-deliver.md +12 -11
  299. package/.agents/workflows/helpers/worktree-lifecycle.md +18 -18
  300. package/.agents/workflows/onboard.md +21 -20
  301. package/.agents/workflows/plan.md +89 -0
  302. package/.agents/workflows/qa-explore.md +1 -1
  303. package/.agents/workflows/qa-run-harness.md +1 -1
  304. package/README.md +17 -20
  305. package/docs/CHANGELOG.md +1149 -0
  306. package/lib/cli/__tests__/update-changelog-surface.test.js +357 -0
  307. package/lib/cli/__tests__/update-reexec.test.js +513 -0
  308. package/lib/cli/init.js +338 -0
  309. package/lib/cli/update.js +413 -52
  310. package/package.json +3 -1
  311. package/.agents/scripts/lib/auto-refresh-baselines.js +0 -308
  312. package/.agents/scripts/lib/close-validation.js +0 -897
  313. package/.agents/scripts/lib/orchestration/cascade-grouping.js +0 -275
  314. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter.js +0 -69
  315. package/.agents/scripts/lib/orchestration/reconciler.js +0 -137
  316. package/.agents/scripts/lib/orchestration/story-close/format-autofix-scoped.js +0 -221
  317. package/.agents/scripts/lib/orchestration/story-close/format-autofix-shared.js +0 -123
  318. package/.agents/scripts/lib/task-utils.js +0 -26
  319. package/.agents/scripts/story-deliver-prepare.js +0 -267
@@ -139,7 +139,7 @@ export function makeGhRunner(cwd) {
139
139
  export function assertDeliverableStory(story, storyId) {
140
140
  if (!story.labels.includes(TYPE_LABELS.STORY)) {
141
141
  throw new Error(
142
- `Issue #${storyId} is not a Story (labels: ${story.labels.join(', ')}). Use /story-deliver or /epic-deliver for Epic-attached work.`,
142
+ `Issue #${storyId} is not a Story (labels: ${story.labels.join(', ')}). Use /deliver or /deliver for Epic-attached work.`,
143
143
  );
144
144
  }
145
145
  if (story.state === 'closed') {
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * stories-wave-tick.js — DAG/wave engine for the top-level /story-deliver workflow.
4
+ * stories-wave-tick.js — DAG/wave engine for the top-level /deliver workflow.
5
5
  *
6
6
  * Consumes an operator-supplied dependency DAG of standalone Story IDs and
7
7
  * emits ordered execution waves. Analogous to wave-tick.js but for standalone
@@ -26,11 +26,11 @@
26
26
  * }
27
27
  *
28
28
  * The per-wave concurrency cap is resolved from the same config seam
29
- * `/epic-deliver` uses — `resolveConfig` + `getRunners` reading
29
+ * `/deliver` uses — `resolveConfig` + `getRunners` reading
30
30
  * `delivery.deliverRunner.concurrencyCap` (default 3) — so a
31
31
  * `.agentrc.local.json` override is honored. A `--concurrency <n>` CLI flag
32
32
  * overrides the config-resolved value for that run only. This puts both the
33
- * standalone (`/story-deliver`) and Epic (`/epic-deliver`) delivery paths on
33
+ * standalone (`/deliver`) and Epic (`/deliver`) delivery paths on
34
34
  * one deterministic config source.
35
35
  *
36
36
  * On cycle detection, exits with code 2 and sets cycleError in the envelope.
@@ -43,6 +43,7 @@ import { runAsCli } from './lib/cli-utils.js';
43
43
  import { getRunners, resolveConfig } from './lib/config-resolver.js';
44
44
  import { assignLayers, detectCycle } from './lib/Graph.js';
45
45
  import { Logger } from './lib/Logger.js';
46
+ import { buildStoryAdjacency } from './lib/story-adjacency.js';
46
47
 
47
48
  const HELP = `Usage: node .agents/scripts/stories-wave-tick.js --dag '<json>' | --dag-file <path> [--concurrency <n>]
48
49
 
@@ -132,21 +133,23 @@ export function parseDag(raw) {
132
133
  * Build an adjacency map from parsed DAG nodes.
133
134
  * Returns Map<id, id[]> where each id maps to its dependencies.
134
135
  *
136
+ * Delegates to the shared story-level builder
137
+ * (`lib/story-adjacency.js#buildStoryAdjacency`) with `dropForeign: false`
138
+ * to preserve the operator-DAG contract: a `dependsOn` id absent from the
139
+ * input set still deepens the dependent's layer (assignLayers treats the
140
+ * unknown id as a root).
141
+ *
135
142
  * @param {Array<{id: number, dependsOn: number[]}>} nodes
136
143
  * @returns {Map<number, number[]>}
137
144
  */
138
145
  export function buildAdjacency(nodes) {
139
- const adjacency = new Map();
140
- for (const node of nodes) {
141
- adjacency.set(node.id, [...node.dependsOn]);
142
- }
143
- return adjacency;
146
+ return buildStoryAdjacency(nodes, { dropForeign: false });
144
147
  }
145
148
 
146
149
  /**
147
150
  * Resolve the per-wave concurrency cap.
148
151
  *
149
- * Mirrors the `/epic-deliver` seam (`epic-deliver-prepare.js`): resolve the
152
+ * Mirrors the `/deliver` seam (`epic-deliver-prepare.js`): resolve the
150
153
  * project config (which deep-merges `.agentrc.local.json` over `.agentrc.json`)
151
154
  * then read `delivery.deliverRunner.concurrencyCap` via `getRunners` (default
152
155
  * 3). An explicit `override` (the `--concurrency <n>` CLI flag) wins over
@@ -174,7 +177,7 @@ export function resolveConcurrencyCap({ cwd, config, override } = {}) {
174
177
  *
175
178
  * Uses detectCycle from Graph.js to validate the DAG before computing
176
179
  * layers via assignLayers. Returns the wave envelope, carrying the resolved
177
- * per-wave `concurrencyCap` so the `/story-deliver` workflow dispatches
180
+ * per-wave `concurrencyCap` so the `/deliver` workflow dispatches
178
181
  * `min(wave.stories.length, concurrencyCap)` from a deterministic field rather
179
182
  * than from recalled prose.
180
183
  *
@@ -22,7 +22,7 @@
22
22
  * 1 error
23
23
  * 2 prior-state (pass --resume / --restart) OR preflight refused
24
24
  *
25
- * @see .agents/workflows/story-deliver.md
25
+ * @see .agents/workflows/helpers/deliver-stories.md
26
26
  */
27
27
 
28
28
  import { runAsCli } from './lib/cli-utils.js';
@@ -15,7 +15,7 @@
15
15
  * 5. branch-initializer — materialise the story branch (single-tree
16
16
  * checkout or isolated worktree).
17
17
  * 6. state-transitioner — flip the Story to `agent::executing`. Under
18
- * the 3-tier hierarchy the Story has inline
18
+ * the 2-tier hierarchy the Story has inline
19
19
  * acceptance and no child Task lifecycle.
20
20
  *
21
21
  * Usage:
@@ -25,7 +25,7 @@
25
25
  * 0 — Initialization complete. Agent can start implementation.
26
26
  * 1 — Blocked or error (details in stderr).
27
27
  *
28
- * @see .agents/workflows/story-deliver.md
28
+ * @see .agents/workflows/helpers/deliver-stories.md
29
29
  */
30
30
 
31
31
  import path from 'node:path';
@@ -38,8 +38,13 @@ import {
38
38
  } from './lib/config-resolver.js';
39
39
  import { parseBlockedBy } from './lib/dependency-parser.js';
40
40
  import { getEpicBranch, getStoryBranch } from './lib/git-utils.js';
41
+ import { runInstallCommand } from './lib/install-cmd-parser.js';
41
42
  import { Logger } from './lib/Logger.js';
42
43
  import { setActiveStoryEnv } from './lib/observability/active-story-env.js';
44
+ import {
45
+ defaultStoryPhases,
46
+ upsertStoryRunProgress,
47
+ } from './lib/orchestration/epic-runner/story-run-progress-writer.js';
43
48
  import { upsertStructuredComment } from './lib/orchestration/ticketing.js';
44
49
  import { createProvider } from './lib/provider-factory.js';
45
50
  import { validateBlockers } from './lib/story-init/blocker-validator.js';
@@ -136,7 +141,7 @@ export async function runStoryInit({
136
141
  progress('INIT', `Initializing Story #${storyId}...`);
137
142
 
138
143
  // Stage 1 — context.
139
- const { story, body, epicId, featureId } = await resolveContext({
144
+ const { story, body, epicId, parentId } = await resolveContext({
140
145
  provider,
141
146
  logger: stageLogger,
142
147
  input: { storyId, recutOf, dryRun },
@@ -149,10 +154,7 @@ export async function runStoryInit({
149
154
  input: { epicId },
150
155
  });
151
156
 
152
- progress(
153
- 'CONTEXT',
154
- `Epic: #${epicId}, Feature/Parent: #${featureId ?? 'none'}`,
155
- );
157
+ progress('CONTEXT', `Epic: #${epicId}, Parent: #${parentId ?? 'none'}`);
156
158
  progress(
157
159
  'CONTEXT',
158
160
  `PRD: #${prdId ?? 'none'}, Tech Spec: #${techSpecId ?? 'none'}`,
@@ -187,8 +189,8 @@ export async function runStoryInit({
187
189
  progress('BLOCKERS', '✅ All blockers resolved');
188
190
 
189
191
  // Stage 4 — task graph. Pass the Story body so buildTaskGraph can detect
190
- // the inline-acceptance 3-tier shape. After Task #3154 collapsed the
191
- // hierarchy flag, 3-tier is the only supported shape.
192
+ // the inline-acceptance 2-tier shape. After Task #3154 collapsed the
193
+ // hierarchy flag, 2-tier is the only supported shape.
192
194
  const { sortedTasks, mode: hierarchyMode } = await buildTaskGraph({
193
195
  provider,
194
196
  logger: stageLogger,
@@ -322,7 +324,7 @@ export async function runStoryInit({
322
324
  worktreeCreated,
323
325
  installStatus,
324
326
  sortedTasks,
325
- featureId,
327
+ parentId,
326
328
  prdId,
327
329
  techSpecId,
328
330
  dryRun,
@@ -330,11 +332,6 @@ export async function runStoryInit({
330
332
  hierarchy: hierarchyMode,
331
333
  });
332
334
 
333
- emitStoryInitResult(result, {
334
- storyId,
335
- dryRun,
336
- });
337
-
338
335
  if (!dryRun) {
339
336
  await postStoryInitComment({
340
337
  provider,
@@ -342,11 +339,153 @@ export async function runStoryInit({
342
339
  result,
343
340
  logger: stageLogger,
344
341
  });
342
+
343
+ // Story #4017 — the formerly standalone prepare CLI (which
344
+ // re-read the story-init structured comment seconds after this process
345
+ // wrote it) is inlined here: apply the install tri-state and render the
346
+ // initial Story-phase snapshot in-process, off the result we already
347
+ // hold.
348
+ result.prepare = await runStoryInitPrepare({
349
+ provider,
350
+ storyId,
351
+ result,
352
+ notify: _notifyFn,
353
+ logger: stageLogger,
354
+ });
345
355
  }
346
356
 
357
+ emitStoryInitResult(result, {
358
+ storyId,
359
+ dryRun,
360
+ });
361
+
347
362
  return { success: true, result };
348
363
  }
349
364
 
365
+ const VALID_INSTALLED_STATES = new Set(['true', 'false', 'skipped']);
366
+
367
+ /**
368
+ * Apply the dependenciesInstalled tri-state to derive the next install
369
+ * action. Pure helper — exposes the Step 0.5 truth table as data so tests
370
+ * can pin each branch without spinning up a child process.
371
+ *
372
+ * @param {'true' | 'false' | 'skipped'} dependenciesInstalled
373
+ * @param {{ skipInstall?: boolean }} [options]
374
+ * @returns {'skip' | 'install'}
375
+ */
376
+ export function deriveInstallAction(dependenciesInstalled, options = {}) {
377
+ if (!VALID_INSTALLED_STATES.has(dependenciesInstalled)) {
378
+ throw new RangeError(
379
+ `deriveInstallAction: dependenciesInstalled "${dependenciesInstalled}" must be one of: ${[...VALID_INSTALLED_STATES].join(', ')}`,
380
+ );
381
+ }
382
+ if (options.skipInstall) return 'skip';
383
+ return dependenciesInstalled === 'false' ? 'install' : 'skip';
384
+ }
385
+
386
+ /**
387
+ * Resolve the install command to run when `dependenciesInstalled === 'false'`.
388
+ * `project.commands` does not currently carry a dedicated install key,
389
+ * so this defaults to `npm ci`. Operators can override per-invocation via
390
+ * the `installCmd` option.
391
+ *
392
+ * @param {{ override?: string }} [options]
393
+ * @returns {string}
394
+ */
395
+ export function resolveInstallCommand(options = {}) {
396
+ const trimmed = options.override?.trim();
397
+ if (trimmed) {
398
+ return trimmed;
399
+ }
400
+ return 'npm ci';
401
+ }
402
+
403
+ /**
404
+ * Post-init prepare step (Story #4017 — formerly a standalone prepare
405
+ * CLI, now consuming the in-process init result
406
+ * instead of re-reading the `story-init` structured comment):
407
+ *
408
+ * 1. Apply the `dependenciesInstalled` tri-state truth table — `'false'`
409
+ * (install attempted and failed) retries the install command in the
410
+ * worktree; `'true'` / `'skipped'` proceed.
411
+ * 2. Render the initial Story-phase snapshot with every phase pinned to
412
+ * `pending` and `phase: 'init'` via `upsertStoryRunProgress`
413
+ * (render-only since Story #3909 — no comment is posted). The
414
+ * `renderedBody` markdown is relayed to chat by the delivery
415
+ * workflows so operators see the initial progress block before the
416
+ * first commit lands.
417
+ *
418
+ * Install failure throws (init exits non-zero); a snapshot-render failure
419
+ * is non-fatal observability loss and only warns.
420
+ *
421
+ * @param {{
422
+ * provider: object,
423
+ * storyId: number,
424
+ * result: { workCwd?: string, dependenciesInstalled?: string, storyBranch?: string },
425
+ * notify?: Function | null,
426
+ * runInstall?: (cmd: string, cwd: string) => { status: number, stderr?: string },
427
+ * skipInstall?: boolean,
428
+ * installCmd?: string,
429
+ * logger?: object,
430
+ * }} args
431
+ * @returns {Promise<{
432
+ * installAction: 'skip' | 'install',
433
+ * installCmd: string | null,
434
+ * installResult: { status: number, stderr?: string } | null,
435
+ * snapshot: object | null,
436
+ * renderedBody: string | null,
437
+ * }>}
438
+ */
439
+ export async function runStoryInitPrepare({
440
+ provider,
441
+ storyId,
442
+ result,
443
+ notify: notifyFn = null,
444
+ runInstall = runInstallCommand,
445
+ skipInstall = false,
446
+ installCmd: installCmdOverride,
447
+ logger = stageLogger,
448
+ }) {
449
+ const dependenciesInstalled = String(
450
+ result?.dependenciesInstalled ?? 'skipped',
451
+ );
452
+ const installAction = deriveInstallAction(dependenciesInstalled, {
453
+ skipInstall,
454
+ });
455
+ let installCmd = null;
456
+ let installResult = null;
457
+ if (installAction === 'install') {
458
+ installCmd = resolveInstallCommand({ override: installCmdOverride });
459
+ installResult = runInstall(installCmd, result.workCwd);
460
+ if (installResult.status !== 0) {
461
+ throw new Error(
462
+ `runStoryInitPrepare: install command \`${installCmd}\` failed with status ${installResult.status}: ${installResult.stderr ?? ''}`,
463
+ );
464
+ }
465
+ }
466
+
467
+ let snapshot = null;
468
+ let renderedBody = null;
469
+ try {
470
+ const { body, payload } = await upsertStoryRunProgress({
471
+ provider,
472
+ storyId,
473
+ branch: result?.storyBranch ?? `story-${storyId}`,
474
+ phase: 'init',
475
+ phases: defaultStoryPhases(),
476
+ notify: notifyFn,
477
+ });
478
+ snapshot = payload;
479
+ renderedBody = body;
480
+ } catch (err) {
481
+ logger?.warn?.(
482
+ `[story-init] ⚠️ Failed to render initial story-run-progress snapshot: ${err?.message ?? err}`,
483
+ );
484
+ }
485
+
486
+ return { installAction, installCmd, installResult, snapshot, renderedBody };
487
+ }
488
+
350
489
  function buildStoryInitResult({
351
490
  storyId,
352
491
  epicId,
@@ -358,7 +497,7 @@ function buildStoryInitResult({
358
497
  worktreeCreated,
359
498
  installStatus,
360
499
  sortedTasks,
361
- featureId,
500
+ parentId,
362
501
  prdId,
363
502
  techSpecId,
364
503
  dryRun,
@@ -372,11 +511,11 @@ function buildStoryInitResult({
372
511
  storyBranch,
373
512
  epicBranch,
374
513
  storyTitle: story.title,
375
- // Hierarchy mode resolved by buildTaskGraph. 3-tier is the only
514
+ // Hierarchy mode resolved by buildTaskGraph. 2-tier is the only
376
515
  // supported shape after Task #3154 deleted the `planning.hierarchy`
377
516
  // flag; this is retained as a constant marker for downstream
378
517
  // consumers and persisted artefacts.
379
- hierarchy: hierarchy ?? '3-tier',
518
+ hierarchy: hierarchy ?? '2-tier',
380
519
  worktreeEnabled,
381
520
  workCwd,
382
521
  worktreeCreated,
@@ -392,7 +531,7 @@ function buildStoryInitResult({
392
531
  labels: t.labels,
393
532
  dependencies: t.dependsOn ?? parseBlockedBy(t.body ?? ''),
394
533
  })),
395
- context: { featureId, prdId, techSpecId },
534
+ context: { parentId, prdId, techSpecId },
396
535
  dryRun,
397
536
  };
398
537
  }
@@ -449,20 +588,17 @@ export function renderStoryInitCommentBody(result) {
449
588
  epicId: result.epicId,
450
589
  storyBranch: result.storyBranch,
451
590
  epicBranch: result.epicBranch,
452
- // Hierarchy mode is always `'3-tier'` after Task #3154 deleted the
591
+ // Hierarchy mode is always `'2-tier'` after Task #3154 deleted the
453
592
  // `planning.hierarchy` flag. Persisted so resumed runs can read it
454
593
  // without re-resolving anything in the worker.
455
- hierarchy: result.hierarchy ?? '3-tier',
594
+ hierarchy: result.hierarchy ?? '2-tier',
456
595
  worktreeEnabled: result.worktreeEnabled,
457
596
  workCwd: result.workCwd,
458
597
  worktreeCreated: result.worktreeCreated,
459
598
  dependenciesInstalled: result.dependenciesInstalled,
460
599
  installStatus: result.installStatus,
461
- // Embed the canonical task list so `story-deliver-prepare.js` can seed the
462
- // initial `story-run-progress` snapshot without re-fetching the task graph.
463
- // Without this field, the prepare CLI silently seeded an empty snapshot,
464
- // breaking every subsequent phase-writer call (it asserts the
465
- // task id is present in the snapshot).
600
+ // Embed the canonical task list so downstream snapshot consumers can
601
+ // seed phase-writer calls without re-fetching the task graph.
466
602
  tasks: Array.isArray(result.tasks)
467
603
  ? result.tasks.map((t) => ({ id: t.id, title: t.title }))
468
604
  : [],
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * story-phase.js — phase snapshot + heartbeat writer (3-tier).
4
+ * story-phase.js — phase snapshot + heartbeat writer (2-tier).
5
5
  *
6
6
  * Replaces the deleted per-Task progress writer from the 4-tier era
7
- * (removed under #3157). `/story-deliver` calls this CLI at each Story-
7
+ * (removed under #3157). `/deliver` calls this CLI at each Story-
8
8
  * level phase transition (init → implementing → closing → done, or any
9
9
  * → blocked). Each call:
10
10
  *
@@ -14,7 +14,7 @@
14
14
  * longer posts a `story-run-progress` comment (the redundant mid-flight
15
15
  * progress surface was deleted); the snapshot is render-only.
16
16
  * 2. Appends one `story.heartbeat` lifecycle record to
17
- * `temp/epic-<epicId>/lifecycle.ndjson` so `/epic-deliver`'s
17
+ * `temp/epic-<epicId>/lifecycle.ndjson` so `/deliver`'s
18
18
  * §2e Idle Watchdog (`wave-tick.js --check-idle 30`) can confirm
19
19
  * forward progress without polling the Story comment.
20
20
  *
@@ -35,7 +35,7 @@
35
35
  *
36
36
  * `renderedBody` is the markdown body upserted onto the Story so the
37
37
  * caller can relay it to chat verbatim (mirrors the contract the deleted
38
- * per-Task progress writer exposed and that `/story-deliver` Step 1 / 3
38
+ * per-Task progress writer exposed and that `/deliver` Step 1 / 3
39
39
  * already documents).
40
40
  */
41
41
 
@@ -175,7 +175,7 @@ async function resolveStoryBranch({ provider, storyId }) {
175
175
  * lease-owner handle the SAME way the lease primitive does
176
176
  * (`normalizeOperatorHandle(github.operatorHandle)`) and stamps it as
177
177
  * `operator` so `latestHeartbeatForOwner({ epicId, owner })` resolves a real
178
- * heartbeat — without it `isClaimLive(null)` is false and /epic-deliver
178
+ * heartbeat — without it `isClaimLive(null)` is false and /deliver
179
179
  * silently reclaims a live foreign claim (audit #3513). The field is attached
180
180
  * only when a handle resolves, preserving the "omit when absent" shape for
181
181
  * repos that have not configured `github.operatorHandle`. A failed append is
@@ -2,9 +2,9 @@
2
2
  /* node:coverage ignore file */
3
3
 
4
4
  /**
5
- * story-plan.js — Local `/story-plan` wrapper.
5
+ * story-plan.js — Local `/plan` wrapper.
6
6
  *
7
- * Standalone counterpart to `/epic-plan` for Stories that do **not**
7
+ * Standalone counterpart to `/plan` for Stories that do **not**
8
8
  * attach to an Epic. The script is deliberately a thin CLI around the
9
9
  * pure helpers in `lib/story-plan.js`:
10
10
  *
@@ -24,7 +24,7 @@
24
24
  * GitHub. Echoes the rendered body and the `gh` argv it would
25
25
  * have run.
26
26
  *
27
- * Mirrors the `/epic-plan` pattern: deterministic Node I/O wrappers
27
+ * Mirrors the `/plan` pattern: deterministic Node I/O wrappers
28
28
  * with HITL gating handled by the host LLM in chat. No external LLM
29
29
  * APIs are called from this script.
30
30
  */
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * Use this from workflow markdown when the operator needs to sync a
8
8
  * working branch with `origin/<baseBranch>` before opening a PR — for
9
- * example as a pre-Phase-6 step in `/epic-deliver` so the Epic→main PR
9
+ * example as a pre-Phase-6 step in `/deliver` so the Epic→main PR
10
10
  * opens with the latest `main` commits already integrated.
11
11
  *
12
12
  * For `/single-story-deliver`, the sync runs in-process inside
@@ -31,10 +31,10 @@
31
31
  import path from 'node:path';
32
32
  import { parseArgs } from 'node:util';
33
33
  import { runAsCli } from './lib/cli-utils.js';
34
- import { PROJECT_ROOT } from './lib/config-resolver.js';
35
34
  import { syncBranchFromBase } from './lib/git/sync-from-base.js';
36
35
  import { gitSpawn, gitSync } from './lib/git-utils.js';
37
36
  import { Logger } from './lib/Logger.js';
37
+ import { PROJECT_ROOT } from './lib/project-root.js';
38
38
 
39
39
  const progress = Logger.createProgress('sync-branch-from-base', {
40
40
  stderr: true,
@@ -201,7 +201,7 @@ export function renderFreshnessFailureMessage(epicId) {
201
201
  return (
202
202
  `[docs-freshness] ❌ Documentation freshness gate FAILED for Epic #${epicId}.\n\n` +
203
203
  `Update each failing file so its commit message or body references #${epicId}, ` +
204
- `then re-run /epic-deliver.`
204
+ `then re-run /deliver.`
205
205
  );
206
206
  }
207
207
 
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * Reads the `epic-run-state` checkpoint plus fresh Story labels and
8
8
  * prints one `WaveTickResult` envelope. The slash-command operator
9
- * (`/epic-deliver`) consumes the envelope to decide whether to dispatch
9
+ * (`/deliver`) consumes the envelope to decide whether to dispatch
10
10
  * the next wave, observe in-flight stories, or finalize the Epic.
11
11
  *
12
12
  * Usage:
@@ -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.