mandrel 1.94.0 → 2.0.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 (393) hide show
  1. package/.agents/README.md +59 -73
  2. package/.agents/agents/story-worker.md +12 -13
  3. package/.agents/docs/SDLC.md +489 -1285
  4. package/.agents/docs/agentrc-reference.json +177 -67
  5. package/.agents/docs/configuration.md +104 -138
  6. package/.agents/docs/execution-reference.md +17 -20
  7. package/.agents/docs/quality-gates.md +13 -19
  8. package/.agents/docs/workflows.md +3 -3
  9. package/.agents/instructions.md +70 -81
  10. package/.agents/rules/ci-remediation.md +8 -12
  11. package/.agents/rules/git-conventions-reference.md +6 -7
  12. package/.agents/rules/git-conventions.md +16 -22
  13. package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
  14. package/.agents/schemas/agentrc.schema.json +54 -214
  15. package/.agents/schemas/lifecycle/ledger-record.schema.json +1 -1
  16. package/.agents/schemas/lifecycle/retro.end.schema.json +1 -1
  17. package/.agents/schemas/risk-verdict.schema.json +0 -13
  18. package/.agents/scripts/analyze-execution.js +1 -1
  19. package/.agents/scripts/audit-to-stories.js +7 -7
  20. package/.agents/scripts/boot-sweep.js +1 -1
  21. package/.agents/scripts/check-lifecycle-lint.js +6 -9
  22. package/.agents/scripts/check-prepush-recovery.js +1 -1
  23. package/.agents/scripts/cleanup-repo-test-temp.js +6 -1
  24. package/.agents/scripts/lib/Logger.js +6 -10
  25. package/.agents/scripts/lib/audit-suite/runner.js +2 -2
  26. package/.agents/scripts/lib/audit-suite/selector.js +5 -5
  27. package/.agents/scripts/lib/audit-to-stories/{seed-epic-from-findings.js → seed-from-findings.js} +9 -9
  28. package/.agents/scripts/lib/baselines/kernel.js +206 -18
  29. package/.agents/scripts/lib/baselines/kinds/maintainability.js +0 -4
  30. package/.agents/scripts/lib/baselines/reader.js +1 -6
  31. package/.agents/scripts/lib/bdd-runner-detect.js +5 -9
  32. package/.agents/scripts/lib/bootstrap/issue-forms-template.js +32 -33
  33. package/.agents/scripts/lib/checks/core-bare-clean.js +2 -2
  34. package/.agents/scripts/lib/checks/index.js +2 -1
  35. package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +23 -21
  36. package/.agents/scripts/lib/cli/standard-args.js +13 -22
  37. package/.agents/scripts/lib/cli-args.js +16 -7
  38. package/.agents/scripts/lib/close-validation/gates.js +2 -2
  39. package/.agents/scripts/lib/config/ci.js +6 -31
  40. package/.agents/scripts/lib/config/delivery-routing.js +45 -29
  41. package/.agents/scripts/lib/config/explain.js +55 -36
  42. package/.agents/scripts/lib/config/limits.js +17 -58
  43. package/.agents/scripts/lib/config/paths.js +0 -2
  44. package/.agents/scripts/lib/config/quality.js +1 -1
  45. package/.agents/scripts/lib/config/runners.js +17 -50
  46. package/.agents/scripts/lib/config/temp-paths.js +19 -14
  47. package/.agents/scripts/lib/config/worktree-isolation.js +0 -5
  48. package/.agents/scripts/lib/config-resolver.js +2 -7
  49. package/.agents/scripts/lib/config-settings-schema-delivery.js +24 -148
  50. package/.agents/scripts/lib/config-settings-schema-quality.js +8 -14
  51. package/.agents/scripts/lib/config-settings-schema.js +52 -38
  52. package/.agents/scripts/lib/dependency-parser.js +3 -2
  53. package/.agents/scripts/lib/doc-tiers.js +2 -2
  54. package/.agents/scripts/lib/duplicate-search.js +211 -41
  55. package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +1 -1
  56. package/.agents/scripts/lib/findings/promote-finding.js +5 -5
  57. package/.agents/scripts/lib/framework-version.js +2 -3
  58. package/.agents/scripts/lib/git-branch-cleanup.js +1 -10
  59. package/.agents/scripts/lib/git-branch-lifecycle.js +17 -22
  60. package/.agents/scripts/lib/git-utils.js +32 -6
  61. package/.agents/scripts/lib/github/framework-repo.js +6 -0
  62. package/.agents/scripts/lib/label-constants.js +10 -23
  63. package/.agents/scripts/lib/label-taxonomy.js +9 -43
  64. package/.agents/scripts/lib/observability/active-story-env.js +1 -1
  65. package/.agents/scripts/lib/observability/hook-heartbeat.js +20 -52
  66. package/.agents/scripts/lib/observability/source-classifier.js +3 -3
  67. package/.agents/scripts/lib/onboard/init-tail.js +1 -3
  68. package/.agents/scripts/lib/orchestration/audit-lens-routing.js +128 -0
  69. package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +8 -5
  70. package/.agents/scripts/lib/orchestration/ceremony-routing.js +83 -20
  71. package/.agents/scripts/lib/orchestration/code-review.js +20 -268
  72. package/.agents/scripts/lib/orchestration/column-sync.js +1 -1
  73. package/.agents/scripts/lib/orchestration/consolidation-precondition.js +1 -1
  74. package/.agents/scripts/lib/orchestration/context-envelope.js +2 -5
  75. package/.agents/scripts/lib/orchestration/docs-digest.js +8 -8
  76. package/.agents/scripts/lib/orchestration/file-assumptions.js +7 -13
  77. package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +1 -1
  78. package/.agents/scripts/lib/orchestration/lifecycle/emit-loop-tick.js +8 -8
  79. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +2 -2
  80. package/.agents/scripts/lib/orchestration/lifecycle/ledger-writer.js +6 -3
  81. package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +17 -43
  82. package/.agents/scripts/lib/orchestration/lint-baseline-service.js +4 -4
  83. package/.agents/scripts/lib/orchestration/merge-block-class.js +1 -1
  84. package/.agents/scripts/lib/orchestration/phase-runner.js +3 -2
  85. package/.agents/scripts/lib/orchestration/plan-context.js +248 -266
  86. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +1 -1
  87. package/.agents/scripts/lib/orchestration/plan-navigation.js +92 -0
  88. package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +61 -0
  89. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +97 -0
  90. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +223 -854
  91. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +361 -0
  92. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +35 -108
  93. package/.agents/scripts/lib/orchestration/plan-reachability.js +9 -14
  94. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +1 -1
  95. package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/authoring-context.js +13 -13
  96. package/.agents/scripts/lib/orchestration/planning/decomposer-context.js +27 -0
  97. package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/risk-verdict.js +3 -4
  98. package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +2 -2
  99. package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +8 -20
  100. package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +3 -2
  101. package/.agents/scripts/lib/orchestration/pr-base-guard.js +18 -28
  102. package/.agents/scripts/lib/orchestration/preflight-cache.js +5 -5
  103. package/.agents/scripts/lib/orchestration/remote-verifier.js +1 -1
  104. package/.agents/scripts/lib/orchestration/resolve-plan-run.js +155 -0
  105. package/.agents/scripts/lib/orchestration/resolves-token.js +1 -1
  106. package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +8 -8
  107. package/.agents/scripts/lib/orchestration/retro-proposals.js +140 -79
  108. package/.agents/scripts/lib/orchestration/review-depth.js +26 -12
  109. package/.agents/scripts/lib/orchestration/review-providers/codex.js +2 -2
  110. package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +21 -56
  111. package/.agents/scripts/lib/orchestration/run-epilogue.js +426 -0
  112. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +1 -1
  113. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +95 -41
  114. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +16 -13
  115. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +40 -0
  116. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +11 -3
  117. package/.agents/scripts/lib/orchestration/spec-freshness.js +14 -205
  118. package/.agents/scripts/lib/orchestration/spec-section-validator.js +4 -5
  119. package/.agents/scripts/lib/orchestration/spec-spill.js +60 -0
  120. package/.agents/scripts/lib/orchestration/split-policy-validator.js +188 -0
  121. package/.agents/scripts/lib/orchestration/story-close/emit-blocked.js +49 -0
  122. package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +15 -12
  123. package/.agents/scripts/lib/orchestration/story-follow-ups.js +237 -0
  124. package/.agents/scripts/lib/orchestration/story-init-remote.js +47 -0
  125. package/.agents/scripts/lib/orchestration/story-plan-state.js +48 -0
  126. package/.agents/scripts/lib/orchestration/{epic-runner → story-progress}/story-run-progress-writer.js +3 -3
  127. package/.agents/scripts/lib/orchestration/structured-comment-parser.js +1 -1
  128. package/.agents/scripts/lib/orchestration/task-body-validator.js +8 -18
  129. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +11 -61
  130. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +189 -373
  131. package/.agents/scripts/lib/orchestration/ticket-validator.js +2 -7
  132. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +0 -25
  133. package/.agents/scripts/lib/orchestration/ticketing/reads.js +29 -26
  134. package/.agents/scripts/lib/orchestration/ticketing/transition.js +5 -5
  135. package/.agents/scripts/lib/planning-corpus.js +16 -11
  136. package/.agents/scripts/lib/preflight-runner.js +2 -2
  137. package/.agents/scripts/lib/qa/coverage-verdict.js +5 -5
  138. package/.agents/scripts/lib/single-story/confirm-merge-follow-ups.js +36 -0
  139. package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +1 -1
  140. package/.agents/scripts/lib/story-adjacency.js +11 -14
  141. package/.agents/scripts/lib/story-body/story-body.js +124 -70
  142. package/.agents/scripts/lib/story-plan.js +2 -4
  143. package/.agents/scripts/lib/templates/decomposer-prompts.js +46 -45
  144. package/.agents/scripts/lib/templates/spec-author-prompts.js +47 -45
  145. package/.agents/scripts/lib/{epic-body-sections.js → ticket-body-sections.js} +26 -26
  146. package/.agents/scripts/lib/validation-evidence.js +1 -1
  147. package/.agents/scripts/lib/wave-runner/ready-set.js +6 -6
  148. package/.agents/scripts/lib/workspace-provisioner.js +1 -1
  149. package/.agents/scripts/lib/worktree/lifecycle/reap.js +5 -7
  150. package/.agents/scripts/lint-issue-body.js +71 -40
  151. package/.agents/scripts/mandrel-update-preflight.js +1 -1
  152. package/.agents/scripts/notify.js +4 -3
  153. package/.agents/scripts/plan-context.js +64 -74
  154. package/.agents/scripts/plan-persist.js +121 -280
  155. package/.agents/scripts/plan-run-epilogue.js +97 -0
  156. package/.agents/scripts/providers/github/issues.js +17 -33
  157. package/.agents/scripts/providers/github/mappers.js +0 -12
  158. package/.agents/scripts/providers/github/tickets.js +2 -5
  159. package/.agents/scripts/resolve-plan-run.js +117 -0
  160. package/.agents/scripts/signals-view.js +24 -19
  161. package/.agents/scripts/single-story-close.js +11 -14
  162. package/.agents/scripts/single-story-confirm-merge.js +39 -23
  163. package/.agents/scripts/single-story-init.js +29 -20
  164. package/.agents/scripts/stories-wave-tick.js +6 -6
  165. package/.agents/scripts/story-plan.js +26 -47
  166. package/.agents/scripts/update-ticket-state.js +6 -15
  167. package/.agents/skills/core/analyze-execution/SKILL.md +21 -18
  168. package/.agents/skills/core/idea-refinement/SKILL.md +6 -6
  169. package/.agents/skills/core/scope-triage/SKILL.md +28 -172
  170. package/.agents/skills/skills.index.json +3 -43
  171. package/.agents/starter-agentrc.json +0 -5
  172. package/.agents/templates/agent-protocol.md +9 -10
  173. package/.agents/workflows/audit-architecture.md +3 -3
  174. package/.agents/workflows/audit-clean-code.md +3 -3
  175. package/.agents/workflows/audit-dependencies.md +3 -3
  176. package/.agents/workflows/audit-devops.md +3 -3
  177. package/.agents/workflows/audit-documentation.md +5 -5
  178. package/.agents/workflows/audit-lighthouse.md +3 -3
  179. package/.agents/workflows/audit-navigability.md +3 -2
  180. package/.agents/workflows/audit-performance.md +3 -3
  181. package/.agents/workflows/audit-privacy.md +3 -3
  182. package/.agents/workflows/audit-quality.md +3 -3
  183. package/.agents/workflows/audit-security.md +3 -3
  184. package/.agents/workflows/audit-seo.md +3 -3
  185. package/.agents/workflows/audit-sre.md +3 -3
  186. package/.agents/workflows/audit-to-stories.md +20 -20
  187. package/.agents/workflows/audit-ux-ui.md +3 -3
  188. package/.agents/workflows/deliver.md +122 -174
  189. package/.agents/workflows/git-cleanup.md +3 -4
  190. package/.agents/workflows/helpers/_merge-conflict-template.md +1 -1
  191. package/.agents/workflows/helpers/acceptance-self-eval.md +16 -29
  192. package/.agents/workflows/helpers/code-review.md +70 -193
  193. package/.agents/workflows/helpers/{single-story-deliver-reference.md → deliver-story-reference.md} +12 -14
  194. package/.agents/workflows/helpers/{single-story-deliver.md → deliver-story.md} +113 -139
  195. package/.agents/workflows/helpers/diagnose.md +10 -10
  196. package/.agents/workflows/helpers/parallel-tooling.md +1 -1
  197. package/.agents/workflows/helpers/signals.md +16 -16
  198. package/.agents/workflows/helpers/worktree-lifecycle.md +48 -64
  199. package/.agents/workflows/mandrel-update.md +2 -1
  200. package/.agents/workflows/plan.md +112 -145
  201. package/.agents/workflows/qa-assist.md +24 -30
  202. package/.agents/workflows/qa-explore.md +29 -38
  203. package/.agents/workflows/qa-run.md +2 -2
  204. package/README.md +9 -8
  205. package/docs/CHANGELOG.md +30 -0
  206. package/lib/migrations/index.js +6 -5
  207. package/package.json +2 -2
  208. package/.agents/agents/retro.md +0 -42
  209. package/.agents/personas/architect.md +0 -113
  210. package/.agents/personas/devops-engineer.md +0 -38
  211. package/.agents/personas/engineer.md +0 -33
  212. package/.agents/personas/project-manager.md +0 -114
  213. package/.agents/personas/qa-engineer.md +0 -95
  214. package/.agents/personas/security-engineer.md +0 -111
  215. package/.agents/personas/technical-writer.md +0 -101
  216. package/.agents/schemas/dispatch-manifest.json +0 -232
  217. package/.agents/schemas/epic-spec.schema.json +0 -153
  218. package/.agents/schemas/lifecycle/slice.end.schema.json +0 -21
  219. package/.agents/schemas/lifecycle/slice.heartbeat.schema.json +0 -20
  220. package/.agents/schemas/lifecycle/slice.start.schema.json +0 -17
  221. package/.agents/scripts/acceptance-spec-reconciler.js +0 -642
  222. package/.agents/scripts/bookkeeping-reconcile.js +0 -117
  223. package/.agents/scripts/dispatcher.js +0 -295
  224. package/.agents/scripts/epic-audit-prepare.js +0 -497
  225. package/.agents/scripts/epic-audit-recheck.js +0 -274
  226. package/.agents/scripts/epic-deliver-note-intervention.js +0 -192
  227. package/.agents/scripts/epic-deliver-preflight.js +0 -462
  228. package/.agents/scripts/epic-deliver-prepare.js +0 -852
  229. package/.agents/scripts/epic-execute-record-wave.js +0 -449
  230. package/.agents/scripts/epic-plan-clarity.js +0 -211
  231. package/.agents/scripts/epic-plan-healthcheck.js +0 -581
  232. package/.agents/scripts/epic-reconcile.js +0 -625
  233. package/.agents/scripts/lib/baseline-snapshot.js +0 -979
  234. package/.agents/scripts/lib/checks/epic-merge-lock-stale.js +0 -54
  235. package/.agents/scripts/lib/checks/stale-origin-epic.js +0 -49
  236. package/.agents/scripts/lib/config/lifecycle.js +0 -40
  237. package/.agents/scripts/lib/config/preflight.js +0 -58
  238. package/.agents/scripts/lib/config/retro.js +0 -77
  239. package/.agents/scripts/lib/epic-merge-lock.js +0 -322
  240. package/.agents/scripts/lib/epic-plan-clarity.js +0 -181
  241. package/.agents/scripts/lib/epic-plan-ideation.js +0 -261
  242. package/.agents/scripts/lib/orchestration/context-hydration-engine.js +0 -539
  243. package/.agents/scripts/lib/orchestration/deliver-route.js +0 -173
  244. package/.agents/scripts/lib/orchestration/dispatch-engine.js +0 -134
  245. package/.agents/scripts/lib/orchestration/dispatch-pipeline.js +0 -183
  246. package/.agents/scripts/lib/orchestration/epic-cleanup.js +0 -801
  247. package/.agents/scripts/lib/orchestration/epic-deliver-lease-guard.js +0 -310
  248. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/context.js +0 -163
  249. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/creation.js +0 -140
  250. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/dag.js +0 -64
  251. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/diagnostics.js +0 -72
  252. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +0 -156
  253. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist.js +0 -345
  254. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +0 -41
  255. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/reconcile-spawn.js +0 -86
  256. package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +0 -391
  257. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/drain.js +0 -94
  258. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +0 -236
  259. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +0 -307
  260. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-freshness.js +0 -117
  261. package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +0 -117
  262. package/.agents/scripts/lib/orchestration/epic-run-state-store.js +0 -621
  263. package/.agents/scripts/lib/orchestration/epic-runner/concurrency-gate.js +0 -186
  264. package/.agents/scripts/lib/orchestration/epic-runner/deliver-phases.js +0 -50
  265. package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +0 -129
  266. package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +0 -103
  267. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/composition.js +0 -267
  268. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/signals.js +0 -210
  269. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/transport.js +0 -238
  270. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/_bullet-format.js +0 -32
  271. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/component-drift.js +0 -203
  272. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/crap-drift.js +0 -227
  273. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/maintainability-drift.js +0 -117
  274. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/stalled-worktree.js +0 -37
  275. package/.agents/scripts/lib/orchestration/epic-runner/story-launcher.js +0 -127
  276. package/.agents/scripts/lib/orchestration/epic-runner/sub-agent-return.js +0 -276
  277. package/.agents/scripts/lib/orchestration/epic-runner/wave-scheduler.js +0 -66
  278. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-apply.js +0 -789
  279. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +0 -676
  280. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-discriminator.js +0 -389
  281. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-format.js +0 -230
  282. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-ops.js +0 -361
  283. package/.agents/scripts/lib/orchestration/finalize/open-or-locate-pr.js +0 -306
  284. package/.agents/scripts/lib/orchestration/finalize/post-handoff-comment.js +0 -489
  285. package/.agents/scripts/lib/orchestration/finalize/sanitize-skip-ci.js +0 -88
  286. package/.agents/scripts/lib/orchestration/lifecycle/emit-slice-lifecycle.js +0 -270
  287. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-dispatch-end.js +0 -147
  288. package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +0 -465
  289. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +0 -501
  290. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +0 -984
  291. package/.agents/scripts/lib/orchestration/lifecycle/listeners/branch-cleaner.js +0 -264
  292. package/.agents/scripts/lib/orchestration/lifecycle/listeners/checkpoint-pointer-writer.js +0 -284
  293. package/.agents/scripts/lib/orchestration/lifecycle/listeners/cleaner.js +0 -355
  294. package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +0 -673
  295. package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +0 -378
  296. package/.agents/scripts/lib/orchestration/lifecycle/listeners/intervention-recorder.js +0 -140
  297. package/.agents/scripts/lib/orchestration/lifecycle/listeners/label-transitioner.js +0 -144
  298. package/.agents/scripts/lib/orchestration/lifecycle/listeners/notify-dispatcher.js +0 -174
  299. package/.agents/scripts/lib/orchestration/manifest-builder.js +0 -222
  300. package/.agents/scripts/lib/orchestration/plan-persist/amend.js +0 -359
  301. package/.agents/scripts/lib/orchestration/plan-persist/delivery-mode.js +0 -127
  302. package/.agents/scripts/lib/orchestration/post-merge-pipeline.js +0 -205
  303. package/.agents/scripts/lib/orchestration/recurring-failure-detector.js +0 -152
  304. package/.agents/scripts/lib/orchestration/retro/phases/checks.js +0 -94
  305. package/.agents/scripts/lib/orchestration/retro/phases/compose-body.js +0 -571
  306. package/.agents/scripts/lib/orchestration/retro/phases/gather-signals.js +0 -450
  307. package/.agents/scripts/lib/orchestration/retro/phases/post-and-mirror.js +0 -191
  308. package/.agents/scripts/lib/orchestration/retro-heuristics.js +0 -57
  309. package/.agents/scripts/lib/orchestration/retro-runner.js +0 -197
  310. package/.agents/scripts/lib/orchestration/spec-renderer.js +0 -447
  311. package/.agents/scripts/lib/orchestration/story-close/auto-refresh-runner.js +0 -747
  312. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/gate-failure.js +0 -211
  313. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/pre-merge-attribution.js +0 -158
  314. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +0 -446
  315. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/regression-projection.js +0 -297
  316. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/scope-discovery.js +0 -48
  317. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution-wiring.js +0 -67
  318. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution.js +0 -161
  319. package/.agents/scripts/lib/orchestration/story-close/baseline-friction-body.js +0 -117
  320. package/.agents/scripts/lib/orchestration/story-close/cd-out-guard.js +0 -86
  321. package/.agents/scripts/lib/orchestration/story-close/cleanup-reconciler.js +0 -147
  322. package/.agents/scripts/lib/orchestration/story-close/close-inputs.js +0 -142
  323. package/.agents/scripts/lib/orchestration/story-close/comment-bodies.js +0 -62
  324. package/.agents/scripts/lib/orchestration/story-close/merge-runner.js +0 -658
  325. package/.agents/scripts/lib/orchestration/story-close/merge-subject.js +0 -198
  326. package/.agents/scripts/lib/orchestration/story-close/phases/branch-restore.js +0 -105
  327. package/.agents/scripts/lib/orchestration/story-close/phases/close.js +0 -222
  328. package/.agents/scripts/lib/orchestration/story-close/phases/gates.js +0 -292
  329. package/.agents/scripts/lib/orchestration/story-close/phases/locked-pipeline.js +0 -270
  330. package/.agents/scripts/lib/orchestration/story-close/phases/preflight.js +0 -110
  331. package/.agents/scripts/lib/orchestration/story-close/phases/refresh.js +0 -86
  332. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked-emitter.js +0 -112
  333. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked.js +0 -157
  334. package/.agents/scripts/lib/orchestration/story-close/post-merge-close.js +0 -421
  335. package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +0 -302
  336. package/.agents/scripts/lib/orchestration/story-close/shared-checkout-guard.js +0 -163
  337. package/.agents/scripts/lib/orchestration/story-close-recovery.js +0 -690
  338. package/.agents/scripts/lib/orchestration/wave-marker.js +0 -28
  339. package/.agents/scripts/lib/orchestration/wave-record-io.js +0 -218
  340. package/.agents/scripts/lib/orchestration/wave-record-notifications.js +0 -145
  341. package/.agents/scripts/lib/orchestration/wave-record-projection.js +0 -212
  342. package/.agents/scripts/lib/presentation/dispatch-manifest-render.js +0 -111
  343. package/.agents/scripts/lib/presentation/manifest-builder.js +0 -239
  344. package/.agents/scripts/lib/presentation/manifest-formatter.js +0 -242
  345. package/.agents/scripts/lib/presentation/manifest-helpers.js +0 -213
  346. package/.agents/scripts/lib/presentation/manifest-persistence.js +0 -261
  347. package/.agents/scripts/lib/presentation/manifest-procedures.js +0 -55
  348. package/.agents/scripts/lib/presentation/manifest-render-waves.js +0 -306
  349. package/.agents/scripts/lib/presentation/manifest-renderer.js +0 -188
  350. package/.agents/scripts/lib/presentation/manifest-story-views.js +0 -110
  351. package/.agents/scripts/lib/push-epic-retry.js +0 -209
  352. package/.agents/scripts/lib/spec/index.js +0 -36
  353. package/.agents/scripts/lib/spec/loader.js +0 -425
  354. package/.agents/scripts/lib/spec/state.js +0 -208
  355. package/.agents/scripts/lib/story-init/blocker-validator.js +0 -68
  356. package/.agents/scripts/lib/story-init/branch-initializer.js +0 -408
  357. package/.agents/scripts/lib/story-init/context-resolver.js +0 -92
  358. package/.agents/scripts/lib/story-init/donor-precheck.js +0 -207
  359. package/.agents/scripts/lib/story-init/state-transitioner.js +0 -80
  360. package/.agents/scripts/lib/story-init/task-graph-builder.js +0 -124
  361. package/.agents/scripts/lib/story-init/transition-summary.js +0 -34
  362. package/.agents/scripts/lib/test-reserved-epic-temp-ids.js +0 -35
  363. package/.agents/scripts/lib/wave-runner/tick.js +0 -754
  364. package/.agents/scripts/lib/wave-runner/wave-runner-error.js +0 -20
  365. package/.agents/scripts/lifecycle-emit-story-dispatch.js +0 -194
  366. package/.agents/scripts/lifecycle-emit.js +0 -510
  367. package/.agents/scripts/retro-run.js +0 -218
  368. package/.agents/scripts/slice-phase.js +0 -361
  369. package/.agents/scripts/standalone-feedback-rollup.js +0 -188
  370. package/.agents/scripts/story-close.js +0 -294
  371. package/.agents/scripts/story-init.js +0 -599
  372. package/.agents/scripts/story-phase.js +0 -369
  373. package/.agents/scripts/wave-tick.js +0 -464
  374. package/.agents/skills/core/epic-plan-consolidate/SKILL.md +0 -172
  375. package/.agents/skills/core/epic-plan-consolidate/examples.md +0 -51
  376. package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +0 -441
  377. package/.agents/skills/core/epic-plan-decompose-author/examples.md +0 -47
  378. package/.agents/skills/core/epic-plan-premortem/SKILL.md +0 -146
  379. package/.agents/skills/core/epic-plan-premortem/examples.md +0 -53
  380. package/.agents/skills/core/epic-plan-spec-author/SKILL.md +0 -383
  381. package/.agents/skills/core/epic-plan-spec-author/examples.md +0 -91
  382. package/.agents/workflows/helpers/deliver-epic-reference.md +0 -547
  383. package/.agents/workflows/helpers/deliver-epic-single.md +0 -331
  384. package/.agents/workflows/helpers/deliver-epic.md +0 -998
  385. package/.agents/workflows/helpers/deliver-stories.md +0 -450
  386. package/.agents/workflows/helpers/epic-audit.md +0 -189
  387. package/.agents/workflows/helpers/epic-deliver-story.md +0 -436
  388. package/.agents/workflows/helpers/epic-testing.md +0 -125
  389. package/.agents/workflows/helpers/plan-epic-reference.md +0 -160
  390. package/.agents/workflows/helpers/plan-epic.md +0 -353
  391. package/.agents/workflows/helpers/plan-story.md +0 -251
  392. package/.agents/workflows/helpers/scope-triage-gate.md +0 -108
  393. /package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/spec-authoring-grounding.js +0 -0
@@ -1,188 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * standalone-feedback-rollup.js — end-of-run feedback rollup for the
5
- * `/deliver` standalone multi-Story path (Epic #4406 / Story #4416).
6
- *
7
- * The standalone delivery path (`helpers/deliver-stories`) drives one or
8
- * more Epic-free Stories to green, and each per-Story sub-agent appends
9
- * `friction` records to its **standalone** signals stream at
10
- * `temp/standalone/stories/story-<sid>/signals.ndjson` (written via
11
- * `appendSignal({ epicId: null, storyId })`). Before this rollup that
12
- * tree was write-only — nothing ever read it back. This CLI closes the
13
- * gap: it scans the standalone streams for the delivered Story set and
14
- * emits a per-category friction summary that `deliver-stories.md`
15
- * surfaces in its Phase 3 run summary.
16
- *
17
- * Usage:
18
- * node standalone-feedback-rollup.js --stories <id,...>
19
- *
20
- * Contract:
21
- * - Stream paths resolve **exclusively** through the `temp-paths`
22
- * helpers via `forEachLine(null, storyId, cb, config)` — the `null`
23
- * Epic sentinel routes to the standalone tree. No hand-built path
24
- * strings.
25
- * - Aggregates `friction` records by their **top-level** `category`
26
- * (Epic #4406 canonical envelope shape); a record with no category
27
- * buckets under `Unknown`.
28
- * - **Never fails a run.** A missing or empty stream degrades to an
29
- * empty contribution; the CLI always prints a JSON summary and
30
- * exits 0. Observability MUST NOT take down the delivering flow.
31
- *
32
- * Output (stdout, one JSON object):
33
- * {
34
- * "kind": "standalone-feedback-rollup",
35
- * "stories": [<id>, ...],
36
- * "totalFriction": <int>,
37
- * "byCategory": { "<category>": <count>, ... },
38
- * "perStory": { "<id>": { "friction": <int>, "missing": <bool> }, ... }
39
- * }
40
- *
41
- * @see .agents/scripts/lib/observability/signals-writer.js (forEachLine, appendSignal)
42
- * @see .agents/scripts/lib/config/temp-paths.js (signalsFile — null Epic sentinel)
43
- * @see .agents/workflows/helpers/deliver-stories.md (Phase 3 summary wiring)
44
- */
45
-
46
- import { runAsCli } from './lib/cli-utils.js';
47
- import { resolveConfig } from './lib/config-resolver.js';
48
- import { forEachLine } from './lib/observability/signals-writer.js';
49
-
50
- const FRICTION_KIND = 'friction';
51
- const UNKNOWN_CATEGORY = 'Unknown';
52
-
53
- /**
54
- * Parse `--stories <id,...>` into an ordered, de-duplicated array of
55
- * positive-integer Story IDs. Accepts a single comma-separated value or
56
- * repeated `--stories` flags. Non-integer / non-positive tokens are
57
- * rejected so a typo surfaces as an input error rather than a silently
58
- * empty rollup.
59
- *
60
- * @param {string[]} args
61
- * @returns {{ stories: number[] }}
62
- */
63
- export function parseArguments(args) {
64
- const raw = [];
65
- for (let i = 0; i < args.length; i++) {
66
- if (args[i] === '--stories') {
67
- const value = args[++i];
68
- if (typeof value === 'string') {
69
- raw.push(...value.split(','));
70
- }
71
- }
72
- }
73
-
74
- const seen = new Set();
75
- const stories = [];
76
- for (const token of raw) {
77
- const trimmed = token.trim();
78
- if (trimmed.length === 0) continue;
79
- const id = Number(trimmed);
80
- if (!Number.isInteger(id) || id <= 0) {
81
- throw new Error(
82
- `--stories expects comma-separated positive integers; got ${JSON.stringify(trimmed)}`,
83
- );
84
- }
85
- if (seen.has(id)) continue;
86
- seen.add(id);
87
- stories.push(id);
88
- }
89
-
90
- if (stories.length === 0) {
91
- throw new Error(
92
- 'Usage: node standalone-feedback-rollup.js --stories <id,...>',
93
- );
94
- }
95
-
96
- return { stories };
97
- }
98
-
99
- /**
100
- * Read one standalone Story's signals stream and aggregate its `friction`
101
- * records by top-level `category`, mutating the shared `byCategory` tally.
102
- *
103
- * Degrades to a zero contribution on a missing / empty / unreadable
104
- * stream — `forEachLine` already swallows fs + JSON faults and reports a
105
- * missing file via `{ missing: true }` rather than throwing.
106
- *
107
- * @param {number} storyId
108
- * @param {Record<string, number>} byCategory Mutated in place.
109
- * @param {object} config
110
- * @returns {Promise<{ friction: number, missing: boolean }>}
111
- */
112
- async function rollupStory(storyId, byCategory, config) {
113
- let friction = 0;
114
- // `epicId: null` routes forEachLine → signalsFile(null, storyId, config)
115
- // → the standalone tree. Never a hand-built path string.
116
- const result = await forEachLine(
117
- null,
118
- storyId,
119
- (record) => {
120
- if (
121
- record === null ||
122
- typeof record !== 'object' ||
123
- record.kind !== FRICTION_KIND
124
- ) {
125
- return;
126
- }
127
- const category =
128
- typeof record.category === 'string' && record.category.length > 0
129
- ? record.category
130
- : UNKNOWN_CATEGORY;
131
- byCategory[category] = (byCategory[category] ?? 0) + 1;
132
- friction += 1;
133
- },
134
- config,
135
- );
136
-
137
- return { friction, missing: Boolean(result?.missing) };
138
- }
139
-
140
- /**
141
- * Aggregate friction across every named standalone Story stream.
142
- *
143
- * @param {number[]} stories
144
- * @param {object} [config]
145
- * @returns {Promise<{
146
- * kind: string,
147
- * stories: number[],
148
- * totalFriction: number,
149
- * byCategory: Record<string, number>,
150
- * perStory: Record<string, { friction: number, missing: boolean }>,
151
- * }>}
152
- */
153
- export async function buildRollup(stories, config) {
154
- const byCategory = {};
155
- const perStory = {};
156
- let totalFriction = 0;
157
-
158
- for (const storyId of stories) {
159
- const { friction, missing } = await rollupStory(
160
- storyId,
161
- byCategory,
162
- config,
163
- );
164
- perStory[storyId] = { friction, missing };
165
- totalFriction += friction;
166
- }
167
-
168
- return {
169
- kind: 'standalone-feedback-rollup',
170
- stories,
171
- totalFriction,
172
- byCategory,
173
- perStory,
174
- };
175
- }
176
-
177
- export async function main(args = process.argv.slice(2)) {
178
- const { stories } = parseArguments(args);
179
- const config = resolveConfig();
180
- const summary = await buildRollup(stories, config);
181
- process.stdout.write(`${JSON.stringify(summary, null, 2)}\n`);
182
- return 0;
183
- }
184
-
185
- runAsCli(import.meta.url, main, {
186
- source: 'StandaloneFeedbackRollup',
187
- propagateExitCode: true,
188
- });
@@ -1,294 +0,0 @@
1
- #!/usr/bin/env node
2
- /* node:coverage ignore file */
3
-
4
- /**
5
- * story-close.js — Story Execution Closure (CLI shell).
6
- *
7
- * Thin pipeline that wires the phase modules under
8
- * `lib/orchestration/story-close/phases/`. Each phase runs as a discrete
9
- * step and may short-circuit the pipeline with a `{ status: 'blocked' }`
10
- * envelope. Pipeline shape:
11
- *
12
- * 1. parse + resolveCloseInputs (lib/orchestration/story-close/close-inputs.js)
13
- * 1.5. already-done no-op guard (inline below) — a Story already at
14
- * `agent::done` AND closed short-circuits here so no phase below it
15
- * ever flips the label away from `agent::done` or reopens the issue.
16
- * 2. preflight (phases/preflight.js)
17
- * 3. state-flip → closing (inline helper below)
18
- * 4. capture starting branch (phases/branch-restore.js)
19
- * 5. acquire per-Epic merge lock + run the locked pipeline
20
- * (phases/locked-pipeline.js — gates, refresh, close)
21
- * 6. restore starting branch (finally; phases/branch-restore.js)
22
- *
23
- * Usage: `node story-close.js --story <ID> [--epic <ID>]`. Exit codes:
24
- * 0 ok
25
- * 1 error
26
- * 2 prior-state (pass --resume / --restart) OR preflight refused
27
- *
28
- * @see .agents/workflows/helpers/deliver-stories.md
29
- */
30
-
31
- import { runAsCli } from './lib/cli-utils.js';
32
- import { tempRootFrom } from './lib/config/temp-paths.js';
33
- import { Logger } from './lib/Logger.js';
34
- import { createBus } from './lib/orchestration/lifecycle/bus.js';
35
- import { createLedgerWriter } from './lib/orchestration/lifecycle/ledger-writer.js';
36
- import { checkCdOutGuard } from './lib/orchestration/story-close/cd-out-guard.js';
37
- import { resolveCloseInputs } from './lib/orchestration/story-close/close-inputs.js';
38
- import { withEpicMergeLock } from './lib/orchestration/story-close/merge-runner.js';
39
- import {
40
- captureStartingBranch,
41
- restoreStartingBranch,
42
- } from './lib/orchestration/story-close/phases/branch-restore.js';
43
- import { runStoryCloseLocked } from './lib/orchestration/story-close/phases/locked-pipeline.js';
44
- import {
45
- emitPreflightBlockedResult,
46
- runStoryClosePreflight,
47
- } from './lib/orchestration/story-close/phases/preflight.js';
48
- import { describeAutoRefreshOutcome } from './lib/orchestration/story-close/phases/refresh.js';
49
- import {
50
- renderCoverageTimeoutFrictionBody,
51
- renderSpawnTimeoutFrictionBody,
52
- resolveSpawnTimeoutReason,
53
- } from './lib/orchestration/story-close/phases/timeout-blocked.js';
54
- import {
55
- STATE_LABELS,
56
- transitionTicketState,
57
- } from './lib/orchestration/ticketing.js';
58
- import { PREFLIGHT_REFUSED_EXIT_CODE } from './lib/preflight-runner.js';
59
- import { notify } from './notify.js';
60
-
61
- // Re-exports preserved for historical test imports. Each underlying
62
- // implementation now lives under `phases/`.
63
- export {
64
- captureStartingBranch,
65
- checkCdOutGuard,
66
- describeAutoRefreshOutcome,
67
- renderCoverageTimeoutFrictionBody,
68
- renderSpawnTimeoutFrictionBody,
69
- resolveSpawnTimeoutReason,
70
- restoreStartingBranch,
71
- runStoryClosePreflight,
72
- };
73
-
74
- const progress = Logger.createProgress('story-close', { stderr: true });
75
- const progressLog = (tag, msg) => progress(tag, msg);
76
-
77
- /**
78
- * Best-effort lifecycle-bus wiring. Story #2241 / Task #2247 — bus emits
79
- * land in the Epic-scoped NDJSON ledger so a sub-agent's `story.merged` /
80
- * `story.blocked` records sit alongside the parent runner's `wave.*`.
81
- * A wiring failure logs and returns `null` — the close result must never
82
- * depend on lifecycle observability.
83
- */
84
- function wireLifecycleBus({ epicId, config }) {
85
- try {
86
- const lifecycleBus = createBus();
87
- const tempRoot = tempRootFrom(config);
88
- const ledger = createLedgerWriter({
89
- epicId: Number(epicId),
90
- tempRoot,
91
- });
92
- ledger.register(lifecycleBus);
93
- return lifecycleBus;
94
- } catch (err) {
95
- Logger.warn?.(
96
- `[story-close] ⚠️ lifecycle bus init failed (continuing without emits): ${err?.message ?? err}`,
97
- );
98
- return null;
99
- }
100
- }
101
-
102
- /**
103
- * Phase 3 — flip the Story label to `agent::closing` once preflight has
104
- * passed and before we acquire the per-Epic merge lock. Best-effort.
105
- */
106
- async function transitionToClosing({ provider, storyId, notifyFn }) {
107
- try {
108
- await transitionTicketState(provider, storyId, STATE_LABELS.CLOSING, {
109
- cascade: false,
110
- notify: notifyFn,
111
- });
112
- progress('STATE', `Story #${storyId} → ${STATE_LABELS.CLOSING}`);
113
- } catch (err) {
114
- Logger.warn?.(
115
- `[story-close] failed to flip Story #${storyId} → ${STATE_LABELS.CLOSING}: ${err?.message ?? err}`,
116
- );
117
- }
118
- }
119
-
120
- /** Orchestrate the Story closure. Exported for testing. */
121
- export async function runStoryClose({
122
- storyId: storyIdParam,
123
- epicId: epicIdParam,
124
- skipDashboard: skipDashboardParam,
125
- skipValidation: skipValidationParam,
126
- cwd: cwdParam,
127
- resume: resumeParam,
128
- restart: restartParam,
129
- injectedProvider,
130
- } = {}) {
131
- const resolved = await resolveCloseInputs({
132
- storyIdParam,
133
- epicIdParam,
134
- skipDashboardParam,
135
- skipValidationParam,
136
- cwdParam,
137
- resumeParam,
138
- restartParam,
139
- injectedProvider,
140
- });
141
- const {
142
- storyId,
143
- epicId,
144
- cwd,
145
- worktreePath,
146
- skipDashboard,
147
- skipValidation: skipValidationResolved,
148
- resumeFlag,
149
- restartFlag,
150
- noEvidenceFlag,
151
- config,
152
- provider,
153
- story,
154
- epicBranch,
155
- storyBranch,
156
- } = resolved;
157
-
158
- // Phase 0 — idempotency guard. A re-run against a Story that is already
159
- // fully closed must be a safe no-op. Without this guard, Phase 3 below
160
- // (`transitionToClosing`) unconditionally flips the label to
161
- // `agent::closing` — and `transitionTicketState`
162
- // (lib/orchestration/ticketing/transition.js) unconditionally sends
163
- // `state: 'open'` for any non-`agent::done` target — so re-running close
164
- // against an already-closed Story reopens the GitHub issue and strips
165
- // `agent::done` *before* the post-merge pipeline even starts. If the
166
- // pipeline then throws or a phase silently no-ops (the merge is already
167
- // fully reaped, so there is nothing left to redo), the Story is left
168
- // regressed at `agent::closing`/OPEN instead of a safe no-op.
169
- //
170
- // The "already fully closed" test mirrors the deepest-level guard in the
171
- // post-merge `ticketClosurePhase` (post-merge/phases/ticket-closure.js):
172
- // label `agent::done` AND issue `state === 'closed'`, an AND — never a
173
- // state-alone check. The `state === 'closed'` disjunct is deliberately
174
- // excluded per the hard-won reasoning in
175
- // `lib/single-story/confirm-merge.js`: a Story can arrive here closed at
176
- // the GitHub layer (a `Closes #<id>` PR footer, or a prior close that set
177
- // `state: closed` but was killed before the label flip landed) while its
178
- // label is legitimately still `agent::closing`. Treating that as
179
- // already-done would skip the very `closing → done` re-assertion the
180
- // re-run exists to perform, stranding the label. Requiring BOTH signals
181
- // no-ops only a genuinely finished Story.
182
- const alreadyDone =
183
- Array.isArray(story?.labels) &&
184
- story.labels.includes(STATE_LABELS.DONE) &&
185
- story?.state === 'closed';
186
- if (alreadyDone) {
187
- progress(
188
- 'SKIP',
189
- `Story #${storyId} is already ${STATE_LABELS.DONE} and closed — no-op re-run.`,
190
- );
191
- return {
192
- success: true,
193
- result: {
194
- storyId,
195
- epicId,
196
- action: 'noop',
197
- reason: 'already-done',
198
- merged: true,
199
- },
200
- };
201
- }
202
-
203
- const notifyFn = (ticketId, payload, opts = {}) =>
204
- notify(ticketId, payload, { config, provider, ...opts });
205
-
206
- const bus = wireLifecycleBus({ epicId, config });
207
-
208
- progress('INIT', `Closing Story #${storyId}...`);
209
-
210
- // Phase 2 — preflight (exit-code 2 reservation when refused).
211
- const preflightOutcome = await runStoryClosePreflight({ storyId, cwd });
212
- if (!preflightOutcome.ok) {
213
- const blockedResult = await emitPreflightBlockedResult({
214
- storyId,
215
- preflight: preflightOutcome,
216
- progress,
217
- });
218
- return {
219
- success: false,
220
- result: blockedResult,
221
- exitCode: PREFLIGHT_REFUSED_EXIT_CODE,
222
- };
223
- }
224
-
225
- // Phase 3 — flip Story → `agent::closing`.
226
- await transitionToClosing({ provider, storyId, notifyFn });
227
-
228
- // Phase 4 — capture the starting branch so the `finally` block can
229
- // restore it on any throw inside the merge-lock-protected region.
230
- const startingBranch = captureStartingBranch(cwd);
231
- if (!startingBranch.ok) {
232
- Logger.warn?.(
233
- `[story-close] branch-restore: could not capture starting branch (${startingBranch.reason}); finally-block restore will be skipped.`,
234
- );
235
- }
236
-
237
- // Phase 5 — acquire per-Epic merge lock for the entire close flow.
238
- try {
239
- return await withEpicMergeLock(
240
- epicId,
241
- { repoRoot: cwd, timeoutMs: 60_000, log: progressLog },
242
- () =>
243
- runStoryCloseLocked({
244
- storyId,
245
- epicId,
246
- cwd,
247
- worktreePath,
248
- skipDashboard,
249
- skipValidationParam: skipValidationResolved,
250
- resumeFlag,
251
- restartFlag,
252
- noEvidenceFlag,
253
- config,
254
- provider,
255
- story,
256
- epicBranch,
257
- storyBranch,
258
- notifyFn,
259
- bus,
260
- progress,
261
- progressLog,
262
- }),
263
- );
264
- } finally {
265
- restoreStartingBranch({ cwd, captured: startingBranch });
266
- }
267
- }
268
-
269
- runAsCli(
270
- import.meta.url,
271
- async () => {
272
- const envelope = await runStoryClose();
273
- if (envelope?.exitCode === PREFLIGHT_REFUSED_EXIT_CODE) {
274
- process.exit(PREFLIGHT_REFUSED_EXIT_CODE);
275
- }
276
- // Story #2840 — a blocked envelope (code-review-critical, etc.) carries
277
- // its own exit code so the CLI fails non-zero without losing the
278
- // envelope shape that callers serialise.
279
- if (Number.isInteger(envelope?.exitCode) && envelope.exitCode !== 0) {
280
- process.exit(envelope.exitCode);
281
- }
282
- return envelope;
283
- },
284
- {
285
- source: 'story-close',
286
- onError: (err) => {
287
- // exitCode=2 covers two reservations: dispatchRecovery's
288
- // prior-state refusal AND Story #1289's preflight refusal.
289
- if (err?.exitCode === 2) process.exit(2);
290
- Logger.error(`[phase=fatal] [story-close] ${err.stack || err.message}`);
291
- process.exit(1);
292
- },
293
- },
294
- );