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
@@ -9,15 +9,22 @@
9
9
  * MI is computed by the in-repo `escomplex-engine` kernel — same upstream
10
10
  * dependency family as CRAP — so the kernel version tracks
11
11
  * `typhonjs-escomplex` too.
12
+ *
13
+ * Higher MI = better. New paths land in the `additions` bucket
14
+ * (Story #2012 — new files MUST NOT register as regressions); removed
15
+ * paths count as improvements when their MI was non-perfect — the file is
16
+ * gone, so its prior debt is gone too. Scaffold (sortRows / rollup /
17
+ * compare / applyEpsilon / mergeRows) is generated by `makeBaselineKind`
18
+ * (Story #3983).
12
19
  */
13
20
 
14
21
  import { readBaselineAtRef } from '../../baseline-loader.js';
15
22
  import { loadBaseline } from '../../gates/baseline-store.js';
16
- import { getBaseline } from '../../maintainability-utils.js';
17
- import { componentMatches } from '../component-matcher.js';
23
+ import { getBaseline } from '../maintainability-baseline-io.js';
18
24
  import { canonicalise } from '../path-canon.js';
19
- import { mergeRowsByScope } from '../scope.js';
25
+ import { percentile } from './_shared-metric.js';
20
26
  import { kernelVersion as crapKernelVersion } from './crap.js';
27
+ import { makeBaselineKind } from './kind-factory.js';
21
28
 
22
29
  export const name = 'maintainability';
23
30
  export const keyField = 'path';
@@ -111,12 +118,6 @@ export function filterExcludedRows(rows) {
111
118
  );
112
119
  }
113
120
 
114
- export function kernelVersion() {
115
- // MI and CRAP share the escomplex kernel — pin them together so a drift
116
- // in either always invalidates both baselines.
117
- return crapKernelVersion();
118
- }
119
-
120
121
  export function projectRow(row) {
121
122
  return {
122
123
  path: canonicalise(row.path),
@@ -124,10 +125,6 @@ export function projectRow(row) {
124
125
  };
125
126
  }
126
127
 
127
- export function sortRows(rows) {
128
- return [...rows].sort((a, b) => a.path.localeCompare(b.path));
129
- }
130
-
131
128
  function aggregate(rows) {
132
129
  if (!rows || rows.length === 0) return { min: 0, p50: 0, p95: 0 };
133
130
  const sorted = [...rows].map((r) => r.mi).sort((a, b) => a - b);
@@ -138,117 +135,27 @@ function aggregate(rows) {
138
135
  };
139
136
  }
140
137
 
141
- function percentile(sortedValues, p) {
142
- if (sortedValues.length === 0) return 0;
143
- const idx = Math.min(
144
- sortedValues.length - 1,
145
- Math.max(0, Math.ceil((p / 100) * sortedValues.length) - 1),
146
- );
147
- return sortedValues[idx];
148
- }
149
-
150
- export function rollup(rows, components = []) {
151
- const out = { '*': aggregate(rows) };
152
- for (const c of components ?? []) {
153
- const matched = (rows ?? []).filter((r) => componentMatches(c, r.path));
154
- out[c.name] = aggregate(matched);
155
- }
156
- return out;
157
- }
158
-
159
- /**
160
- * Pure compare(head, base) for the maintainability kind. Diffs rows by
161
- * `path`. Higher MI = better — a row regresses when its mi drops vs
162
- * base, improves when it rises, unchanged when equal. New paths (head
163
- * has a row that base lacks) land in the `additions` bucket; absolute-
164
- * floor enforcement is the unified `check-baselines` gate's job and runs
165
- * independently. Removed paths (base has a row that head dropped) count
166
- * as improvements when their MI was non-perfect; the file is gone, so
167
- * its prior debt is gone too.
168
- *
169
- * Story #2012 — new files MUST NOT register as regressions. The prior
170
- * behaviour treated missing-in-base as base.mi = 100 and any real-world
171
- * MI under 100 (i.e., almost every file) flipped to a regression.
172
- *
173
- * No I/O. No process exit. No friction emission.
174
- */
175
- export function compare(head, base) {
176
- const headRows = Array.isArray(head?.rows) ? head.rows : [];
177
- const baseRows = Array.isArray(base?.rows) ? base.rows : [];
178
- const baseByKey = new Map();
179
- for (const r of baseRows) baseByKey.set(r.path, r);
180
- const seen = new Set();
181
- const regressions = [];
182
- const improvements = [];
183
- const unchanged = [];
184
- const additions = [];
185
- for (const h of headRows) {
186
- seen.add(h.path);
187
- const b = baseByKey.get(h.path);
188
- if (!b) {
189
- additions.push({ key: h.path, head: h, base: null });
190
- continue;
191
- }
192
- const delta = (h.mi ?? 0) - (b.mi ?? 0);
193
- if (delta < 0) regressions.push({ key: h.path, head: h, base: b });
194
- else if (delta > 0) improvements.push({ key: h.path, head: h, base: b });
195
- else unchanged.push({ key: h.path, head: h, base: b });
196
- }
197
- for (const b of baseRows) {
198
- if (seen.has(b.path)) continue;
199
- if ((b.mi ?? 0) < 100) {
200
- improvements.push({ key: b.path, head: null, base: b });
201
- } else {
202
- unchanged.push({ key: b.path, head: null, base: b });
203
- }
204
- }
205
- return { regressions, improvements, unchanged, additions };
206
- }
207
-
208
- /**
209
- * Pure stabilizer for s-stability-epsilon (Story #1964). Folds sub-epsilon
210
- * MI deltas back to the prior bytes so env variance does not rewrite the
211
- * on-disk baseline. Missing-prior rows fall through to the regenerated
212
- * row.
213
- *
214
- * @param {Array<{path: string, mi: number}>} prior
215
- * @param {Array<{path: string, mi: number}>} regenerated
216
- * @param {number} epsilon non-negative absolute tolerance on MI
217
- * @returns {Array<object>}
218
- */
219
- export function applyEpsilon(prior, regenerated, epsilon) {
220
- const priorRows = Array.isArray(prior) ? prior : [];
221
- const regenRows = Array.isArray(regenerated) ? regenerated : [];
222
- const eps = Number.isFinite(epsilon) && epsilon >= 0 ? epsilon : 0;
223
- const priorByKey = new Map();
224
- for (const r of priorRows) priorByKey.set(r.path, r);
225
- return regenRows.map((row) => {
226
- const p = priorByKey.get(row.path);
227
- if (!p) return row;
228
- return Math.abs((row.mi ?? 0) - (p.mi ?? 0)) <= eps ? p : row;
229
- });
230
- }
231
-
232
- /**
233
- * Pure scope-aware merge for s-diff-scoped-writes (Story #1974). MI rows
234
- * match by `path`. In diff mode, rows whose `path` is OUTSIDE
235
- * `scope.files` are preserved from `prior` verbatim; in-scope rows come
236
- * from `regenerated`. In full mode (or no scope), regenerated wins
237
- * everywhere.
238
- *
239
- * @param {Array<{path: string, mi: number}>} prior
240
- * @param {Array<{path: string, mi: number}>} regenerated
241
- * @param {{mode: 'full'|'diff', files: Set<string>}|null|undefined} scope
242
- * @returns {Array<object>}
243
- */
244
- export function mergeRows(prior, regenerated, scope) {
245
- return mergeRowsByScope({
246
- prior,
247
- regenerated,
248
- scope,
249
- scopeKey: (row) => row.path,
250
- });
251
- }
138
+ export const {
139
+ kernelVersion,
140
+ sortRows,
141
+ rollup,
142
+ compare,
143
+ applyEpsilon,
144
+ mergeRows,
145
+ } = makeBaselineKind({
146
+ keyField,
147
+ // MI and CRAP share the escomplex kernel — pin them together so a drift
148
+ // in either always invalidates both baselines.
149
+ kernelVersion: crapKernelVersion,
150
+ axes: ['mi'],
151
+ betterWhen: 'higher',
152
+ aggregate,
153
+ missingBasePolicy: 'addition',
154
+ removedRowPolicy: {
155
+ kind: 'improvement-when',
156
+ when: (b) => (b.mi ?? 0) < 100,
157
+ },
158
+ });
252
159
 
253
160
  // ---------------------------------------------------------------------------
254
161
  // CLI-facing pure helpers (Story #1981, Task #1989).
@@ -4,19 +4,18 @@
4
4
  * carries score/killed/survived/noCoverage. Stryker is the upstream
5
5
  * kernel; we pin a static `1.0.0` until a Mandrel-side retrofit story
6
6
  * wires the running Stryker version through (#1908).
7
+ *
8
+ * Higher score = better. New paths land in the `additions` bucket
9
+ * (Story #2012 — any real-world score under 100 must never flip to a
10
+ * regression); removed paths count as improvements when their score was
11
+ * non-perfect. Scaffold is generated by `makeBaselineKind` (Story #3983).
7
12
  */
8
13
 
9
- import { componentMatches } from '../component-matcher.js';
10
14
  import { canonicalise } from '../path-canon.js';
11
- import { mergeRowsByScope } from '../scope.js';
15
+ import { makeBaselineKind } from './kind-factory.js';
12
16
 
13
17
  export const name = 'mutation';
14
18
  export const keyField = 'path';
15
- const KERNEL_VERSION = '1.0.0';
16
-
17
- export function kernelVersion() {
18
- return KERNEL_VERSION;
19
- }
20
19
 
21
20
  export function projectRow(row) {
22
21
  return {
@@ -27,10 +26,6 @@ export function projectRow(row) {
27
26
  };
28
27
  }
29
28
 
30
- export function sortRows(rows) {
31
- return [...rows].sort((a, b) => a.path.localeCompare(b.path));
32
- }
33
-
34
29
  function aggregate(rows) {
35
30
  if (!rows || rows.length === 0) {
36
31
  return { score: 0, killed: 0, survived: 0, noCoverage: 0 };
@@ -51,103 +46,22 @@ function aggregate(rows) {
51
46
  };
52
47
  }
53
48
 
54
- export function rollup(rows, components = []) {
55
- const out = { '*': aggregate(rows) };
56
- for (const c of components ?? []) {
57
- const matched = (rows ?? []).filter((r) => componentMatches(c, r.path));
58
- out[c.name] = aggregate(matched);
59
- }
60
- return out;
61
- }
62
-
63
- /**
64
- * Pure compare(head, base) for the mutation kind. Diffs rows by `path`.
65
- * Higher score = better — a row regresses when its score drops vs base,
66
- * improves when it rises, unchanged when equal. New paths (head has a
67
- * row that base lacks) land in the `additions` bucket; absolute-floor
68
- * enforcement is the unified `check-baselines` gate's job and runs
69
- * independently. Removed paths (base has a row that head dropped) count
70
- * as improvements when their score was non-perfect.
71
- *
72
- * Story #2012 — sibling fix to maintainability.compare. The prior
73
- * behaviour treated missing-in-base as base.score = 100 and any real-
74
- * world mutation score under 100 flipped to a regression.
75
- *
76
- * No I/O. No process exit. No friction emission.
77
- */
78
- export function compare(head, base) {
79
- const headRows = Array.isArray(head?.rows) ? head.rows : [];
80
- const baseRows = Array.isArray(base?.rows) ? base.rows : [];
81
- const baseByKey = new Map();
82
- for (const r of baseRows) baseByKey.set(r.path, r);
83
- const seen = new Set();
84
- const regressions = [];
85
- const improvements = [];
86
- const unchanged = [];
87
- const additions = [];
88
- for (const h of headRows) {
89
- seen.add(h.path);
90
- const b = baseByKey.get(h.path);
91
- if (!b) {
92
- additions.push({ key: h.path, head: h, base: null });
93
- continue;
94
- }
95
- const delta = (h.score ?? 0) - (b.score ?? 0);
96
- if (delta < 0) regressions.push({ key: h.path, head: h, base: b });
97
- else if (delta > 0) improvements.push({ key: h.path, head: h, base: b });
98
- else unchanged.push({ key: h.path, head: h, base: b });
99
- }
100
- for (const b of baseRows) {
101
- if (seen.has(b.path)) continue;
102
- if ((b.score ?? 0) < 100) {
103
- improvements.push({ key: b.path, head: null, base: b });
104
- } else {
105
- unchanged.push({ key: b.path, head: null, base: b });
106
- }
107
- }
108
- return { regressions, improvements, unchanged, additions };
109
- }
110
-
111
- /**
112
- * Pure stabilizer for s-stability-epsilon (Story #1964). Folds sub-epsilon
113
- * mutation-score deltas back to the prior bytes. Missing-prior rows fall
114
- * through to the regenerated row.
115
- *
116
- * @param {Array<{path: string, score: number, killed: number, survived: number}>} prior
117
- * @param {Array<{path: string, score: number, killed: number, survived: number}>} regenerated
118
- * @param {number} epsilon non-negative absolute tolerance on mutation score
119
- * @returns {Array<object>}
120
- */
121
- export function applyEpsilon(prior, regenerated, epsilon) {
122
- const priorRows = Array.isArray(prior) ? prior : [];
123
- const regenRows = Array.isArray(regenerated) ? regenerated : [];
124
- const eps = Number.isFinite(epsilon) && epsilon >= 0 ? epsilon : 0;
125
- const priorByKey = new Map();
126
- for (const r of priorRows) priorByKey.set(r.path, r);
127
- return regenRows.map((row) => {
128
- const p = priorByKey.get(row.path);
129
- if (!p) return row;
130
- return Math.abs((row.score ?? 0) - (p.score ?? 0)) <= eps ? p : row;
131
- });
132
- }
133
-
134
- /**
135
- * Pure scope-aware merge for s-diff-scoped-writes (Story #1974). Mutation
136
- * rows match by `path`. In diff mode, rows whose `path` is OUTSIDE
137
- * `scope.files` are preserved from `prior` verbatim; in-scope rows come
138
- * from `regenerated`. In full mode (or no scope), regenerated wins
139
- * everywhere.
140
- *
141
- * @param {Array<{path: string, score: number, killed: number, survived: number}>} prior
142
- * @param {Array<{path: string, score: number, killed: number, survived: number}>} regenerated
143
- * @param {{mode: 'full'|'diff', files: Set<string>}|null|undefined} scope
144
- * @returns {Array<object>}
145
- */
146
- export function mergeRows(prior, regenerated, scope) {
147
- return mergeRowsByScope({
148
- prior,
149
- regenerated,
150
- scope,
151
- scopeKey: (row) => row.path,
152
- });
153
- }
49
+ export const {
50
+ kernelVersion,
51
+ sortRows,
52
+ rollup,
53
+ compare,
54
+ applyEpsilon,
55
+ mergeRows,
56
+ } = makeBaselineKind({
57
+ keyField,
58
+ kernelVersion: '1.0.0',
59
+ axes: ['score'],
60
+ betterWhen: 'higher',
61
+ aggregate,
62
+ missingBasePolicy: 'addition',
63
+ removedRowPolicy: {
64
+ kind: 'improvement-when',
65
+ when: (b) => (b.score ?? 0) < 100,
66
+ },
67
+ });
@@ -0,0 +1,59 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { Logger } from '../Logger.js';
4
+
5
+ /**
6
+ * Story #1895: project the canonical maintainability envelope back to the
7
+ * legacy flat `{ path: mi }` map so existing gate consumers keep working
8
+ * without churn — Story #1912 will replace this shim with the shared
9
+ * reader. Returns the parsed input unchanged when it doesn't look like an
10
+ * envelope (legacy flat shape stays flat).
11
+ */
12
+ function projectMaintainabilityEnvelopeToFlat(parsed) {
13
+ if (
14
+ !parsed ||
15
+ typeof parsed !== 'object' ||
16
+ Array.isArray(parsed) ||
17
+ !Array.isArray(parsed.rows) ||
18
+ typeof parsed.$schema !== 'string'
19
+ ) {
20
+ return parsed;
21
+ }
22
+ const flat = {};
23
+ for (const row of parsed.rows) {
24
+ if (row && typeof row.path === 'string' && typeof row.mi === 'number') {
25
+ flat[row.path] = row.mi;
26
+ }
27
+ }
28
+ return flat;
29
+ }
30
+
31
+ /**
32
+ * Loads the current maintainability baseline from disk. The on-disk path is
33
+ * resolved by the caller via {@link getBaselines}; passing it explicitly
34
+ * removes the silent-default behaviour the framework dropped in Epic #730
35
+ * Story 5.5.
36
+ *
37
+ * @param {string} baselinePath Repo-relative or absolute path to the baseline
38
+ * JSON. Required.
39
+ * @returns {Record<string, number>}
40
+ */
41
+ export function getBaseline(baselinePath) {
42
+ if (typeof baselinePath !== 'string' || baselinePath.length === 0) {
43
+ throw new TypeError(
44
+ 'maintainability-utils.getBaseline: baselinePath is required (Epic #730 ' +
45
+ 'Story 5.5 — callers resolve the path via getBaselines(config).maintainability.path).',
46
+ );
47
+ }
48
+ const abs = path.isAbsolute(baselinePath)
49
+ ? baselinePath
50
+ : path.resolve(process.cwd(), baselinePath);
51
+ if (!fs.existsSync(abs)) return {};
52
+ try {
53
+ const parsed = JSON.parse(fs.readFileSync(abs, 'utf-8'));
54
+ return projectMaintainabilityEnvelopeToFlat(parsed);
55
+ } catch (err) {
56
+ Logger.warn(`[Maintainability] Failed to parse baseline: ${err.message}`);
57
+ return {};
58
+ }
59
+ }
@@ -0,0 +1,37 @@
1
+ import path from 'node:path';
2
+ import {
3
+ write as writeBaselineEnvelope,
4
+ writeFile as writeBaselineFile,
5
+ } from './writer.js';
6
+
7
+ /**
8
+ * Saves a new maintainability baseline to disk at `baselinePath`.
9
+ *
10
+ * Accepts the legacy flat `{ path: mi }` shape for backwards compatibility
11
+ * with existing callers (`regenerateMainFromTree`, refresh helpers). The
12
+ * map is transformed into the canonical envelope shape (`$schema`,
13
+ * `kernelVersion`, `generatedAt`, `rollup`, `rows`) via the shared
14
+ * `lib/baselines/writer.js` pipeline before being persisted, so every
15
+ * write produces a file that round-trips through `lib/baselines/reader.js`
16
+ * without schema errors.
17
+ *
18
+ * @param {Record<string, number>} baseline path→MI flat map.
19
+ * @param {string} baselinePath Required — caller supplies via getBaselines().
20
+ */
21
+ export function saveBaseline(baseline, baselinePath) {
22
+ if (typeof baselinePath !== 'string' || baselinePath.length === 0) {
23
+ throw new TypeError(
24
+ 'maintainability-utils.saveBaseline: baselinePath is required.',
25
+ );
26
+ }
27
+ const abs = path.isAbsolute(baselinePath)
28
+ ? baselinePath
29
+ : path.resolve(process.cwd(), baselinePath);
30
+
31
+ const rows = Object.entries(baseline ?? {}).map(([p, mi]) => ({
32
+ path: p,
33
+ mi,
34
+ }));
35
+ const envelope = writeBaselineEnvelope({ kind: 'maintainability', rows });
36
+ writeBaselineFile(abs, envelope);
37
+ }
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Every legacy baseline-refresh script (`update-crap-baseline.js`,
5
5
  * `update-maintainability-baseline.js`, `lib/coverage-baseline.js`,
6
- * `lib/auto-refresh-baselines.js`) used to assemble its own envelope and
6
+ * the auto-refresh evaluator, now inside `auto-refresh-runner.js`) used to assemble its own envelope and
7
7
  * call `fs.writeFileSync`. That meant the path canonicalisation, rollup
8
8
  * math, kernel-version stamping, and JSON-serialisation conventions were
9
9
  * duplicated five-ish times, each with subtly different rules. The
@@ -13,7 +13,7 @@
13
13
  * The verification is **static**: we inspect `package.json` for a known BDD
14
14
  * runner dependency, and consult a small lookup table of which runners
15
15
  * support which pending/skip tag. We do not boot the runner. This keeps
16
- * `/epic-plan` Phase 7 hermetic and offline.
16
+ * `/plan` Phase 7 hermetic and offline.
17
17
  *
18
18
  * **Workspace awareness (Story #2956).** In a pnpm / npm / yarn monorepo the
19
19
  * BDD runner is rarely a root devDependency — it lives in the workspace
@@ -1,5 +1,5 @@
1
1
  /**
2
- * bdd-scenario-scanner.js — Gherkin scenario index for /epic-plan Phase 7.
2
+ * bdd-scenario-scanner.js — Gherkin scenario index for /plan Phase 7.
3
3
  *
4
4
  * Story #2637 (sibling to #2634 codebase-snapshot, #2635 spec-freshness,
5
5
  * #2636 file-assumption gate). The Acceptance Engineer step of
@@ -7,7 +7,7 @@
7
7
  * alone — it never inspects the consumer project's existing `.feature`
8
8
  * files. Planned ACs frequently duplicate scenarios that already exist or
9
9
  * re-specify behaviour the codebase already proves; the duplication is
10
- * only discovered (at best) during `/story-deliver` or (at worst) after
10
+ * only discovered (at best) during `/deliver` or (at worst) after
11
11
  * a redundant PR ships.
12
12
  *
13
13
  * `scanBddScenarios` walks every configured feature root, parses each
@@ -20,7 +20,7 @@
20
20
  * have a matching scenario.
21
21
  *
22
22
  * Determinism is load-bearing: the matcher is keyword-based, not
23
- * embedding-based, so re-running `/epic-plan` against the same
23
+ * embedding-based, so re-running `/plan` against the same
24
24
  * acceptance spec produces the same disposition annotations.
25
25
  */
26
26
 
@@ -15,7 +15,7 @@
15
15
  *
16
16
  * All three shapes are relocated under `<repoRoot>/temp/epic/<id>/baselines/`,
17
17
  * where they inherit the existing per-epic temp-tree cleanup contract:
18
- * `/epic-deliver` reaps `temp/epic/<id>/` on merge, so the ratchet snapshots
18
+ * `/deliver` reaps `temp/epic/<id>/` on merge, so the ratchet snapshots
19
19
  * are ephemeral scratch state — never committed, no manual prune.
20
20
  *
21
21
  * The main-tracked `baselines/{maintainability,crap}.json` files are NOT
@@ -7,7 +7,7 @@
7
7
  * - `enforce_admins: true` — admins do not bypass the prGate suite.
8
8
  * - `required_pull_request_reviews.required_approving_review_count: 0` —
9
9
  * CI is the gate; the operator monitors and iterates the open PR
10
- * to green via `/epic-deliver`'s Phase 7 watch loop.
10
+ * to green via `/deliver`'s Phase 7 watch loop.
11
11
  *
12
12
  * Behaviour rules
13
13
  * ---------------
@@ -14,7 +14,7 @@
14
14
  * `--full-scope` so a self-diff doesn't degrade to "no files in diff".
15
15
  *
16
16
  * 2. **Pass `--epic-ref` where the firing site is Epic-aware.** Inside
17
- * `/story-deliver` the close-validation chain already threads
17
+ * `/deliver` the close-validation chain already threads
18
18
  * `--epic-ref epic/<id>`; on CI the equivalent surface is the PR's
19
19
  * base branch. The template wires `--epic-ref ${EPIC_REF}` through an
20
20
  * env var the workflow computes from `github.head_ref` (story-N
@@ -112,8 +112,8 @@ export function buildManualInstructions({ stagePaths, baseBranch }) {
112
112
  ` git push -u origin ${baseBranch}`,
113
113
  '',
114
114
  'Story delivery runs in git worktrees that check out tracked files only,',
115
- 'so the .agents/ wiring MUST be committed before any /story-deliver or',
116
- '/epic-deliver run — otherwise the worktree has no scripts and breaks.',
115
+ 'so the .agents/ wiring MUST be committed before any /deliver or',
116
+ '/deliver run — otherwise the worktree has no scripts and breaks.',
117
117
  ].join('\n');
118
118
  }
119
119