mandrel 1.93.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (463) hide show
  1. package/.agents/README.md +59 -73
  2. package/.agents/agents/acceptance-critic.md +129 -0
  3. package/.agents/agents/story-worker.md +161 -0
  4. package/.agents/docs/SDLC.md +489 -1285
  5. package/.agents/docs/agentrc-reference.json +177 -67
  6. package/.agents/docs/configuration.md +108 -136
  7. package/.agents/docs/execution-reference.md +44 -22
  8. package/.agents/docs/quality-gates.md +13 -19
  9. package/.agents/docs/workflows.md +3 -3
  10. package/.agents/instructions.md +107 -108
  11. package/.agents/rules/ci-remediation.md +8 -12
  12. package/.agents/rules/git-conventions-reference.md +224 -0
  13. package/.agents/rules/git-conventions.md +42 -223
  14. package/.agents/rules/security-baseline.md +5 -0
  15. package/.agents/rules/testing-standards.md +106 -13
  16. package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
  17. package/.agents/schemas/agentrc.schema.json +71 -201
  18. package/.agents/schemas/lifecycle/ledger-record.schema.json +1 -1
  19. package/.agents/schemas/lifecycle/retro.end.schema.json +1 -1
  20. package/.agents/schemas/risk-verdict.schema.json +0 -13
  21. package/.agents/scripts/acceptance-eval.js +62 -18
  22. package/.agents/scripts/agents-bootstrap-github.js +1 -1
  23. package/.agents/scripts/analyze-execution.js +1 -1
  24. package/.agents/scripts/audit-to-stories.js +7 -7
  25. package/.agents/scripts/boot-sweep.js +1 -1
  26. package/.agents/scripts/check-context-budget.js +62 -5
  27. package/.agents/scripts/check-lifecycle-lint.js +6 -9
  28. package/.agents/scripts/check-prepush-recovery.js +1 -1
  29. package/.agents/scripts/cleanup-repo-test-temp.js +6 -1
  30. package/.agents/scripts/diagnose-friction.js +0 -6
  31. package/.agents/scripts/lib/Logger.js +6 -10
  32. package/.agents/scripts/lib/audit-suite/runner.js +2 -2
  33. package/.agents/scripts/lib/audit-suite/selector.js +5 -5
  34. package/.agents/scripts/lib/audit-to-stories/{seed-epic-from-findings.js → seed-from-findings.js} +9 -9
  35. package/.agents/scripts/lib/baselines/kernel.js +206 -18
  36. package/.agents/scripts/lib/baselines/kinds/maintainability.js +0 -4
  37. package/.agents/scripts/lib/baselines/reader.js +1 -6
  38. package/.agents/scripts/lib/bdd-runner-detect.js +5 -9
  39. package/.agents/scripts/lib/bootstrap/issue-forms-template.js +32 -33
  40. package/.agents/scripts/lib/bootstrap/project-bootstrap.js +56 -18
  41. package/.agents/scripts/lib/checks/core-bare-clean.js +2 -2
  42. package/.agents/scripts/lib/checks/index.js +2 -1
  43. package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +23 -21
  44. package/.agents/scripts/lib/cli/standard-args.js +13 -22
  45. package/.agents/scripts/lib/cli-args.js +16 -7
  46. package/.agents/scripts/lib/close-validation/gates.js +160 -22
  47. package/.agents/scripts/lib/config/acceptance-eval.js +52 -5
  48. package/.agents/scripts/lib/config/ci.js +6 -31
  49. package/.agents/scripts/lib/config/delivery-routing.js +103 -0
  50. package/.agents/scripts/lib/config/explain.js +57 -36
  51. package/.agents/scripts/lib/config/limits.js +17 -58
  52. package/.agents/scripts/lib/config/paths.js +0 -2
  53. package/.agents/scripts/lib/config/quality.js +1 -1
  54. package/.agents/scripts/lib/config/runners.js +17 -50
  55. package/.agents/scripts/lib/config/temp-paths.js +19 -14
  56. package/.agents/scripts/lib/config/worktree-isolation.js +0 -5
  57. package/.agents/scripts/lib/config-resolver.js +3 -8
  58. package/.agents/scripts/lib/config-settings-schema-delivery.js +46 -136
  59. package/.agents/scripts/lib/config-settings-schema-quality.js +17 -14
  60. package/.agents/scripts/lib/config-settings-schema.js +52 -38
  61. package/.agents/scripts/lib/dependency-parser.js +3 -2
  62. package/.agents/scripts/lib/doc-tiers.js +39 -4
  63. package/.agents/scripts/lib/duplicate-search.js +211 -41
  64. package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +1 -1
  65. package/.agents/scripts/lib/findings/promote-finding.js +5 -5
  66. package/.agents/scripts/lib/framework-version.js +2 -3
  67. package/.agents/scripts/lib/git-branch-cleanup.js +1 -10
  68. package/.agents/scripts/lib/git-branch-lifecycle.js +17 -22
  69. package/.agents/scripts/lib/git-utils.js +32 -6
  70. package/.agents/scripts/lib/github/framework-repo.js +6 -0
  71. package/.agents/scripts/lib/label-constants.js +10 -23
  72. package/.agents/scripts/lib/label-taxonomy.js +9 -43
  73. package/.agents/scripts/lib/observability/active-story-env.js +112 -3
  74. package/.agents/scripts/lib/observability/hook-heartbeat.js +187 -0
  75. package/.agents/scripts/lib/observability/source-classifier.js +3 -3
  76. package/.agents/scripts/lib/observability/tool-trace-hook.js +15 -4
  77. package/.agents/scripts/lib/onboard/init-tail.js +1 -3
  78. package/.agents/scripts/lib/orchestration/acceptance-clusters.js +111 -0
  79. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +32 -4
  80. package/.agents/scripts/lib/orchestration/audit-lens-routing.js +128 -0
  81. package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +273 -0
  82. package/.agents/scripts/lib/orchestration/ceremony-routing.js +204 -0
  83. package/.agents/scripts/lib/orchestration/code-review.js +20 -268
  84. package/.agents/scripts/lib/orchestration/column-sync.js +1 -1
  85. package/.agents/scripts/lib/orchestration/consolidation-precondition.js +1 -1
  86. package/.agents/scripts/lib/orchestration/context-envelope.js +2 -5
  87. package/.agents/scripts/lib/orchestration/docs-digest.js +8 -8
  88. package/.agents/scripts/lib/orchestration/file-assumptions.js +7 -13
  89. package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +1 -1
  90. package/.agents/scripts/lib/orchestration/lifecycle/emit-loop-tick.js +8 -8
  91. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +2 -2
  92. package/.agents/scripts/lib/orchestration/lifecycle/ledger-writer.js +6 -3
  93. package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +17 -43
  94. package/.agents/scripts/lib/orchestration/lint-baseline-service.js +4 -4
  95. package/.agents/scripts/lib/orchestration/merge-block-class.js +1 -1
  96. package/.agents/scripts/lib/orchestration/phase-runner.js +3 -2
  97. package/.agents/scripts/lib/orchestration/plan-context.js +248 -266
  98. package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +3 -2
  99. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +1 -1
  100. package/.agents/scripts/lib/orchestration/plan-navigation.js +92 -0
  101. package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +61 -0
  102. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +97 -0
  103. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +223 -854
  104. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +361 -0
  105. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +35 -108
  106. package/.agents/scripts/lib/orchestration/plan-reachability.js +9 -14
  107. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +1 -1
  108. package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/authoring-context.js +14 -14
  109. package/.agents/scripts/lib/orchestration/planning/decomposer-context.js +27 -0
  110. package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/risk-verdict.js +3 -4
  111. package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +2 -2
  112. package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +8 -20
  113. package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +3 -2
  114. package/.agents/scripts/lib/orchestration/pr-base-guard.js +18 -28
  115. package/.agents/scripts/lib/orchestration/preflight-cache.js +5 -5
  116. package/.agents/scripts/lib/orchestration/remote-verifier.js +1 -1
  117. package/.agents/scripts/lib/orchestration/resolve-plan-run.js +155 -0
  118. package/.agents/scripts/lib/orchestration/resolves-token.js +1 -1
  119. package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +8 -8
  120. package/.agents/scripts/lib/orchestration/retro-proposals.js +140 -79
  121. package/.agents/scripts/lib/orchestration/review-depth.js +26 -12
  122. package/.agents/scripts/lib/orchestration/review-providers/codex.js +2 -2
  123. package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +21 -56
  124. package/.agents/scripts/lib/orchestration/run-epilogue.js +426 -0
  125. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +1 -1
  126. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +1 -0
  127. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +95 -41
  128. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +16 -13
  129. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +40 -0
  130. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +11 -3
  131. package/.agents/scripts/lib/orchestration/spec-freshness.js +14 -205
  132. package/.agents/scripts/lib/orchestration/spec-section-validator.js +4 -5
  133. package/.agents/scripts/lib/orchestration/spec-spill.js +60 -0
  134. package/.agents/scripts/lib/orchestration/split-policy-validator.js +188 -0
  135. package/.agents/scripts/lib/orchestration/story-close/emit-blocked.js +49 -0
  136. package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +15 -12
  137. package/.agents/scripts/lib/orchestration/story-follow-ups.js +237 -0
  138. package/.agents/scripts/lib/orchestration/story-init-remote.js +47 -0
  139. package/.agents/scripts/lib/orchestration/story-plan-state.js +48 -0
  140. package/.agents/scripts/lib/orchestration/{epic-runner → story-progress}/story-run-progress-writer.js +3 -3
  141. package/.agents/scripts/lib/orchestration/structured-comment-parser.js +1 -1
  142. package/.agents/scripts/lib/orchestration/task-body-validator.js +8 -18
  143. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +11 -61
  144. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +189 -373
  145. package/.agents/scripts/lib/orchestration/ticket-validator.js +3 -8
  146. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +0 -25
  147. package/.agents/scripts/lib/orchestration/ticketing/reads.js +29 -26
  148. package/.agents/scripts/lib/orchestration/ticketing/transition.js +5 -5
  149. package/.agents/scripts/lib/planning-corpus.js +16 -11
  150. package/.agents/scripts/lib/preflight-runner.js +2 -2
  151. package/.agents/scripts/lib/provider-factory.js +1 -1
  152. package/.agents/scripts/lib/qa/coverage-verdict.js +5 -5
  153. package/.agents/scripts/lib/single-story/confirm-merge-follow-ups.js +36 -0
  154. package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +1 -1
  155. package/.agents/scripts/lib/story-adjacency.js +11 -14
  156. package/.agents/scripts/lib/story-body/story-body.js +124 -70
  157. package/.agents/scripts/lib/story-plan.js +2 -4
  158. package/.agents/scripts/lib/templates/decomposer-prompts.js +46 -45
  159. package/.agents/scripts/lib/templates/spec-author-prompts.js +47 -45
  160. package/.agents/scripts/lib/{epic-body-sections.js → ticket-body-sections.js} +26 -26
  161. package/.agents/scripts/lib/validation-evidence.js +1 -1
  162. package/.agents/scripts/lib/wave-runner/ready-set.js +6 -6
  163. package/.agents/scripts/lib/workspace-provisioner.js +1 -1
  164. package/.agents/scripts/lib/worktree/lifecycle/reap.js +5 -7
  165. package/.agents/scripts/lint-issue-body.js +71 -40
  166. package/.agents/scripts/mandrel-update-preflight.js +1 -1
  167. package/.agents/scripts/notify.js +4 -3
  168. package/.agents/scripts/plan-context.js +64 -74
  169. package/.agents/scripts/plan-persist.js +121 -280
  170. package/.agents/scripts/plan-run-epilogue.js +97 -0
  171. package/.agents/scripts/post-structured-comment.js +38 -0
  172. package/.agents/scripts/providers/github/issues.js +17 -33
  173. package/.agents/scripts/providers/github/mappers.js +0 -12
  174. package/.agents/scripts/providers/github/tickets.js +2 -5
  175. package/.agents/scripts/resolve-plan-run.js +117 -0
  176. package/.agents/scripts/signals-view.js +24 -19
  177. package/.agents/scripts/single-story-close.js +11 -14
  178. package/.agents/scripts/single-story-confirm-merge.js +39 -23
  179. package/.agents/scripts/single-story-init.js +29 -20
  180. package/.agents/scripts/stories-wave-tick.js +6 -6
  181. package/.agents/scripts/story-plan.js +26 -47
  182. package/.agents/scripts/sync-claude-agents.js +165 -0
  183. package/.agents/scripts/update-ticket-state.js +37 -15
  184. package/.agents/skills/core/analyze-execution/SKILL.md +21 -18
  185. package/.agents/skills/core/api-and-interface-design/SKILL.md +5 -3
  186. package/.agents/skills/core/code-review-and-quality/SKILL.md +63 -7
  187. package/.agents/skills/core/debugging-and-error-recovery/SKILL.md +1 -1
  188. package/.agents/skills/core/gates-and-baselines/SKILL.md +149 -0
  189. package/.agents/skills/core/idea-refinement/SKILL.md +8 -14
  190. package/.agents/skills/core/qa-coverage-mapping/SKILL.md +7 -7
  191. package/.agents/skills/core/scope-triage/SKILL.md +28 -172
  192. package/.agents/skills/skills.index.json +8 -418
  193. package/.agents/starter-agentrc.json +0 -5
  194. package/.agents/templates/agent-protocol.md +9 -10
  195. package/.agents/workflows/audit-architecture.md +3 -3
  196. package/.agents/workflows/audit-clean-code.md +3 -3
  197. package/.agents/workflows/audit-dependencies.md +3 -3
  198. package/.agents/workflows/audit-devops.md +3 -3
  199. package/.agents/workflows/audit-documentation.md +5 -5
  200. package/.agents/workflows/audit-lighthouse.md +3 -3
  201. package/.agents/workflows/audit-navigability.md +3 -2
  202. package/.agents/workflows/audit-performance.md +3 -3
  203. package/.agents/workflows/audit-privacy.md +3 -3
  204. package/.agents/workflows/audit-quality.md +3 -3
  205. package/.agents/workflows/audit-security.md +3 -3
  206. package/.agents/workflows/audit-seo.md +3 -3
  207. package/.agents/workflows/audit-sre.md +3 -3
  208. package/.agents/workflows/audit-to-stories.md +20 -20
  209. package/.agents/workflows/audit-ux-ui.md +3 -3
  210. package/.agents/workflows/deliver.md +122 -131
  211. package/.agents/workflows/git-cleanup.md +3 -4
  212. package/.agents/workflows/helpers/_merge-conflict-template.md +1 -1
  213. package/.agents/workflows/helpers/acceptance-self-eval.md +52 -40
  214. package/.agents/workflows/helpers/code-review.md +70 -193
  215. package/.agents/workflows/helpers/{single-story-deliver-reference.md → deliver-story-reference.md} +12 -14
  216. package/.agents/workflows/helpers/{single-story-deliver.md → deliver-story.md} +113 -139
  217. package/.agents/workflows/helpers/diagnose.md +10 -10
  218. package/.agents/workflows/helpers/mandrel-sync-config.md +1 -1
  219. package/.agents/workflows/helpers/parallel-tooling.md +1 -1
  220. package/.agents/workflows/helpers/signals.md +16 -16
  221. package/.agents/workflows/helpers/worktree-lifecycle.md +48 -64
  222. package/.agents/workflows/mandrel-update.md +3 -2
  223. package/.agents/workflows/plan.md +112 -145
  224. package/.agents/workflows/qa-assist.md +24 -30
  225. package/.agents/workflows/qa-explore.md +29 -38
  226. package/.agents/workflows/qa-run.md +2 -2
  227. package/README.md +9 -8
  228. package/docs/CHANGELOG.md +46 -0
  229. package/lib/cli/registry.js +95 -0
  230. package/lib/migrations/index.js +6 -5
  231. package/package.json +5 -3
  232. package/.agents/personas/architect.md +0 -113
  233. package/.agents/personas/devops-engineer.md +0 -38
  234. package/.agents/personas/engineer-mobile.md +0 -120
  235. package/.agents/personas/engineer-web.md +0 -111
  236. package/.agents/personas/engineer.md +0 -119
  237. package/.agents/personas/product.md +0 -94
  238. package/.agents/personas/project-manager.md +0 -114
  239. package/.agents/personas/qa-engineer.md +0 -95
  240. package/.agents/personas/refactorer.md +0 -113
  241. package/.agents/personas/security-engineer.md +0 -112
  242. package/.agents/personas/sre.md +0 -86
  243. package/.agents/personas/technical-writer.md +0 -101
  244. package/.agents/personas/ux-designer.md +0 -95
  245. package/.agents/schemas/dispatch-manifest.json +0 -232
  246. package/.agents/schemas/epic-spec.schema.json +0 -153
  247. package/.agents/scripts/acceptance-spec-reconciler.js +0 -642
  248. package/.agents/scripts/dispatcher.js +0 -295
  249. package/.agents/scripts/epic-audit-prepare.js +0 -497
  250. package/.agents/scripts/epic-audit-recheck.js +0 -274
  251. package/.agents/scripts/epic-deliver-note-intervention.js +0 -192
  252. package/.agents/scripts/epic-deliver-preflight.js +0 -462
  253. package/.agents/scripts/epic-deliver-prepare.js +0 -590
  254. package/.agents/scripts/epic-execute-record-wave.js +0 -449
  255. package/.agents/scripts/epic-plan-clarity.js +0 -211
  256. package/.agents/scripts/epic-plan-decompose.js +0 -54
  257. package/.agents/scripts/epic-plan-healthcheck.js +0 -581
  258. package/.agents/scripts/epic-plan-spec.js +0 -64
  259. package/.agents/scripts/epic-reconcile.js +0 -625
  260. package/.agents/scripts/lib/baseline-snapshot.js +0 -979
  261. package/.agents/scripts/lib/checks/epic-merge-lock-stale.js +0 -54
  262. package/.agents/scripts/lib/checks/stale-origin-epic.js +0 -49
  263. package/.agents/scripts/lib/config/lifecycle.js +0 -40
  264. package/.agents/scripts/lib/config/preflight.js +0 -58
  265. package/.agents/scripts/lib/config/retro.js +0 -77
  266. package/.agents/scripts/lib/epic-merge-lock.js +0 -322
  267. package/.agents/scripts/lib/epic-plan-clarity.js +0 -181
  268. package/.agents/scripts/lib/epic-plan-ideation.js +0 -261
  269. package/.agents/scripts/lib/orchestration/context-hydration-engine.js +0 -660
  270. package/.agents/scripts/lib/orchestration/dispatch-engine.js +0 -134
  271. package/.agents/scripts/lib/orchestration/dispatch-pipeline.js +0 -183
  272. package/.agents/scripts/lib/orchestration/epic-cleanup.js +0 -801
  273. package/.agents/scripts/lib/orchestration/epic-deliver-lease-guard.js +0 -310
  274. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/context.js +0 -163
  275. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/creation.js +0 -140
  276. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/dag.js +0 -64
  277. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/diagnostics.js +0 -72
  278. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +0 -156
  279. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist.js +0 -345
  280. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +0 -41
  281. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/reconcile-spawn.js +0 -86
  282. package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +0 -391
  283. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/drain.js +0 -94
  284. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +0 -236
  285. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +0 -307
  286. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-freshness.js +0 -117
  287. package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +0 -117
  288. package/.agents/scripts/lib/orchestration/epic-run-state-store.js +0 -388
  289. package/.agents/scripts/lib/orchestration/epic-runner/concurrency-gate.js +0 -186
  290. package/.agents/scripts/lib/orchestration/epic-runner/deliver-phases.js +0 -50
  291. package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +0 -129
  292. package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +0 -103
  293. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/composition.js +0 -267
  294. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/signals.js +0 -210
  295. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/transport.js +0 -238
  296. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/_bullet-format.js +0 -32
  297. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/component-drift.js +0 -203
  298. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/crap-drift.js +0 -227
  299. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/maintainability-drift.js +0 -117
  300. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/stalled-worktree.js +0 -37
  301. package/.agents/scripts/lib/orchestration/epic-runner/story-launcher.js +0 -127
  302. package/.agents/scripts/lib/orchestration/epic-runner/sub-agent-return.js +0 -276
  303. package/.agents/scripts/lib/orchestration/epic-runner/wave-scheduler.js +0 -66
  304. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-apply.js +0 -789
  305. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +0 -676
  306. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-discriminator.js +0 -389
  307. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-format.js +0 -230
  308. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-ops.js +0 -361
  309. package/.agents/scripts/lib/orchestration/finalize/open-or-locate-pr.js +0 -306
  310. package/.agents/scripts/lib/orchestration/finalize/post-handoff-comment.js +0 -489
  311. package/.agents/scripts/lib/orchestration/finalize/sanitize-skip-ci.js +0 -88
  312. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-dispatch-end.js +0 -147
  313. package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +0 -384
  314. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +0 -501
  315. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +0 -984
  316. package/.agents/scripts/lib/orchestration/lifecycle/listeners/branch-cleaner.js +0 -264
  317. package/.agents/scripts/lib/orchestration/lifecycle/listeners/checkpoint-pointer-writer.js +0 -278
  318. package/.agents/scripts/lib/orchestration/lifecycle/listeners/cleaner.js +0 -355
  319. package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +0 -673
  320. package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +0 -378
  321. package/.agents/scripts/lib/orchestration/lifecycle/listeners/intervention-recorder.js +0 -140
  322. package/.agents/scripts/lib/orchestration/lifecycle/listeners/label-transitioner.js +0 -144
  323. package/.agents/scripts/lib/orchestration/lifecycle/listeners/notify-dispatcher.js +0 -174
  324. package/.agents/scripts/lib/orchestration/manifest-builder.js +0 -222
  325. package/.agents/scripts/lib/orchestration/plan-persist/amend.js +0 -359
  326. package/.agents/scripts/lib/orchestration/plan-persist/delivery-mode.js +0 -127
  327. package/.agents/scripts/lib/orchestration/post-merge-pipeline.js +0 -205
  328. package/.agents/scripts/lib/orchestration/recurring-failure-detector.js +0 -152
  329. package/.agents/scripts/lib/orchestration/retro/phases/checks.js +0 -94
  330. package/.agents/scripts/lib/orchestration/retro/phases/compose-body.js +0 -571
  331. package/.agents/scripts/lib/orchestration/retro/phases/gather-signals.js +0 -450
  332. package/.agents/scripts/lib/orchestration/retro/phases/post-and-mirror.js +0 -191
  333. package/.agents/scripts/lib/orchestration/retro-heuristics.js +0 -57
  334. package/.agents/scripts/lib/orchestration/retro-runner.js +0 -197
  335. package/.agents/scripts/lib/orchestration/skill-capsule-loader.js +0 -109
  336. package/.agents/scripts/lib/orchestration/spec-renderer.js +0 -447
  337. package/.agents/scripts/lib/orchestration/story-close/auto-refresh-runner.js +0 -747
  338. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/gate-failure.js +0 -211
  339. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/pre-merge-attribution.js +0 -158
  340. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +0 -446
  341. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/regression-projection.js +0 -297
  342. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/scope-discovery.js +0 -48
  343. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution-wiring.js +0 -67
  344. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution.js +0 -161
  345. package/.agents/scripts/lib/orchestration/story-close/baseline-friction-body.js +0 -117
  346. package/.agents/scripts/lib/orchestration/story-close/cd-out-guard.js +0 -86
  347. package/.agents/scripts/lib/orchestration/story-close/cleanup-reconciler.js +0 -147
  348. package/.agents/scripts/lib/orchestration/story-close/close-inputs.js +0 -142
  349. package/.agents/scripts/lib/orchestration/story-close/comment-bodies.js +0 -62
  350. package/.agents/scripts/lib/orchestration/story-close/merge-runner.js +0 -658
  351. package/.agents/scripts/lib/orchestration/story-close/merge-subject.js +0 -198
  352. package/.agents/scripts/lib/orchestration/story-close/phases/branch-restore.js +0 -105
  353. package/.agents/scripts/lib/orchestration/story-close/phases/close.js +0 -222
  354. package/.agents/scripts/lib/orchestration/story-close/phases/gates.js +0 -292
  355. package/.agents/scripts/lib/orchestration/story-close/phases/locked-pipeline.js +0 -270
  356. package/.agents/scripts/lib/orchestration/story-close/phases/preflight.js +0 -110
  357. package/.agents/scripts/lib/orchestration/story-close/phases/refresh.js +0 -86
  358. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked-emitter.js +0 -112
  359. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked.js +0 -157
  360. package/.agents/scripts/lib/orchestration/story-close/post-merge-close.js +0 -421
  361. package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +0 -301
  362. package/.agents/scripts/lib/orchestration/story-close/shared-checkout-guard.js +0 -163
  363. package/.agents/scripts/lib/orchestration/story-close-recovery.js +0 -690
  364. package/.agents/scripts/lib/orchestration/wave-marker.js +0 -28
  365. package/.agents/scripts/lib/orchestration/wave-record-io.js +0 -218
  366. package/.agents/scripts/lib/orchestration/wave-record-notifications.js +0 -145
  367. package/.agents/scripts/lib/orchestration/wave-record-projection.js +0 -212
  368. package/.agents/scripts/lib/presentation/dispatch-manifest-render.js +0 -111
  369. package/.agents/scripts/lib/presentation/manifest-builder.js +0 -239
  370. package/.agents/scripts/lib/presentation/manifest-formatter.js +0 -242
  371. package/.agents/scripts/lib/presentation/manifest-helpers.js +0 -213
  372. package/.agents/scripts/lib/presentation/manifest-persistence.js +0 -261
  373. package/.agents/scripts/lib/presentation/manifest-procedures.js +0 -55
  374. package/.agents/scripts/lib/presentation/manifest-render-waves.js +0 -306
  375. package/.agents/scripts/lib/presentation/manifest-renderer.js +0 -188
  376. package/.agents/scripts/lib/presentation/manifest-story-views.js +0 -110
  377. package/.agents/scripts/lib/push-epic-retry.js +0 -209
  378. package/.agents/scripts/lib/spec/index.js +0 -36
  379. package/.agents/scripts/lib/spec/loader.js +0 -425
  380. package/.agents/scripts/lib/spec/state.js +0 -208
  381. package/.agents/scripts/lib/story-init/blocker-validator.js +0 -68
  382. package/.agents/scripts/lib/story-init/branch-initializer.js +0 -408
  383. package/.agents/scripts/lib/story-init/context-resolver.js +0 -92
  384. package/.agents/scripts/lib/story-init/donor-precheck.js +0 -207
  385. package/.agents/scripts/lib/story-init/state-transitioner.js +0 -80
  386. package/.agents/scripts/lib/story-init/task-graph-builder.js +0 -124
  387. package/.agents/scripts/lib/story-init/transition-summary.js +0 -34
  388. package/.agents/scripts/lib/test-reserved-epic-temp-ids.js +0 -35
  389. package/.agents/scripts/lib/wave-runner/tick.js +0 -754
  390. package/.agents/scripts/lib/wave-runner/wave-runner-error.js +0 -20
  391. package/.agents/scripts/lifecycle-emit-story-dispatch.js +0 -194
  392. package/.agents/scripts/lifecycle-emit.js +0 -510
  393. package/.agents/scripts/plan-critics.js +0 -199
  394. package/.agents/scripts/retro-run.js +0 -218
  395. package/.agents/scripts/standalone-feedback-rollup.js +0 -188
  396. package/.agents/scripts/story-close.js +0 -294
  397. package/.agents/scripts/story-init.js +0 -599
  398. package/.agents/scripts/story-phase.js +0 -369
  399. package/.agents/scripts/wave-tick.js +0 -335
  400. package/.agents/skills/core/baseline-refresh/SKILL.md +0 -181
  401. package/.agents/skills/core/ci-cd-and-automation/SKILL.md +0 -274
  402. package/.agents/skills/core/ci-cd-and-automation/examples.md +0 -211
  403. package/.agents/skills/core/code-simplification/SKILL.md +0 -389
  404. package/.agents/skills/core/context-engineering/SKILL.md +0 -309
  405. package/.agents/skills/core/context-engineering/examples.md +0 -58
  406. package/.agents/skills/core/deprecation-and-migration/SKILL.md +0 -250
  407. package/.agents/skills/core/epic-plan-consolidate/SKILL.md +0 -172
  408. package/.agents/skills/core/epic-plan-consolidate/examples.md +0 -51
  409. package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +0 -441
  410. package/.agents/skills/core/epic-plan-decompose-author/examples.md +0 -47
  411. package/.agents/skills/core/epic-plan-premortem/SKILL.md +0 -146
  412. package/.agents/skills/core/epic-plan-premortem/examples.md +0 -53
  413. package/.agents/skills/core/epic-plan-spec-author/SKILL.md +0 -413
  414. package/.agents/skills/core/epic-plan-spec-author/examples.md +0 -91
  415. package/.agents/skills/core/frontend-ui-engineering/SKILL.md +0 -357
  416. package/.agents/skills/core/hydrate-context/SKILL.md +0 -123
  417. package/.agents/skills/core/idea-refinement/examples.md +0 -437
  418. package/.agents/skills/core/idea-refinement/frameworks.md +0 -135
  419. package/.agents/skills/core/incremental-implementation/SKILL.md +0 -271
  420. package/.agents/skills/core/introducing-a-baseline-gate/SKILL.md +0 -213
  421. package/.agents/skills/core/knowledge-transfer/SKILL.md +0 -180
  422. package/.agents/skills/core/mutation-survivor-remediation/SKILL.md +0 -117
  423. package/.agents/skills/core/performance-optimization/SKILL.md +0 -314
  424. package/.agents/skills/core/planning-and-task-breakdown/SKILL.md +0 -277
  425. package/.agents/skills/core/property-based-testing/SKILL.md +0 -148
  426. package/.agents/skills/core/refactoring-discipline/SKILL.md +0 -111
  427. package/.agents/skills/core/shipping-and-launch/SKILL.md +0 -328
  428. package/.agents/skills/core/spec-driven-development/SKILL.md +0 -252
  429. package/.agents/skills/core/test-driven-development/SKILL.md +0 -475
  430. package/.agents/skills/core/using-agent-skills/SKILL.md +0 -232
  431. package/.agents/skills/stack/architecture/monorepo-path-strategist/SKILL.md +0 -31
  432. package/.agents/skills/stack/architecture/structured-output-zod/SKILL.md +0 -51
  433. package/.agents/skills/stack/architecture/subagent-orchestration/SKILL.md +0 -76
  434. package/.agents/skills/stack/backend/cloudflare-hono-architect/SKILL.md +0 -31
  435. package/.agents/skills/stack/backend/cloudflare-hono-architect/examples/route-template.ts +0 -33
  436. package/.agents/skills/stack/backend/cloudflare-queue-manager/SKILL.md +0 -31
  437. package/.agents/skills/stack/backend/cloudflare-workers/SKILL.md +0 -51
  438. package/.agents/skills/stack/backend/highlevel-crm/SKILL.md +0 -54
  439. package/.agents/skills/stack/backend/sqlite-drizzle-expert/SKILL.md +0 -29
  440. package/.agents/skills/stack/backend/sqlite-drizzle-expert/examples/schema-template.ts +0 -30
  441. package/.agents/skills/stack/backend/stripe-integration/SKILL.md +0 -57
  442. package/.agents/skills/stack/backend/stripe-integration/scripts/listen-stripe.sh +0 -9
  443. package/.agents/skills/stack/backend/turso-sqlite/SKILL.md +0 -48
  444. package/.agents/skills/stack/frontend/astro/SKILL.md +0 -62
  445. package/.agents/skills/stack/frontend/astro-react-island-strategist/SKILL.md +0 -30
  446. package/.agents/skills/stack/frontend/expo-react-native-developer/SKILL.md +0 -29
  447. package/.agents/skills/stack/frontend/google-analytics-v4/SKILL.md +0 -50
  448. package/.agents/skills/stack/frontend/tailwind-v4/SKILL.md +0 -58
  449. package/.agents/skills/stack/frontend/ui-accessibility-engineer/SKILL.md +0 -34
  450. package/.agents/skills/stack/qa/audit-accessibility/SKILL.md +0 -51
  451. package/.agents/skills/stack/qa/lighthouse-baseline/SKILL.md +0 -199
  452. package/.agents/skills/stack/security/backend-security-patterns/SKILL.md +0 -68
  453. package/.agents/workflows/helpers/deliver-epic-reference.md +0 -534
  454. package/.agents/workflows/helpers/deliver-epic.md +0 -955
  455. package/.agents/workflows/helpers/deliver-stories.md +0 -440
  456. package/.agents/workflows/helpers/epic-audit.md +0 -189
  457. package/.agents/workflows/helpers/epic-deliver-story.md +0 -427
  458. package/.agents/workflows/helpers/epic-testing.md +0 -125
  459. package/.agents/workflows/helpers/plan-epic-reference.md +0 -160
  460. package/.agents/workflows/helpers/plan-epic.md +0 -351
  461. package/.agents/workflows/helpers/plan-story.md +0 -251
  462. package/.agents/workflows/helpers/scope-triage-gate.md +0 -108
  463. /package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/spec-authoring-grounding.js +0 -0
@@ -1,378 +0,0 @@
1
- // .agents/scripts/lib/orchestration/lifecycle/listeners/index.js
2
- /**
3
- * Default listener-chain builder for the standalone `lifecycle-emit`
4
- * CLI surface (Story #2510, Epic #2501).
5
- *
6
- * This is the SOLE production wiring path for the close-tail listener
7
- * roster. (The in-process `epic-runner/factory.js` that previously
8
- * mirrored this roster for an in-session runner was deleted with the
9
- * dead epic-runner stratum in Story #3908; the host-LLM-drives-CLIs
10
- * model reaches every close-tail listener through the `lifecycle-emit.js`
11
- * CLI shells in `/deliver`'s Phase 6 / 7.5 / 8 markdown invocations,
12
- * which call this builder.)
13
- *
14
- * Canonical roster (registration order):
15
- * 1. LedgerWriter (privileged hooks via `register(bus)`)
16
- * 2. AcceptanceReconciler (epic.close.end → acceptance.reconcile.*)
17
- * 3. Finalizer (acceptance.reconcile.{ok,waived} → pr.created)
18
- * 4. AutomergeArmer (epic.merge.ready → epic.merge.armed)
19
- * 5. AutomergePredicate (epic.watch.end → epic.merge.{ready,blocked})
20
- * 6. BranchCleaner (epic.cleanup.start → branch reap)
21
- * 7. MergeWatcher (epic.merge.armed → epic.merge.confirmed)
22
- * 8. Cleaner (epic.merge.confirmed → epic.cleanup.* / epic.complete)
23
- * 9. LabelTransitioner (epic.complete → Epic ticket flips to agent::done)
24
- * 10. CheckpointPointerWriter (every *.end → checkpoint.json)
25
- *
26
- * The bus contract requires LedgerWriter first: its `onEmitted` hook
27
- * lands the `emitted` ledger record on disk BEFORE any listener body
28
- * executes, so a crash mid-chain leaves a recoverable trail.
29
- *
30
- * Listeners whose constructors require collaborators that are not
31
- * available outside the runner (e.g. AutomergePredicate's `provider`,
32
- * BranchCleaner's `checkpointer`) are SKIPPED with a debug log rather
33
- * than constructed. This matches the factory's defensive guard pattern
34
- * — registration is best-effort; the chain still wires every listener
35
- * whose dependencies are satisfiable.
36
- *
37
- * Signature: `buildDefaultListenerChain({ bus, ledgerPath, repoRoot })`.
38
- * The Tech Spec for Epic #2501 (§ Story 4) fixes the public shape at
39
- * those three keys. `ledgerPath` is decomposed into `tempRoot` and
40
- * `epicId` so the listener constructors receive what they need;
41
- * `repoRoot` threads through as `cwd` for listeners that shell out
42
- * (`Finalizer`, `AutomergeArmer`).
43
- *
44
- * Maintainability exemption (refs #3685): this module is listed under
45
- * `delivery.quality.gates.maintainability.ignoreGlobs` in `.agentrc.json`.
46
- * Its sole content is a linear, low-branching listener-registration
47
- * sequence; the maintainability index mis-gauges that shape (the same
48
- * reason the declarative `config-settings-schema*` files are exempt).
49
- * Splitting the sequence across sibling builder modules purely to clear
50
- * the floor would add indirection without making the wiring easier to
51
- * read, so the debt is carried explicitly here rather than hidden behind
52
- * a blanket low floor.
53
- */
54
-
55
- import path from 'node:path';
56
-
57
- import { createLedgerWriter } from '../ledger-writer.js';
58
- import { AcceptanceReconciler } from './acceptance-reconciler.js';
59
- import { AutomergeArmer } from './automerge-armer.js';
60
- import { AutomergePredicate } from './automerge-predicate.js';
61
- import { BranchCleaner } from './branch-cleaner.js';
62
- import { CheckpointPointerWriter } from './checkpoint-pointer-writer.js';
63
- import { Cleaner } from './cleaner.js';
64
- import { Finalizer } from './finalizer.js';
65
- import { LabelTransitioner } from './label-transitioner.js';
66
- import { MergeWatcher } from './merge-watcher.js';
67
-
68
- /**
69
- * Parse `temp/epic-<id>/lifecycle.ndjson` into `{ tempRoot, epicId }`.
70
- *
71
- * Throws when the input does not match the canonical layout. The
72
- * standalone `lifecycle-emit` CLI is the sole production caller and it
73
- * always feeds the canonical `epicLedgerPath(eid)` value, so a mismatch
74
- * here is a programmer error — surface it loudly.
75
- *
76
- * @param {string} ledgerPath
77
- * @returns {{ tempRoot: string, epicId: number }}
78
- */
79
- export function parseLedgerPath(ledgerPath) {
80
- if (typeof ledgerPath !== 'string' || ledgerPath.length === 0) {
81
- throw new TypeError(
82
- 'buildDefaultListenerChain: ledgerPath must be a non-empty string',
83
- );
84
- }
85
- const epicDir = path.dirname(ledgerPath);
86
- const tempRoot = path.dirname(epicDir);
87
- const epicDirName = path.basename(epicDir);
88
- const m = /^epic-(\d+)$/.exec(epicDirName);
89
- if (!m) {
90
- throw new Error(
91
- `buildDefaultListenerChain: ledgerPath does not match temp/epic-<id>/lifecycle.ndjson layout (got ${ledgerPath})`,
92
- );
93
- }
94
- const epicId = Number.parseInt(m[1], 10);
95
- if (!Number.isInteger(epicId) || epicId < 1) {
96
- throw new Error(
97
- `buildDefaultListenerChain: parsed epicId from ledgerPath is not a positive integer (got ${m[1]})`,
98
- );
99
- }
100
- return { tempRoot, epicId };
101
- }
102
-
103
- /**
104
- * Build and subscribe the canonical default listener chain onto the
105
- * supplied bus.
106
- *
107
- * @param {object} opts
108
- * @param {object} opts.bus Lifecycle bus instance (must expose `on`,
109
- * `emit`, and the privileged `onEmitted` / `onCompleted` / `onFailed`
110
- * hook seam).
111
- * @param {string} opts.ledgerPath Absolute or repo-relative path to the
112
- * Epic's `lifecycle.ndjson`. Decomposed into `{ tempRoot, epicId }`
113
- * for downstream constructors.
114
- * @param {string} opts.repoRoot Absolute path used as `cwd` for
115
- * listeners that shell out (Finalizer, AutomergeArmer, BranchCleaner).
116
- * @param {object} [opts.provider] Ticketing provider. When omitted,
117
- * AutomergePredicate is skipped (the listener constructor throws on
118
- * a missing provider).
119
- * @param {object} [opts.config] Resolved agent config. Forwarded to the
120
- * AcceptanceReconciler.
121
- * @param {object} [opts.checkpointer] Epic-run-state checkpoint reader.
122
- * When omitted, BranchCleaner is skipped.
123
- * @param {object} [opts.logger] Logger surface (`debug`/`warn`/`error`).
124
- * @param {boolean} [opts.headless] Explicit must-land signal (Story
125
- * #4427), threaded straight through to `MergeWatcher`. Defaults to
126
- * `false` (attended-mode behavior unchanged). `lifecycle-emit.js`
127
- * resolves this from its own `--headless` runtime flag — an explicit
128
- * input, never an ambient global.
129
- *
130
- * @returns {Promise<{
131
- * ledgerWriter: object,
132
- * acceptanceReconciler: object,
133
- * finalizer: object,
134
- * automergeArmer: object,
135
- * automergePredicate: object|null,
136
- * branchCleaner: object|null,
137
- * cleaner: object,
138
- * checkpointPointerWriter: object,
139
- * order: string[]
140
- * }>}
141
- */
142
- export async function buildDefaultListenerChain(opts = {}) {
143
- const {
144
- bus,
145
- ledgerPath,
146
- repoRoot,
147
- provider = null,
148
- config = null,
149
- checkpointer = null,
150
- logger = console,
151
- headless = false,
152
- } = opts;
153
- if (
154
- !bus ||
155
- typeof bus.on !== 'function' ||
156
- typeof bus.emit !== 'function' ||
157
- typeof bus.onEmitted !== 'function'
158
- ) {
159
- throw new TypeError(
160
- 'buildDefaultListenerChain: bus must expose on/emit and the privileged onEmitted/onCompleted/onFailed seam',
161
- );
162
- }
163
- if (typeof repoRoot !== 'string' || repoRoot.length === 0) {
164
- throw new TypeError(
165
- 'buildDefaultListenerChain: repoRoot must be a non-empty string',
166
- );
167
- }
168
- const { tempRoot, epicId } = parseLedgerPath(ledgerPath);
169
-
170
- const order = [];
171
-
172
- // 1. LedgerWriter — MUST be first. Uses the privileged hook seam, so
173
- // its registration call is `register(bus)` rather than a regular
174
- // `bus.on()` subscription. The bus contract guarantees `emitted`
175
- // lands on disk before any listener body executes.
176
- const ledgerWriter = createLedgerWriter({ epicId, tempRoot });
177
- ledgerWriter.register(bus);
178
- order.push('LedgerWriter');
179
-
180
- // 2. AcceptanceReconciler — gates Finalize on close-time AC coverage.
181
- const acceptanceReconciler = new AcceptanceReconciler({
182
- bus,
183
- epicId,
184
- cwd: repoRoot,
185
- provider,
186
- config,
187
- logger,
188
- });
189
- acceptanceReconciler.register();
190
- order.push('AcceptanceReconciler');
191
-
192
- // 3. Finalizer — opens the PR on acceptance.reconcile.ok or .waived
193
- // (Story #2893 split waiver out of .skipped) via the bus-owned
194
- // default (`composeBusOwnedFinalize`, Story #2894), which chains
195
- // openOrLocatePr → postHandoffComment and
196
- // emits `epic.merge.ready` on success. The legacy
197
- // `d1-default-no-op` blocker is gone; the listener constructed
198
- // with no `runFinalizeFn` override always runs the real flow.
199
- // The code-review / audit-results graduator steps (Stories
200
- // #2555 / #2615) remain best-effort and are silently skipped
201
- // when `provider` / `currentRepo` are not wired in. `currentRepo`
202
- // is resolved from `config.github.{owner,repo}`; `frameworkRepo`
203
- // from `config.github.frameworkRepo` when distinct, otherwise omitted.
204
- const currentRepo =
205
- config?.github?.owner && config?.github?.repo
206
- ? { owner: config.github.owner, repo: config.github.repo }
207
- : null;
208
- const frameworkRepo =
209
- config?.github?.frameworkRepo?.owner && config?.github?.frameworkRepo?.repo
210
- ? {
211
- owner: config.github.frameworkRepo.owner,
212
- repo: config.github.frameworkRepo.repo,
213
- }
214
- : null;
215
- const finalizer = new Finalizer({
216
- bus,
217
- epicId,
218
- cwd: repoRoot,
219
- provider,
220
- config,
221
- currentRepo,
222
- frameworkRepo,
223
- logger,
224
- });
225
- finalizer.register();
226
- order.push('Finalizer');
227
-
228
- // 4. AutomergeArmer — arms `gh pr merge --auto --squash --delete-branch`
229
- // on epic.merge.ready. Story #4472: `headless` gates the direct-merge
230
- // fallback's terminal escalation (a genuine arm failure emits
231
- // `merge.unlanded` + `epic.blocked` in a `--yes` run instead of
232
- // returning silently); `epicId` scopes the `merge.unlanded` ledger row.
233
- const automergeArmer = new AutomergeArmer({
234
- bus,
235
- epicId,
236
- cwd: repoRoot,
237
- headless,
238
- logger,
239
- });
240
- automergeArmer.register();
241
- order.push('AutomergeArmer');
242
-
243
- // 5. AutomergePredicate — emits epic.merge.{ready,blocked} based on
244
- // the runtime predicate evaluation. Requires a truthy `provider`;
245
- // skip cleanly when the caller omitted one (lifecycle-emit CLI
246
- // has no provider wired in by default). `config` selects the
247
- // `delivery.ci.autoMerge` posture (trust-ci default vs strict) and
248
- // `cwd` (repoRoot) is where the live `gh pr checks --required`
249
- // probe shells out (Story #4361).
250
- let automergePredicate = null;
251
- if (provider) {
252
- automergePredicate = new AutomergePredicate({
253
- bus,
254
- epicId,
255
- provider,
256
- config,
257
- cwd: repoRoot,
258
- headless,
259
- logger,
260
- });
261
- automergePredicate.register();
262
- order.push('AutomergePredicate');
263
- } else {
264
- logger?.debug?.(
265
- '[lifecycle] buildDefaultListenerChain: skipping AutomergePredicate (no provider)',
266
- );
267
- }
268
-
269
- // 6. BranchCleaner — reaps story/epic branches on epic.cleanup.start.
270
- // Requires a checkpointer exposing `read()`; skip cleanly when
271
- // the caller omitted one.
272
- let branchCleaner = null;
273
- if (checkpointer && typeof checkpointer.read === 'function') {
274
- branchCleaner = new BranchCleaner({
275
- bus,
276
- epicId,
277
- checkpointer,
278
- cwd: repoRoot,
279
- logger,
280
- });
281
- branchCleaner.register();
282
- order.push('BranchCleaner');
283
- } else {
284
- logger?.debug?.(
285
- '[lifecycle] buildDefaultListenerChain: skipping BranchCleaner (no checkpointer)',
286
- );
287
- }
288
-
289
- // 7. MergeWatcher (Story #2896, Epic #2880) — polls `gh pr view`
290
- // after `epic.merge.armed` until the PR's mergeCommit is
291
- // non-null, then emits `epic.merge.confirmed`. Cleaner now
292
- // waits on the confirmed event rather than the armed event so
293
- // the Epic only transitions to its terminal state after the
294
- // merge is actually observed on GitHub. Reads `intervalSeconds`
295
- // and `maxBudgetSeconds` from `config.delivery.mergeWatch.*`
296
- // when supplied; otherwise uses the listener's framework
297
- // defaults (30s / 3600s).
298
- const mergeWatchConfig = config?.delivery?.mergeWatch ?? {};
299
- const mergeWatcher = new MergeWatcher({
300
- bus,
301
- epicId,
302
- tempRoot,
303
- cwd: repoRoot,
304
- intervalSeconds: mergeWatchConfig.intervalSeconds,
305
- maxBudgetSeconds: mergeWatchConfig.maxBudgetSeconds,
306
- headless,
307
- logger,
308
- });
309
- mergeWatcher.register();
310
- order.push('MergeWatcher');
311
-
312
- // 8. Cleaner — archives temp/epic-<id>/ and emits the terminal
313
- // epic.cleanup.start → .end → epic.complete sequence. Story
314
- // #2896 rebound this listener from `epic.merge.armed` to
315
- // `epic.merge.confirmed`.
316
- const cleaner = new Cleaner({
317
- bus,
318
- epicId,
319
- tempRoot,
320
- logger,
321
- });
322
- cleaner.register();
323
- order.push('Cleaner');
324
-
325
- // 9. LabelTransitioner — flips the Epic ticket to `agent::done` (and
326
- // closes it as completed, idempotently) on the terminal
327
- // `epic.complete` event. Requires a truthy `provider`; skip
328
- // cleanly when the caller omitted one — the same guard pattern as
329
- // AutomergePredicate. Restores the contract the Cleaner /
330
- // BranchCleaner / MergeWatcher docstrings have referenced since
331
- // the original listener was deleted with the epic-runner stratum
332
- // (#3936): without this registration the flip had NO owner and
333
- // cleanly-merged Epics stranded at `agent::executing`.
334
- let labelTransitioner = null;
335
- if (provider) {
336
- labelTransitioner = new LabelTransitioner({
337
- bus,
338
- epicId,
339
- provider,
340
- logger,
341
- });
342
- labelTransitioner.register();
343
- order.push('LabelTransitioner');
344
- } else {
345
- logger?.debug?.(
346
- '[lifecycle] buildDefaultListenerChain: skipping LabelTransitioner (no provider)',
347
- );
348
- }
349
-
350
- // 10. CheckpointPointerWriter — persists `{ lastCompletedSeqId, phase }`
351
- // on every `*.end` event.
352
- const checkpointPointerWriter = new CheckpointPointerWriter({
353
- bus,
354
- epicId,
355
- tempRoot,
356
- logger,
357
- });
358
- checkpointPointerWriter.register();
359
- order.push('CheckpointPointerWriter');
360
-
361
- logger?.debug?.(
362
- `[lifecycle] buildDefaultListenerChain registered listeners: ${order.join(' → ')}`,
363
- );
364
-
365
- return {
366
- ledgerWriter,
367
- acceptanceReconciler,
368
- finalizer,
369
- automergeArmer,
370
- automergePredicate,
371
- branchCleaner,
372
- mergeWatcher,
373
- cleaner,
374
- labelTransitioner,
375
- checkpointPointerWriter,
376
- order,
377
- };
378
- }
@@ -1,140 +0,0 @@
1
- // .agents/scripts/lib/orchestration/lifecycle/listeners/intervention-recorder.js
2
- /**
3
- * InterventionRecorder — lifecycle listener that persists out-of-band
4
- * manual interventions to the `epic-run-state` structured comment.
5
- *
6
- * Subscribes to (per Story #2410 / Task #2416):
7
- * - `intervention.recorded` → calls `appendIntervention` on the
8
- * `epic-run-state-store` so the `manualInterventions` array on the
9
- * epic-run-state checkpoint comment grows by exactly one record.
10
- *
11
- * The lifecycle event is the canonical signal that the host LLM has
12
- * performed an out-of-band recovery (`AskUserQuestion`, manual
13
- * `git restore`, `--no-ff` recovery merge, `story-close --skipValidation`,
14
- * etc.). The auto-merge predicate reads the persisted array and only
15
- * fires when it is empty, so getting one record per emit is load-bearing.
16
- *
17
- * Idempotency contract (listeners/README.md): the listener keeps a
18
- * per-instance `Set<seqId>` of seqIds it has handled. A repeat
19
- * invocation with the same seqId short-circuits without calling the
20
- * store. (`epic-run-state-store.appendIntervention` is NOT idempotent
21
- * on its own — it always appends — so the seqId guard is the only
22
- * thing standing between a bus replay and a duplicated record.)
23
- *
24
- * Side-effect firewall (listeners/README.md):
25
- * - MAY read/write the epic-run-state comment via the injected
26
- * `provider` (through `epic-run-state-store`).
27
- * - MUST NOT `bus.emit()` from inside the handler body — the bus is a
28
- * sequential mediator and cannot re-enter safely.
29
- * - MUST NOT import any module from
30
- * `STATE_MUTATING_MODULES` in `check-lifecycle-lint.js`. The
31
- * epic-run-state-store module is NOT on that blocklist; the lint
32
- * rule treats it as a safe persistence boundary for listeners.
33
- */
34
-
35
- import { appendIntervention } from '../../epic-run-state-store.js';
36
-
37
- export const INTERVENTION_RECORDED_EVENT = 'intervention.recorded';
38
-
39
- export class InterventionRecorder {
40
- /**
41
- * @param {object} opts
42
- * @param {object} opts.provider Ticketing provider threaded through to
43
- * `appendIntervention`.
44
- * @param {number} opts.epicId Target ticket id (the Epic). Used both
45
- * to scope `appendIntervention` and to filter incoming emits — a
46
- * payload whose `epicId` does not match this listener's Epic is
47
- * ignored (defensive; production wiring only ever emits with the
48
- * listener's own epicId).
49
- * @param {{ warn?: Function, debug?: Function }} [opts.logger]
50
- * @param {Function} [opts.appendIntervention] Injected store fn —
51
- * defaults to the canonical import. Tests pass a spy.
52
- */
53
- constructor(opts = {}) {
54
- if (!opts.provider) {
55
- throw new TypeError('InterventionRecorder requires a provider');
56
- }
57
- if (!Number.isInteger(opts.epicId) || opts.epicId < 1) {
58
- throw new TypeError('InterventionRecorder requires a numeric epicId');
59
- }
60
- this.provider = opts.provider;
61
- this.epicId = opts.epicId;
62
- this.logger = opts.logger ?? console;
63
- this._appendIntervention =
64
- typeof opts.appendIntervention === 'function'
65
- ? opts.appendIntervention
66
- : appendIntervention;
67
- /** @type {Set<number>} seqIds we've already handled. */
68
- this._seen = new Set();
69
- this.events = Object.freeze([INTERVENTION_RECORDED_EVENT]);
70
- }
71
-
72
- /**
73
- * Subscribe to `intervention.recorded`. Returns the unsubscribe
74
- * handles so tests / teardown can detach without re-binding through
75
- * the bus's private registry.
76
- */
77
- register(bus) {
78
- if (!bus || typeof bus.on !== 'function') {
79
- throw new TypeError(
80
- 'InterventionRecorder.register requires a bus with on()',
81
- );
82
- }
83
- return this.events.map((event) =>
84
- bus.on(event, async (ctx) => this.handle(ctx)),
85
- );
86
- }
87
-
88
- /**
89
- * Handle one `intervention.recorded` emit. Idempotent on seqId. The
90
- * payload has already been schema-validated by the bus, so `reason`
91
- * is guaranteed to be a non-empty string and `epicId` a positive
92
- * integer.
93
- *
94
- * @param {{ event: string, seqId: number, payload: { epicId: number, reason: string, source?: string, ts?: string } }} ctx
95
- */
96
- async handle({ event, seqId, payload }) {
97
- if (event !== INTERVENTION_RECORDED_EVENT) return;
98
- if (this._seen.has(seqId)) {
99
- this.logger.debug?.(
100
- `[InterventionRecorder] skip duplicate seqId=${seqId} (idempotent)`,
101
- );
102
- return;
103
- }
104
- // Defensive epicId filter — a misrouted emit (e.g., a shared bus in
105
- // tests) should not pollute a different Epic's state comment.
106
- if (payload?.epicId !== this.epicId) {
107
- this.logger.debug?.(
108
- `[InterventionRecorder] skip payload.epicId=${payload?.epicId} (listener bound to #${this.epicId})`,
109
- );
110
- return;
111
- }
112
- this._seen.add(seqId);
113
-
114
- const entry = {
115
- reason: payload.reason,
116
- };
117
- if (typeof payload.source === 'string' && payload.source.length > 0) {
118
- entry.source = payload.source;
119
- }
120
- if (typeof payload.ts === 'string' && payload.ts.length > 0) {
121
- entry.ts = payload.ts;
122
- }
123
- try {
124
- await this._appendIntervention({
125
- provider: this.provider,
126
- epicId: this.epicId,
127
- entry,
128
- });
129
- } catch (err) {
130
- this.logger.warn?.(
131
- `[InterventionRecorder] appendIntervention failed for seqId=${seqId}: ${err?.message ?? err}`,
132
- );
133
- throw err;
134
- }
135
- }
136
-
137
- resetSeen() {
138
- this._seen.clear();
139
- }
140
- }
@@ -1,144 +0,0 @@
1
- // .agents/scripts/lib/orchestration/lifecycle/listeners/label-transitioner.js
2
- /**
3
- * LabelTransitioner — lifecycle listener that owns the terminal Epic
4
- * ticket-state flip: on `epic.complete` it transitions the Epic to
5
- * `agent::done` via the canonical `transitionTicketState` API (which
6
- * also closes the issue with `state_reason: completed` and mirrors the
7
- * Projects-v2 status column).
8
- *
9
- * Subscribes to:
10
- * - `epic.complete` → and ONLY this event.
11
- *
12
- * Why this listener exists (regression history): the original
13
- * LabelTransitioner lived in the in-process epic-runner stratum and was
14
- * deleted with it (Story #3908 / #3936) — but the `lifecycle-emit`
15
- * listener chain never re-registered a replacement, so the Epic
16
- * `agent::done` flip silently had NO owner. Every docstring in
17
- * `cleaner.js` / `branch-cleaner.js` / `merge-watcher.js` that says
18
- * "LabelTransitioner flips the Epic ticket to `agent::done` on
19
- * epic.complete" referenced a ghost. In practice the flip only happened
20
- * when a driving session (or the operator) ran `update-ticket-state.js`
21
- * by hand — observed live on 2026-07-11 when Epics #4405 / #4425 /
22
- * #4429 merged cleanly (Cleaner archived, `epic.complete` on the
23
- * ledger) yet stayed at `agent::executing`. This listener restores the
24
- * documented contract on the SOLE production wiring path
25
- * (`buildDefaultListenerChain`).
26
- *
27
- * Side effects executed inside `handle()`:
28
- * 1. `transitionTicketState(provider, epicId, STATE_LABELS.DONE)` —
29
- * adds `agent::done`, removes every other `agent::*` label, closes
30
- * the issue as completed (idempotent when the GitHub Closes-#N
31
- * linkage already closed it), syncs the board column, and runs the
32
- * upward cascade (a no-op sweep here: story-close already flipped
33
- * every child Story).
34
- *
35
- * Failure posture: a failed transition THROWS (per
36
- * `rules/orchestration-error-handling.md` — throw, never fatal). The
37
- * bus's `onFailed` hook records the failure on the ledger and
38
- * `lifecycle-emit`'s `collectOutcomes` → `emitBlockedSignal` path
39
- * surfaces it loudly, so a provider outage cannot silently strand the
40
- * Epic at `agent::executing` again — the exact failure mode this
41
- * listener exists to close.
42
- *
43
- * Idempotency contract: per-instance `Set<string>` of
44
- * `${event}:${seqId}` keys (the standard bus-replay defence). The
45
- * transition itself is also idempotent at the provider layer (label
46
- * add/remove and a close on an already-closed issue are no-ops), so a
47
- * cross-process replay after a crash re-runs the flip harmlessly.
48
- *
49
- * Side-effect firewall: exactly one provider call per handled event. No
50
- * filesystem writes, no follow-up bus emits, no `gh` shell-outs.
51
- */
52
-
53
- import { STATE_LABELS } from '../../ticketing/reads.js';
54
- import { transitionTicketState } from '../../ticketing/transition.js';
55
-
56
- /**
57
- * The single lifecycle event this listener subscribes to. `epic.complete`
58
- * is the terminal event of a successful Epic run, emitted by Cleaner
59
- * AFTER the MergeWatcher observed a non-null mergeCommit — so the flip
60
- * can never fire for an Epic whose PR did not actually merge.
61
- */
62
- export const SUBSCRIBED_EVENT = 'epic.complete';
63
-
64
- export class LabelTransitioner {
65
- /**
66
- * @param {object} opts
67
- * @param {object} opts.bus Lifecycle bus exposing `on()`.
68
- * @param {number} opts.epicId Epic ticket id.
69
- * @param {import('../../../ITicketingProvider.js').ITicketingProvider} opts.provider
70
- * Ticketing provider. Required — the chain builder skips this
71
- * listener entirely when no provider is wired (parity with
72
- * AutomergePredicate's guard), so construction can demand one.
73
- * @param {{ info?: Function, warn?: Function, debug?: Function }} [opts.logger]
74
- */
75
- constructor(opts = {}) {
76
- if (!opts.bus || typeof opts.bus.on !== 'function') {
77
- throw new TypeError('LabelTransitioner requires a bus with on()');
78
- }
79
- if (!Number.isInteger(opts.epicId) || opts.epicId < 1) {
80
- throw new TypeError('LabelTransitioner requires a numeric epicId');
81
- }
82
- if (!opts.provider) {
83
- // Truthiness-only, parity with AutomergePredicate: the chain
84
- // builder's best-effort registration must not explode on a
85
- // shape-minimal provider — a malformed one fails loudly at
86
- // handle time instead, where the ledger records the outcome.
87
- throw new TypeError('LabelTransitioner requires a provider');
88
- }
89
- this.bus = opts.bus;
90
- this.epicId = opts.epicId;
91
- this.provider = opts.provider;
92
- this.logger = opts.logger ?? console;
93
- /** @type {Set<string>} `${event}:${seqId}` idempotency cache. */
94
- this._seen = new Set();
95
- // Canonical subscription-set shape: the lifecycle doc-drift gate
96
- // (`check-lifecycle-doc-drift.js#extractCodeEvents`) and the
97
- // event-connectivity contract test both resolve this frozen array
98
- // (constant references included) to derive the subscriber table.
99
- this.events = Object.freeze([SUBSCRIBED_EVENT]);
100
- }
101
-
102
- /**
103
- * Register the listener on `epic.complete`. Returns the array of
104
- * unsubscribe callbacks the bus produced (parity with the sibling
105
- * listeners).
106
- */
107
- register() {
108
- return this.events.map((event) =>
109
- this.bus.on(event, async (ctx) => this.handle(ctx)),
110
- );
111
- }
112
-
113
- /**
114
- * Bus listener body. Idempotent on `(event, seqId)`; flips the Epic
115
- * to `agent::done` exactly once per observed `epic.complete`.
116
- */
117
- async handle({ event, seqId }) {
118
- const key = `${event}:${seqId}`;
119
- if (this._seen.has(key)) {
120
- this.logger.debug?.(
121
- `[LabelTransitioner] skip duplicate ${key} (idempotent)`,
122
- );
123
- return;
124
- }
125
- this._seen.add(key);
126
-
127
- this.logger.info?.(
128
- `[LabelTransitioner] epic.complete observed — transitioning Epic #${this.epicId} to ${STATE_LABELS.DONE}.`,
129
- );
130
- // Throws on failure by design: the ledger records the failed
131
- // listener outcome and lifecycle-emit surfaces it (see the failure
132
- // posture note in the module docstring). Swallowing here would
133
- // recreate the silent agent::executing strand this listener fixes.
134
- await transitionTicketState(this.provider, this.epicId, STATE_LABELS.DONE);
135
- }
136
-
137
- /**
138
- * Test-only — clear the idempotency cache so a single instance can
139
- * exercise replay scenarios without re-constructing the listener.
140
- */
141
- resetSeen() {
142
- this._seen.clear();
143
- }
144
- }