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
@@ -16,11 +16,10 @@
16
16
  */
17
17
 
18
18
  import { Logger } from '../../lib/Logger.js';
19
- import { TYPE_LABELS } from '../../lib/label-constants.js';
20
19
  import { concurrentMap } from '../../lib/util/concurrent-map.js';
21
20
  import { isNotFoundError } from './branch-protection.js';
22
21
  import { withTransientRetry } from './errors.js';
23
- import { issueToEpic, issueToEpicListItem } from './mappers.js';
22
+ import { issueToEpic } from './mappers.js';
24
23
  import {
25
24
  defaultRetryWarn,
26
25
  paginateRest,
@@ -114,13 +113,15 @@ export class IssuesGateway {
114
113
  * are returned (no `state:` qualifier is appended) so a closed-fingerprint
115
114
  * match can surface as `regression-of-closed`.
116
115
  *
117
- * Returns the trimmed `[{ number, state, body }]` projection the dedup
118
- * port expects. `state` is normalised to the REST lowercase form
119
- * (`open` / `closed`).
116
+ * Returns the trimmed `[{ number, state, body, title, html_url }]`
117
+ * projection. Dedup callers use `{ number, state, body }`; duplicate-
118
+ * search also needs `title` / `html_url`. `state` is normalised to the
119
+ * REST lowercase form (`open` / `closed`). Results are capped at one
120
+ * Search API page (`per_page=100`).
120
121
  *
121
122
  * @param {{ query: string, owner?: string, repo?: string }} params
122
- * @returns {Promise<Array<{ number: number, state: string, body: string }>>}
123
- * @field-manifest GET /search/issues: total_count, items[number, state, body]
123
+ * @returns {Promise<Array<{ number: number, state: string, body: string, title: string, html_url?: string }>>}
124
+ * @field-manifest GET /search/issues: total_count, items[number, state, body, title, html_url]
124
125
  */
125
126
  async searchIssues({ query, owner, repo } = {}) {
126
127
  if (typeof query !== 'string' || query.trim().length === 0) {
@@ -133,7 +134,8 @@ export class IssuesGateway {
133
134
  // issue body where the `<!-- audit-fingerprints: ... -->` footer lives.
134
135
  const qualifiers = [`repo:${scopeOwner}/${scopeRepo}`, 'type:issue'];
135
136
  const q = `${query.trim()} ${qualifiers.join(' ')}`;
136
- const endpoint = `/search/issues?q=${encodeURIComponent(q)}`;
137
+ const params = new URLSearchParams({ q, per_page: '100' });
138
+ const endpoint = `/search/issues?${params}`;
137
139
  const result = await withTransientRetry(
138
140
  () => this._gh.api({ method: 'GET', endpoint }),
139
141
  { label: `searchIssues ${query}`, onRetry: defaultRetryWarn },
@@ -144,37 +146,19 @@ export class IssuesGateway {
144
146
  number: item.number,
145
147
  state: item.state ?? 'open',
146
148
  body: item.body ?? '',
149
+ title: item.title ?? '',
150
+ html_url: item.html_url ?? undefined,
147
151
  }));
148
152
  }
149
153
 
150
154
  /**
151
- * List Epic-typed issues. Filter shape preserved from the old code.
152
- *
153
- * `filters.pageCap` / `filters.perPage` pass through to `paginateRest`
154
- * so a caller that only needs a bounded shortlist (e.g. the
155
- * standalone-Story corpus lookup in `planning-corpus.js`, which ranks
156
- * candidates down to a top-5 shortlist) can cap the scan instead of
157
- * inheriting the default 50-page / 5000-item ceiling. Omitted, both
158
- * fall back to `paginateRest`'s own defaults — unchanged behavior for
159
- * existing callers (e.g. `duplicate-search.js`).
160
- *
161
- * @field-manifest /repos/{owner}/{repo}/issues?labels=type::epic: number,
162
- * title, labels, state, state_reason, pull_request
155
+ * Historical Epic enumeration surface. Stage 5 removed the Epic type from
156
+ * the taxonomy; callers that have not yet collapsed their planning corpus
157
+ * reads receive an empty list rather than querying a deleted label.
163
158
  */
164
159
  /* node:coverage ignore next */
165
- async getEpics(filters = {}) {
166
- const params = new URLSearchParams({
167
- state: filters.state ?? 'all',
168
- labels: TYPE_LABELS.EPIC,
169
- });
170
- const endpoint = `/repos/${this.owner}/${this.repo}/issues?${params}`;
171
- const issues = await paginateRest(this._gh, endpoint, {
172
- pageCap: filters.pageCap,
173
- perPage: filters.perPage,
174
- });
175
- return issues
176
- .filter((issue) => !issue.pull_request)
177
- .map(issueToEpicListItem);
160
+ async getEpics(_filters = {}) {
161
+ return [];
178
162
  }
179
163
 
180
164
  /**
@@ -109,15 +109,3 @@ export function issueToListItem(issue) {
109
109
  state: issue.state,
110
110
  };
111
111
  }
112
-
113
- export function issueToEpicListItem(issue) {
114
- const labels = normalizeLabels(issue);
115
- return {
116
- id: issue.number,
117
- title: issue.title,
118
- labels,
119
- labelSet: new Set(labels),
120
- state: issue.state,
121
- state_reason: issue.state_reason,
122
- };
123
- }
@@ -336,12 +336,9 @@ export class TicketGateway {
336
336
  dependencies: ticketData.dependencies ?? [],
337
337
  });
338
338
 
339
- // Mirror the Epic create path (issues.js:160 `labels: TYPE_LABELS.EPIC`):
340
- // inject TYPE_LABELS.STORY so a spec that omits the labels array cannot
339
+ // Inject TYPE_LABELS.STORY so a spec that omits the labels array cannot
341
340
  // produce an unlabeled, undispatchable Story. Dedupe to avoid duplicates
342
- // when the caller already carries the label. (Story #4324 retired the
343
- // `context::*` ticket classes, so every ticket created through this
344
- // factory is a Story.)
341
+ // when the caller already carries the label.
345
342
  const callerLabels = ticketData.labels ?? [];
346
343
  const labels = callerLabels.includes(TYPE_LABELS.STORY)
347
344
  ? callerLabels
@@ -0,0 +1,117 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * resolve-plan-run.js — resolve Stories labeled `plan-run::<id>` for
5
+ * `/deliver --run <planRunId>` (v2 Stage 4).
6
+ *
7
+ * Thin CLI over `lib/orchestration/resolve-plan-run.js`.
8
+ *
9
+ * Usage:
10
+ * node .agents/scripts/resolve-plan-run.js --run <planRunId>
11
+ * node .agents/scripts/resolve-plan-run.js --run <planRunId> --state all
12
+ * node .agents/scripts/resolve-plan-run.js --run <planRunId> --pretty
13
+ *
14
+ * Exit codes: 0 ok, 1 usage/error, 2 no Stories found for the run.
15
+ */
16
+
17
+ import { parseArgs } from 'node:util';
18
+
19
+ import { runAsCli } from './lib/cli-utils.js';
20
+ import { resolveConfig } from './lib/config-resolver.js';
21
+ import {
22
+ assertIssueState,
23
+ buildPlanRunEnvelope,
24
+ fetchPlanRunIssues,
25
+ normalizePlanRunLabel,
26
+ planRunIdFromLabel,
27
+ resolvePlanRunFromIssues,
28
+ } from './lib/orchestration/resolve-plan-run.js';
29
+ import { createProvider } from './lib/provider-factory.js';
30
+
31
+ export {
32
+ buildPlanRunEnvelope,
33
+ fetchPlanRunIssues,
34
+ normalizePlanRunLabel,
35
+ planRunIdFromLabel,
36
+ resolvePlanRunFromIssues,
37
+ };
38
+
39
+ const HELP = `\
40
+ Usage:
41
+ resolve-plan-run.js --run <planRunId> [--state open|all|closed] [--pretty]
42
+
43
+ Resolve Stories labeled plan-run::<planRunId> for /deliver --run.
44
+
45
+ Options:
46
+ --run <id> Plan-run token (with or without the plan-run:: prefix).
47
+ --state <s> Issue state filter (default: open).
48
+ --pretty Pretty-print the JSON envelope.
49
+ --help Show this help.
50
+ `;
51
+
52
+ function writeEnvelope(envelope, pretty) {
53
+ const text = pretty
54
+ ? `${JSON.stringify(envelope, null, 2)}\n`
55
+ : `${JSON.stringify(envelope)}\n`;
56
+ process.stdout.write(text);
57
+ }
58
+
59
+ /**
60
+ * Resolve config once and pass it to the provider factory. Kept as an
61
+ * injectable seam so the CLI contract is covered without network access.
62
+ *
63
+ * @param {object} [deps]
64
+ * @param {Function} [deps.resolveConfigFn]
65
+ * @param {Function} [deps.createProviderFn]
66
+ * @returns {object}
67
+ */
68
+ export function resolvePlanRunProvider({
69
+ resolveConfigFn = resolveConfig,
70
+ createProviderFn = createProvider,
71
+ } = {}) {
72
+ const config = resolveConfigFn();
73
+ return createProviderFn(config);
74
+ }
75
+
76
+ async function main() {
77
+ const { values } = parseArgs({
78
+ options: {
79
+ run: { type: 'string' },
80
+ state: { type: 'string', default: 'open' },
81
+ pretty: { type: 'boolean', default: false },
82
+ help: { type: 'boolean', default: false },
83
+ },
84
+ allowPositionals: false,
85
+ });
86
+
87
+ if (values.help) {
88
+ process.stdout.write(HELP);
89
+ return 0;
90
+ }
91
+ if (!values.run) {
92
+ process.stderr.write(HELP);
93
+ throw new Error('resolve-plan-run: --run <planRunId> is required');
94
+ }
95
+
96
+ const state = assertIssueState(values.state);
97
+ const planRunLabel = normalizePlanRunLabel(values.run);
98
+ const planRunId = planRunIdFromLabel(planRunLabel);
99
+
100
+ const provider = resolvePlanRunProvider();
101
+ const issues = await fetchPlanRunIssues(provider, { planRunLabel, state });
102
+ const envelope = buildPlanRunEnvelope(issues, { planRunId, planRunLabel });
103
+ writeEnvelope(envelope, values.pretty);
104
+
105
+ if (envelope.stories.length === 0) {
106
+ process.stderr.write(
107
+ `resolve-plan-run: no type::story issues with label ${planRunLabel} (state=${state})\n`,
108
+ );
109
+ return 2;
110
+ }
111
+ return 0;
112
+ }
113
+
114
+ runAsCli(import.meta.url, main, {
115
+ source: 'resolve-plan-run',
116
+ propagateExitCode: true,
117
+ });
@@ -5,7 +5,7 @@
5
5
  * Task #1463).
6
6
  *
7
7
  * Reads signals via `lib/signals/read`, materialises a span-tree via
8
- * `lib/signals/buildSpanTree`, and prints a readable Epic → Story → Task →
8
+ * `lib/signals/buildSpanTree`, and prints a readable run → Story →
9
9
  * events tree to stdout. The output is **plain text via
10
10
  * `process.stdout.write`** — no Ink, no blessed, no terminal-control
11
11
  * escape sequences — so it works on Windows + bash hosts (see
@@ -16,10 +16,10 @@
16
16
  * stdout uses `process.stdout.write`, not the console).
17
17
  *
18
18
  * Usage:
19
- * node .agents/scripts/signals-view.js <epic-id> [--story <id>]
19
+ * node .agents/scripts/signals-view.js <run-id> [--story <id>]
20
20
  *
21
21
  * Args:
22
- * <epic-id> Positive integer Epic ID. Required.
22
+ * <run-id> Positive integer run ID. Required.
23
23
  * --story <id> Optional positive integer Story ID. When set,
24
24
  * narrows the printed tree to a single Story
25
25
  * subtree.
@@ -27,7 +27,7 @@
27
27
  * Exit codes:
28
28
  * 0 — happy path, OR missing signals file (friendly message printed,
29
29
  * no stack trace).
30
- * 1 — bad arguments (non-integer epic, missing positional, etc.).
30
+ * 1 — bad arguments (non-integer run, missing positional, etc.).
31
31
  *
32
32
  * Tempfile contract:
33
33
  * The viewer resolves the on-disk signals path via the configured
@@ -57,7 +57,7 @@ function println(line) {
57
57
  }
58
58
 
59
59
  const USAGE =
60
- 'Usage: node .agents/scripts/signals-view.js <epic-id> [--story <id>] [--temp-root <path>]';
60
+ 'Usage: node .agents/scripts/signals-view.js <run-id> [--story <id>] [--temp-root <path>]';
61
61
 
62
62
  /**
63
63
  * Parse a token as a strict positive integer (no leading +, no float, no
@@ -86,7 +86,7 @@ const HELP_FLAGS = new Set(['--help', '-h']);
86
86
  * print a friendly message and exit 1 without a stack trace.
87
87
  *
88
88
  * Delegates the flag walking to `parseStandardCliArgs` and post-validates
89
- * the diagnose-specific invariants (single positional epic-id, strictly
89
+ * the signals-view-specific invariants (single positional run-id, strictly
90
90
  * positive integers for both ids).
91
91
  *
92
92
  * @param {string[]} argv
@@ -94,7 +94,7 @@ const HELP_FLAGS = new Set(['--help', '-h']);
94
94
  */
95
95
  export function parseArgs(argv) {
96
96
  if (!Array.isArray(argv) || argv.length === 0) {
97
- return err(`missing <epic-id>. ${USAGE}`);
97
+ return err(`missing <run-id>. ${USAGE}`);
98
98
  }
99
99
  if (argv.some((t) => HELP_FLAGS.has(t))) return err(USAGE);
100
100
 
@@ -118,7 +118,7 @@ export function parseArgs(argv) {
118
118
  // Exactly one positional, which must be a strictly positive integer
119
119
  // (no leading `+`, no float, no trailing junk).
120
120
  if (positionals.length === 0) {
121
- return err(`missing <epic-id>. ${USAGE}`);
121
+ return err(`missing <run-id>. ${USAGE}`);
122
122
  }
123
123
  if (positionals.length > 1) {
124
124
  return err(`unexpected token ${JSON.stringify(positionals[1])}. ${USAGE}`);
@@ -126,7 +126,7 @@ export function parseArgs(argv) {
126
126
  const epic = parseStrictPositiveInt(positionals[0]);
127
127
  if (epic == null) {
128
128
  return err(
129
- `<epic-id> must be a positive integer; got ${JSON.stringify(positionals[0])}. ${USAGE}`,
129
+ `<run-id> must be a positive integer; got ${JSON.stringify(positionals[0])}. ${USAGE}`,
130
130
  );
131
131
  }
132
132
 
@@ -180,7 +180,7 @@ function describeEvent(evt) {
180
180
  */
181
181
  export function renderTree(tree, opts = {}) {
182
182
  const filter = opts.storyFilter ?? null;
183
- println(`Epic #${tree.epic ?? '?'}`);
183
+ println(`Run #${tree.epic ?? '?'}`);
184
184
  const stories =
185
185
  filter == null ? tree.stories : tree.stories.filter((s) => s.id === filter);
186
186
 
@@ -226,12 +226,16 @@ export async function main(argv, deps = {}) {
226
226
  println(parsed.error);
227
227
  return 1;
228
228
  }
229
- const { epic, story, tempRoot } = parsed;
229
+ const { epic: runId, story, tempRoot } = parsed;
230
230
  const read = deps.read ?? signals.read;
231
231
  const buildSpanTree = deps.buildSpanTree ?? signals.buildSpanTree;
232
232
  const config = buildConfig(tempRoot);
233
233
 
234
- const iter = read(story != null ? { epic, story, config } : { epic, config });
234
+ // The reader API still accepts the historical `epic` key while resolving
235
+ // the run directory through temp-paths (`temp/run-<id>/`).
236
+ const iter = read(
237
+ story != null ? { epic: runId, story, config } : { epic: runId, config },
238
+ );
235
239
 
236
240
  // Eagerly collect to detect the missing-file case before we start
237
241
  // printing — when the iterator yields nothing we want a friendly
@@ -241,7 +245,7 @@ export async function main(argv, deps = {}) {
241
245
  tree = await buildSpanTree(iter);
242
246
  } catch (err) {
243
247
  println(
244
- `signals: failed to read signals for Epic #${epic}: ${
248
+ `signals: failed to read signals for run #${runId}: ${
245
249
  err instanceof Error ? err.message : String(err)
246
250
  }`,
247
251
  );
@@ -250,7 +254,7 @@ export async function main(argv, deps = {}) {
250
254
 
251
255
  if (tree.stories.length === 0) {
252
256
  const scope = story != null ? ` (Story #${story})` : '';
253
- println(`No signals found for Epic #${epic}${scope}.`);
257
+ println(`No signals found for run #${runId}${scope}.`);
254
258
  return 0;
255
259
  }
256
260
 
@@ -258,15 +262,16 @@ export async function main(argv, deps = {}) {
258
262
  // `story` is omitted. If the requested Story filter doesn't match any
259
263
  // observed Story id, treat that as the missing-file case too.
260
264
  if (story != null && !tree.stories.some((s) => s.id === story)) {
261
- println(`No signals found for Epic #${epic} (Story #${story}).`);
265
+ println(`No signals found for run #${runId} (Story #${story}).`);
262
266
  return 0;
263
267
  }
264
268
 
265
- // Pin the Epic id on the tree to the requested one — `buildSpanTree`
266
- // pins it from the first observed event, which is normally the same,
267
- // but if every event lacks an `epic` field the tree's `epic` would be
269
+ // Pin the run id on the tree to the requested one — `buildSpanTree`
270
+ // stores it in the legacy `epic` field from the first observed event,
271
+ // which is normally the same, but if every event lacks that field the
272
+ // tree's `epic` would be
268
273
  // `null` while we still know what was requested.
269
- if (tree.epic == null) tree = { ...tree, epic };
274
+ if (tree.epic == null) tree = { ...tree, epic: runId };
270
275
 
271
276
  renderTree(tree, { storyFilter: story });
272
277
  return 0;
@@ -1,13 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * single-story-close.js — Close a standalone Story (no parent Epic).
4
+ * single-story-close.js — Close a Story against `main` (v2 `/deliver` path).
5
5
  *
6
- * Thin CLI entry for the `/single-story-deliver` workflow. Counterpart to
7
- * `story-close.js`, but skips the Epic-attached machinery (epic-merge-lock,
8
- * dispatchRecovery, auto-refresh, post-merge pipeline) because a standalone
9
- * Story has no parent to cascade to and reaches `main` via a human-approved
10
- * PR rather than an in-script merge.
6
+ * Thin CLI entry for `/deliver` / `helpers/deliver-story`. Opens a PR from
7
+ * `story-<id>` to `project.baseBranch`, runs Story-scope review, and arms
8
+ * auto-merge. There is no Epic parent, epic-merge-lock, or wave merge.
11
9
  *
12
10
  * Pipeline (each step is a phase under
13
11
  * `./lib/orchestration/single-story-close/phases/`):
@@ -44,18 +42,17 @@
44
42
  * [--wait-merge | --no-wait-merge]
45
43
  *
46
44
  * `--wait-merge` is the headless must-land signal (Story #4428, Epic
47
- * #4425): the invoking surface (a headless `/single-story-deliver` run, a
48
- * CI-driven wrapper, or `/deliver`'s standalone multi-Story fan-out) opts
49
- * in explicitly attended runs never pass it, so the default exit shape
50
- * (rest at `agent::closing`, issue OPEN) is unchanged. `--no-wait-merge` is
51
- * the explicit opt-out that always wins over `--wait-merge`, for a caller
52
- * that wants to manage merge confirmation externally even in an otherwise
53
- * headless context.
45
+ * #4425): the invoking surface (a headless `/deliver` run or a CI-driven
46
+ * wrapper) opts in explicitly attended runs never pass it, so the default
47
+ * exit shape (rest at `agent::closing`, issue OPEN) is unchanged.
48
+ * `--no-wait-merge` is the explicit opt-out that always wins over
49
+ * `--wait-merge`, for a caller that wants to manage merge confirmation
50
+ * externally even in an otherwise headless context.
54
51
  *
55
52
  * Exit codes: 0 ok, 1 error (including a headless `--wait-merge` run that
56
53
  * gave up without a confirmed merge — see phase 9 above).
57
54
  *
58
- * @see .agents/workflows/helpers/single-story-deliver.md
55
+ * @see .agents/workflows/helpers/deliver-story.md
59
56
  */
60
57
 
61
58
  import { runAsCli } from './lib/cli-utils.js';
@@ -10,7 +10,7 @@
10
10
  * auto-merge completes *asynchronously* after the close script exits, so
11
11
  * the `agent::done` flip (which closes the issue) is deferred to this
12
12
  * confirmation step, invoked by the CI-watch loop in
13
- * `single-story-deliver.md` Step 5 once `pr-watch-with-update.js` exits.
13
+ * `helpers/deliver-story.md` once `pr-watch-with-update.js` exits.
14
14
  *
15
15
  * The script:
16
16
  * 1. Resolves the PR number (`--pr <n>`, or probes
@@ -32,7 +32,7 @@
32
32
  *
33
33
  * Exit codes: 0 ok (merged, pending, or noop), 1 error.
34
34
  *
35
- * @see .agents/workflows/helpers/single-story-deliver.md § Step 5
35
+ * @see .agents/workflows/helpers/deliver-story.md
36
36
  */
37
37
 
38
38
  import { parseArgs } from 'node:util';
@@ -45,6 +45,7 @@ import { parsePrNumber } from './lib/orchestration/single-story-close/phases/cod
45
45
  import { parseCloseOptions } from './lib/orchestration/single-story-close/phases/options.js';
46
46
  import { createProvider } from './lib/provider-factory.js';
47
47
  import { confirmStoryMerged } from './lib/single-story/confirm-merge.js';
48
+ import { withConfirmFollowUps } from './lib/single-story/confirm-merge-follow-ups.js';
48
49
 
49
50
  const progress = Logger.createProgress('single-story-confirm-merge', {
50
51
  stderr: true,
@@ -98,6 +99,22 @@ async function resolvePrNumber({ cwd, storyBranch, gh }) {
98
99
  }
99
100
  }
100
101
 
102
+ function logConfirmResult(result) {
103
+ Logger.info(
104
+ `\n--- CONFIRM MERGE RESULT ---\n${JSON.stringify(result, null, 2)}\n--- END RESULT ---\n`,
105
+ );
106
+ return { success: true, result };
107
+ }
108
+
109
+ async function resolveConfirmPrNumber({ prParam, cwd, storyBranch, gh }) {
110
+ const rawPr = prParam ?? readPrFlag();
111
+ let prNumber = Number.parseInt(String(rawPr ?? ''), 10);
112
+ if (!Number.isInteger(prNumber) || prNumber <= 0) {
113
+ prNumber = await resolvePrNumber({ cwd, storyBranch, gh });
114
+ }
115
+ return Number.isInteger(prNumber) && prNumber > 0 ? prNumber : null;
116
+ }
117
+
101
118
  /**
102
119
  * Confirm a standalone Story's merge. Exported for testing.
103
120
  */
@@ -125,34 +142,28 @@ export async function runConfirmMerge({
125
142
  const config = injectedConfig || resolveConfig({ cwd });
126
143
  const provider = injectedProvider || createProvider(config);
127
144
  const gh = injectedGh ?? defaultGh;
128
- const storyBranch = getStoryBranch(0, storyId);
145
+ const storyBranch = getStoryBranch(storyId);
129
146
 
130
147
  progress('INIT', `Confirming merge for standalone Story #${storyId}...`);
131
148
 
132
- // Resolve the PR number: explicit injection wins; otherwise read the
133
- // `--pr` CLI flag; otherwise probe `gh pr list`.
134
- const rawPr = prParam ?? readPrFlag();
135
- let prNumber = Number.parseInt(String(rawPr ?? ''), 10);
136
- if (!Number.isInteger(prNumber) || prNumber <= 0) {
137
- prNumber = await resolvePrNumber({ cwd, storyBranch, gh });
138
- }
139
-
140
- if (!Number.isInteger(prNumber) || prNumber <= 0) {
149
+ const prNumber = await resolveConfirmPrNumber({
150
+ prParam,
151
+ cwd,
152
+ storyBranch,
153
+ gh,
154
+ });
155
+ if (prNumber == null) {
141
156
  progress(
142
157
  'CONFIRM',
143
158
  `⚠️ No PR found for ${storyBranch}; cannot confirm merge. Story stays at agent::closing.`,
144
159
  );
145
- const result = {
160
+ return logConfirmResult({
146
161
  storyId,
147
162
  standalone: true,
148
163
  action: 'pending',
149
164
  reason: 'no-pr',
150
165
  merged: false,
151
- };
152
- Logger.info(
153
- `\n--- CONFIRM MERGE RESULT ---\n${JSON.stringify(result, null, 2)}\n--- END RESULT ---\n`,
154
- );
155
- return { success: true, result };
166
+ });
156
167
  }
157
168
 
158
169
  const confirmation = await confirmStoryMerged({
@@ -168,14 +179,19 @@ export async function runConfirmMerge({
168
179
  readPrMergeStateFn: injectedReadPrMergeState,
169
180
  });
170
181
 
171
- const result = { standalone: true, prNumber, ...confirmation };
172
- Logger.info(
173
- `\n--- CONFIRM MERGE RESULT ---\n${JSON.stringify(result, null, 2)}\n--- END RESULT ---\n`,
174
- );
182
+ const result = await withConfirmFollowUps({
183
+ confirmation,
184
+ storyId,
185
+ prNumber,
186
+ provider,
187
+ config,
188
+ cwd,
189
+ progress,
190
+ });
175
191
  if (result.action === 'done') {
176
192
  progress('DONE', `✅ Standalone Story #${storyId} → agent::done (merged).`);
177
193
  }
178
- return { success: true, result };
194
+ return logConfirmResult(result);
179
195
  }
180
196
 
181
197
  runAsCli(import.meta.url, runConfirmMerge, {
@@ -2,14 +2,12 @@
2
2
  /* node:coverage ignore file */
3
3
 
4
4
  /**
5
- * single-story-init.js — Initialize a standalone Story (no parent Epic).
5
+ * single-story-init.js — Initialize a Story for v2 `/deliver`.
6
6
  *
7
- * Counterpart to `story-init.js` for the `/single-story-deliver` workflow.
8
- * The framework's main `story-init.js` requires an `Epic: #N` reference in
9
- * the Story body to trace hierarchy, seed the Story branch from
10
- * `epic/<id>`, and gate execution on the epic's dispatch manifest. None of
11
- * that applies to a standalone Story — a top-level work unit that branches
12
- * directly from `main` and opens its PR straight to `main`.
7
+ * Seeds `story-<id>` from `project.baseBranch` (default `main`), materialises
8
+ * the per-Story worktree when isolation is enabled, upserts a `story-init`
9
+ * structured comment, and flips the Story to `agent::executing`. There is no
10
+ * Epic parent, epic branch, or dispatch-manifest gate.
13
11
  *
14
12
  * What this script does:
15
13
  * 1. Validate the Story (type::story, not closed).
@@ -22,17 +20,14 @@
22
20
  * `standalone: true`.
23
21
  * 6. Flip the Story to `agent::executing`.
24
22
  *
25
- * What this script does NOT do (and why):
26
- * - Skips `validateBlockers` against the body's `Blocked by:` markers
27
- * pre-flight is still the operator's responsibility, but the Epic-scope
28
- * blocker chain doesn't fit.
29
- * - Skips child-Task transitions — a standalone Story is treated as
30
- * atomic (one branch, one commit-set, one PR).
23
+ * What this script does NOT do:
24
+ * - Child-Task transitions a Story is atomic (one branch, one
25
+ * commit-set, one PR to `main`).
31
26
  *
32
27
  * Usage: `node single-story-init.js --story <STORY_ID> [--dry-run]`
33
28
  * Exit codes: 0 ok, 1 error.
34
29
  *
35
- * @see .agents/workflows/helpers/single-story-deliver.md
30
+ * @see .agents/workflows/helpers/deliver-story.md
36
31
  */
37
32
 
38
33
  import { existsSync } from 'node:fs';
@@ -61,6 +56,7 @@ import {
61
56
  } from './lib/orchestration/git-cleanup/phases/fast-forward.js';
62
57
  import { verifyRemote } from './lib/orchestration/remote-verifier.js';
63
58
  import { acquireStoryLease } from './lib/orchestration/single-story-lease-guard.js';
59
+ import { handleRemoteVerificationFailure } from './lib/orchestration/story-init-remote.js';
64
60
  import {
65
61
  STATE_LABELS,
66
62
  transitionTicketState,
@@ -74,6 +70,7 @@ import { buildProtectionCtx } from './lib/single-story-sweep/protection-ctx.js';
74
70
  // friendly "run npm install" message.
75
71
  import { WorktreeManager } from './lib/worktree-manager.js';
76
72
 
73
+ export { handleRemoteVerificationFailure } from './lib/orchestration/story-init-remote.js';
77
74
  // `makeGhRunner` moved to the shared `single-story-sweep/protection-ctx.js`
78
75
  // module (Story #4373) so the three boot callers build an identical
79
76
  // protection ctx. Re-exported here to preserve its existing import path.
@@ -114,12 +111,20 @@ const progress = Logger.createProgress('single-story-init', { stderr: true });
114
111
  export function assertDeliverableStory(story, storyId) {
115
112
  if (!story.labels.includes(TYPE_LABELS.STORY)) {
116
113
  throw new Error(
117
- `Issue #${storyId} is not a Story (labels: ${story.labels.join(', ')}). Use /deliver or /deliver for Epic-attached work.`,
114
+ `Issue #${storyId} is not a Story (labels: ${story.labels.join(', ')}). ` +
115
+ 'v2 /deliver accepts type::story tickets only.',
118
116
  );
119
117
  }
120
118
  if (story.state === 'closed') {
121
119
  throw new Error(`Story #${storyId} is already closed.`);
122
120
  }
121
+ const body = typeof story.body === 'string' ? story.body : '';
122
+ if (/\b(?:Epic|Parent):\s*#\d+/i.test(body)) {
123
+ throw new Error(
124
+ `Story #${storyId} still declares an Epic/Parent footer. ` +
125
+ 'v2 delivery is Story-only — re-plan as a standalone Story before /deliver.',
126
+ );
127
+ }
123
128
  }
124
129
 
125
130
  /**
@@ -478,9 +483,7 @@ export async function runSingleStoryInit({
478
483
  const provider = injectedProvider || createProvider(config);
479
484
 
480
485
  const baseBranch = config.project?.baseBranch ?? 'main';
481
- // The first arg is unused (legacy epicId slot); pass 0 to satisfy the
482
- // numeric-validation guard.
483
- const storyBranch = getStoryBranch(0, storyId);
486
+ const storyBranch = getStoryBranch(storyId);
484
487
 
485
488
  const runtime = resolveRuntime({ config });
486
489
  progress(
@@ -489,8 +492,8 @@ export async function runSingleStoryInit({
489
492
  );
490
493
  progress('INIT', `Initializing standalone Story #${storyId}...`);
491
494
 
492
- // Issue #4483 — deterministic remote evidence at the standalone entry
493
- // seam (the counterpart to `epic-deliver-preflight.js`'s probe). The
495
+ // Issue #4483 — deterministic remote evidence at the v2 `/deliver` entry
496
+ // seam (`single-story-init.js`). The
494
497
  // probe is read-only, so it runs under --dry-run too. The CLI records
495
498
  // the fact; the workflow owns the `agent::blocked` transition on
496
499
  // `remoteVerified: false` — inline delivery to local `main` is never a
@@ -505,6 +508,12 @@ export async function runSingleStoryInit({
505
508
 
506
509
  const story = await provider.getTicket(storyId);
507
510
  assertDeliverableStory(story, storyId);
511
+ await handleRemoteVerificationFailure({
512
+ provider,
513
+ storyId,
514
+ remote,
515
+ dryRun,
516
+ });
508
517
 
509
518
  progress(
510
519
  'CONTEXT',