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,292 +0,0 @@
1
- /**
2
- * phases/gates.js — pre-merge gates phase (Story #2460, Epic #2453 —
3
- * CLI thinning pilot).
4
- *
5
- * Runs the close-validation chain (format-autofix → attribution-aware
6
- * baseline gates → maintainability projection) against the Story
7
- * worktree before the merge. Outcomes:
8
- *
9
- * - `{ status: 'ok' }` — gates passed; caller continues.
10
- * - `{ status: 'blocked' }` — baseline drift not attributable
11
- * to the Story; caller emits `emitBaselineBlockedResult`.
12
- * - `{ status: 'blocked-timeout' }` — one of the bounded-timeout
13
- * spawns tripped its watchdog; caller routes through
14
- * `emitSpawnTimeoutBlockedResult`.
15
- *
16
- * Story #2995 split the pre-merge body into a pure summarizer
17
- * (`summarizeGateResults`) plus a side-effecting emitter
18
- * (`emitGateOutcome`). `runPreMergeValidation` is now a thin sequencer:
19
- * it runs the format-autofix and attribution gate side effects, hands
20
- * the raw outcomes to the summarizer, and then routes through the
21
- * emitter. Output is byte-identical to the pre-refactor function.
22
- *
23
- * Public surface:
24
- * - shouldSkipValidation(input)
25
- * - summarizeGateResults(results)
26
- * - emitGateOutcome(summary, ctx)
27
- * - runPreMergeValidation(input)
28
- * - emitBaselineBlockedResult(input)
29
- */
30
-
31
- import { Logger } from '../../../Logger.js';
32
- import { runPreMergeGatesWithAttribution } from '../baseline-attribution-wiring.js';
33
- import { runFormatAutofix, runScopedFormatAutofix } from '../format-autofix.js';
34
- import { emitBlockedCloseResult } from '../merge-runner.js';
35
- import { emitMaintainabilityProjection } from '../pre-merge-validation.js';
36
-
37
- /**
38
- * Format the `{ status: 'blocked' }` result returned by
39
- * `runPreMergeGatesWithAttribution` into the canonical close-result
40
- * envelope + console marker (Story #1124 — non-attributable baseline
41
- * drift).
42
- */
43
- export async function emitBaselineBlockedResult({
44
- storyId,
45
- gateOutcome,
46
- progress: log,
47
- bus = null,
48
- }) {
49
- const nonAttributable = gateOutcome.nonAttributable ?? [];
50
- return emitBlockedCloseResult({
51
- storyId,
52
- phase: 'closing',
53
- reason: 'baseline-drift-not-attributable',
54
- extra: {
55
- nonAttributable,
56
- commentId: gateOutcome.commentId ?? null,
57
- },
58
- bus,
59
- progress: log,
60
- blockedMessage: `Story #${storyId} blocked: baseline drift on ${nonAttributable.length} path(s) not attributable to this Story.`,
61
- logger: Logger,
62
- });
63
- }
64
-
65
- /**
66
- * Compute whether the pre-merge gate chain should be skipped on this
67
- * close. Resume-from-anywhere paths skip; an explicit `--skip-validation`
68
- * also skips.
69
- */
70
- export function shouldSkipValidation({
71
- skipValidationParam,
72
- resumeFromConflict,
73
- resumeFromMerge,
74
- resumeFromPostMerge,
75
- }) {
76
- return (
77
- !!skipValidationParam ||
78
- resumeFromConflict ||
79
- resumeFromMerge ||
80
- resumeFromPostMerge
81
- );
82
- }
83
-
84
- /**
85
- * Pure aggregator over the raw outcomes produced by the close-validation
86
- * side effects (Story #2995 split). Consumes the format-autofix outcome
87
- * and the attribution-aware gate outcome, then classifies the combined
88
- * result into a verdict + blocker/advisory lists.
89
- *
90
- * Verdicts:
91
- * - `'blocked-timeout'` — format-autofix spawn watchdog tripped, or the
92
- * attribution gate chain itself returned `blocked-timeout`. The
93
- * originating outcome is carried on the blocker entry so the emitter
94
- * can return the canonical envelope verbatim.
95
- * - `'blocked'` — attribution gate chain reported baseline
96
- * drift not attributable to the Story.
97
- * - `'ok'` — gates passed; the maintainability projection
98
- * should be emitted and the gate envelope returned to the caller.
99
- *
100
- * Inputs are tolerated as `null`/`undefined` so callers that only ran a
101
- * subset of the chain (resume paths, partial mocks) get a deterministic
102
- * `'ok'` verdict instead of a thrown error.
103
- *
104
- * NO I/O. NO logger calls. NO label transitions. This function is the
105
- * unit-testable shape of the pre-merge decision.
106
- */
107
- export function summarizeGateResults({
108
- formatAutofixOutcome = null,
109
- gateOutcome = null,
110
- } = {}) {
111
- if (formatAutofixOutcome?.timedOut) {
112
- return {
113
- verdict: 'blocked-timeout',
114
- blockers: [
115
- {
116
- kind: 'format-autofix-timeout',
117
- formatAutofixOutcome,
118
- },
119
- ],
120
- advisories: [],
121
- };
122
- }
123
- if (gateOutcome?.status === 'blocked') {
124
- return {
125
- verdict: 'blocked',
126
- blockers: [
127
- {
128
- kind: 'baseline-drift',
129
- gateOutcome,
130
- },
131
- ],
132
- advisories: [],
133
- };
134
- }
135
- if (gateOutcome?.status === 'blocked-timeout') {
136
- return {
137
- verdict: 'blocked-timeout',
138
- blockers: [
139
- {
140
- kind: 'gate-timeout',
141
- gateOutcome,
142
- },
143
- ],
144
- advisories: [],
145
- };
146
- }
147
- return {
148
- verdict: 'ok',
149
- blockers: [],
150
- advisories: [],
151
- gateOutcome,
152
- };
153
- }
154
-
155
- /**
156
- * Side-effecting emitter: consumes a `summarizeGateResults` summary plus
157
- * the orchestration context and performs the actions implied by the
158
- * verdict (Story #2995 split).
159
- *
160
- * - `blocked-timeout` from format-autofix → return the canonical
161
- * timeout envelope built from `formatAutofixOutcome`.
162
- * - `blocked` / `blocked-timeout` from the attribution gate chain →
163
- * return the gate outcome verbatim (caller routes through
164
- * `emitBaselineBlockedResult` / spawn-timeout handler).
165
- * - `ok` → emit the maintainability projection (Logger side effect) and
166
- * return the gate outcome verbatim.
167
- *
168
- * Maintaining output byte-equivalence with the pre-refactor function is
169
- * the contract: the gate-outcome objects flow through unchanged.
170
- */
171
- export function emitGateOutcome(summary, ctx) {
172
- if (summary.verdict === 'blocked-timeout') {
173
- const blocker = summary.blockers[0];
174
- if (blocker?.kind === 'format-autofix-timeout') {
175
- const fao = blocker.formatAutofixOutcome;
176
- return {
177
- status: 'blocked-timeout',
178
- gateName: 'format-autofix',
179
- exitCode: fao.exitCode ?? 124,
180
- spawnCmd: fao.writeCmdString ?? null,
181
- timeoutMs: fao.timeoutMs ?? null,
182
- };
183
- }
184
- return blocker?.gateOutcome ?? null;
185
- }
186
- if (summary.verdict === 'blocked') {
187
- return summary.blockers[0]?.gateOutcome ?? null;
188
- }
189
- // verdict === 'ok'
190
- emitMaintainabilityProjection({
191
- cwd: ctx.cwd,
192
- epicBranch: ctx.epicBranch,
193
- storyBranch: ctx.storyBranch,
194
- config: ctx.config,
195
- logger: Logger,
196
- });
197
- return summary.gateOutcome;
198
- }
199
-
200
- /**
201
- * Run the close-validation gate chain against the Story worktree. The
202
- * format-autofix self-heal step runs first (Story #2165 — bounded
203
- * timeout) and short-circuits the chain when the formatter spawn is
204
- * SIGKILLed. Otherwise the attribution-aware gate chain runs.
205
- *
206
- * Story #2995 split this body into a pure summarizer
207
- * (`summarizeGateResults`) + a side-effecting emitter
208
- * (`emitGateOutcome`). This function is now a thin sequencer.
209
- *
210
- * Returns the gate envelope verbatim so the caller can route by
211
- * `status` (`blocked` vs `blocked-timeout` vs `ok`).
212
- */
213
- export async function runPreMergeValidation({
214
- cwd,
215
- worktreePath,
216
- epicBranch,
217
- storyBranch,
218
- config,
219
- storyId,
220
- epicId,
221
- noEvidenceFlag,
222
- phaseTimer,
223
- provider,
224
- bus = null,
225
- cycleState = null,
226
- }) {
227
- // Story #2533: scope-narrowed biome-format auto-apply on the Epic→Story
228
- // diff. The scoped step folds format drift introduced by Story commits
229
- // into a dedicated `fix(story-close):` commit on the Story branch and
230
- // emits Logger.warn naming the auto-fixed files.
231
- //
232
- // Story #3407: when branch refs are available, this scoped step is the
233
- // formatter autofix path. Falling through to the whole-tree `.` formatter
234
- // from inside `.worktrees/story-*` is fragile against consumer ignore
235
- // globs that exclude `.worktrees`, so the broad autofix is retained only
236
- // for resume/legacy callers that cannot supply a diff anchor.
237
- let formatAutofixOutcome = null;
238
- if (epicBranch && storyBranch) {
239
- // Story #3907 — pass `worktreePath` so the formatter writes + the scoped
240
- // `fix(story-close):` commit land in the Story worktree (where
241
- // `story-<id>` is checked out), never the main checkout's current branch.
242
- formatAutofixOutcome = runScopedFormatAutofix({
243
- cwd,
244
- worktreePath,
245
- storyId,
246
- epicBranch,
247
- storyBranch,
248
- config,
249
- logger: Logger,
250
- });
251
- } else {
252
- formatAutofixOutcome = runFormatAutofix({
253
- cwd,
254
- storyId,
255
- config,
256
- logger: Logger,
257
- });
258
- }
259
- if (formatAutofixOutcome?.timedOut) {
260
- const summary = summarizeGateResults({ formatAutofixOutcome });
261
- return emitGateOutcome(summary, {
262
- cwd,
263
- epicBranch,
264
- storyBranch,
265
- config,
266
- });
267
- }
268
- const gateOutcome = await runPreMergeGatesWithAttribution({
269
- cwd,
270
- worktreePath,
271
- epicBranch,
272
- storyBranch,
273
- config,
274
- storyId,
275
- epicId,
276
- cycleState,
277
- useEvidence: !noEvidenceFlag,
278
- phaseTimer,
279
- provider,
280
- bus,
281
- });
282
- const summary = summarizeGateResults({
283
- formatAutofixOutcome,
284
- gateOutcome,
285
- });
286
- return emitGateOutcome(summary, {
287
- cwd,
288
- epicBranch,
289
- storyBranch,
290
- config,
291
- });
292
- }
@@ -1,270 +0,0 @@
1
- /**
2
- * phases/locked-pipeline.js — the per-Epic-merge-lock-protected body of
3
- * `runStoryClose` (Story #2460, Epic #2453 — CLI thinning pilot).
4
- *
5
- * Sits behind `withEpicMergeLock` in story-close.js. Owns:
6
- *
7
- * 1. dispatchRecovery — prior-state detection + --resume / --restart
8
- * dispatch
9
- * 2. fetchChildTickets — hydrate the cascade target set
10
- * 3. phase-timer restore — pick up the snapshot story-init wrote
11
- * 4. gates — pre-merge validation (skipped on resume)
12
- * 5. refresh — bounded baseline auto-refresh (gates ok path)
13
- * 6. close — merge + post-merge close pipeline
14
- *
15
- * The split out of story-close.js keeps the CLI shell at ≤ 300 LOC and
16
- * means a future test can drive the locked pipeline with the lock
17
- * mocked out — without re-acquiring the per-Epic lock or re-entering
18
- * the preflight gate.
19
- */
20
-
21
- import { Logger } from '../../../Logger.js';
22
- import { hasInlineAcceptance } from '../../../story-init/task-graph-builder.js';
23
- import { fetchChildTickets } from '../../../story-lifecycle.js';
24
- import { createPhaseTimer } from '../../../util/phase-timer.js';
25
- import {
26
- clearPhaseTimerState,
27
- loadPhaseTimerState,
28
- } from '../../../util/phase-timer-state.js';
29
- import { read as readPlanState } from '../../epic-plan-state-store.js';
30
- import { dispatchRecovery } from '../../story-close-recovery.js';
31
- import { runClosePhase } from './close.js';
32
- import { runStoryCodeReview } from './code-review.js';
33
- import {
34
- emitBaselineBlockedResult,
35
- runPreMergeValidation,
36
- shouldSkipValidation,
37
- } from './gates.js';
38
- import { runAutoRefreshSafely } from './refresh.js';
39
- import { emitSpawnTimeoutBlockedResult } from './timeout-blocked-emitter.js';
40
-
41
- /**
42
- * Run pre-merge gates and, on a clean outcome, the bounded baseline
43
- * auto-refresh. Returns `{ blocked }` so the locked pipeline can
44
- * short-circuit on a `blocked` / `blocked-timeout` gate outcome.
45
- *
46
- * `runPreMergeValidation` is an injectable seam (Story #3973): the
47
- * forwarding of `config: ctx.config` into the gate builder is load-bearing
48
- * — without it the typecheck gate ignores `project.commands.typecheck` and
49
- * falls back to the hardcoded `npm run typecheck`, blocking every close for
50
- * any consumer with a non-default typecheck command. The default is the
51
- * module-level `runPreMergeValidation`; tests inject a spy to pin that
52
- * `config` reaches the gate builder through this call site.
53
- *
54
- * @param {object} ctx - The locked-pipeline context bundle.
55
- * @param {object} [deps] - Injectable collaborators.
56
- * @param {typeof runPreMergeValidation} [deps.runPreMergeValidationFn]
57
- * @param {typeof runAutoRefreshSafely} [deps.runAutoRefreshSafelyFn]
58
- */
59
- export async function runGatesAndRefresh(
60
- ctx,
61
- {
62
- runPreMergeValidationFn = runPreMergeValidation,
63
- runAutoRefreshSafelyFn = runAutoRefreshSafely,
64
- } = {},
65
- ) {
66
- // Story #4017 — one shared cycle-state object per close cycle. The
67
- // gate-failure attribution retry and the post-gates auto-refresh both
68
- // funnel through `runRefreshCommit`, which keys its idempotency token
69
- // off this object so each baseline kind is refreshed (scored +
70
- // committed) at most once per close.
71
- const cycleState = { refreshedKinds: new Set(), lastRefreshSha: null };
72
- const gateOutcome = await runPreMergeValidationFn({
73
- cwd: ctx.cwd,
74
- worktreePath: ctx.worktreePath,
75
- epicBranch: ctx.epicBranch,
76
- storyBranch: ctx.storyBranch,
77
- config: ctx.config,
78
- storyId: ctx.storyId,
79
- epicId: ctx.epicId,
80
- noEvidenceFlag: ctx.noEvidenceFlag,
81
- phaseTimer: ctx.phaseTimer,
82
- provider: ctx.provider,
83
- bus: ctx.bus,
84
- cycleState,
85
- });
86
- if (gateOutcome?.status === 'blocked') {
87
- return {
88
- blocked: await emitBaselineBlockedResult({
89
- storyId: ctx.storyId,
90
- gateOutcome,
91
- progress: ctx.progress,
92
- bus: ctx.bus,
93
- }),
94
- };
95
- }
96
- if (gateOutcome?.status === 'blocked-timeout') {
97
- return {
98
- blocked: await emitSpawnTimeoutBlockedResult({
99
- storyId: ctx.storyId,
100
- epicId: ctx.epicId,
101
- spawnName: gateOutcome.gateName ?? 'coverage-capture',
102
- spawnCmd: gateOutcome.spawnCmd ?? null,
103
- timeoutMs: gateOutcome.timeoutMs ?? null,
104
- exitCode: gateOutcome.exitCode ?? 124,
105
- config: ctx.config,
106
- provider: ctx.provider,
107
- progress: ctx.progress,
108
- bus: ctx.bus,
109
- }),
110
- };
111
- }
112
- await runAutoRefreshSafelyFn(
113
- {
114
- storyId: ctx.storyId,
115
- epicId: ctx.epicId,
116
- cwd: ctx.worktreePath || ctx.cwd,
117
- epicBranch: ctx.epicBranch,
118
- storyBranch: ctx.storyBranch,
119
- config: ctx.config,
120
- cycleState,
121
- },
122
- { progress: ctx.progress },
123
- );
124
- return { blocked: null };
125
- }
126
-
127
- /**
128
- * Read the parent Epic's judged `planningRisk` envelope off its
129
- * `epic-plan-state` checkpoint so the Story-scope review can inherit the
130
- * Epic's review depth (Story #3940). Best-effort and total — it reuses the
131
- * shared `read` from `epic-plan-state-store.js` (the same reader `/plan
132
- * --resume` and `epic-audit-prepare.js`'s `resolveRiskRoutedLenses` use, no
133
- * third bespoke reader) and never fails the close:
134
- *
135
- * - absent/non-integer `epicId` (a Story that is not Epic-attached) → `null`
136
- * - missing/unparseable checkpoint, no `planningRisk` field → `null`
137
- * - any read throw (provider error, malformed comment) → `null`
138
- *
139
- * A `null` result threads through `runStoryCodeReview` → `runCodeReview`
140
- * unchanged, so depth resolves from diff width alone (`standard`), preserving
141
- * today's behaviour for an Epic that skipped `/plan`.
142
- *
143
- * @param {{ provider: object, epicId: number|null|undefined, readPlanStateFn?: typeof readPlanState }} args
144
- * @returns {Promise<{ overallLevel?: string, axes?: Array<object> }|null>}
145
- */
146
- export async function resolveParentEpicPlanningRisk({
147
- provider,
148
- epicId,
149
- readPlanStateFn = readPlanState,
150
- }) {
151
- if (!Number.isInteger(epicId) || epicId <= 0) return null;
152
- try {
153
- const state = await readPlanStateFn({ provider, epicId });
154
- return state?.planningRisk ?? null;
155
- } catch {
156
- return null;
157
- }
158
- }
159
-
160
- /**
161
- * Body of `withEpicMergeLock(epicId, ..., () => …)` from story-close.js.
162
- *
163
- * @param {object} args - resolved-close-input bundle from
164
- * `resolveCloseInputs` plus the orchestrator-injected `progress` /
165
- * `progressLog` callbacks and the lifecycle bus.
166
- * @returns {Promise<{ success: boolean, result?: object } | object>}
167
- */
168
- export async function runStoryCloseLocked(args) {
169
- const {
170
- cwd,
171
- storyId,
172
- epicId,
173
- epicBranch,
174
- storyBranch,
175
- config,
176
- skipValidationParam,
177
- resumeFlag,
178
- restartFlag,
179
- provider,
180
- story,
181
- progress,
182
- } = args;
183
-
184
- // Prior-state detection + --resume / --restart dispatch.
185
- // `dispatchRecovery` only reads `orchestration.worktreeIsolation`; surface
186
- // it from the canonical `delivery.worktreeIsolation` view directly.
187
- const { resumeFromConflict, resumeFromMerge, resumeFromPostMerge } =
188
- dispatchRecovery({
189
- cwd,
190
- storyId,
191
- epicId,
192
- epicBranch,
193
- storyBranch,
194
- orchestration: { worktreeIsolation: config.delivery?.worktreeIsolation },
195
- resume: resumeFlag,
196
- restart: restartFlag,
197
- progress,
198
- logger: Logger,
199
- });
200
-
201
- // Story #4251 — mirror the init-side short-circuit: a 2-tier Story (inline
202
- // acceptance on its body) has no children, so skip the `fetchChildTickets`
203
- // probe (empty sub-issues GraphQL query + never-matching `/search/issues`
204
- // scan) entirely. The cascade target is just the Story itself. A body
205
- // lacking inline acceptance still enumerates children for legacy / Epic
206
- // callers.
207
- const tasks = hasInlineAcceptance(story?.body)
208
- ? []
209
- : await fetchChildTickets(provider, storyId);
210
- provider.primeTicketCache([story, ...tasks]);
211
- progress('TICKETS', `Found ${tasks.length} child ticket(s)`);
212
-
213
- const prior = loadPhaseTimerState({ mainCwd: cwd, storyId });
214
- const phaseTimer = createPhaseTimer(storyId, prior ? { restore: prior } : {});
215
-
216
- const skipValidation = shouldSkipValidation({
217
- skipValidationParam,
218
- resumeFromConflict,
219
- resumeFromMerge,
220
- resumeFromPostMerge,
221
- });
222
-
223
- const ctx = {
224
- ...args,
225
- tasks,
226
- phaseTimer,
227
- resumeFromConflict,
228
- resumeFromMerge,
229
- resumeFromPostMerge,
230
- clearPhaseTimerState,
231
- };
232
-
233
- if (!skipValidation) {
234
- const { blocked } = await runGatesAndRefresh(ctx);
235
- if (blocked) return blocked;
236
-
237
- // Story #2840 — Story-scope code review runs after the gate chain
238
- // passes (so we know the diff is build-clean) but before the merge
239
- // into `epic/<id>`. Critical findings short-circuit the close and
240
- // exit non-zero; non-critical findings post a structured comment
241
- // and let close proceed.
242
- //
243
- // Story #3940 — the review inherits the parent Epic's judged review
244
- // depth: read the Epic's `planningRisk` envelope best-effort off its
245
- // `epic-plan-state` checkpoint and forward it so `runCodeReview`
246
- // resolves depth from BOTH that risk and the Story-scope
247
- // (`epic/<id>...story-<id>`) changed-file count. A missing/unreadable
248
- // checkpoint degrades to `null` (→ `standard`) without failing close.
249
- const planningRisk = await resolveParentEpicPlanningRisk({
250
- provider: ctx.provider,
251
- epicId: ctx.epicId,
252
- });
253
- const review = await runStoryCodeReview({
254
- storyId: ctx.storyId,
255
- epicBranch: ctx.epicBranch,
256
- storyBranch: ctx.storyBranch,
257
- provider: ctx.provider,
258
- bus: ctx.bus,
259
- progress: ctx.progress,
260
- planningRisk,
261
- });
262
- if (review.blocked) return review.blocked;
263
- }
264
-
265
- // Everything past validation is the `close` phase; the post-merge
266
- // pipeline marks `api-sync` once the merge lands.
267
- phaseTimer.mark('close');
268
-
269
- return runClosePhase(ctx);
270
- }
@@ -1,110 +0,0 @@
1
- /**
2
- * phases/preflight.js — story-close preflight phase (Story #2460, Epic
3
- * #2453 — CLI thinning pilot).
4
- *
5
- * Wraps the registry-driven preflight scan + the canonical "preflight
6
- * refused" close-result envelope. Runs BEFORE `withEpicMergeLock` so the
7
- * per-Epic lock is not acquired just to release it on a refused
8
- * preflight (the project-wide exit-code 2 reservation).
9
- *
10
- * Public surface:
11
- * - runStoryClosePreflight(opts) ← exported (story-close.js re-export)
12
- * - emitPreflightBlockedResult(opts)
13
- * - runPreflightPhase(ctx) ← pipeline entry
14
- */
15
-
16
- import { Logger } from '../../../Logger.js';
17
- import {
18
- PREFLIGHT_REFUSED_EXIT_CODE,
19
- runPreflight,
20
- } from '../../../preflight-runner.js';
21
- import { emitBlockedCloseResult } from '../merge-runner.js';
22
-
23
- /**
24
- * Run the story-close preflight gate. Exported so tests can drive it
25
- * with an inline registry / probe spies without re-entering the full
26
- * close orchestrator.
27
- *
28
- * @param {object} opts
29
- * @param {string|number} opts.storyId
30
- * @param {string} [opts.cwd=process.cwd()]
31
- * @param {object} [opts.probes]
32
- * @param {object} [opts.registry]
33
- * @param {string} [opts.dir]
34
- * @param {object} [opts.logger]
35
- * @returns {Promise<{ ok: boolean, findings: Array, fixed: Array }>}
36
- */
37
- export async function runStoryClosePreflight({
38
- storyId,
39
- cwd = process.cwd(),
40
- probes,
41
- registry,
42
- dir,
43
- logger,
44
- } = {}) {
45
- Logger.info(
46
- `[story-close] Running preflight checks (scope=story-close) for Story #${storyId ?? '?'}...`,
47
- );
48
- const preflight = await runPreflight({
49
- scope: 'story-close',
50
- autoFix: true,
51
- cwd,
52
- probes,
53
- registry,
54
- dir,
55
- logger,
56
- });
57
- return {
58
- ok: !preflight.blocked,
59
- findings: preflight.findings,
60
- fixed: preflight.fixed,
61
- };
62
- }
63
-
64
- /**
65
- * Emit the canonical close-result envelope for the "preflight refused"
66
- * exit. Shape mirrors `emitBaselineBlockedResult` so the wave aggregator's
67
- * label-derivation fallback sees a consistent envelope.
68
- */
69
- export async function emitPreflightBlockedResult({
70
- storyId,
71
- preflight,
72
- progress,
73
- }) {
74
- return emitBlockedCloseResult({
75
- storyId,
76
- phase: 'preflight',
77
- reason: 'preflight-refused',
78
- extra: { findings: preflight.findings },
79
- progress,
80
- blockedMessage: `Story #${storyId} blocked: preflight refused — ${preflight.findings.length} blocker finding(s).`,
81
- logger: Logger,
82
- });
83
- }
84
-
85
- /**
86
- * Phase pipeline entry. Returns one of:
87
- * - { ok: true } when preflight passed (caller continues)
88
- * - { ok: false, exitEnvelope } when preflight refused (caller short-circuits
89
- * with `{ success: false, result: exitEnvelope, exitCode: PREFLIGHT_REFUSED_EXIT_CODE }`)
90
- */
91
- export async function runPreflightPhase({ ctx }) {
92
- const outcome = await runStoryClosePreflight({
93
- storyId: ctx.storyId,
94
- cwd: ctx.cwd,
95
- });
96
- if (outcome.ok) return { ok: true };
97
- const exitEnvelope = await emitPreflightBlockedResult({
98
- storyId: ctx.storyId,
99
- preflight: outcome,
100
- progress: ctx.progress,
101
- });
102
- return {
103
- ok: false,
104
- exitEnvelope: {
105
- success: false,
106
- result: exitEnvelope,
107
- exitCode: PREFLIGHT_REFUSED_EXIT_CODE,
108
- },
109
- };
110
- }