mandrel 1.93.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 (463) hide show
  1. package/.agents/README.md +59 -73
  2. package/.agents/agents/acceptance-critic.md +129 -0
  3. package/.agents/agents/story-worker.md +161 -0
  4. package/.agents/docs/SDLC.md +489 -1285
  5. package/.agents/docs/agentrc-reference.json +177 -67
  6. package/.agents/docs/configuration.md +108 -136
  7. package/.agents/docs/execution-reference.md +44 -22
  8. package/.agents/docs/quality-gates.md +13 -19
  9. package/.agents/docs/workflows.md +3 -3
  10. package/.agents/instructions.md +107 -108
  11. package/.agents/rules/ci-remediation.md +8 -12
  12. package/.agents/rules/git-conventions-reference.md +224 -0
  13. package/.agents/rules/git-conventions.md +42 -223
  14. package/.agents/rules/security-baseline.md +5 -0
  15. package/.agents/rules/testing-standards.md +106 -13
  16. package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
  17. package/.agents/schemas/agentrc.schema.json +71 -201
  18. package/.agents/schemas/lifecycle/ledger-record.schema.json +1 -1
  19. package/.agents/schemas/lifecycle/retro.end.schema.json +1 -1
  20. package/.agents/schemas/risk-verdict.schema.json +0 -13
  21. package/.agents/scripts/acceptance-eval.js +62 -18
  22. package/.agents/scripts/agents-bootstrap-github.js +1 -1
  23. package/.agents/scripts/analyze-execution.js +1 -1
  24. package/.agents/scripts/audit-to-stories.js +7 -7
  25. package/.agents/scripts/boot-sweep.js +1 -1
  26. package/.agents/scripts/check-context-budget.js +62 -5
  27. package/.agents/scripts/check-lifecycle-lint.js +6 -9
  28. package/.agents/scripts/check-prepush-recovery.js +1 -1
  29. package/.agents/scripts/cleanup-repo-test-temp.js +6 -1
  30. package/.agents/scripts/diagnose-friction.js +0 -6
  31. package/.agents/scripts/lib/Logger.js +6 -10
  32. package/.agents/scripts/lib/audit-suite/runner.js +2 -2
  33. package/.agents/scripts/lib/audit-suite/selector.js +5 -5
  34. package/.agents/scripts/lib/audit-to-stories/{seed-epic-from-findings.js → seed-from-findings.js} +9 -9
  35. package/.agents/scripts/lib/baselines/kernel.js +206 -18
  36. package/.agents/scripts/lib/baselines/kinds/maintainability.js +0 -4
  37. package/.agents/scripts/lib/baselines/reader.js +1 -6
  38. package/.agents/scripts/lib/bdd-runner-detect.js +5 -9
  39. package/.agents/scripts/lib/bootstrap/issue-forms-template.js +32 -33
  40. package/.agents/scripts/lib/bootstrap/project-bootstrap.js +56 -18
  41. package/.agents/scripts/lib/checks/core-bare-clean.js +2 -2
  42. package/.agents/scripts/lib/checks/index.js +2 -1
  43. package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +23 -21
  44. package/.agents/scripts/lib/cli/standard-args.js +13 -22
  45. package/.agents/scripts/lib/cli-args.js +16 -7
  46. package/.agents/scripts/lib/close-validation/gates.js +160 -22
  47. package/.agents/scripts/lib/config/acceptance-eval.js +52 -5
  48. package/.agents/scripts/lib/config/ci.js +6 -31
  49. package/.agents/scripts/lib/config/delivery-routing.js +103 -0
  50. package/.agents/scripts/lib/config/explain.js +57 -36
  51. package/.agents/scripts/lib/config/limits.js +17 -58
  52. package/.agents/scripts/lib/config/paths.js +0 -2
  53. package/.agents/scripts/lib/config/quality.js +1 -1
  54. package/.agents/scripts/lib/config/runners.js +17 -50
  55. package/.agents/scripts/lib/config/temp-paths.js +19 -14
  56. package/.agents/scripts/lib/config/worktree-isolation.js +0 -5
  57. package/.agents/scripts/lib/config-resolver.js +3 -8
  58. package/.agents/scripts/lib/config-settings-schema-delivery.js +46 -136
  59. package/.agents/scripts/lib/config-settings-schema-quality.js +17 -14
  60. package/.agents/scripts/lib/config-settings-schema.js +52 -38
  61. package/.agents/scripts/lib/dependency-parser.js +3 -2
  62. package/.agents/scripts/lib/doc-tiers.js +39 -4
  63. package/.agents/scripts/lib/duplicate-search.js +211 -41
  64. package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +1 -1
  65. package/.agents/scripts/lib/findings/promote-finding.js +5 -5
  66. package/.agents/scripts/lib/framework-version.js +2 -3
  67. package/.agents/scripts/lib/git-branch-cleanup.js +1 -10
  68. package/.agents/scripts/lib/git-branch-lifecycle.js +17 -22
  69. package/.agents/scripts/lib/git-utils.js +32 -6
  70. package/.agents/scripts/lib/github/framework-repo.js +6 -0
  71. package/.agents/scripts/lib/label-constants.js +10 -23
  72. package/.agents/scripts/lib/label-taxonomy.js +9 -43
  73. package/.agents/scripts/lib/observability/active-story-env.js +112 -3
  74. package/.agents/scripts/lib/observability/hook-heartbeat.js +187 -0
  75. package/.agents/scripts/lib/observability/source-classifier.js +3 -3
  76. package/.agents/scripts/lib/observability/tool-trace-hook.js +15 -4
  77. package/.agents/scripts/lib/onboard/init-tail.js +1 -3
  78. package/.agents/scripts/lib/orchestration/acceptance-clusters.js +111 -0
  79. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +32 -4
  80. package/.agents/scripts/lib/orchestration/audit-lens-routing.js +128 -0
  81. package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +273 -0
  82. package/.agents/scripts/lib/orchestration/ceremony-routing.js +204 -0
  83. package/.agents/scripts/lib/orchestration/code-review.js +20 -268
  84. package/.agents/scripts/lib/orchestration/column-sync.js +1 -1
  85. package/.agents/scripts/lib/orchestration/consolidation-precondition.js +1 -1
  86. package/.agents/scripts/lib/orchestration/context-envelope.js +2 -5
  87. package/.agents/scripts/lib/orchestration/docs-digest.js +8 -8
  88. package/.agents/scripts/lib/orchestration/file-assumptions.js +7 -13
  89. package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +1 -1
  90. package/.agents/scripts/lib/orchestration/lifecycle/emit-loop-tick.js +8 -8
  91. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +2 -2
  92. package/.agents/scripts/lib/orchestration/lifecycle/ledger-writer.js +6 -3
  93. package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +17 -43
  94. package/.agents/scripts/lib/orchestration/lint-baseline-service.js +4 -4
  95. package/.agents/scripts/lib/orchestration/merge-block-class.js +1 -1
  96. package/.agents/scripts/lib/orchestration/phase-runner.js +3 -2
  97. package/.agents/scripts/lib/orchestration/plan-context.js +248 -266
  98. package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +3 -2
  99. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +1 -1
  100. package/.agents/scripts/lib/orchestration/plan-navigation.js +92 -0
  101. package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +61 -0
  102. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +97 -0
  103. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +223 -854
  104. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +361 -0
  105. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +35 -108
  106. package/.agents/scripts/lib/orchestration/plan-reachability.js +9 -14
  107. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +1 -1
  108. package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/authoring-context.js +14 -14
  109. package/.agents/scripts/lib/orchestration/planning/decomposer-context.js +27 -0
  110. package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/risk-verdict.js +3 -4
  111. package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +2 -2
  112. package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +8 -20
  113. package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +3 -2
  114. package/.agents/scripts/lib/orchestration/pr-base-guard.js +18 -28
  115. package/.agents/scripts/lib/orchestration/preflight-cache.js +5 -5
  116. package/.agents/scripts/lib/orchestration/remote-verifier.js +1 -1
  117. package/.agents/scripts/lib/orchestration/resolve-plan-run.js +155 -0
  118. package/.agents/scripts/lib/orchestration/resolves-token.js +1 -1
  119. package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +8 -8
  120. package/.agents/scripts/lib/orchestration/retro-proposals.js +140 -79
  121. package/.agents/scripts/lib/orchestration/review-depth.js +26 -12
  122. package/.agents/scripts/lib/orchestration/review-providers/codex.js +2 -2
  123. package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +21 -56
  124. package/.agents/scripts/lib/orchestration/run-epilogue.js +426 -0
  125. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +1 -1
  126. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +1 -0
  127. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +95 -41
  128. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +16 -13
  129. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +40 -0
  130. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +11 -3
  131. package/.agents/scripts/lib/orchestration/spec-freshness.js +14 -205
  132. package/.agents/scripts/lib/orchestration/spec-section-validator.js +4 -5
  133. package/.agents/scripts/lib/orchestration/spec-spill.js +60 -0
  134. package/.agents/scripts/lib/orchestration/split-policy-validator.js +188 -0
  135. package/.agents/scripts/lib/orchestration/story-close/emit-blocked.js +49 -0
  136. package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +15 -12
  137. package/.agents/scripts/lib/orchestration/story-follow-ups.js +237 -0
  138. package/.agents/scripts/lib/orchestration/story-init-remote.js +47 -0
  139. package/.agents/scripts/lib/orchestration/story-plan-state.js +48 -0
  140. package/.agents/scripts/lib/orchestration/{epic-runner → story-progress}/story-run-progress-writer.js +3 -3
  141. package/.agents/scripts/lib/orchestration/structured-comment-parser.js +1 -1
  142. package/.agents/scripts/lib/orchestration/task-body-validator.js +8 -18
  143. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +11 -61
  144. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +189 -373
  145. package/.agents/scripts/lib/orchestration/ticket-validator.js +3 -8
  146. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +0 -25
  147. package/.agents/scripts/lib/orchestration/ticketing/reads.js +29 -26
  148. package/.agents/scripts/lib/orchestration/ticketing/transition.js +5 -5
  149. package/.agents/scripts/lib/planning-corpus.js +16 -11
  150. package/.agents/scripts/lib/preflight-runner.js +2 -2
  151. package/.agents/scripts/lib/provider-factory.js +1 -1
  152. package/.agents/scripts/lib/qa/coverage-verdict.js +5 -5
  153. package/.agents/scripts/lib/single-story/confirm-merge-follow-ups.js +36 -0
  154. package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +1 -1
  155. package/.agents/scripts/lib/story-adjacency.js +11 -14
  156. package/.agents/scripts/lib/story-body/story-body.js +124 -70
  157. package/.agents/scripts/lib/story-plan.js +2 -4
  158. package/.agents/scripts/lib/templates/decomposer-prompts.js +46 -45
  159. package/.agents/scripts/lib/templates/spec-author-prompts.js +47 -45
  160. package/.agents/scripts/lib/{epic-body-sections.js → ticket-body-sections.js} +26 -26
  161. package/.agents/scripts/lib/validation-evidence.js +1 -1
  162. package/.agents/scripts/lib/wave-runner/ready-set.js +6 -6
  163. package/.agents/scripts/lib/workspace-provisioner.js +1 -1
  164. package/.agents/scripts/lib/worktree/lifecycle/reap.js +5 -7
  165. package/.agents/scripts/lint-issue-body.js +71 -40
  166. package/.agents/scripts/mandrel-update-preflight.js +1 -1
  167. package/.agents/scripts/notify.js +4 -3
  168. package/.agents/scripts/plan-context.js +64 -74
  169. package/.agents/scripts/plan-persist.js +121 -280
  170. package/.agents/scripts/plan-run-epilogue.js +97 -0
  171. package/.agents/scripts/post-structured-comment.js +38 -0
  172. package/.agents/scripts/providers/github/issues.js +17 -33
  173. package/.agents/scripts/providers/github/mappers.js +0 -12
  174. package/.agents/scripts/providers/github/tickets.js +2 -5
  175. package/.agents/scripts/resolve-plan-run.js +117 -0
  176. package/.agents/scripts/signals-view.js +24 -19
  177. package/.agents/scripts/single-story-close.js +11 -14
  178. package/.agents/scripts/single-story-confirm-merge.js +39 -23
  179. package/.agents/scripts/single-story-init.js +29 -20
  180. package/.agents/scripts/stories-wave-tick.js +6 -6
  181. package/.agents/scripts/story-plan.js +26 -47
  182. package/.agents/scripts/sync-claude-agents.js +165 -0
  183. package/.agents/scripts/update-ticket-state.js +37 -15
  184. package/.agents/skills/core/analyze-execution/SKILL.md +21 -18
  185. package/.agents/skills/core/api-and-interface-design/SKILL.md +5 -3
  186. package/.agents/skills/core/code-review-and-quality/SKILL.md +63 -7
  187. package/.agents/skills/core/debugging-and-error-recovery/SKILL.md +1 -1
  188. package/.agents/skills/core/gates-and-baselines/SKILL.md +149 -0
  189. package/.agents/skills/core/idea-refinement/SKILL.md +8 -14
  190. package/.agents/skills/core/qa-coverage-mapping/SKILL.md +7 -7
  191. package/.agents/skills/core/scope-triage/SKILL.md +28 -172
  192. package/.agents/skills/skills.index.json +8 -418
  193. package/.agents/starter-agentrc.json +0 -5
  194. package/.agents/templates/agent-protocol.md +9 -10
  195. package/.agents/workflows/audit-architecture.md +3 -3
  196. package/.agents/workflows/audit-clean-code.md +3 -3
  197. package/.agents/workflows/audit-dependencies.md +3 -3
  198. package/.agents/workflows/audit-devops.md +3 -3
  199. package/.agents/workflows/audit-documentation.md +5 -5
  200. package/.agents/workflows/audit-lighthouse.md +3 -3
  201. package/.agents/workflows/audit-navigability.md +3 -2
  202. package/.agents/workflows/audit-performance.md +3 -3
  203. package/.agents/workflows/audit-privacy.md +3 -3
  204. package/.agents/workflows/audit-quality.md +3 -3
  205. package/.agents/workflows/audit-security.md +3 -3
  206. package/.agents/workflows/audit-seo.md +3 -3
  207. package/.agents/workflows/audit-sre.md +3 -3
  208. package/.agents/workflows/audit-to-stories.md +20 -20
  209. package/.agents/workflows/audit-ux-ui.md +3 -3
  210. package/.agents/workflows/deliver.md +122 -131
  211. package/.agents/workflows/git-cleanup.md +3 -4
  212. package/.agents/workflows/helpers/_merge-conflict-template.md +1 -1
  213. package/.agents/workflows/helpers/acceptance-self-eval.md +52 -40
  214. package/.agents/workflows/helpers/code-review.md +70 -193
  215. package/.agents/workflows/helpers/{single-story-deliver-reference.md → deliver-story-reference.md} +12 -14
  216. package/.agents/workflows/helpers/{single-story-deliver.md → deliver-story.md} +113 -139
  217. package/.agents/workflows/helpers/diagnose.md +10 -10
  218. package/.agents/workflows/helpers/mandrel-sync-config.md +1 -1
  219. package/.agents/workflows/helpers/parallel-tooling.md +1 -1
  220. package/.agents/workflows/helpers/signals.md +16 -16
  221. package/.agents/workflows/helpers/worktree-lifecycle.md +48 -64
  222. package/.agents/workflows/mandrel-update.md +3 -2
  223. package/.agents/workflows/plan.md +112 -145
  224. package/.agents/workflows/qa-assist.md +24 -30
  225. package/.agents/workflows/qa-explore.md +29 -38
  226. package/.agents/workflows/qa-run.md +2 -2
  227. package/README.md +9 -8
  228. package/docs/CHANGELOG.md +46 -0
  229. package/lib/cli/registry.js +95 -0
  230. package/lib/migrations/index.js +6 -5
  231. package/package.json +5 -3
  232. package/.agents/personas/architect.md +0 -113
  233. package/.agents/personas/devops-engineer.md +0 -38
  234. package/.agents/personas/engineer-mobile.md +0 -120
  235. package/.agents/personas/engineer-web.md +0 -111
  236. package/.agents/personas/engineer.md +0 -119
  237. package/.agents/personas/product.md +0 -94
  238. package/.agents/personas/project-manager.md +0 -114
  239. package/.agents/personas/qa-engineer.md +0 -95
  240. package/.agents/personas/refactorer.md +0 -113
  241. package/.agents/personas/security-engineer.md +0 -112
  242. package/.agents/personas/sre.md +0 -86
  243. package/.agents/personas/technical-writer.md +0 -101
  244. package/.agents/personas/ux-designer.md +0 -95
  245. package/.agents/schemas/dispatch-manifest.json +0 -232
  246. package/.agents/schemas/epic-spec.schema.json +0 -153
  247. package/.agents/scripts/acceptance-spec-reconciler.js +0 -642
  248. package/.agents/scripts/dispatcher.js +0 -295
  249. package/.agents/scripts/epic-audit-prepare.js +0 -497
  250. package/.agents/scripts/epic-audit-recheck.js +0 -274
  251. package/.agents/scripts/epic-deliver-note-intervention.js +0 -192
  252. package/.agents/scripts/epic-deliver-preflight.js +0 -462
  253. package/.agents/scripts/epic-deliver-prepare.js +0 -590
  254. package/.agents/scripts/epic-execute-record-wave.js +0 -449
  255. package/.agents/scripts/epic-plan-clarity.js +0 -211
  256. package/.agents/scripts/epic-plan-decompose.js +0 -54
  257. package/.agents/scripts/epic-plan-healthcheck.js +0 -581
  258. package/.agents/scripts/epic-plan-spec.js +0 -64
  259. package/.agents/scripts/epic-reconcile.js +0 -625
  260. package/.agents/scripts/lib/baseline-snapshot.js +0 -979
  261. package/.agents/scripts/lib/checks/epic-merge-lock-stale.js +0 -54
  262. package/.agents/scripts/lib/checks/stale-origin-epic.js +0 -49
  263. package/.agents/scripts/lib/config/lifecycle.js +0 -40
  264. package/.agents/scripts/lib/config/preflight.js +0 -58
  265. package/.agents/scripts/lib/config/retro.js +0 -77
  266. package/.agents/scripts/lib/epic-merge-lock.js +0 -322
  267. package/.agents/scripts/lib/epic-plan-clarity.js +0 -181
  268. package/.agents/scripts/lib/epic-plan-ideation.js +0 -261
  269. package/.agents/scripts/lib/orchestration/context-hydration-engine.js +0 -660
  270. package/.agents/scripts/lib/orchestration/dispatch-engine.js +0 -134
  271. package/.agents/scripts/lib/orchestration/dispatch-pipeline.js +0 -183
  272. package/.agents/scripts/lib/orchestration/epic-cleanup.js +0 -801
  273. package/.agents/scripts/lib/orchestration/epic-deliver-lease-guard.js +0 -310
  274. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/context.js +0 -163
  275. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/creation.js +0 -140
  276. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/dag.js +0 -64
  277. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/diagnostics.js +0 -72
  278. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +0 -156
  279. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist.js +0 -345
  280. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +0 -41
  281. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/reconcile-spawn.js +0 -86
  282. package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +0 -391
  283. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/drain.js +0 -94
  284. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +0 -236
  285. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +0 -307
  286. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-freshness.js +0 -117
  287. package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +0 -117
  288. package/.agents/scripts/lib/orchestration/epic-run-state-store.js +0 -388
  289. package/.agents/scripts/lib/orchestration/epic-runner/concurrency-gate.js +0 -186
  290. package/.agents/scripts/lib/orchestration/epic-runner/deliver-phases.js +0 -50
  291. package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +0 -129
  292. package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +0 -103
  293. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/composition.js +0 -267
  294. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/signals.js +0 -210
  295. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/transport.js +0 -238
  296. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/_bullet-format.js +0 -32
  297. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/component-drift.js +0 -203
  298. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/crap-drift.js +0 -227
  299. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/maintainability-drift.js +0 -117
  300. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/stalled-worktree.js +0 -37
  301. package/.agents/scripts/lib/orchestration/epic-runner/story-launcher.js +0 -127
  302. package/.agents/scripts/lib/orchestration/epic-runner/sub-agent-return.js +0 -276
  303. package/.agents/scripts/lib/orchestration/epic-runner/wave-scheduler.js +0 -66
  304. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-apply.js +0 -789
  305. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +0 -676
  306. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-discriminator.js +0 -389
  307. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-format.js +0 -230
  308. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-ops.js +0 -361
  309. package/.agents/scripts/lib/orchestration/finalize/open-or-locate-pr.js +0 -306
  310. package/.agents/scripts/lib/orchestration/finalize/post-handoff-comment.js +0 -489
  311. package/.agents/scripts/lib/orchestration/finalize/sanitize-skip-ci.js +0 -88
  312. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-dispatch-end.js +0 -147
  313. package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +0 -384
  314. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +0 -501
  315. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +0 -984
  316. package/.agents/scripts/lib/orchestration/lifecycle/listeners/branch-cleaner.js +0 -264
  317. package/.agents/scripts/lib/orchestration/lifecycle/listeners/checkpoint-pointer-writer.js +0 -278
  318. package/.agents/scripts/lib/orchestration/lifecycle/listeners/cleaner.js +0 -355
  319. package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +0 -673
  320. package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +0 -378
  321. package/.agents/scripts/lib/orchestration/lifecycle/listeners/intervention-recorder.js +0 -140
  322. package/.agents/scripts/lib/orchestration/lifecycle/listeners/label-transitioner.js +0 -144
  323. package/.agents/scripts/lib/orchestration/lifecycle/listeners/notify-dispatcher.js +0 -174
  324. package/.agents/scripts/lib/orchestration/manifest-builder.js +0 -222
  325. package/.agents/scripts/lib/orchestration/plan-persist/amend.js +0 -359
  326. package/.agents/scripts/lib/orchestration/plan-persist/delivery-mode.js +0 -127
  327. package/.agents/scripts/lib/orchestration/post-merge-pipeline.js +0 -205
  328. package/.agents/scripts/lib/orchestration/recurring-failure-detector.js +0 -152
  329. package/.agents/scripts/lib/orchestration/retro/phases/checks.js +0 -94
  330. package/.agents/scripts/lib/orchestration/retro/phases/compose-body.js +0 -571
  331. package/.agents/scripts/lib/orchestration/retro/phases/gather-signals.js +0 -450
  332. package/.agents/scripts/lib/orchestration/retro/phases/post-and-mirror.js +0 -191
  333. package/.agents/scripts/lib/orchestration/retro-heuristics.js +0 -57
  334. package/.agents/scripts/lib/orchestration/retro-runner.js +0 -197
  335. package/.agents/scripts/lib/orchestration/skill-capsule-loader.js +0 -109
  336. package/.agents/scripts/lib/orchestration/spec-renderer.js +0 -447
  337. package/.agents/scripts/lib/orchestration/story-close/auto-refresh-runner.js +0 -747
  338. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/gate-failure.js +0 -211
  339. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/pre-merge-attribution.js +0 -158
  340. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +0 -446
  341. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/regression-projection.js +0 -297
  342. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/scope-discovery.js +0 -48
  343. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution-wiring.js +0 -67
  344. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution.js +0 -161
  345. package/.agents/scripts/lib/orchestration/story-close/baseline-friction-body.js +0 -117
  346. package/.agents/scripts/lib/orchestration/story-close/cd-out-guard.js +0 -86
  347. package/.agents/scripts/lib/orchestration/story-close/cleanup-reconciler.js +0 -147
  348. package/.agents/scripts/lib/orchestration/story-close/close-inputs.js +0 -142
  349. package/.agents/scripts/lib/orchestration/story-close/comment-bodies.js +0 -62
  350. package/.agents/scripts/lib/orchestration/story-close/merge-runner.js +0 -658
  351. package/.agents/scripts/lib/orchestration/story-close/merge-subject.js +0 -198
  352. package/.agents/scripts/lib/orchestration/story-close/phases/branch-restore.js +0 -105
  353. package/.agents/scripts/lib/orchestration/story-close/phases/close.js +0 -222
  354. package/.agents/scripts/lib/orchestration/story-close/phases/gates.js +0 -292
  355. package/.agents/scripts/lib/orchestration/story-close/phases/locked-pipeline.js +0 -270
  356. package/.agents/scripts/lib/orchestration/story-close/phases/preflight.js +0 -110
  357. package/.agents/scripts/lib/orchestration/story-close/phases/refresh.js +0 -86
  358. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked-emitter.js +0 -112
  359. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked.js +0 -157
  360. package/.agents/scripts/lib/orchestration/story-close/post-merge-close.js +0 -421
  361. package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +0 -301
  362. package/.agents/scripts/lib/orchestration/story-close/shared-checkout-guard.js +0 -163
  363. package/.agents/scripts/lib/orchestration/story-close-recovery.js +0 -690
  364. package/.agents/scripts/lib/orchestration/wave-marker.js +0 -28
  365. package/.agents/scripts/lib/orchestration/wave-record-io.js +0 -218
  366. package/.agents/scripts/lib/orchestration/wave-record-notifications.js +0 -145
  367. package/.agents/scripts/lib/orchestration/wave-record-projection.js +0 -212
  368. package/.agents/scripts/lib/presentation/dispatch-manifest-render.js +0 -111
  369. package/.agents/scripts/lib/presentation/manifest-builder.js +0 -239
  370. package/.agents/scripts/lib/presentation/manifest-formatter.js +0 -242
  371. package/.agents/scripts/lib/presentation/manifest-helpers.js +0 -213
  372. package/.agents/scripts/lib/presentation/manifest-persistence.js +0 -261
  373. package/.agents/scripts/lib/presentation/manifest-procedures.js +0 -55
  374. package/.agents/scripts/lib/presentation/manifest-render-waves.js +0 -306
  375. package/.agents/scripts/lib/presentation/manifest-renderer.js +0 -188
  376. package/.agents/scripts/lib/presentation/manifest-story-views.js +0 -110
  377. package/.agents/scripts/lib/push-epic-retry.js +0 -209
  378. package/.agents/scripts/lib/spec/index.js +0 -36
  379. package/.agents/scripts/lib/spec/loader.js +0 -425
  380. package/.agents/scripts/lib/spec/state.js +0 -208
  381. package/.agents/scripts/lib/story-init/blocker-validator.js +0 -68
  382. package/.agents/scripts/lib/story-init/branch-initializer.js +0 -408
  383. package/.agents/scripts/lib/story-init/context-resolver.js +0 -92
  384. package/.agents/scripts/lib/story-init/donor-precheck.js +0 -207
  385. package/.agents/scripts/lib/story-init/state-transitioner.js +0 -80
  386. package/.agents/scripts/lib/story-init/task-graph-builder.js +0 -124
  387. package/.agents/scripts/lib/story-init/transition-summary.js +0 -34
  388. package/.agents/scripts/lib/test-reserved-epic-temp-ids.js +0 -35
  389. package/.agents/scripts/lib/wave-runner/tick.js +0 -754
  390. package/.agents/scripts/lib/wave-runner/wave-runner-error.js +0 -20
  391. package/.agents/scripts/lifecycle-emit-story-dispatch.js +0 -194
  392. package/.agents/scripts/lifecycle-emit.js +0 -510
  393. package/.agents/scripts/plan-critics.js +0 -199
  394. package/.agents/scripts/retro-run.js +0 -218
  395. package/.agents/scripts/standalone-feedback-rollup.js +0 -188
  396. package/.agents/scripts/story-close.js +0 -294
  397. package/.agents/scripts/story-init.js +0 -599
  398. package/.agents/scripts/story-phase.js +0 -369
  399. package/.agents/scripts/wave-tick.js +0 -335
  400. package/.agents/skills/core/baseline-refresh/SKILL.md +0 -181
  401. package/.agents/skills/core/ci-cd-and-automation/SKILL.md +0 -274
  402. package/.agents/skills/core/ci-cd-and-automation/examples.md +0 -211
  403. package/.agents/skills/core/code-simplification/SKILL.md +0 -389
  404. package/.agents/skills/core/context-engineering/SKILL.md +0 -309
  405. package/.agents/skills/core/context-engineering/examples.md +0 -58
  406. package/.agents/skills/core/deprecation-and-migration/SKILL.md +0 -250
  407. package/.agents/skills/core/epic-plan-consolidate/SKILL.md +0 -172
  408. package/.agents/skills/core/epic-plan-consolidate/examples.md +0 -51
  409. package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +0 -441
  410. package/.agents/skills/core/epic-plan-decompose-author/examples.md +0 -47
  411. package/.agents/skills/core/epic-plan-premortem/SKILL.md +0 -146
  412. package/.agents/skills/core/epic-plan-premortem/examples.md +0 -53
  413. package/.agents/skills/core/epic-plan-spec-author/SKILL.md +0 -413
  414. package/.agents/skills/core/epic-plan-spec-author/examples.md +0 -91
  415. package/.agents/skills/core/frontend-ui-engineering/SKILL.md +0 -357
  416. package/.agents/skills/core/hydrate-context/SKILL.md +0 -123
  417. package/.agents/skills/core/idea-refinement/examples.md +0 -437
  418. package/.agents/skills/core/idea-refinement/frameworks.md +0 -135
  419. package/.agents/skills/core/incremental-implementation/SKILL.md +0 -271
  420. package/.agents/skills/core/introducing-a-baseline-gate/SKILL.md +0 -213
  421. package/.agents/skills/core/knowledge-transfer/SKILL.md +0 -180
  422. package/.agents/skills/core/mutation-survivor-remediation/SKILL.md +0 -117
  423. package/.agents/skills/core/performance-optimization/SKILL.md +0 -314
  424. package/.agents/skills/core/planning-and-task-breakdown/SKILL.md +0 -277
  425. package/.agents/skills/core/property-based-testing/SKILL.md +0 -148
  426. package/.agents/skills/core/refactoring-discipline/SKILL.md +0 -111
  427. package/.agents/skills/core/shipping-and-launch/SKILL.md +0 -328
  428. package/.agents/skills/core/spec-driven-development/SKILL.md +0 -252
  429. package/.agents/skills/core/test-driven-development/SKILL.md +0 -475
  430. package/.agents/skills/core/using-agent-skills/SKILL.md +0 -232
  431. package/.agents/skills/stack/architecture/monorepo-path-strategist/SKILL.md +0 -31
  432. package/.agents/skills/stack/architecture/structured-output-zod/SKILL.md +0 -51
  433. package/.agents/skills/stack/architecture/subagent-orchestration/SKILL.md +0 -76
  434. package/.agents/skills/stack/backend/cloudflare-hono-architect/SKILL.md +0 -31
  435. package/.agents/skills/stack/backend/cloudflare-hono-architect/examples/route-template.ts +0 -33
  436. package/.agents/skills/stack/backend/cloudflare-queue-manager/SKILL.md +0 -31
  437. package/.agents/skills/stack/backend/cloudflare-workers/SKILL.md +0 -51
  438. package/.agents/skills/stack/backend/highlevel-crm/SKILL.md +0 -54
  439. package/.agents/skills/stack/backend/sqlite-drizzle-expert/SKILL.md +0 -29
  440. package/.agents/skills/stack/backend/sqlite-drizzle-expert/examples/schema-template.ts +0 -30
  441. package/.agents/skills/stack/backend/stripe-integration/SKILL.md +0 -57
  442. package/.agents/skills/stack/backend/stripe-integration/scripts/listen-stripe.sh +0 -9
  443. package/.agents/skills/stack/backend/turso-sqlite/SKILL.md +0 -48
  444. package/.agents/skills/stack/frontend/astro/SKILL.md +0 -62
  445. package/.agents/skills/stack/frontend/astro-react-island-strategist/SKILL.md +0 -30
  446. package/.agents/skills/stack/frontend/expo-react-native-developer/SKILL.md +0 -29
  447. package/.agents/skills/stack/frontend/google-analytics-v4/SKILL.md +0 -50
  448. package/.agents/skills/stack/frontend/tailwind-v4/SKILL.md +0 -58
  449. package/.agents/skills/stack/frontend/ui-accessibility-engineer/SKILL.md +0 -34
  450. package/.agents/skills/stack/qa/audit-accessibility/SKILL.md +0 -51
  451. package/.agents/skills/stack/qa/lighthouse-baseline/SKILL.md +0 -199
  452. package/.agents/skills/stack/security/backend-security-patterns/SKILL.md +0 -68
  453. package/.agents/workflows/helpers/deliver-epic-reference.md +0 -534
  454. package/.agents/workflows/helpers/deliver-epic.md +0 -955
  455. package/.agents/workflows/helpers/deliver-stories.md +0 -440
  456. package/.agents/workflows/helpers/epic-audit.md +0 -189
  457. package/.agents/workflows/helpers/epic-deliver-story.md +0 -427
  458. package/.agents/workflows/helpers/epic-testing.md +0 -125
  459. package/.agents/workflows/helpers/plan-epic-reference.md +0 -160
  460. package/.agents/workflows/helpers/plan-epic.md +0 -351
  461. package/.agents/workflows/helpers/plan-story.md +0 -251
  462. package/.agents/workflows/helpers/scope-triage-gate.md +0 -108
  463. /package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/spec-authoring-grounding.js +0 -0
@@ -1,198 +0,0 @@
1
- /**
2
- * merge-subject.js — assemble the conventional-commit subject used by
3
- * `runFinalizeMerge` and `runResumeMerge` and auto-truncate it on a
4
- * word boundary when it would exceed commitlint's `header-max-length`.
5
- *
6
- * Story #2466 (Epic #2453) auto-generated a 102-char merge subject that
7
- * commitlint rejected; `story-close.js`'s merge step silently rolled
8
- * back to staged-only on each retry. This helper prevents the rejection
9
- * by shaping the subject pre-commit:
10
- *
11
- * - The Conventional-Commits prefix (`<type>(<scope>): ` if scope is
12
- * provided, otherwise `<type>: `) is preserved verbatim.
13
- * - The ` (resolves #N)` suffix is preserved verbatim.
14
- * - The title segment is truncated on a word boundary (whitespace),
15
- * never mid-word, until the assembled subject's byte length fits
16
- * within the cap.
17
- * - On truncation, an operator-facing `Logger.warn` fires once and a
18
- * `truncated-from: <original>` body trailer is returned so the
19
- * caller can append it to the commit body.
20
- *
21
- * The cap is loaded from commitlint config via `@commitlint/load`,
22
- * cached per-cwd, and falls back to 100 (the
23
- * `@commitlint/config-conventional` default) when load fails.
24
- *
25
- * Pure (the shape function) + cached async loader. No I/O at shape time.
26
- */
27
-
28
- import path from 'node:path';
29
- import { Logger as DefaultLogger } from '../../Logger.js';
30
- import { resolvesToken } from '../resolves-token.js';
31
-
32
- const COMMITLINT_DEFAULT_HEADER_MAX_LENGTH = 100;
33
- const headerCapCache = new Map();
34
-
35
- /**
36
- * Load commitlint's `header-max-length` rule value for the given cwd.
37
- * Caches the resolved cap per absolute cwd so repeated close-path calls
38
- * inside a single process do not re-read commitlint config.
39
- *
40
- * Returns the default (100) when commitlint is not installed, the
41
- * config is missing, or the rule is absent / disabled.
42
- *
43
- * @param {string} cwd
44
- * @param {{ logger?: { warn?: Function } }} [opts]
45
- * @returns {Promise<number>}
46
- */
47
- export async function loadHeaderMaxLength(cwd, opts = {}) {
48
- const logger = opts.logger ?? DefaultLogger;
49
- const key = path.resolve(cwd);
50
- if (headerCapCache.has(key)) return headerCapCache.get(key);
51
- let cap = COMMITLINT_DEFAULT_HEADER_MAX_LENGTH;
52
- try {
53
- const mod = await import('@commitlint/load');
54
- const load = mod.default ?? mod.load ?? mod;
55
- const loaded = await load({}, { cwd: key });
56
- const rule = loaded?.rules?.['header-max-length'];
57
- if (Array.isArray(rule) && rule.length >= 3) {
58
- const [level, _applicable, value] = rule;
59
- if (level > 0 && Number.isFinite(value) && value > 0) {
60
- cap = value;
61
- }
62
- }
63
- } catch (err) {
64
- logger?.warn?.(
65
- `[merge-subject] commitlint header-max-length load failed; ` +
66
- `using default ${COMMITLINT_DEFAULT_HEADER_MAX_LENGTH}: ${err?.message ?? err}`,
67
- );
68
- }
69
- headerCapCache.set(key, cap);
70
- return cap;
71
- }
72
-
73
- /**
74
- * Test-only: clear the per-cwd cap cache.
75
- */
76
- export function _resetHeaderMaxLengthCache() {
77
- headerCapCache.clear();
78
- }
79
-
80
- function buildPrefix(type, scope) {
81
- return scope ? `${type}(${scope}): ` : `${type}: `;
82
- }
83
-
84
- // Caps the `truncated-from: <subject>` trailer at `cap` bytes so it
85
- // satisfies commitlint's `footer-max-line-length` rule. Without this
86
- // cap, an original subject near the header cap (100) produces a
87
- // ~116-char trailer line.
88
- function buildTruncatedFromTrailer(originalSubject, cap) {
89
- const prefix = 'truncated-from: ';
90
- const budget = Math.max(0, cap - Buffer.byteLength(prefix, 'utf8'));
91
- if (Buffer.byteLength(originalSubject, 'utf8') <= budget) {
92
- return `${prefix}${originalSubject}`;
93
- }
94
- const ellipsisBytes = Buffer.byteLength('…', 'utf8');
95
- let value = originalSubject;
96
- while (Buffer.byteLength(value, 'utf8') + ellipsisBytes > budget) {
97
- value = value.slice(0, -1);
98
- }
99
- return `${prefix}${value}…`;
100
- }
101
-
102
- function truncateTitleOnWordBoundary(title, budget) {
103
- if (budget <= 0) return '';
104
- if (Buffer.byteLength(title, 'utf8') <= budget) return title;
105
- // Greedy: drop trailing tokens until the title fits the byte budget.
106
- let truncated = title;
107
- while (Buffer.byteLength(truncated, 'utf8') > budget) {
108
- const lastWs = truncated.search(/\s+\S*$/u);
109
- if (lastWs <= 0) {
110
- // No earlier whitespace — fall back to byte-safe slice.
111
- truncated = truncated.slice(0, Math.max(0, truncated.length - 1));
112
- continue;
113
- }
114
- truncated = truncated.slice(0, lastWs);
115
- }
116
- return truncated.replace(/\s+$/u, '');
117
- }
118
-
119
- /**
120
- * Shape a Conventional-Commits subject so it fits within `headerMaxLength`.
121
- *
122
- * Returns `{ subject, original, truncated, bodyTrailer }`:
123
- * - `subject` — the (possibly truncated) one-line subject.
124
- * - `original` — the un-truncated subject (always populated).
125
- * - `truncated` — boolean, true iff truncation fired.
126
- * - `bodyTrailer` — `truncated-from: <original>` when truncated, else null.
127
- *
128
- * Side effects: on truncation, emits a single `Logger.warn` line naming
129
- * the original and truncated subjects.
130
- *
131
- * @param {{
132
- * type: string,
133
- * scope?: string|null,
134
- * title: string,
135
- * storyId: number|string,
136
- * headerMaxLength?: number,
137
- * logger?: { warn?: Function },
138
- * }} args
139
- * @returns {{ subject: string, original: string, truncated: boolean, bodyTrailer: string|null }}
140
- */
141
- export function shapeMergeSubject({
142
- type,
143
- scope = null,
144
- title,
145
- storyId,
146
- headerMaxLength = COMMITLINT_DEFAULT_HEADER_MAX_LENGTH,
147
- logger = DefaultLogger,
148
- }) {
149
- const lcTitle = title.charAt(0).toLowerCase() + title.slice(1);
150
- const prefix = buildPrefix(type, scope);
151
- const suffix = resolvesToken(storyId);
152
- const originalSubject = `${prefix}${lcTitle}${suffix}`;
153
- if (Buffer.byteLength(originalSubject, 'utf8') <= headerMaxLength) {
154
- return {
155
- subject: originalSubject,
156
- original: originalSubject,
157
- truncated: false,
158
- bodyTrailer: null,
159
- };
160
- }
161
- const fixedBytes =
162
- Buffer.byteLength(prefix, 'utf8') + Buffer.byteLength(suffix, 'utf8');
163
- const titleBudget = headerMaxLength - fixedBytes;
164
- const truncatedTitle = truncateTitleOnWordBoundary(lcTitle, titleBudget);
165
- const subject = `${prefix}${truncatedTitle}${suffix}`;
166
- logger?.warn?.(
167
- `[merge-subject] subject exceeded commitlint cap (${headerMaxLength}); ` +
168
- `truncated on word boundary. original="${originalSubject}" ` +
169
- `truncated="${subject}"`,
170
- );
171
- return {
172
- subject,
173
- original: originalSubject,
174
- truncated: true,
175
- bodyTrailer: buildTruncatedFromTrailer(originalSubject, headerMaxLength),
176
- };
177
- }
178
-
179
- /**
180
- * Convenience: shape a subject and assemble the final commit message
181
- * (subject plus optional trailer block). Returns a single string suitable
182
- * for passing as the `-m` argument to `git commit` / `git merge`.
183
- *
184
- * @param {Parameters<typeof shapeMergeSubject>[0]} args
185
- * @returns {{ message: string, subject: string, original: string, truncated: boolean }}
186
- */
187
- export function buildMergeMessageWithCap(args) {
188
- const shaped = shapeMergeSubject(args);
189
- const message = shaped.bodyTrailer
190
- ? `${shaped.subject}\n\n${shaped.bodyTrailer}`
191
- : shaped.subject;
192
- return {
193
- message,
194
- subject: shaped.subject,
195
- original: shaped.original,
196
- truncated: shaped.truncated,
197
- };
198
- }
@@ -1,105 +0,0 @@
1
- /**
2
- * phases/branch-restore.js — capture + restore the main-repo's starting
3
- * branch around the merge-lock-protected close (Story #2138 / #2141; moved
4
- * into the phases pipeline by Story #2460, Epic #2453).
5
- *
6
- * The orchestrator captures the starting branch BEFORE entering the
7
- * merge lock and runs `restoreStartingBranch` in a `finally` block, so
8
- * any throw inside `runStoryCloseLocked` leaves the operator on the
9
- * branch they came in on rather than stranded mid-rebase / mid-merge.
10
- *
11
- * Public surface:
12
- * - captureStartingBranch(cwd, deps?) ← exported (story-close.js re-export)
13
- * - restoreStartingBranch(opts, deps?) ← exported (story-close.js re-export)
14
- */
15
-
16
- import { gitSpawn as defaultGitSpawn } from '../../../git-utils.js';
17
- import { Logger } from '../../../Logger.js';
18
-
19
- /**
20
- * Capture the main-repo's current branch name before `runStoryCloseLocked`
21
- * runs. Returns `{ ok: true, branch }` on success, `{ ok: false, reason }`
22
- * when HEAD is detached or `git rev-parse` fails.
23
- *
24
- * @param {string} cwd
25
- * @param {{ gitSpawn?: typeof defaultGitSpawn }} [deps]
26
- * @returns {{ ok: true, branch: string } | { ok: false, reason: string }}
27
- */
28
- export function captureStartingBranch(cwd, deps = {}) {
29
- const gitSpawn = deps.gitSpawn ?? defaultGitSpawn;
30
- const res = gitSpawn(cwd, 'rev-parse', '--abbrev-ref', 'HEAD');
31
- if (res.status !== 0) {
32
- return {
33
- ok: false,
34
- reason: `rev-parse-failed: ${res.stderr || 'unknown'}`,
35
- };
36
- }
37
- const branch = (res.stdout || '').trim();
38
- if (!branch || branch === 'HEAD') {
39
- return { ok: false, reason: 'detached-head' };
40
- }
41
- return { ok: true, branch };
42
- }
43
-
44
- /**
45
- * Restore the main-repo to `startingBranch` via `git switch`. Refuses the
46
- * switch when the destination tree is dirty (`git status --porcelain` is
47
- * non-empty). Never invokes `git reset --hard` or `git checkout --force`.
48
- *
49
- * Returns a structured envelope so callers (and tests) can assert which
50
- * branch they end up on and why.
51
- *
52
- * @param {object} opts
53
- * @param {string} opts.cwd
54
- * @param {{ ok: boolean, branch?: string, reason?: string }} opts.captured
55
- * @param {{ gitSpawn?: typeof defaultGitSpawn, logger?: object }} [deps]
56
- * @returns {{ restored: boolean, branch?: string, reason?: string, skipped?: boolean }}
57
- */
58
- export function restoreStartingBranch({ cwd, captured }, deps = {}) {
59
- const gitSpawn = deps.gitSpawn ?? defaultGitSpawn;
60
- const log = deps.logger ?? Logger;
61
- if (!captured || captured.ok !== true) {
62
- return {
63
- restored: false,
64
- skipped: true,
65
- reason: captured?.reason
66
- ? `no-starting-branch: ${captured.reason}`
67
- : 'no-starting-branch',
68
- };
69
- }
70
- const { branch } = captured;
71
- const currentRes = gitSpawn(cwd, 'rev-parse', '--abbrev-ref', 'HEAD');
72
- if (currentRes.status === 0 && currentRes.stdout.trim() === branch) {
73
- return { restored: true, branch, reason: 'already-on-branch' };
74
- }
75
- const statusRes = gitSpawn(cwd, 'status', '--porcelain');
76
- if (statusRes.status !== 0) {
77
- log.warn?.(
78
- `[story-close] branch-restore: \`git status --porcelain\` failed in ${cwd}: ${statusRes.stderr || 'unknown'}`,
79
- );
80
- return {
81
- restored: false,
82
- branch,
83
- reason: `status-failed: ${statusRes.stderr || 'unknown'}`,
84
- };
85
- }
86
- if (statusRes.stdout.length > 0) {
87
- log.error?.(
88
- `[story-close] branch-restore: refusing to switch to \`${branch}\` — working tree is dirty in ${cwd}. ` +
89
- `Resolve the local changes manually, then \`git switch ${branch}\`.`,
90
- );
91
- return { restored: false, branch, reason: 'dirty-tree' };
92
- }
93
- const switchRes = gitSpawn(cwd, 'switch', branch);
94
- if (switchRes.status !== 0) {
95
- log.warn?.(
96
- `[story-close] branch-restore: \`git switch ${branch}\` failed: ${switchRes.stderr || 'unknown'}`,
97
- );
98
- return {
99
- restored: false,
100
- branch,
101
- reason: `switch-failed: ${switchRes.stderr || 'unknown'}`,
102
- };
103
- }
104
- return { restored: true, branch };
105
- }
@@ -1,222 +0,0 @@
1
- /**
2
- * phases/close.js — merge + post-merge pipeline phase (Story #2460,
3
- * Epic #2453 — CLI thinning pilot).
4
- *
5
- * Runs once the pre-merge gates have passed (or been skipped on a
6
- * resume path). Owns:
7
- * - the resume-aware merge runner dispatch (`runResumeMerge` vs
8
- * `runFinalizeMerge`, skipped entirely on a `resumeFromPostMerge` path),
9
- * - the post-merge close pipeline (ticket transitions, cascade, health,
10
- * dashboard regen) via `runPostMergeClose`,
11
- * - the success-path close-result envelope serialisation.
12
- *
13
- * Public surface:
14
- * - runMergePhase(ctx)
15
- * - runPostMergePhase(ctx)
16
- * - runClosePhase(ctx) ← composite (merge → post-merge)
17
- *
18
- * The split between `runMergePhase` and `runPostMergePhase` keeps each
19
- * function at one level of abstraction (and well under the < 200 LOC /
20
- * CC < 12 phase-file budget).
21
- */
22
-
23
- import { Logger } from '../../../Logger.js';
24
- import { PROJECT_ROOT } from '../../../project-root.js';
25
- import { STATE_LABELS } from '../../ticketing.js';
26
- import { runFinalizeMerge, runResumeMerge } from '../merge-runner.js';
27
- import { runPostMergeClose } from '../post-merge-close.js';
28
-
29
- /**
30
- * Story #2961 — final assertion that the Story ticket reached
31
- * `agent::done` after the post-merge cascade. The cascade is the single
32
- * writer of the `closing → done` label flip; without this readback,
33
- * `runStoryClose` returns `success: true` even when the flip silently
34
- * failed (the failure mode that Epic #2880 wave 0's friction note
35
- * F-W0-2 surfaced via the runner's GitHub probe — see Story #2894).
36
- *
37
- * Outcomes:
38
- * - `{ ok: true }` — ticket has `agent::done` (or is closed).
39
- * - `{ ok: false, actualLabels }` — cascade returned but the label
40
- * never reached `agent::done`. The caller must downgrade
41
- * `success: true` → `success: false`.
42
- * - `{ ok: 'skipped', warning }` — `provider.getTicket` threw. The
43
- * verification could not run, but the close itself succeeded, so
44
- * the caller returns the success envelope with a `warnings[]` entry.
45
- */
46
- export async function verifyFinalStoryLabel({ provider, storyId }) {
47
- if (!provider || typeof provider.getTicket !== 'function') {
48
- return {
49
- ok: 'skipped',
50
- warning: `label-verification-skipped: provider.getTicket unavailable`,
51
- };
52
- }
53
- let ticket;
54
- try {
55
- ticket = await provider.getTicket(storyId, { fresh: true });
56
- } catch (err) {
57
- return {
58
- ok: 'skipped',
59
- warning: `label-verification-skipped: ${err?.message ?? err}`,
60
- };
61
- }
62
- const labels = Array.isArray(ticket?.labels) ? ticket.labels : [];
63
- if (labels.includes(STATE_LABELS.DONE) || ticket?.state === 'closed') {
64
- return { ok: true };
65
- }
66
- return { ok: false, actualLabels: labels };
67
- }
68
-
69
- /**
70
- * Run the merge step. Skipped entirely on the already-merged resume path
71
- * — the merge already landed on `origin/epic/<id>` during the prior close
72
- * attempt; the only remaining work is the post-merge pipeline.
73
- */
74
- export async function runMergePhase(ctx) {
75
- const {
76
- resumeFromConflict,
77
- resumeFromPostMerge,
78
- cwd,
79
- epicBranch,
80
- storyBranch,
81
- story,
82
- storyId,
83
- epicId,
84
- config,
85
- bus,
86
- progress,
87
- progressLog,
88
- } = ctx;
89
-
90
- if (resumeFromPostMerge) {
91
- progress(
92
- 'MERGE',
93
- `Skipping rebase + merge — story tip already reachable from ${epicBranch}`,
94
- );
95
- return;
96
- }
97
-
98
- const mergeArgs = {
99
- cwd,
100
- epicBranch,
101
- storyBranch,
102
- storyTitle: story.title,
103
- storyId,
104
- epicId,
105
- config,
106
- bus,
107
- log: progressLog,
108
- };
109
- await (resumeFromConflict ? runResumeMerge : runFinalizeMerge)(mergeArgs);
110
- }
111
-
112
- /**
113
- * Run the post-merge close pipeline — ticket transitions, cascade, health
114
- * regen, dashboard regen. Returns the final close-result envelope.
115
- */
116
- export async function runPostMergePhase(ctx) {
117
- const {
118
- config,
119
- storyId,
120
- epicId,
121
- story,
122
- storyBranch,
123
- epicBranch,
124
- cwd,
125
- provider,
126
- notifyFn,
127
- tasks,
128
- skipDashboard,
129
- progress,
130
- phaseTimer,
131
- clearPhaseTimerState,
132
- bus,
133
- } = ctx;
134
-
135
- return runPostMergeClose({
136
- config,
137
- storyId,
138
- epicId,
139
- story,
140
- storyBranch,
141
- epicBranch,
142
- cwd,
143
- projectRoot: PROJECT_ROOT,
144
- provider,
145
- notify: notifyFn,
146
- tasks,
147
- skipDashboard,
148
- progress,
149
- logger: Logger,
150
- phaseTimer,
151
- clearPhaseTimerState,
152
- bus,
153
- });
154
- }
155
-
156
- /**
157
- * Pure envelope builder. Given the post-merge `result` and the
158
- * `verifyFinalStoryLabel` verdict, returns the close-result envelope
159
- * `runClosePhase` will surface back to `runStoryClose`. Exported so the
160
- * contract test can drive the failure / skipped / success branches
161
- * without spinning up the merge + cascade pipeline.
162
- */
163
- export function buildCloseEnvelope({ result, verdict, storyId }) {
164
- if (verdict.ok === false) {
165
- const failedResult = {
166
- ...result,
167
- status: 'failed',
168
- phase: 'closing',
169
- reason: 'label-transition-failed',
170
- actualLabels: verdict.actualLabels,
171
- };
172
- Logger.warn?.(
173
- `[story-close] ❌ Story #${storyId} cascade returned but label is not ` +
174
- `${STATE_LABELS.DONE} (actual: ${JSON.stringify(verdict.actualLabels)}). ` +
175
- `Returning failure envelope.`,
176
- );
177
- return { success: false, result: failedResult };
178
- }
179
- if (verdict.ok === 'skipped') {
180
- return {
181
- success: true,
182
- result: { ...result, warnings: [verdict.warning] },
183
- };
184
- }
185
- return { success: true, result };
186
- }
187
-
188
- /**
189
- * Composite phase: merge → post-merge close → final-label readback →
190
- * envelope serialise. The caller (`runStoryCloseLocked` in
191
- * story-close.js) marks the `close` phase on its phase timer before
192
- * calling in.
193
- */
194
- export async function runClosePhase(ctx) {
195
- await runMergePhase(ctx);
196
- const result = await runPostMergePhase(ctx);
197
-
198
- // Story #2961 — final readback before declaring success. The
199
- // post-merge cascade is the single writer for the `closing → done`
200
- // label flip; if it silently failed, surface a failure envelope here
201
- // rather than relying on the runner's downstream GitHub probe.
202
- const verdict = await verifyFinalStoryLabel({
203
- provider: ctx.provider,
204
- storyId: ctx.storyId,
205
- });
206
- const envelope = buildCloseEnvelope({
207
- result,
208
- verdict,
209
- storyId: ctx.storyId,
210
- });
211
-
212
- Logger.info(
213
- `\n--- STORY CLOSE RESULT ---\n${JSON.stringify(envelope.result, null, 2)}\n--- END RESULT ---\n`,
214
- );
215
- if (envelope.success) {
216
- ctx.progress(
217
- 'DONE',
218
- `✅ Story #${ctx.storyId} merged into ${ctx.epicBranch}. ${envelope.result.ticketsClosed.length} ticket(s) closed.`,
219
- );
220
- }
221
- return envelope;
222
- }