mandrel 1.94.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (393) hide show
  1. package/.agents/README.md +59 -73
  2. package/.agents/agents/story-worker.md +12 -13
  3. package/.agents/docs/SDLC.md +489 -1285
  4. package/.agents/docs/agentrc-reference.json +177 -67
  5. package/.agents/docs/configuration.md +104 -138
  6. package/.agents/docs/execution-reference.md +17 -20
  7. package/.agents/docs/quality-gates.md +13 -19
  8. package/.agents/docs/workflows.md +3 -3
  9. package/.agents/instructions.md +70 -81
  10. package/.agents/rules/ci-remediation.md +8 -12
  11. package/.agents/rules/git-conventions-reference.md +6 -7
  12. package/.agents/rules/git-conventions.md +16 -22
  13. package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
  14. package/.agents/schemas/agentrc.schema.json +54 -214
  15. package/.agents/schemas/lifecycle/ledger-record.schema.json +1 -1
  16. package/.agents/schemas/lifecycle/retro.end.schema.json +1 -1
  17. package/.agents/schemas/risk-verdict.schema.json +0 -13
  18. package/.agents/scripts/analyze-execution.js +1 -1
  19. package/.agents/scripts/audit-to-stories.js +7 -7
  20. package/.agents/scripts/boot-sweep.js +1 -1
  21. package/.agents/scripts/check-lifecycle-lint.js +6 -9
  22. package/.agents/scripts/check-prepush-recovery.js +1 -1
  23. package/.agents/scripts/cleanup-repo-test-temp.js +6 -1
  24. package/.agents/scripts/lib/Logger.js +6 -10
  25. package/.agents/scripts/lib/audit-suite/runner.js +2 -2
  26. package/.agents/scripts/lib/audit-suite/selector.js +5 -5
  27. package/.agents/scripts/lib/audit-to-stories/{seed-epic-from-findings.js → seed-from-findings.js} +9 -9
  28. package/.agents/scripts/lib/baselines/kernel.js +206 -18
  29. package/.agents/scripts/lib/baselines/kinds/maintainability.js +0 -4
  30. package/.agents/scripts/lib/baselines/reader.js +1 -6
  31. package/.agents/scripts/lib/bdd-runner-detect.js +5 -9
  32. package/.agents/scripts/lib/bootstrap/issue-forms-template.js +32 -33
  33. package/.agents/scripts/lib/checks/core-bare-clean.js +2 -2
  34. package/.agents/scripts/lib/checks/index.js +2 -1
  35. package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +23 -21
  36. package/.agents/scripts/lib/cli/standard-args.js +13 -22
  37. package/.agents/scripts/lib/cli-args.js +16 -7
  38. package/.agents/scripts/lib/close-validation/gates.js +2 -2
  39. package/.agents/scripts/lib/config/ci.js +6 -31
  40. package/.agents/scripts/lib/config/delivery-routing.js +45 -29
  41. package/.agents/scripts/lib/config/explain.js +55 -36
  42. package/.agents/scripts/lib/config/limits.js +17 -58
  43. package/.agents/scripts/lib/config/paths.js +0 -2
  44. package/.agents/scripts/lib/config/quality.js +1 -1
  45. package/.agents/scripts/lib/config/runners.js +17 -50
  46. package/.agents/scripts/lib/config/temp-paths.js +19 -14
  47. package/.agents/scripts/lib/config/worktree-isolation.js +0 -5
  48. package/.agents/scripts/lib/config-resolver.js +2 -7
  49. package/.agents/scripts/lib/config-settings-schema-delivery.js +24 -148
  50. package/.agents/scripts/lib/config-settings-schema-quality.js +8 -14
  51. package/.agents/scripts/lib/config-settings-schema.js +52 -38
  52. package/.agents/scripts/lib/dependency-parser.js +3 -2
  53. package/.agents/scripts/lib/doc-tiers.js +2 -2
  54. package/.agents/scripts/lib/duplicate-search.js +211 -41
  55. package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +1 -1
  56. package/.agents/scripts/lib/findings/promote-finding.js +5 -5
  57. package/.agents/scripts/lib/framework-version.js +2 -3
  58. package/.agents/scripts/lib/git-branch-cleanup.js +1 -10
  59. package/.agents/scripts/lib/git-branch-lifecycle.js +17 -22
  60. package/.agents/scripts/lib/git-utils.js +32 -6
  61. package/.agents/scripts/lib/github/framework-repo.js +6 -0
  62. package/.agents/scripts/lib/label-constants.js +10 -23
  63. package/.agents/scripts/lib/label-taxonomy.js +9 -43
  64. package/.agents/scripts/lib/observability/active-story-env.js +1 -1
  65. package/.agents/scripts/lib/observability/hook-heartbeat.js +20 -52
  66. package/.agents/scripts/lib/observability/source-classifier.js +3 -3
  67. package/.agents/scripts/lib/onboard/init-tail.js +1 -3
  68. package/.agents/scripts/lib/orchestration/audit-lens-routing.js +128 -0
  69. package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +8 -5
  70. package/.agents/scripts/lib/orchestration/ceremony-routing.js +83 -20
  71. package/.agents/scripts/lib/orchestration/code-review.js +20 -268
  72. package/.agents/scripts/lib/orchestration/column-sync.js +1 -1
  73. package/.agents/scripts/lib/orchestration/consolidation-precondition.js +1 -1
  74. package/.agents/scripts/lib/orchestration/context-envelope.js +2 -5
  75. package/.agents/scripts/lib/orchestration/docs-digest.js +8 -8
  76. package/.agents/scripts/lib/orchestration/file-assumptions.js +7 -13
  77. package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +1 -1
  78. package/.agents/scripts/lib/orchestration/lifecycle/emit-loop-tick.js +8 -8
  79. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +2 -2
  80. package/.agents/scripts/lib/orchestration/lifecycle/ledger-writer.js +6 -3
  81. package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +17 -43
  82. package/.agents/scripts/lib/orchestration/lint-baseline-service.js +4 -4
  83. package/.agents/scripts/lib/orchestration/merge-block-class.js +1 -1
  84. package/.agents/scripts/lib/orchestration/phase-runner.js +3 -2
  85. package/.agents/scripts/lib/orchestration/plan-context.js +248 -266
  86. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +1 -1
  87. package/.agents/scripts/lib/orchestration/plan-navigation.js +92 -0
  88. package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +61 -0
  89. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +97 -0
  90. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +223 -854
  91. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +361 -0
  92. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +35 -108
  93. package/.agents/scripts/lib/orchestration/plan-reachability.js +9 -14
  94. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +1 -1
  95. package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/authoring-context.js +13 -13
  96. package/.agents/scripts/lib/orchestration/planning/decomposer-context.js +27 -0
  97. package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/risk-verdict.js +3 -4
  98. package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +2 -2
  99. package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +8 -20
  100. package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +3 -2
  101. package/.agents/scripts/lib/orchestration/pr-base-guard.js +18 -28
  102. package/.agents/scripts/lib/orchestration/preflight-cache.js +5 -5
  103. package/.agents/scripts/lib/orchestration/remote-verifier.js +1 -1
  104. package/.agents/scripts/lib/orchestration/resolve-plan-run.js +155 -0
  105. package/.agents/scripts/lib/orchestration/resolves-token.js +1 -1
  106. package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +8 -8
  107. package/.agents/scripts/lib/orchestration/retro-proposals.js +140 -79
  108. package/.agents/scripts/lib/orchestration/review-depth.js +26 -12
  109. package/.agents/scripts/lib/orchestration/review-providers/codex.js +2 -2
  110. package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +21 -56
  111. package/.agents/scripts/lib/orchestration/run-epilogue.js +426 -0
  112. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +1 -1
  113. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +95 -41
  114. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +16 -13
  115. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +40 -0
  116. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +11 -3
  117. package/.agents/scripts/lib/orchestration/spec-freshness.js +14 -205
  118. package/.agents/scripts/lib/orchestration/spec-section-validator.js +4 -5
  119. package/.agents/scripts/lib/orchestration/spec-spill.js +60 -0
  120. package/.agents/scripts/lib/orchestration/split-policy-validator.js +188 -0
  121. package/.agents/scripts/lib/orchestration/story-close/emit-blocked.js +49 -0
  122. package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +15 -12
  123. package/.agents/scripts/lib/orchestration/story-follow-ups.js +237 -0
  124. package/.agents/scripts/lib/orchestration/story-init-remote.js +47 -0
  125. package/.agents/scripts/lib/orchestration/story-plan-state.js +48 -0
  126. package/.agents/scripts/lib/orchestration/{epic-runner → story-progress}/story-run-progress-writer.js +3 -3
  127. package/.agents/scripts/lib/orchestration/structured-comment-parser.js +1 -1
  128. package/.agents/scripts/lib/orchestration/task-body-validator.js +8 -18
  129. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +11 -61
  130. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +189 -373
  131. package/.agents/scripts/lib/orchestration/ticket-validator.js +2 -7
  132. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +0 -25
  133. package/.agents/scripts/lib/orchestration/ticketing/reads.js +29 -26
  134. package/.agents/scripts/lib/orchestration/ticketing/transition.js +5 -5
  135. package/.agents/scripts/lib/planning-corpus.js +16 -11
  136. package/.agents/scripts/lib/preflight-runner.js +2 -2
  137. package/.agents/scripts/lib/qa/coverage-verdict.js +5 -5
  138. package/.agents/scripts/lib/single-story/confirm-merge-follow-ups.js +36 -0
  139. package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +1 -1
  140. package/.agents/scripts/lib/story-adjacency.js +11 -14
  141. package/.agents/scripts/lib/story-body/story-body.js +124 -70
  142. package/.agents/scripts/lib/story-plan.js +2 -4
  143. package/.agents/scripts/lib/templates/decomposer-prompts.js +46 -45
  144. package/.agents/scripts/lib/templates/spec-author-prompts.js +47 -45
  145. package/.agents/scripts/lib/{epic-body-sections.js → ticket-body-sections.js} +26 -26
  146. package/.agents/scripts/lib/validation-evidence.js +1 -1
  147. package/.agents/scripts/lib/wave-runner/ready-set.js +6 -6
  148. package/.agents/scripts/lib/workspace-provisioner.js +1 -1
  149. package/.agents/scripts/lib/worktree/lifecycle/reap.js +5 -7
  150. package/.agents/scripts/lint-issue-body.js +71 -40
  151. package/.agents/scripts/mandrel-update-preflight.js +1 -1
  152. package/.agents/scripts/notify.js +4 -3
  153. package/.agents/scripts/plan-context.js +64 -74
  154. package/.agents/scripts/plan-persist.js +121 -280
  155. package/.agents/scripts/plan-run-epilogue.js +97 -0
  156. package/.agents/scripts/providers/github/issues.js +17 -33
  157. package/.agents/scripts/providers/github/mappers.js +0 -12
  158. package/.agents/scripts/providers/github/tickets.js +2 -5
  159. package/.agents/scripts/resolve-plan-run.js +117 -0
  160. package/.agents/scripts/signals-view.js +24 -19
  161. package/.agents/scripts/single-story-close.js +11 -14
  162. package/.agents/scripts/single-story-confirm-merge.js +39 -23
  163. package/.agents/scripts/single-story-init.js +29 -20
  164. package/.agents/scripts/stories-wave-tick.js +6 -6
  165. package/.agents/scripts/story-plan.js +26 -47
  166. package/.agents/scripts/update-ticket-state.js +6 -15
  167. package/.agents/skills/core/analyze-execution/SKILL.md +21 -18
  168. package/.agents/skills/core/idea-refinement/SKILL.md +6 -6
  169. package/.agents/skills/core/scope-triage/SKILL.md +28 -172
  170. package/.agents/skills/skills.index.json +3 -43
  171. package/.agents/starter-agentrc.json +0 -5
  172. package/.agents/templates/agent-protocol.md +9 -10
  173. package/.agents/workflows/audit-architecture.md +3 -3
  174. package/.agents/workflows/audit-clean-code.md +3 -3
  175. package/.agents/workflows/audit-dependencies.md +3 -3
  176. package/.agents/workflows/audit-devops.md +3 -3
  177. package/.agents/workflows/audit-documentation.md +5 -5
  178. package/.agents/workflows/audit-lighthouse.md +3 -3
  179. package/.agents/workflows/audit-navigability.md +3 -2
  180. package/.agents/workflows/audit-performance.md +3 -3
  181. package/.agents/workflows/audit-privacy.md +3 -3
  182. package/.agents/workflows/audit-quality.md +3 -3
  183. package/.agents/workflows/audit-security.md +3 -3
  184. package/.agents/workflows/audit-seo.md +3 -3
  185. package/.agents/workflows/audit-sre.md +3 -3
  186. package/.agents/workflows/audit-to-stories.md +20 -20
  187. package/.agents/workflows/audit-ux-ui.md +3 -3
  188. package/.agents/workflows/deliver.md +122 -174
  189. package/.agents/workflows/git-cleanup.md +3 -4
  190. package/.agents/workflows/helpers/_merge-conflict-template.md +1 -1
  191. package/.agents/workflows/helpers/acceptance-self-eval.md +16 -29
  192. package/.agents/workflows/helpers/code-review.md +70 -193
  193. package/.agents/workflows/helpers/{single-story-deliver-reference.md → deliver-story-reference.md} +12 -14
  194. package/.agents/workflows/helpers/{single-story-deliver.md → deliver-story.md} +113 -139
  195. package/.agents/workflows/helpers/diagnose.md +10 -10
  196. package/.agents/workflows/helpers/parallel-tooling.md +1 -1
  197. package/.agents/workflows/helpers/signals.md +16 -16
  198. package/.agents/workflows/helpers/worktree-lifecycle.md +48 -64
  199. package/.agents/workflows/mandrel-update.md +2 -1
  200. package/.agents/workflows/plan.md +112 -145
  201. package/.agents/workflows/qa-assist.md +24 -30
  202. package/.agents/workflows/qa-explore.md +29 -38
  203. package/.agents/workflows/qa-run.md +2 -2
  204. package/README.md +9 -8
  205. package/docs/CHANGELOG.md +30 -0
  206. package/lib/migrations/index.js +6 -5
  207. package/package.json +2 -2
  208. package/.agents/agents/retro.md +0 -42
  209. package/.agents/personas/architect.md +0 -113
  210. package/.agents/personas/devops-engineer.md +0 -38
  211. package/.agents/personas/engineer.md +0 -33
  212. package/.agents/personas/project-manager.md +0 -114
  213. package/.agents/personas/qa-engineer.md +0 -95
  214. package/.agents/personas/security-engineer.md +0 -111
  215. package/.agents/personas/technical-writer.md +0 -101
  216. package/.agents/schemas/dispatch-manifest.json +0 -232
  217. package/.agents/schemas/epic-spec.schema.json +0 -153
  218. package/.agents/schemas/lifecycle/slice.end.schema.json +0 -21
  219. package/.agents/schemas/lifecycle/slice.heartbeat.schema.json +0 -20
  220. package/.agents/schemas/lifecycle/slice.start.schema.json +0 -17
  221. package/.agents/scripts/acceptance-spec-reconciler.js +0 -642
  222. package/.agents/scripts/bookkeeping-reconcile.js +0 -117
  223. package/.agents/scripts/dispatcher.js +0 -295
  224. package/.agents/scripts/epic-audit-prepare.js +0 -497
  225. package/.agents/scripts/epic-audit-recheck.js +0 -274
  226. package/.agents/scripts/epic-deliver-note-intervention.js +0 -192
  227. package/.agents/scripts/epic-deliver-preflight.js +0 -462
  228. package/.agents/scripts/epic-deliver-prepare.js +0 -852
  229. package/.agents/scripts/epic-execute-record-wave.js +0 -449
  230. package/.agents/scripts/epic-plan-clarity.js +0 -211
  231. package/.agents/scripts/epic-plan-healthcheck.js +0 -581
  232. package/.agents/scripts/epic-reconcile.js +0 -625
  233. package/.agents/scripts/lib/baseline-snapshot.js +0 -979
  234. package/.agents/scripts/lib/checks/epic-merge-lock-stale.js +0 -54
  235. package/.agents/scripts/lib/checks/stale-origin-epic.js +0 -49
  236. package/.agents/scripts/lib/config/lifecycle.js +0 -40
  237. package/.agents/scripts/lib/config/preflight.js +0 -58
  238. package/.agents/scripts/lib/config/retro.js +0 -77
  239. package/.agents/scripts/lib/epic-merge-lock.js +0 -322
  240. package/.agents/scripts/lib/epic-plan-clarity.js +0 -181
  241. package/.agents/scripts/lib/epic-plan-ideation.js +0 -261
  242. package/.agents/scripts/lib/orchestration/context-hydration-engine.js +0 -539
  243. package/.agents/scripts/lib/orchestration/deliver-route.js +0 -173
  244. package/.agents/scripts/lib/orchestration/dispatch-engine.js +0 -134
  245. package/.agents/scripts/lib/orchestration/dispatch-pipeline.js +0 -183
  246. package/.agents/scripts/lib/orchestration/epic-cleanup.js +0 -801
  247. package/.agents/scripts/lib/orchestration/epic-deliver-lease-guard.js +0 -310
  248. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/context.js +0 -163
  249. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/creation.js +0 -140
  250. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/dag.js +0 -64
  251. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/diagnostics.js +0 -72
  252. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +0 -156
  253. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist.js +0 -345
  254. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +0 -41
  255. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/reconcile-spawn.js +0 -86
  256. package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +0 -391
  257. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/drain.js +0 -94
  258. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +0 -236
  259. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +0 -307
  260. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-freshness.js +0 -117
  261. package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +0 -117
  262. package/.agents/scripts/lib/orchestration/epic-run-state-store.js +0 -621
  263. package/.agents/scripts/lib/orchestration/epic-runner/concurrency-gate.js +0 -186
  264. package/.agents/scripts/lib/orchestration/epic-runner/deliver-phases.js +0 -50
  265. package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +0 -129
  266. package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +0 -103
  267. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/composition.js +0 -267
  268. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/signals.js +0 -210
  269. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/transport.js +0 -238
  270. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/_bullet-format.js +0 -32
  271. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/component-drift.js +0 -203
  272. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/crap-drift.js +0 -227
  273. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/maintainability-drift.js +0 -117
  274. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/stalled-worktree.js +0 -37
  275. package/.agents/scripts/lib/orchestration/epic-runner/story-launcher.js +0 -127
  276. package/.agents/scripts/lib/orchestration/epic-runner/sub-agent-return.js +0 -276
  277. package/.agents/scripts/lib/orchestration/epic-runner/wave-scheduler.js +0 -66
  278. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-apply.js +0 -789
  279. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +0 -676
  280. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-discriminator.js +0 -389
  281. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-format.js +0 -230
  282. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-ops.js +0 -361
  283. package/.agents/scripts/lib/orchestration/finalize/open-or-locate-pr.js +0 -306
  284. package/.agents/scripts/lib/orchestration/finalize/post-handoff-comment.js +0 -489
  285. package/.agents/scripts/lib/orchestration/finalize/sanitize-skip-ci.js +0 -88
  286. package/.agents/scripts/lib/orchestration/lifecycle/emit-slice-lifecycle.js +0 -270
  287. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-dispatch-end.js +0 -147
  288. package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +0 -465
  289. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +0 -501
  290. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +0 -984
  291. package/.agents/scripts/lib/orchestration/lifecycle/listeners/branch-cleaner.js +0 -264
  292. package/.agents/scripts/lib/orchestration/lifecycle/listeners/checkpoint-pointer-writer.js +0 -284
  293. package/.agents/scripts/lib/orchestration/lifecycle/listeners/cleaner.js +0 -355
  294. package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +0 -673
  295. package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +0 -378
  296. package/.agents/scripts/lib/orchestration/lifecycle/listeners/intervention-recorder.js +0 -140
  297. package/.agents/scripts/lib/orchestration/lifecycle/listeners/label-transitioner.js +0 -144
  298. package/.agents/scripts/lib/orchestration/lifecycle/listeners/notify-dispatcher.js +0 -174
  299. package/.agents/scripts/lib/orchestration/manifest-builder.js +0 -222
  300. package/.agents/scripts/lib/orchestration/plan-persist/amend.js +0 -359
  301. package/.agents/scripts/lib/orchestration/plan-persist/delivery-mode.js +0 -127
  302. package/.agents/scripts/lib/orchestration/post-merge-pipeline.js +0 -205
  303. package/.agents/scripts/lib/orchestration/recurring-failure-detector.js +0 -152
  304. package/.agents/scripts/lib/orchestration/retro/phases/checks.js +0 -94
  305. package/.agents/scripts/lib/orchestration/retro/phases/compose-body.js +0 -571
  306. package/.agents/scripts/lib/orchestration/retro/phases/gather-signals.js +0 -450
  307. package/.agents/scripts/lib/orchestration/retro/phases/post-and-mirror.js +0 -191
  308. package/.agents/scripts/lib/orchestration/retro-heuristics.js +0 -57
  309. package/.agents/scripts/lib/orchestration/retro-runner.js +0 -197
  310. package/.agents/scripts/lib/orchestration/spec-renderer.js +0 -447
  311. package/.agents/scripts/lib/orchestration/story-close/auto-refresh-runner.js +0 -747
  312. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/gate-failure.js +0 -211
  313. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/pre-merge-attribution.js +0 -158
  314. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +0 -446
  315. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/regression-projection.js +0 -297
  316. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/scope-discovery.js +0 -48
  317. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution-wiring.js +0 -67
  318. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution.js +0 -161
  319. package/.agents/scripts/lib/orchestration/story-close/baseline-friction-body.js +0 -117
  320. package/.agents/scripts/lib/orchestration/story-close/cd-out-guard.js +0 -86
  321. package/.agents/scripts/lib/orchestration/story-close/cleanup-reconciler.js +0 -147
  322. package/.agents/scripts/lib/orchestration/story-close/close-inputs.js +0 -142
  323. package/.agents/scripts/lib/orchestration/story-close/comment-bodies.js +0 -62
  324. package/.agents/scripts/lib/orchestration/story-close/merge-runner.js +0 -658
  325. package/.agents/scripts/lib/orchestration/story-close/merge-subject.js +0 -198
  326. package/.agents/scripts/lib/orchestration/story-close/phases/branch-restore.js +0 -105
  327. package/.agents/scripts/lib/orchestration/story-close/phases/close.js +0 -222
  328. package/.agents/scripts/lib/orchestration/story-close/phases/gates.js +0 -292
  329. package/.agents/scripts/lib/orchestration/story-close/phases/locked-pipeline.js +0 -270
  330. package/.agents/scripts/lib/orchestration/story-close/phases/preflight.js +0 -110
  331. package/.agents/scripts/lib/orchestration/story-close/phases/refresh.js +0 -86
  332. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked-emitter.js +0 -112
  333. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked.js +0 -157
  334. package/.agents/scripts/lib/orchestration/story-close/post-merge-close.js +0 -421
  335. package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +0 -302
  336. package/.agents/scripts/lib/orchestration/story-close/shared-checkout-guard.js +0 -163
  337. package/.agents/scripts/lib/orchestration/story-close-recovery.js +0 -690
  338. package/.agents/scripts/lib/orchestration/wave-marker.js +0 -28
  339. package/.agents/scripts/lib/orchestration/wave-record-io.js +0 -218
  340. package/.agents/scripts/lib/orchestration/wave-record-notifications.js +0 -145
  341. package/.agents/scripts/lib/orchestration/wave-record-projection.js +0 -212
  342. package/.agents/scripts/lib/presentation/dispatch-manifest-render.js +0 -111
  343. package/.agents/scripts/lib/presentation/manifest-builder.js +0 -239
  344. package/.agents/scripts/lib/presentation/manifest-formatter.js +0 -242
  345. package/.agents/scripts/lib/presentation/manifest-helpers.js +0 -213
  346. package/.agents/scripts/lib/presentation/manifest-persistence.js +0 -261
  347. package/.agents/scripts/lib/presentation/manifest-procedures.js +0 -55
  348. package/.agents/scripts/lib/presentation/manifest-render-waves.js +0 -306
  349. package/.agents/scripts/lib/presentation/manifest-renderer.js +0 -188
  350. package/.agents/scripts/lib/presentation/manifest-story-views.js +0 -110
  351. package/.agents/scripts/lib/push-epic-retry.js +0 -209
  352. package/.agents/scripts/lib/spec/index.js +0 -36
  353. package/.agents/scripts/lib/spec/loader.js +0 -425
  354. package/.agents/scripts/lib/spec/state.js +0 -208
  355. package/.agents/scripts/lib/story-init/blocker-validator.js +0 -68
  356. package/.agents/scripts/lib/story-init/branch-initializer.js +0 -408
  357. package/.agents/scripts/lib/story-init/context-resolver.js +0 -92
  358. package/.agents/scripts/lib/story-init/donor-precheck.js +0 -207
  359. package/.agents/scripts/lib/story-init/state-transitioner.js +0 -80
  360. package/.agents/scripts/lib/story-init/task-graph-builder.js +0 -124
  361. package/.agents/scripts/lib/story-init/transition-summary.js +0 -34
  362. package/.agents/scripts/lib/test-reserved-epic-temp-ids.js +0 -35
  363. package/.agents/scripts/lib/wave-runner/tick.js +0 -754
  364. package/.agents/scripts/lib/wave-runner/wave-runner-error.js +0 -20
  365. package/.agents/scripts/lifecycle-emit-story-dispatch.js +0 -194
  366. package/.agents/scripts/lifecycle-emit.js +0 -510
  367. package/.agents/scripts/retro-run.js +0 -218
  368. package/.agents/scripts/slice-phase.js +0 -361
  369. package/.agents/scripts/standalone-feedback-rollup.js +0 -188
  370. package/.agents/scripts/story-close.js +0 -294
  371. package/.agents/scripts/story-init.js +0 -599
  372. package/.agents/scripts/story-phase.js +0 -369
  373. package/.agents/scripts/wave-tick.js +0 -464
  374. package/.agents/skills/core/epic-plan-consolidate/SKILL.md +0 -172
  375. package/.agents/skills/core/epic-plan-consolidate/examples.md +0 -51
  376. package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +0 -441
  377. package/.agents/skills/core/epic-plan-decompose-author/examples.md +0 -47
  378. package/.agents/skills/core/epic-plan-premortem/SKILL.md +0 -146
  379. package/.agents/skills/core/epic-plan-premortem/examples.md +0 -53
  380. package/.agents/skills/core/epic-plan-spec-author/SKILL.md +0 -383
  381. package/.agents/skills/core/epic-plan-spec-author/examples.md +0 -91
  382. package/.agents/workflows/helpers/deliver-epic-reference.md +0 -547
  383. package/.agents/workflows/helpers/deliver-epic-single.md +0 -331
  384. package/.agents/workflows/helpers/deliver-epic.md +0 -998
  385. package/.agents/workflows/helpers/deliver-stories.md +0 -450
  386. package/.agents/workflows/helpers/epic-audit.md +0 -189
  387. package/.agents/workflows/helpers/epic-deliver-story.md +0 -436
  388. package/.agents/workflows/helpers/epic-testing.md +0 -125
  389. package/.agents/workflows/helpers/plan-epic-reference.md +0 -160
  390. package/.agents/workflows/helpers/plan-epic.md +0 -353
  391. package/.agents/workflows/helpers/plan-story.md +0 -251
  392. package/.agents/workflows/helpers/scope-triage-gate.md +0 -108
  393. /package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/spec-authoring-grounding.js +0 -0
@@ -1,465 +0,0 @@
1
- // .agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js
2
- /**
3
- * AcceptanceReconciler — lifecycle listener that gates Finalize on the
4
- * close-time acceptance-spec reconciliation. Story #2253 (Epic #2172):
5
- * the reconciliation moves *ahead* of the push + `gh pr create` call so
6
- * that AC coverage gaps block PR creation (review High-2).
7
- *
8
- * Subscribes to:
9
- * - `epic.close.end` → emit `acceptance.reconcile.start`, run the
10
- * `reconcileAcceptanceSpec` helper, emit one of
11
- * `acceptance.reconcile.ok | .waived | .skipped | .failed`, and on
12
- * `.failed` also emit `epic.blocked` so the LabelTransitioner /
13
- * StructuredCommentPoster / NotifyDispatcher trio fire the blocker
14
- * side effects exactly as a `story.blocked` cascade would.
15
- *
16
- * The Finalizer listener subscribes ONLY to `acceptance.reconcile.ok`,
17
- * so this listener is the authoritative safety gate ahead of any push
18
- * or PR-create work. The legacy `epic-deliver-finalize.js` shim still
19
- * exists for backwards compatibility, but its in-line reconciliation
20
- * call is replaced by the event-driven path.
21
- *
22
- * Idempotency contract (Acceptance Spec AC-10):
23
- * - Per-instance `Set<string>` of `${event}:${seqId}` keys. A repeat
24
- * `(event, seqId)` short-circuits without re-running reconciliation
25
- * and emits no events.
26
- * - The reconciler helper's only write is the section-scoped
27
- * disposition record inside the Epic body's ## Acceptance Table
28
- * region (Story #4324) — itself idempotent — so the seqId guard is
29
- * the only defence the listener needs.
30
- *
31
- * Side-effect firewall: the listener owns the reconciliation call and
32
- * the four outcome emits. It does NOT mutate labels, post comments, or
33
- * call `notify` directly — those are downstream listener concerns.
34
- */
35
-
36
- import { reconcileAcceptanceSpec as defaultReconcileAcceptanceSpec } from '../../../../acceptance-spec-reconciler.js';
37
- import { DELIVERY_SINGLE_LABEL } from '../../deliver-route.js';
38
- import { read as readEpicRunState } from '../../epic-run-state-store.js';
39
-
40
- /**
41
- * Default single-delivery resolver (Epic #4475, M4-B, design §2c). Decides
42
- * whether the Epic under reconciliation is the single-delivery shape — the
43
- * signal that flips a `waived` reconcile into a hard failure (the back gate
44
- * of the non-waivable epic-level acceptance contract). Two sources, primary
45
- * first:
46
- *
47
- * 1. `epic-run-state.deliveryShape === 'single'` — the durable checkpoint
48
- * the single-delivery prepare writes.
49
- * 2. The `delivery::single` label on the Epic ticket — the plan-time marker.
50
- *
51
- * Best-effort + fail-open-to-fan-out: any probe failure (null provider in a
52
- * unit fixture, a GitHub read error) degrades to `false` (treat as fan-out),
53
- * so the defence-in-depth back gate never *invents* a block — the front gate
54
- * (prepare refusing `acceptance::n-a`) is the primary guard. Tests inject
55
- * `resolveSingleFn` directly to bypass the probes.
56
- *
57
- * @param {{ provider?: object|null, epicId: number, config?: object|null }} args
58
- * @returns {Promise<boolean>}
59
- */
60
- export async function defaultResolveSingle({ provider, epicId }) {
61
- if (!provider) return false;
62
- try {
63
- const checkpoint = await readEpicRunState({ provider, epicId });
64
- if (checkpoint?.deliveryShape === 'single') return true;
65
- } catch {
66
- // Fall through to the label probe.
67
- }
68
- try {
69
- const epic = await provider.getTicket(epicId);
70
- const labels = Array.isArray(epic?.labels) ? epic.labels : [];
71
- return labels.some(
72
- (l) => (typeof l === 'string' ? l : l?.name) === DELIVERY_SINGLE_LABEL,
73
- );
74
- } catch {
75
- return false;
76
- }
77
- }
78
-
79
- /**
80
- * Classify a `reconcileAcceptanceSpec` result envelope into the typed
81
- * outcome event the listener should emit. Pure function — exported so
82
- * unit tests can drive every branch without a bus instance.
83
- *
84
- * The reconciler exposes a four-value `status` discriminant:
85
- * - `'waived'` → the Epic carries `acceptance::n-a` (or no linked
86
- * spec under `--skip-when-waived`). Emit
87
- * `acceptance.reconcile.waived` with reason
88
- * `'waiver'`. Story #2893 split this out from
89
- * `.skipped` so the Finalizer can subscribe to
90
- * `.waived` and route waived Epics through to PR
91
- * creation, while empty-spec Epics still
92
- * terminate without a PR via `.skipped`.
93
- * **Non-waivable under single delivery (Epic #4475,
94
- * M4-B, design §2c):** when `opts.single` is true the
95
- * epic-level reconcile is the ONLY acceptance gate
96
- * left, so a `waived` status is treated as a hard
97
- * `failed` (reason `single-delivery-non-waivable`)
98
- * instead of passing through — the back gate that
99
- * forecloses the cohort's dilution (waived reconcile
100
- * as the sole gate). The front gate (prepare refusing
101
- * `acceptance::n-a`) already blocks this at seed time;
102
- * this is defence in depth.
103
- * - `'empty-spec'` → the linked spec exists but declares zero AC IDs.
104
- * Treated as "no work to do"; emit `.skipped` with
105
- * reason `'empty-spec'` so operators see the
106
- * outcome explicitly (no silent skip).
107
- * - `'ok'` → the spec has AC IDs and every one is covered by
108
- * a non-pending scenario. Emit `.ok`.
109
- * - `'gap'` → at least one AC is pending or missing. Emit
110
- * `.failed` carrying a compact reason summary;
111
- * the listener then emits `epic.blocked` to flip
112
- * the Epic ticket.
113
- *
114
- * @param {object|undefined|null} result reconciler envelope.
115
- * @param {{ single?: boolean }} [opts] `single: true` flips a `waived` status
116
- * into a hard `failed` (the non-waivable epic reconcile back gate).
117
- * @returns {{ outcome: 'ok'|'waived'|'skipped'|'failed', reason?: string }}
118
- */
119
- export function classifyReconcileResult(result, opts = {}) {
120
- const single = opts?.single === true;
121
- if (!result || typeof result !== 'object') {
122
- return { outcome: 'failed', reason: 'reconciler-no-result' };
123
- }
124
- const status = result.status;
125
- if (status === 'waived') {
126
- if (single) {
127
- return {
128
- outcome: 'failed',
129
- reason: 'single-delivery-non-waivable',
130
- };
131
- }
132
- return { outcome: 'waived', reason: 'waiver' };
133
- }
134
- if (status === 'empty-spec') {
135
- return { outcome: 'skipped', reason: 'empty-spec' };
136
- }
137
- if (status === 'ok') {
138
- return { outcome: 'ok' };
139
- }
140
- if (status === 'gap') {
141
- const missing = Array.isArray(result.missing) ? result.missing : [];
142
- const pending = Array.isArray(result.pending) ? result.pending : [];
143
- const parts = [];
144
- if (missing.length > 0) parts.push(`missing=${missing.join(',')}`);
145
- if (pending.length > 0) parts.push(`pending=${pending.join(',')}`);
146
- const reason =
147
- parts.length > 0 ? `gap:${parts.join(';')}` : 'gap:unspecified';
148
- return { outcome: 'failed', reason };
149
- }
150
- // Unknown status — fail closed so the operator sees the surprise.
151
- return { outcome: 'failed', reason: `unknown-status:${String(status)}` };
152
- }
153
-
154
- /**
155
- * AcceptanceReconciler — instantiate one per Epic run and call
156
- * `register()` to wire it onto the bus. Stateless w.r.t. the system
157
- * under orchestration; per-run state is the `(event, seqId)`
158
- * idempotency cache + the classification log.
159
- */
160
- export class AcceptanceReconciler {
161
- /**
162
- * @param {object} opts
163
- * @param {object} opts.bus Lifecycle bus instance (must expose
164
- * `on()` and `emit()`).
165
- * @param {number} opts.epicId Epic ticket id.
166
- * @param {string} [opts.cwd] Working directory passed through to the
167
- * reconciler helper. Defaults to `process.cwd()`.
168
- * @param {object} [opts.provider] Ticketing provider — injected into
169
- * the reconciler call so the lifecycle bus does not need to
170
- * construct one itself.
171
- * @param {object} [opts.config] Resolved orchestration config —
172
- * injected for the same reason.
173
- * @param {Function} [opts.reconcileAcceptanceSpecFn] Override of the
174
- * helper for tests; defaults to the production export.
175
- * @param {Function} [opts.resolveSingleFn] Override of the single-delivery
176
- * resolver for tests (Epic #4475, M4-B); defaults to `defaultResolveSingle`
177
- * (checkpoint `deliveryShape` → `delivery::single` label).
178
- * @param {{ info?: Function, warn?: Function, debug?: Function }} [opts.logger]
179
- */
180
- constructor(opts = {}) {
181
- if (
182
- !opts.bus ||
183
- typeof opts.bus.on !== 'function' ||
184
- typeof opts.bus.emit !== 'function'
185
- ) {
186
- throw new TypeError(
187
- 'AcceptanceReconciler requires a bus with on() and emit()',
188
- );
189
- }
190
- if (!Number.isInteger(opts.epicId) || opts.epicId < 1) {
191
- throw new TypeError('AcceptanceReconciler requires a numeric epicId');
192
- }
193
- this.bus = opts.bus;
194
- this.epicId = opts.epicId;
195
- this.cwd = opts.cwd ?? process.cwd();
196
- this.provider = opts.provider ?? null;
197
- this.config = opts.config ?? null;
198
- this.reconcileAcceptanceSpecFn =
199
- opts.reconcileAcceptanceSpecFn ?? defaultReconcileAcceptanceSpec;
200
- this.resolveSingleFn = opts.resolveSingleFn ?? defaultResolveSingle;
201
- this.logger = opts.logger ?? console;
202
- /** @type {Set<string>} `${event}:${seqId}` keys we've handled. */
203
- this._seen = new Set();
204
- /**
205
- * Classification log — mirrors the BlockerHandler "no silent skip"
206
- * surface so tests can confirm every `epic.close.end` we observed
207
- * was classified into exactly one outcome.
208
- *
209
- * @type {Array<{ event: string, seqId: number, outcome: string, reason?: string }>}
210
- */
211
- this.classifications = [];
212
- this.events = Object.freeze(['epic.close.end']);
213
- }
214
-
215
- /**
216
- * Register this listener on the bus. Returns an array of unsubscribe
217
- * functions (one per event) for test teardown.
218
- */
219
- register() {
220
- return this.events.map((event) =>
221
- this.bus.on(event, async (ctx) => this.handle(ctx)),
222
- );
223
- }
224
-
225
- /**
226
- * Bus listener body. The bus passes `{ event, seqId, payload }`. The
227
- * listener:
228
- * 1. Idempotently short-circuits a repeat `(event, seqId)`.
229
- * 2. Emits `acceptance.reconcile.start`.
230
- * 3. Runs `reconcileAcceptanceSpec` with injected provider/config.
231
- * 4. Emits exactly one of `.ok` / `.skipped` / `.failed`.
232
- * 5. On `.failed`, additionally emits `epic.blocked` so the
233
- * downstream listener trio (label flip + structured comment +
234
- * notify) fires the operator-visible blocker side effects.
235
- *
236
- * The listener does NOT throw on reconciler failures: the bus's
237
- * `onFailed` boundary already persists the originating
238
- * `epic.close.end` record; surfacing a throw here would short-circuit
239
- * other `epic.close.end` listeners (e.g. trace logger) and is not
240
- * needed for correctness — the `acceptance.reconcile.failed` +
241
- * `epic.blocked` emits are the cascade contract.
242
- *
243
- * @param {{ event: string, seqId: number, payload: object }} ctx
244
- */
245
- async handle({ event, seqId, payload }) {
246
- const key = `${event}:${seqId}`;
247
- if (this._seen.has(key)) {
248
- this.classifications.push({
249
- event,
250
- seqId,
251
- outcome: 'skipped',
252
- reason: 'duplicate-seqId',
253
- });
254
- this.logger.debug?.(
255
- `[AcceptanceReconciler] skip duplicate ${key} (idempotent)`,
256
- );
257
- return;
258
- }
259
- this._seen.add(key);
260
-
261
- const epicIdFromPayload = Number(payload?.epicId);
262
- const epicId = Number.isInteger(epicIdFromPayload)
263
- ? epicIdFromPayload
264
- : this.epicId;
265
-
266
- // 1. Start emit. The downstream ledger-diff `reconcile-ordering`
267
- // assert checks for `acceptance.reconcile.ok` before `pr.created`,
268
- // but operators want to see the `.start` marker in the trace too.
269
- try {
270
- await this.bus.emit('acceptance.reconcile.start', { epicId });
271
- } catch (err) {
272
- // Schema validation against a known-good payload should never
273
- // throw; if it does, surface and bail — there's no point running
274
- // the reconciler when we cannot announce its outcome.
275
- this.classifications.push({
276
- event,
277
- seqId,
278
- outcome: 'failed',
279
- reason: `start-emit-failed:${err?.message ?? err}`,
280
- });
281
- this.logger.warn?.(
282
- `[AcceptanceReconciler] acceptance.reconcile.start emit failed: ${err?.message ?? err}`,
283
- );
284
- return;
285
- }
286
-
287
- // 2. Run the reconciler. The helper itself throws on hard errors
288
- // (no linked spec + no waiver, etc.); convert those into
289
- // `.failed` emits rather than re-propagating, so the cascade
290
- // contract holds even when the spec is malformed.
291
- let result;
292
- let thrown = null;
293
- try {
294
- result = await this.reconcileAcceptanceSpecFn({
295
- epicId,
296
- cwd: this.cwd,
297
- injectedProvider: this.provider ?? undefined,
298
- injectedConfig: this.config ?? undefined,
299
- loggerImpl: this.logger,
300
- // Honour `acceptance::n-a` — the helper already returns
301
- // `status: 'waived'` for that label, but `skipWhenWaived: true`
302
- // additionally tolerates a missing acceptance-table section under
303
- // the waiver (we want the same forgiving stance the inline
304
- // finalize call had).
305
- skipWhenWaived: true,
306
- // Close time is the one place the verification outcome is
307
- // recorded into the Epic body's ## Acceptance Table section
308
- // (section-scoped write, Story #4324).
309
- writeDispositions: true,
310
- });
311
- } catch (err) {
312
- thrown = err;
313
- }
314
-
315
- const baseRead = thrown == null && result != null;
316
-
317
- if (thrown != null) {
318
- const reason = `reconcile-threw:${thrown?.message ?? thrown}`;
319
- await this._emitFailure({ event, seqId, baseRead, reason });
320
- return;
321
- }
322
-
323
- // Resolve the delivery shape before classifying: under single delivery a
324
- // `waived` reconcile is non-waivable (design §2c). Best-effort — a probe
325
- // failure degrades to `false` (fan-out pass-through), never inventing a
326
- // block.
327
- let single = false;
328
- try {
329
- single = await this.resolveSingleFn({
330
- provider: this.provider,
331
- epicId,
332
- config: this.config,
333
- });
334
- } catch (err) {
335
- this.logger.warn?.(
336
- `[AcceptanceReconciler] single-delivery probe failed (treating as fan-out): ${err?.message ?? err}`,
337
- );
338
- }
339
-
340
- const classification = classifyReconcileResult(result, { single });
341
- if (classification.outcome === 'ok') {
342
- await this._emitOk({ event, seqId, baseRead });
343
- return;
344
- }
345
- if (classification.outcome === 'waived') {
346
- await this._emitWaived({
347
- event,
348
- seqId,
349
- baseRead,
350
- reason: classification.reason ?? 'waiver',
351
- });
352
- return;
353
- }
354
- if (classification.outcome === 'skipped') {
355
- await this._emitSkipped({
356
- event,
357
- seqId,
358
- baseRead,
359
- reason: classification.reason ?? 'skipped',
360
- });
361
- return;
362
- }
363
- await this._emitFailure({
364
- event,
365
- seqId,
366
- baseRead,
367
- reason: classification.reason ?? 'gap',
368
- });
369
- }
370
-
371
- /**
372
- * Emit `acceptance.reconcile.ok` and record the classification.
373
- * Helper carved out so each branch in `handle()` reads as a single
374
- * decision.
375
- */
376
- async _emitOk({ event, seqId, baseRead }) {
377
- this.classifications.push({ event, seqId, outcome: 'ok' });
378
- try {
379
- await this.bus.emit('acceptance.reconcile.ok', { baseRead });
380
- } catch (err) {
381
- this.logger.warn?.(
382
- `[AcceptanceReconciler] acceptance.reconcile.ok emit failed (swallowed): ${err?.message ?? err}`,
383
- );
384
- }
385
- }
386
-
387
- /**
388
- * Emit `acceptance.reconcile.waived` for the `acceptance::n-a` path.
389
- * Story #2893 split this out of `.skipped` so the Finalizer can
390
- * subscribe to `.waived` and route waived Epics through to PR
391
- * creation. The schema pins `reason` to `'waiver'`.
392
- */
393
- async _emitWaived({ event, seqId, baseRead, reason }) {
394
- this.classifications.push({ event, seqId, outcome: 'waived', reason });
395
- try {
396
- await this.bus.emit('acceptance.reconcile.waived', {
397
- baseRead,
398
- reason,
399
- });
400
- } catch (err) {
401
- this.logger.warn?.(
402
- `[AcceptanceReconciler] acceptance.reconcile.waived emit failed (swallowed): ${err?.message ?? err}`,
403
- );
404
- }
405
- }
406
-
407
- /**
408
- * Emit `acceptance.reconcile.skipped` carrying a typed `reason`. The
409
- * schema requires `reason` to be non-empty so callers always pass one
410
- * (no silent skip).
411
- */
412
- async _emitSkipped({ event, seqId, baseRead, reason }) {
413
- this.classifications.push({ event, seqId, outcome: 'skipped', reason });
414
- try {
415
- await this.bus.emit('acceptance.reconcile.skipped', {
416
- baseRead,
417
- reason,
418
- });
419
- } catch (err) {
420
- this.logger.warn?.(
421
- `[AcceptanceReconciler] acceptance.reconcile.skipped emit failed (swallowed): ${err?.message ?? err}`,
422
- );
423
- }
424
- }
425
-
426
- /**
427
- * Emit `acceptance.reconcile.failed` and then `epic.blocked`, in that
428
- * order. The `epic.blocked` emit drives the LabelTransitioner /
429
- * StructuredCommentPoster / NotifyDispatcher trio so the operator
430
- * sees the blocker label flip + structured comment + webhook,
431
- * exactly as a `story.blocked` cascade would.
432
- *
433
- * Failures inside the `epic.blocked` emit are swallowed (the
434
- * `.failed` record is already on the ledger; double-throwing here
435
- * would mask the original reason).
436
- */
437
- async _emitFailure({ event, seqId, baseRead, reason }) {
438
- this.classifications.push({ event, seqId, outcome: 'failed', reason });
439
- try {
440
- await this.bus.emit('acceptance.reconcile.failed', {
441
- baseRead,
442
- reason,
443
- });
444
- } catch (err) {
445
- this.logger.warn?.(
446
- `[AcceptanceReconciler] acceptance.reconcile.failed emit failed (swallowed): ${err?.message ?? err}`,
447
- );
448
- }
449
- try {
450
- await this.bus.emit('epic.blocked', {
451
- reason: `acceptance-reconcile:${reason}`,
452
- });
453
- } catch (err) {
454
- this.logger.warn?.(
455
- `[AcceptanceReconciler] epic.blocked emit failed (swallowed): ${err?.message ?? err}`,
456
- );
457
- }
458
- }
459
-
460
- /** Test helper — wipe the idempotency cache. */
461
- reset() {
462
- this._seen.clear();
463
- this.classifications = [];
464
- }
465
- }