mandrel 1.94.0 → 2.1.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 (560) hide show
  1. package/.agents/README.md +116 -99
  2. package/.agents/agents/acceptance-critic.md +9 -7
  3. package/.agents/agents/story-worker.md +45 -51
  4. package/.agents/audit-checklists/performance.md +1 -1
  5. package/.agents/docs/SDLC.md +498 -1287
  6. package/.agents/docs/agentrc-reference.json +185 -80
  7. package/.agents/docs/configuration.md +132 -190
  8. package/.agents/docs/execution-reference.md +51 -25
  9. package/.agents/docs/quality-gates.md +25 -33
  10. package/.agents/docs/workflows.md +8 -8
  11. package/.agents/instructions.md +113 -139
  12. package/.agents/rules/ci-remediation.md +11 -15
  13. package/.agents/rules/git-conventions-reference.md +48 -58
  14. package/.agents/rules/git-conventions.md +16 -22
  15. package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
  16. package/.agents/schemas/agentrc.schema.json +83 -254
  17. package/.agents/schemas/audit-rules.json +59 -1
  18. package/.agents/schemas/audit-rules.schema.json +33 -1
  19. package/.agents/schemas/lifecycle/README.md +1 -2
  20. package/.agents/schemas/lifecycle/ledger-record.schema.json +1 -1
  21. package/.agents/schemas/lifecycle/merge.flip-failed.schema.json +33 -0
  22. package/.agents/schemas/lifecycle/merge.unlanded.schema.json +1 -0
  23. package/.agents/schemas/lifecycle/retro.end.schema.json +1 -1
  24. package/.agents/schemas/lifecycle/story.merged.schema.json +1 -1
  25. package/.agents/schemas/signal-event.schema.json +3 -3
  26. package/.agents/schemas/story-deliver-terminal.schema.json +152 -0
  27. package/.agents/schemas/validation-evidence.schema.json +1 -1
  28. package/.agents/scripts/acceptance-eval.js +22 -66
  29. package/.agents/scripts/agents-bootstrap-github.js +1 -1
  30. package/.agents/scripts/audit-to-stories.js +7 -7
  31. package/.agents/scripts/boot-sweep.js +1 -1
  32. package/.agents/scripts/bootstrap.js +3 -3
  33. package/.agents/scripts/check-dead-exports.js +43 -104
  34. package/.agents/scripts/check-doc-links.js +2 -2
  35. package/.agents/scripts/check-lifecycle-lint.js +7 -10
  36. package/.agents/scripts/check-workflow-cli-lint.js +91 -0
  37. package/.agents/scripts/cleanup-repo-test-temp.js +6 -1
  38. package/.agents/scripts/deliver-recover.js +122 -0
  39. package/.agents/scripts/drain-pending-cleanup.js +1 -1
  40. package/.agents/scripts/evidence-gate.js +20 -50
  41. package/.agents/scripts/generate-skills-index.js +17 -1
  42. package/.agents/scripts/generate-workflows-doc.js +4 -4
  43. package/.agents/scripts/lib/ITicketingProvider.js +1 -19
  44. package/.agents/scripts/lib/Logger.js +6 -10
  45. package/.agents/scripts/lib/audit-suite/runner.js +2 -2
  46. package/.agents/scripts/lib/audit-suite/selector.js +328 -28
  47. package/.agents/scripts/lib/audit-to-stories/{seed-epic-from-findings.js → seed-from-findings.js} +9 -9
  48. package/.agents/scripts/lib/baselines/kernel.js +206 -18
  49. package/.agents/scripts/lib/baselines/kinds/maintainability.js +0 -15
  50. package/.agents/scripts/lib/baselines/reader.js +1 -6
  51. package/.agents/scripts/lib/bdd-runner-detect.js +5 -9
  52. package/.agents/scripts/lib/bootstrap/ci-workflow-template.js +28 -33
  53. package/.agents/scripts/lib/bootstrap/issue-forms-template.js +32 -33
  54. package/.agents/scripts/lib/bootstrap/manifest.js +8 -11
  55. package/.agents/scripts/lib/bootstrap/project-bootstrap.js +30 -53
  56. package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +0 -2
  57. package/.agents/scripts/lib/checks/core-bare-clean.js +6 -3
  58. package/.agents/scripts/lib/checks/index.js +3 -2
  59. package/.agents/scripts/lib/checks/loop-health.js +12 -11
  60. package/.agents/scripts/lib/checks/state.js +17 -248
  61. package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +26 -24
  62. package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +3 -4
  63. package/.agents/scripts/lib/checks/worktree-bootstrap-env.js +2 -2
  64. package/.agents/scripts/lib/checks/worktree-residue-biome.js +3 -3
  65. package/.agents/scripts/lib/cli/standard-args.js +13 -22
  66. package/.agents/scripts/lib/cli-args.js +39 -9
  67. package/.agents/scripts/lib/close-validation/gates.js +15 -15
  68. package/.agents/scripts/lib/close-validation/projections/inputs.js +7 -7
  69. package/.agents/scripts/lib/close-validation/projections/maintainability.js +12 -12
  70. package/.agents/scripts/lib/close-validation/runner.js +13 -21
  71. package/.agents/scripts/lib/close-validation/telemetry.js +17 -8
  72. package/.agents/scripts/lib/config/ci.js +6 -31
  73. package/.agents/scripts/lib/config/delivery-routing.js +52 -35
  74. package/.agents/scripts/lib/config/explain.js +61 -48
  75. package/.agents/scripts/lib/config/github.js +7 -5
  76. package/.agents/scripts/lib/config/limits.js +29 -80
  77. package/.agents/scripts/lib/config/paths.js +0 -2
  78. package/.agents/scripts/lib/config/quality.js +12 -15
  79. package/.agents/scripts/lib/config/runners.js +20 -66
  80. package/.agents/scripts/lib/config/temp-paths.js +30 -63
  81. package/.agents/scripts/lib/config/worktree-isolation.js +0 -5
  82. package/.agents/scripts/lib/config-resolver.js +2 -7
  83. package/.agents/scripts/lib/config-settings-schema-delivery.js +55 -161
  84. package/.agents/scripts/lib/config-settings-schema-quality.js +17 -16
  85. package/.agents/scripts/lib/config-settings-schema.js +100 -60
  86. package/.agents/scripts/lib/dead-exports-knip.js +105 -0
  87. package/.agents/scripts/lib/dead-exports-mode.js +51 -0
  88. package/.agents/scripts/lib/dependency-parser.js +3 -2
  89. package/.agents/scripts/lib/doc-tiers.js +2 -2
  90. package/.agents/scripts/lib/duplicate-search.js +242 -41
  91. package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +1 -1
  92. package/.agents/scripts/lib/findings/promote-finding.js +23 -14
  93. package/.agents/scripts/lib/format-generated-json.js +97 -0
  94. package/.agents/scripts/lib/framework-version.js +19 -190
  95. package/.agents/scripts/lib/gh-exec.js +8 -0
  96. package/.agents/scripts/lib/git-branch-cleanup.js +1 -10
  97. package/.agents/scripts/lib/git-branch-lifecycle.js +17 -180
  98. package/.agents/scripts/lib/git-utils.js +32 -20
  99. package/.agents/scripts/lib/github/framework-repo.js +6 -0
  100. package/.agents/scripts/lib/json-utils.js +1 -2
  101. package/.agents/scripts/lib/label-constants.js +10 -38
  102. package/.agents/scripts/lib/label-taxonomy.js +10 -55
  103. package/.agents/scripts/lib/observability/active-story-env.js +44 -165
  104. package/.agents/scripts/lib/observability/runtime-friction.js +243 -0
  105. package/.agents/scripts/lib/observability/signal-validator.js +4 -4
  106. package/.agents/scripts/lib/observability/signals-writer.js +6 -82
  107. package/.agents/scripts/lib/observability/source-classifier.js +5 -5
  108. package/.agents/scripts/lib/observability/tool-trace-hook.js +2 -12
  109. package/.agents/scripts/lib/onboard/init-tail.js +1 -3
  110. package/.agents/scripts/lib/orchestration/acceptance-clusters.js +1 -1
  111. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +2 -2
  112. package/.agents/scripts/lib/orchestration/ceremony-routing.js +105 -44
  113. package/.agents/scripts/lib/orchestration/code-review.js +78 -436
  114. package/.agents/scripts/lib/orchestration/column-sync.js +1 -1
  115. package/.agents/scripts/lib/orchestration/consolidation-precondition.js +4 -4
  116. package/.agents/scripts/lib/orchestration/context-envelope.js +2 -5
  117. package/.agents/scripts/lib/orchestration/deliver-recover.js +328 -0
  118. package/.agents/scripts/lib/orchestration/detectors-phase.js +12 -6
  119. package/.agents/scripts/lib/orchestration/docs-digest.js +8 -8
  120. package/.agents/scripts/lib/orchestration/file-assumptions.js +7 -13
  121. package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +1 -1
  122. package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +34 -0
  123. package/.agents/scripts/lib/orchestration/lease-guard-shared.js +3 -2
  124. package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +142 -0
  125. package/.agents/scripts/lib/orchestration/lifecycle/emit-loop-tick.js +17 -19
  126. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +86 -0
  127. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +37 -103
  128. package/.agents/scripts/lib/orchestration/lifecycle/ledger-writer.js +6 -3
  129. package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +21 -43
  130. package/.agents/scripts/lib/orchestration/lifecycle/listeners/watcher.js +50 -85
  131. package/.agents/scripts/lib/orchestration/lifecycle/trace-logger.js +3 -14
  132. package/.agents/scripts/lib/orchestration/lint-baseline-service.js +4 -4
  133. package/.agents/scripts/lib/orchestration/merge-block-class.js +77 -21
  134. package/.agents/scripts/lib/orchestration/merge-poll.js +104 -0
  135. package/.agents/scripts/lib/orchestration/phase-runner.js +3 -2
  136. package/.agents/scripts/lib/orchestration/plan-context.js +354 -282
  137. package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +11 -22
  138. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +4 -8
  139. package/.agents/scripts/lib/orchestration/plan-metrics.js +38 -6
  140. package/.agents/scripts/lib/orchestration/plan-navigation.js +92 -0
  141. package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +71 -0
  142. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +245 -0
  143. package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +116 -0
  144. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +432 -858
  145. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +778 -0
  146. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +47 -115
  147. package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +509 -0
  148. package/.agents/scripts/lib/orchestration/plan-reachability.js +9 -14
  149. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +1 -1
  150. package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/authoring-context.js +52 -51
  151. package/.agents/scripts/lib/orchestration/planning/decomposer-context.js +27 -0
  152. package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/spec-authoring-grounding.js +1 -1
  153. package/.agents/scripts/lib/orchestration/pr-base-guard.js +18 -28
  154. package/.agents/scripts/lib/orchestration/remote-verifier.js +1 -1
  155. package/.agents/scripts/lib/orchestration/resolve-stories.js +344 -0
  156. package/.agents/scripts/lib/orchestration/resolves-token.js +1 -1
  157. package/.agents/scripts/lib/orchestration/retro-proposals.js +140 -79
  158. package/.agents/scripts/lib/orchestration/review-depth.js +126 -47
  159. package/.agents/scripts/lib/orchestration/review-providers/codex.js +2 -2
  160. package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +3 -13
  161. package/.agents/scripts/lib/orchestration/review-providers/native.js +1 -154
  162. package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +3 -2
  163. package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +21 -56
  164. package/.agents/scripts/lib/orchestration/review-providers/security-review.js +1 -1
  165. package/.agents/scripts/lib/orchestration/review-providers/types.js +5 -4
  166. package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +1 -1
  167. package/.agents/scripts/lib/orchestration/run-epilogue.js +784 -0
  168. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +25 -1
  169. package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +11 -9
  170. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +4 -4
  171. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +86 -41
  172. package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +608 -152
  173. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +77 -32
  174. package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +305 -0
  175. package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +1 -1
  176. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +44 -0
  177. package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +37 -4
  178. package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +2 -2
  179. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +275 -46
  180. package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +1 -1
  181. package/.agents/scripts/lib/orchestration/spec-freshness.js +14 -205
  182. package/.agents/scripts/lib/orchestration/spec-section-validator.js +4 -5
  183. package/.agents/scripts/lib/orchestration/spec-spill.js +60 -0
  184. package/.agents/scripts/lib/orchestration/split-policy-validator.js +188 -0
  185. package/.agents/scripts/lib/orchestration/story-close/emit-blocked.js +49 -0
  186. package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +10 -10
  187. package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +28 -42
  188. package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +360 -0
  189. package/.agents/scripts/lib/orchestration/story-follow-ups.js +298 -0
  190. package/.agents/scripts/lib/orchestration/story-init-remote.js +51 -0
  191. package/.agents/scripts/lib/orchestration/story-plan-state.js +33 -0
  192. package/.agents/scripts/lib/orchestration/structured-comment-parser.js +1 -1
  193. package/.agents/scripts/lib/orchestration/task-body-validator.js +60 -25
  194. package/.agents/scripts/lib/orchestration/ticket-lease.js +27 -74
  195. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +130 -75
  196. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +192 -377
  197. package/.agents/scripts/lib/orchestration/ticket-validator.js +123 -25
  198. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +14 -72
  199. package/.agents/scripts/lib/orchestration/ticketing/reads.js +45 -55
  200. package/.agents/scripts/lib/orchestration/ticketing/transition.js +66 -6
  201. package/.agents/scripts/lib/orchestration/ticketing.js +0 -1
  202. package/.agents/scripts/lib/plan-phase-cleanup.js +12 -14
  203. package/.agents/scripts/lib/planning-corpus.js +12 -281
  204. package/.agents/scripts/lib/preflight-runner.js +4 -4
  205. package/.agents/scripts/lib/qa/coverage-verdict.js +5 -5
  206. package/.agents/scripts/lib/qa/qa-context-hydrator.js +5 -5
  207. package/.agents/scripts/lib/signals/index.js +4 -17
  208. package/.agents/scripts/lib/signals/read.js +35 -35
  209. package/.agents/scripts/lib/signals/schema.js +8 -11
  210. package/.agents/scripts/lib/signals/span-tree.js +7 -7
  211. package/.agents/scripts/lib/signals/write.js +0 -1
  212. package/.agents/scripts/lib/single-story/story-merged-notify.js +13 -2
  213. package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +1 -1
  214. package/.agents/scripts/lib/skills/parse-skill.js +16 -3
  215. package/.agents/scripts/lib/story-adjacency.js +17 -19
  216. package/.agents/scripts/lib/story-body/story-body.js +130 -75
  217. package/.agents/scripts/lib/story-plan.js +2 -4
  218. package/.agents/scripts/lib/templates/decomposer-prompts.js +51 -46
  219. package/.agents/scripts/lib/templates/spec-author-prompts.js +47 -45
  220. package/.agents/scripts/lib/test-env.js +14 -1
  221. package/.agents/scripts/lib/test-tiers.js +0 -3
  222. package/.agents/scripts/lib/{epic-body-sections.js → ticket-body-sections.js} +25 -39
  223. package/.agents/scripts/lib/validation-evidence.js +32 -60
  224. package/.agents/scripts/lib/wave-runner/ready-set.js +38 -12
  225. package/.agents/scripts/lib/workspace-provisioner.js +1 -1
  226. package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +1 -1
  227. package/.agents/scripts/lib/worktree/lifecycle/reap.js +72 -25
  228. package/.agents/scripts/lib/worktree/lifecycle-manager.js +1 -2
  229. package/.agents/scripts/lint-issue-body.js +71 -40
  230. package/.agents/scripts/mandrel-update-preflight.js +1 -1
  231. package/.agents/scripts/notify.js +4 -3
  232. package/.agents/scripts/plan-context.js +102 -80
  233. package/.agents/scripts/plan-persist.js +230 -279
  234. package/.agents/scripts/plan-run-epilogue.js +142 -0
  235. package/.agents/scripts/post-structured-comment.js +0 -38
  236. package/.agents/scripts/pr-watch-with-update.js +43 -22
  237. package/.agents/scripts/providers/github/compose.js +0 -1
  238. package/.agents/scripts/providers/github/errors.js +0 -19
  239. package/.agents/scripts/providers/github/issues.js +13 -39
  240. package/.agents/scripts/providers/github/mappers.js +5 -12
  241. package/.agents/scripts/providers/github/sub-issues.js +0 -47
  242. package/.agents/scripts/providers/github/tickets.js +33 -156
  243. package/.agents/scripts/providers/github.js +17 -6
  244. package/.agents/scripts/resolve-stories.js +236 -0
  245. package/.agents/scripts/run-coverage.js +4 -1
  246. package/.agents/scripts/run-lint.js +2 -2
  247. package/.agents/scripts/run-verify.js +31 -2
  248. package/.agents/scripts/signals-view.js +25 -21
  249. package/.agents/scripts/single-story-close.js +178 -26
  250. package/.agents/scripts/single-story-confirm-merge.js +313 -24
  251. package/.agents/scripts/single-story-init.js +35 -30
  252. package/.agents/scripts/stories-wave-tick.js +85 -10
  253. package/.agents/scripts/story-plan.js +28 -49
  254. package/.agents/scripts/update-ticket-state.js +14 -65
  255. package/.agents/skills/core/code-review-and-quality/SKILL.md +28 -450
  256. package/.agents/skills/core/code-review-and-quality/reference.md +458 -0
  257. package/.agents/skills/core/debugging-and-error-recovery/SKILL.md +22 -315
  258. package/.agents/skills/core/debugging-and-error-recovery/reference.md +323 -0
  259. package/.agents/skills/core/diagnose-friction/SKILL.md +14 -18
  260. package/.agents/skills/core/documentation-and-adrs/SKILL.md +25 -397
  261. package/.agents/skills/core/documentation-and-adrs/reference.md +403 -0
  262. package/.agents/skills/core/gates-and-baselines/SKILL.md +12 -12
  263. package/.agents/skills/core/idea-refinement/SKILL.md +9 -9
  264. package/.agents/skills/core/scope-triage/SKILL.md +31 -172
  265. package/.agents/skills/core/security-and-hardening/SKILL.md +22 -367
  266. package/.agents/skills/core/security-and-hardening/reference.md +375 -0
  267. package/.agents/skills/skills.index.json +3 -53
  268. package/.agents/skills/stack/qa/playwright-bdd/SKILL.md +2 -4
  269. package/.agents/skills/stack/qa/qa-explore-driving/SKILL.md +1 -1
  270. package/.agents/skills/stack/qa/qa-harness/SKILL.md +1 -3
  271. package/.agents/starter-agentrc.json +0 -5
  272. package/.agents/templates/agent-protocol.md +9 -10
  273. package/.agents/workflows/audit-architecture.md +6 -7
  274. package/.agents/workflows/audit-clean-code.md +7 -7
  275. package/.agents/workflows/audit-dependencies.md +3 -3
  276. package/.agents/workflows/audit-devops.md +3 -3
  277. package/.agents/workflows/audit-documentation.md +9 -10
  278. package/.agents/workflows/audit-lighthouse.md +11 -3
  279. package/.agents/workflows/audit-navigability.md +13 -2
  280. package/.agents/workflows/audit-performance.md +5 -6
  281. package/.agents/workflows/audit-privacy.md +3 -3
  282. package/.agents/workflows/audit-quality.md +11 -12
  283. package/.agents/workflows/audit-security.md +4 -5
  284. package/.agents/workflows/audit-seo.md +13 -3
  285. package/.agents/workflows/audit-sre.md +3 -3
  286. package/.agents/workflows/audit-to-stories.md +20 -20
  287. package/.agents/workflows/audit-ux-ui.md +10 -3
  288. package/.agents/workflows/deliver.md +177 -176
  289. package/.agents/workflows/git-cleanup.md +5 -6
  290. package/.agents/workflows/git-deliver.md +1 -1
  291. package/.agents/workflows/helpers/_merge-conflict-template.md +1 -1
  292. package/.agents/workflows/helpers/acceptance-self-eval.md +35 -40
  293. package/.agents/workflows/helpers/code-quality-guardrails.md +7 -7
  294. package/.agents/workflows/helpers/code-review.md +75 -196
  295. package/.agents/workflows/helpers/{single-story-deliver-reference.md → deliver-story-reference.md} +83 -44
  296. package/.agents/workflows/helpers/deliver-story.md +606 -0
  297. package/.agents/workflows/helpers/diagnose.md +10 -10
  298. package/.agents/workflows/helpers/parallel-tooling.md +3 -3
  299. package/.agents/workflows/helpers/signals.md +16 -16
  300. package/.agents/workflows/helpers/worktree-lifecycle.md +66 -86
  301. package/.agents/workflows/mandrel-update.md +2 -1
  302. package/.agents/workflows/plan.md +277 -145
  303. package/.agents/workflows/qa-assist.md +27 -33
  304. package/.agents/workflows/qa-explore.md +29 -38
  305. package/.agents/workflows/qa-run.md +2 -6
  306. package/README.md +9 -8
  307. package/bin/mandrel.js +12 -1
  308. package/docs/CHANGELOG.md +70 -0
  309. package/lib/cli/registry.js +262 -19
  310. package/lib/cli/sync-agents.js +157 -0
  311. package/lib/cli/sync-commands.js +115 -6
  312. package/lib/cli/sync.js +168 -6
  313. package/lib/cli/update.js +105 -8
  314. package/lib/cli/version-helpers.js +131 -0
  315. package/lib/migrations/README.md +7 -5
  316. package/lib/migrations/index.js +12 -8
  317. package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +100 -0
  318. package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +101 -0
  319. package/package.json +2 -2
  320. package/.agents/agents/retro.md +0 -42
  321. package/.agents/personas/architect.md +0 -113
  322. package/.agents/personas/devops-engineer.md +0 -38
  323. package/.agents/personas/engineer.md +0 -33
  324. package/.agents/personas/project-manager.md +0 -114
  325. package/.agents/personas/qa-engineer.md +0 -95
  326. package/.agents/personas/security-engineer.md +0 -111
  327. package/.agents/personas/technical-writer.md +0 -101
  328. package/.agents/schemas/dispatch-manifest.json +0 -232
  329. package/.agents/schemas/epic-perf-report.schema.json +0 -89
  330. package/.agents/schemas/epic-spec.schema.json +0 -153
  331. package/.agents/schemas/lifecycle/acceptance.reconcile.failed.schema.json +0 -13
  332. package/.agents/schemas/lifecycle/acceptance.reconcile.ok.schema.json +0 -13
  333. package/.agents/schemas/lifecycle/acceptance.reconcile.skipped.schema.json +0 -13
  334. package/.agents/schemas/lifecycle/acceptance.reconcile.start.schema.json +0 -12
  335. package/.agents/schemas/lifecycle/acceptance.reconcile.waived.schema.json +0 -13
  336. package/.agents/schemas/lifecycle/epic.automerge.end.schema.json +0 -15
  337. package/.agents/schemas/lifecycle/epic.automerge.start.schema.json +0 -13
  338. package/.agents/schemas/lifecycle/epic.blocked.schema.json +0 -13
  339. package/.agents/schemas/lifecycle/epic.cleanup.end.schema.json +0 -12
  340. package/.agents/schemas/lifecycle/epic.cleanup.start.schema.json +0 -12
  341. package/.agents/schemas/lifecycle/epic.close.end.schema.json +0 -12
  342. package/.agents/schemas/lifecycle/epic.complete.schema.json +0 -13
  343. package/.agents/schemas/lifecycle/epic.finalize.end.schema.json +0 -13
  344. package/.agents/schemas/lifecycle/epic.finalize.start.schema.json +0 -12
  345. package/.agents/schemas/lifecycle/epic.merge.armed.schema.json +0 -13
  346. package/.agents/schemas/lifecycle/epic.merge.blocked.schema.json +0 -14
  347. package/.agents/schemas/lifecycle/epic.merge.confirmed.schema.json +0 -17
  348. package/.agents/schemas/lifecycle/epic.merge.ready.schema.json +0 -15
  349. package/.agents/schemas/lifecycle/epic.plan.end.schema.json +0 -18
  350. package/.agents/schemas/lifecycle/epic.plan.start.schema.json +0 -12
  351. package/.agents/schemas/lifecycle/epic.snapshot.end.schema.json +0 -16
  352. package/.agents/schemas/lifecycle/epic.snapshot.start.schema.json +0 -12
  353. package/.agents/schemas/lifecycle/epic.watch.end.schema.json +0 -29
  354. package/.agents/schemas/lifecycle/epic.watch.start.schema.json +0 -16
  355. package/.agents/schemas/lifecycle/slice.end.schema.json +0 -21
  356. package/.agents/schemas/lifecycle/slice.heartbeat.schema.json +0 -20
  357. package/.agents/schemas/lifecycle/slice.start.schema.json +0 -17
  358. package/.agents/schemas/lifecycle/story.heartbeat.schema.json +0 -20
  359. package/.agents/schemas/risk-verdict.schema.json +0 -66
  360. package/.agents/schemas/story-perf-summary.schema.json +0 -73
  361. package/.agents/scripts/acceptance-spec-reconciler.js +0 -642
  362. package/.agents/scripts/analyze-execution.js +0 -444
  363. package/.agents/scripts/bookkeeping-reconcile.js +0 -117
  364. package/.agents/scripts/check-prepush-recovery.js +0 -90
  365. package/.agents/scripts/dispatcher.js +0 -295
  366. package/.agents/scripts/epic-audit-prepare.js +0 -497
  367. package/.agents/scripts/epic-audit-recheck.js +0 -274
  368. package/.agents/scripts/epic-deliver-note-intervention.js +0 -192
  369. package/.agents/scripts/epic-deliver-preflight.js +0 -462
  370. package/.agents/scripts/epic-deliver-prepare.js +0 -852
  371. package/.agents/scripts/epic-execute-record-wave.js +0 -449
  372. package/.agents/scripts/epic-plan-clarity.js +0 -211
  373. package/.agents/scripts/epic-plan-healthcheck.js +0 -581
  374. package/.agents/scripts/epic-reconcile.js +0 -625
  375. package/.agents/scripts/lib/baseline-snapshot.js +0 -979
  376. package/.agents/scripts/lib/checks/epic-merge-lock-stale.js +0 -54
  377. package/.agents/scripts/lib/checks/stale-origin-epic.js +0 -49
  378. package/.agents/scripts/lib/config/lifecycle.js +0 -40
  379. package/.agents/scripts/lib/config/preflight.js +0 -58
  380. package/.agents/scripts/lib/config/retro.js +0 -77
  381. package/.agents/scripts/lib/epic-merge-lock.js +0 -322
  382. package/.agents/scripts/lib/epic-plan-clarity.js +0 -181
  383. package/.agents/scripts/lib/epic-plan-ideation.js +0 -261
  384. package/.agents/scripts/lib/git-merge-orchestrator.js +0 -261
  385. package/.agents/scripts/lib/observability/baseline-refresh-rate.js +0 -221
  386. package/.agents/scripts/lib/observability/hook-heartbeat.js +0 -219
  387. package/.agents/scripts/lib/observability/perf-aggregator.js +0 -813
  388. package/.agents/scripts/lib/observability/perf-report-readers.js +0 -328
  389. package/.agents/scripts/lib/observability/perf-report-render.js +0 -182
  390. package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +0 -270
  391. package/.agents/scripts/lib/orchestration/context-hydration-engine.js +0 -539
  392. package/.agents/scripts/lib/orchestration/deliver-route.js +0 -173
  393. package/.agents/scripts/lib/orchestration/dispatch-engine.js +0 -134
  394. package/.agents/scripts/lib/orchestration/dispatch-pipeline.js +0 -183
  395. package/.agents/scripts/lib/orchestration/epic-cleanup.js +0 -801
  396. package/.agents/scripts/lib/orchestration/epic-deliver-lease-guard.js +0 -310
  397. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/context.js +0 -163
  398. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/creation.js +0 -140
  399. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/dag.js +0 -64
  400. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/diagnostics.js +0 -72
  401. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +0 -156
  402. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist.js +0 -345
  403. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +0 -41
  404. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/reconcile-spawn.js +0 -86
  405. package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +0 -391
  406. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/drain.js +0 -94
  407. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +0 -236
  408. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/risk-verdict.js +0 -105
  409. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +0 -307
  410. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-freshness.js +0 -117
  411. package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +0 -117
  412. package/.agents/scripts/lib/orchestration/epic-run-state-store.js +0 -621
  413. package/.agents/scripts/lib/orchestration/epic-runner/concurrency-gate.js +0 -186
  414. package/.agents/scripts/lib/orchestration/epic-runner/deliver-phases.js +0 -50
  415. package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +0 -129
  416. package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +0 -103
  417. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/composition.js +0 -267
  418. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/signals.js +0 -210
  419. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/transport.js +0 -238
  420. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/_bullet-format.js +0 -32
  421. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/component-drift.js +0 -203
  422. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/crap-drift.js +0 -227
  423. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/maintainability-drift.js +0 -117
  424. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/stalled-worktree.js +0 -37
  425. package/.agents/scripts/lib/orchestration/epic-runner/story-launcher.js +0 -127
  426. package/.agents/scripts/lib/orchestration/epic-runner/story-run-progress-writer.js +0 -400
  427. package/.agents/scripts/lib/orchestration/epic-runner/sub-agent-return.js +0 -276
  428. package/.agents/scripts/lib/orchestration/epic-runner/wave-scheduler.js +0 -66
  429. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-apply.js +0 -789
  430. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +0 -676
  431. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-discriminator.js +0 -389
  432. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-format.js +0 -230
  433. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-ops.js +0 -361
  434. package/.agents/scripts/lib/orchestration/error-journal.js +0 -139
  435. package/.agents/scripts/lib/orchestration/finalize/open-or-locate-pr.js +0 -306
  436. package/.agents/scripts/lib/orchestration/finalize/post-handoff-comment.js +0 -489
  437. package/.agents/scripts/lib/orchestration/finalize/sanitize-skip-ci.js +0 -88
  438. package/.agents/scripts/lib/orchestration/lifecycle/emit-slice-lifecycle.js +0 -270
  439. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-dispatch-end.js +0 -147
  440. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +0 -155
  441. package/.agents/scripts/lib/orchestration/lifecycle/ledger-diff.js +0 -140
  442. package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +0 -465
  443. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +0 -501
  444. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +0 -984
  445. package/.agents/scripts/lib/orchestration/lifecycle/listeners/branch-cleaner.js +0 -264
  446. package/.agents/scripts/lib/orchestration/lifecycle/listeners/checkpoint-pointer-writer.js +0 -284
  447. package/.agents/scripts/lib/orchestration/lifecycle/listeners/cleaner.js +0 -355
  448. package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +0 -673
  449. package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +0 -378
  450. package/.agents/scripts/lib/orchestration/lifecycle/listeners/intervention-recorder.js +0 -140
  451. package/.agents/scripts/lib/orchestration/lifecycle/listeners/label-transitioner.js +0 -144
  452. package/.agents/scripts/lib/orchestration/lifecycle/listeners/merge-watcher.js +0 -665
  453. package/.agents/scripts/lib/orchestration/lifecycle/listeners/notify-dispatcher.js +0 -174
  454. package/.agents/scripts/lib/orchestration/manifest-builder.js +0 -222
  455. package/.agents/scripts/lib/orchestration/plan-persist/amend.js +0 -359
  456. package/.agents/scripts/lib/orchestration/plan-persist/delivery-mode.js +0 -127
  457. package/.agents/scripts/lib/orchestration/plan-review-routing.js +0 -63
  458. package/.agents/scripts/lib/orchestration/planning-context-budget.js +0 -213
  459. package/.agents/scripts/lib/orchestration/planning-risk.js +0 -194
  460. package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +0 -56
  461. package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +0 -33
  462. package/.agents/scripts/lib/orchestration/post-merge/phases/notification.js +0 -78
  463. package/.agents/scripts/lib/orchestration/post-merge/phases/temp-cleanup.js +0 -68
  464. package/.agents/scripts/lib/orchestration/post-merge/phases/ticket-closure.js +0 -118
  465. package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +0 -396
  466. package/.agents/scripts/lib/orchestration/post-merge-pipeline.js +0 -205
  467. package/.agents/scripts/lib/orchestration/preflight-cache.js +0 -187
  468. package/.agents/scripts/lib/orchestration/recurring-failure-detector.js +0 -152
  469. package/.agents/scripts/lib/orchestration/retro/phases/checks.js +0 -94
  470. package/.agents/scripts/lib/orchestration/retro/phases/compose-body.js +0 -571
  471. package/.agents/scripts/lib/orchestration/retro/phases/gather-signals.js +0 -450
  472. package/.agents/scripts/lib/orchestration/retro/phases/post-and-mirror.js +0 -191
  473. package/.agents/scripts/lib/orchestration/retro-heuristics.js +0 -57
  474. package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +0 -275
  475. package/.agents/scripts/lib/orchestration/retro-runner.js +0 -197
  476. package/.agents/scripts/lib/orchestration/spec-renderer.js +0 -447
  477. package/.agents/scripts/lib/orchestration/story-close/auto-refresh-runner.js +0 -747
  478. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/gate-failure.js +0 -211
  479. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/pre-merge-attribution.js +0 -158
  480. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +0 -446
  481. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/regression-projection.js +0 -297
  482. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/scope-discovery.js +0 -48
  483. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution-wiring.js +0 -67
  484. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution.js +0 -161
  485. package/.agents/scripts/lib/orchestration/story-close/baseline-friction-body.js +0 -117
  486. package/.agents/scripts/lib/orchestration/story-close/cd-out-guard.js +0 -86
  487. package/.agents/scripts/lib/orchestration/story-close/cleanup-reconciler.js +0 -147
  488. package/.agents/scripts/lib/orchestration/story-close/close-inputs.js +0 -142
  489. package/.agents/scripts/lib/orchestration/story-close/comment-bodies.js +0 -62
  490. package/.agents/scripts/lib/orchestration/story-close/merge-runner.js +0 -658
  491. package/.agents/scripts/lib/orchestration/story-close/merge-subject.js +0 -198
  492. package/.agents/scripts/lib/orchestration/story-close/phases/branch-restore.js +0 -105
  493. package/.agents/scripts/lib/orchestration/story-close/phases/close.js +0 -222
  494. package/.agents/scripts/lib/orchestration/story-close/phases/gates.js +0 -292
  495. package/.agents/scripts/lib/orchestration/story-close/phases/locked-pipeline.js +0 -270
  496. package/.agents/scripts/lib/orchestration/story-close/phases/preflight.js +0 -110
  497. package/.agents/scripts/lib/orchestration/story-close/phases/refresh.js +0 -86
  498. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked-emitter.js +0 -112
  499. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked.js +0 -157
  500. package/.agents/scripts/lib/orchestration/story-close/post-merge-close.js +0 -421
  501. package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +0 -302
  502. package/.agents/scripts/lib/orchestration/story-close/shared-checkout-guard.js +0 -163
  503. package/.agents/scripts/lib/orchestration/story-close-recovery.js +0 -690
  504. package/.agents/scripts/lib/orchestration/wave-marker.js +0 -28
  505. package/.agents/scripts/lib/orchestration/wave-record-io.js +0 -218
  506. package/.agents/scripts/lib/orchestration/wave-record-notifications.js +0 -145
  507. package/.agents/scripts/lib/orchestration/wave-record-projection.js +0 -212
  508. package/.agents/scripts/lib/presentation/dispatch-manifest-render.js +0 -111
  509. package/.agents/scripts/lib/presentation/manifest-builder.js +0 -239
  510. package/.agents/scripts/lib/presentation/manifest-formatter.js +0 -242
  511. package/.agents/scripts/lib/presentation/manifest-helpers.js +0 -213
  512. package/.agents/scripts/lib/presentation/manifest-persistence.js +0 -261
  513. package/.agents/scripts/lib/presentation/manifest-procedures.js +0 -55
  514. package/.agents/scripts/lib/presentation/manifest-render-waves.js +0 -306
  515. package/.agents/scripts/lib/presentation/manifest-renderer.js +0 -188
  516. package/.agents/scripts/lib/presentation/manifest-story-views.js +0 -110
  517. package/.agents/scripts/lib/push-epic-retry.js +0 -209
  518. package/.agents/scripts/lib/spec/index.js +0 -36
  519. package/.agents/scripts/lib/spec/loader.js +0 -425
  520. package/.agents/scripts/lib/spec/state.js +0 -208
  521. package/.agents/scripts/lib/story-init/blocker-validator.js +0 -68
  522. package/.agents/scripts/lib/story-init/branch-initializer.js +0 -408
  523. package/.agents/scripts/lib/story-init/context-resolver.js +0 -92
  524. package/.agents/scripts/lib/story-init/donor-precheck.js +0 -207
  525. package/.agents/scripts/lib/story-init/state-transitioner.js +0 -80
  526. package/.agents/scripts/lib/story-init/task-graph-builder.js +0 -124
  527. package/.agents/scripts/lib/story-init/transition-summary.js +0 -34
  528. package/.agents/scripts/lib/test-reserved-epic-temp-ids.js +0 -35
  529. package/.agents/scripts/lib/wave-runner/tick.js +0 -754
  530. package/.agents/scripts/lib/wave-runner/wave-runner-error.js +0 -20
  531. package/.agents/scripts/lifecycle-emit-story-dispatch.js +0 -194
  532. package/.agents/scripts/lifecycle-emit.js +0 -510
  533. package/.agents/scripts/retro-run.js +0 -218
  534. package/.agents/scripts/slice-phase.js +0 -361
  535. package/.agents/scripts/standalone-feedback-rollup.js +0 -188
  536. package/.agents/scripts/story-close.js +0 -294
  537. package/.agents/scripts/story-init.js +0 -599
  538. package/.agents/scripts/story-phase.js +0 -369
  539. package/.agents/scripts/wave-tick.js +0 -464
  540. package/.agents/skills/core/analyze-execution/SKILL.md +0 -98
  541. package/.agents/skills/core/epic-plan-consolidate/SKILL.md +0 -172
  542. package/.agents/skills/core/epic-plan-consolidate/examples.md +0 -51
  543. package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +0 -441
  544. package/.agents/skills/core/epic-plan-decompose-author/examples.md +0 -47
  545. package/.agents/skills/core/epic-plan-premortem/SKILL.md +0 -146
  546. package/.agents/skills/core/epic-plan-premortem/examples.md +0 -53
  547. package/.agents/skills/core/epic-plan-spec-author/SKILL.md +0 -383
  548. package/.agents/skills/core/epic-plan-spec-author/examples.md +0 -91
  549. package/.agents/workflows/helpers/deliver-epic-reference.md +0 -547
  550. package/.agents/workflows/helpers/deliver-epic-single.md +0 -331
  551. package/.agents/workflows/helpers/deliver-epic.md +0 -998
  552. package/.agents/workflows/helpers/deliver-stories.md +0 -450
  553. package/.agents/workflows/helpers/epic-audit.md +0 -189
  554. package/.agents/workflows/helpers/epic-deliver-story.md +0 -436
  555. package/.agents/workflows/helpers/epic-testing.md +0 -125
  556. package/.agents/workflows/helpers/plan-epic-reference.md +0 -160
  557. package/.agents/workflows/helpers/plan-epic.md +0 -353
  558. package/.agents/workflows/helpers/plan-story.md +0 -251
  559. package/.agents/workflows/helpers/scope-triage-gate.md +0 -108
  560. package/.agents/workflows/helpers/single-story-deliver.md +0 -557
@@ -1,173 +0,0 @@
1
- /**
2
- * lib/orchestration/deliver-route.js — the deliver-side reader for the
3
- * plan-time single-delivery seam (Epic #4475, M4-A).
4
- *
5
- * The plan path already ships the seam inert (Epic #4474): the risk verdict's
6
- * `deliveryShape`, the `delivery::single` label, and the
7
- * `epic-plan-state.decompose = { ticketCount: 0, shape: "single" }`
8
- * checkpoint. Nothing on the deliver side read them — until this module. It
9
- * folds those two markers (plus the global kill-switch) into a single
10
- * delivery-route verdict for `/deliver`.
11
- *
12
- * Pure and total — inputs in, verdict out. No GitHub calls, no I/O, no
13
- * throws. It mirrors how `review-depth.js#resolveDepth` and
14
- * `epic-audit-prepare.js` read `planningRisk` / `decompose` off the
15
- * `epic-plan-state` checkpoint: the caller fetches the Epic labels + the
16
- * checkpoint, then hands both here.
17
- *
18
- * ── Routing precedence (highest wins) ──────────────────────────────────
19
- * 1. Kill-switch. `delivery.routing.singleDelivery === false` forces
20
- * `fan-out` for EVERY Epic, even a single-labelled one — the instant
21
- * global revert (`lib/config/delivery-routing.js`). Overrides all.
22
- * 2. Single marker. The `delivery::single` label (primary) OR
23
- * `checkpoint.decompose.shape === "single"` (secondary) → `single`.
24
- * 3. Wide-DAG advisory. A fan-out-shaped Epic whose ready-width > 1 is
25
- * genuine parallelism → `fan-out`. Deliver-time width only ADVISES —
26
- * it never reroutes a single-marked Epic (that would orphan a Story
27
- * tree that does not exist; re-route = re-plan).
28
- * 4. Legacy / no marker → `fan-out` (safe backward-compat: a legacy Epic
29
- * has an authored Story tree the fan-out engine consumes).
30
- *
31
- * BEHAVIOR-PRESERVING in M4-A: the router consumes a `single` verdict via a
32
- * stub that continues at `deliver-epic.md` (fan-out), so no `/deliver`
33
- * observably changes until M4-B lands `deliver-epic-single.md`.
34
- *
35
- * @typedef {'single'|'fan-out'} DeliveryRoute
36
- */
37
-
38
- import { getDeliveryRouting } from '../config/delivery-routing.js';
39
-
40
- /** The canonical single-delivery routing marker label. */
41
- export const DELIVERY_SINGLE_LABEL = 'delivery::single';
42
-
43
- /**
44
- * True when the Epic carries the `delivery::single` routing label. Tolerant
45
- * of the two label shapes callers hold: an array of label-name strings, or an
46
- * array of `{ name }` objects (the GitHub REST label shape).
47
- *
48
- * @param {{ labels?: Array<string | { name?: string }> } | null | undefined} epic
49
- * @returns {boolean}
50
- */
51
- function hasSingleLabel(epic) {
52
- const labels = Array.isArray(epic?.labels) ? epic.labels : [];
53
- return labels.some((l) => {
54
- const name = typeof l === 'string' ? l : l?.name;
55
- return name === DELIVERY_SINGLE_LABEL;
56
- });
57
- }
58
-
59
- /**
60
- * True when the plan-state checkpoint's `decompose.shape` is the deliberate
61
- * single shape. `plan-persist.js` writes `decompose = { ticketCount: 0,
62
- * shape: "single" }` for a spec-only plan; every other value (including a
63
- * legacy checkpoint with no `shape` field) is not-single.
64
- *
65
- * @param {{ decompose?: { shape?: string } } | null | undefined} checkpoint
66
- * @returns {boolean}
67
- */
68
- function hasSingleDecomposeShape(checkpoint) {
69
- return checkpoint?.decompose?.shape === 'single';
70
- }
71
-
72
- /**
73
- * Resolve the delivery route for one Epic from its labels, its plan-state
74
- * checkpoint, and the resolved config. See the module header for the full
75
- * precedence. Pure — never throws; malformed / absent inputs degrade to the
76
- * safe `fan-out` default.
77
- *
78
- * @param {{ labels?: Array<string | { name?: string }> } | null | undefined} epic
79
- * The Epic ticket snapshot (only `labels` is read here).
80
- * @param {{ decompose?: { shape?: string } } | null | undefined} checkpoint
81
- * The `epic-plan-state` structured comment, parsed (or `null` on a legacy
82
- * Epic that predates the checkpoint — treated as no marker).
83
- * @param {object | null | undefined} config
84
- * The resolved config; `delivery.routing.singleDelivery` is the kill-switch.
85
- * @returns {{ route: DeliveryRoute, reason: string, singleDeliveryEnabled: boolean }}
86
- */
87
- export function resolveEpicDeliveryRoute(epic, checkpoint, config) {
88
- const { singleDelivery } = getDeliveryRouting(config);
89
-
90
- // 1. Kill-switch — overrides all. A `false` value forces fan-out even for
91
- // an Epic the planner marked single (the instant global revert).
92
- if (singleDelivery === false) {
93
- return {
94
- route: 'fan-out',
95
- reason:
96
- 'kill-switch: delivery.routing.singleDelivery=false forces fan-out for every Epic',
97
- singleDeliveryEnabled: false,
98
- };
99
- }
100
-
101
- // 2. Single marker — label (primary) OR checkpoint decompose shape
102
- // (secondary). Either alone routes single.
103
- const labelled = hasSingleLabel(epic);
104
- const shaped = hasSingleDecomposeShape(checkpoint);
105
- if (labelled || shaped) {
106
- const via =
107
- labelled && shaped
108
- ? `${DELIVERY_SINGLE_LABEL} label + decompose.shape="single"`
109
- : labelled
110
- ? `${DELIVERY_SINGLE_LABEL} label`
111
- : 'decompose.shape="single"';
112
- return {
113
- route: 'single',
114
- reason: `single marker present (${via})`,
115
- singleDeliveryEnabled: true,
116
- };
117
- }
118
-
119
- // 3/4. No single marker → fan-out (a wide DAG or a legacy Story tree; the
120
- // deliver-time width only advises and never reroutes here).
121
- return {
122
- route: 'fan-out',
123
- reason: 'no single marker — fan-out (legacy Story tree or wide DAG)',
124
- singleDeliveryEnabled: true,
125
- };
126
- }
127
-
128
- /**
129
- * Compute the ready-width of a delivery plan — the count of work units that
130
- * could dispatch on the first beat. It is the mechanical parallelism signal
131
- * the planner uses at plan time to mark a genuinely-wide Epic `fan-out`, and
132
- * that `/deliver` may surface as an advisory at deliver time (it never
133
- * reroutes — see the module header).
134
- *
135
- * Accepts either input shape the framework already produces:
136
- * - Delivery-Slicing rows — `[{ independent: boolean }, …]` from
137
- * `parseDeliverySlicingTable`. A serial chain (every row
138
- * `Independent: No`, or a lone independent slice) has width 1; two or
139
- * more independent slices yield a width equal to that independent count
140
- * (> 1) — genuine parallelism.
141
- * - A wave DAG — `[[…], […], …]` (the array-of-waves `state.waves` shape
142
- * `runBuildWaveDagPhase` produces). The width is the largest wave — the
143
- * most Stories ready to dispatch on a single beat.
144
- *
145
- * Pure and total: an empty / malformed / unrecognized input degrades to
146
- * width 1 (the safe "not wide" signal). Never throws.
147
- *
148
- * @param {Array<{ independent?: boolean }> | Array<Array<unknown>> | null | undefined} deliverySlicingRowsOrDag
149
- * @returns {number} an integer ≥ 1.
150
- */
151
- export function computeReadyWidth(deliverySlicingRowsOrDag) {
152
- const input = deliverySlicingRowsOrDag;
153
- if (!Array.isArray(input) || input.length === 0) return 1;
154
-
155
- // Wave-DAG shape: an array whose entries are themselves arrays.
156
- if (input.every((entry) => Array.isArray(entry))) {
157
- let widest = 1;
158
- for (const wave of input) {
159
- if (wave.length > widest) widest = wave.length;
160
- }
161
- return widest;
162
- }
163
-
164
- // Delivery-Slicing rows: entries are `{ independent }` records.
165
- const independentCount = input.reduce(
166
- (acc, row) =>
167
- row && typeof row === 'object' && row.independent === true
168
- ? acc + 1
169
- : acc,
170
- 0,
171
- );
172
- return independentCount >= 2 ? independentCount : 1;
173
- }
@@ -1,134 +0,0 @@
1
- /**
2
- * lib/orchestration/dispatch-engine.js — Core Dispatch Engine (SDK coordinator)
3
- *
4
- * Thin facade composing:
5
- * - `dispatch-pipeline.js` — internal resolve/fetch/reconcile/graph helpers
6
- *
7
- * Every Epic is 2-tier (Epic → Story); `dispatch()` computes a
8
- * Story-level wave plan and emits a 2-tier manifest. The legacy Task-tier
9
- * dispatch runtime (Task fetcher, single-Story executor, the per-Task
10
- * wave fan-out, and the Epic-completion detector) was removed in Epic
11
- * #3163.
12
- */
13
-
14
- import { PROJECT_ROOT, resolveConfig } from '../config-resolver.js';
15
- import { ConflictingTypeLabelsError } from '../errors/index.js';
16
- import { ensureLocalBranch } from '../git-branch-lifecycle.js';
17
- import { Logger } from '../Logger.js';
18
- import { TYPE_LABELS } from '../label-constants.js';
19
- import { createProvider } from '../provider-factory.js';
20
- import {
21
- buildStoryDispatchGraph,
22
- fetchEpicContext,
23
- isTwoTierDispatch,
24
- resolveDispatchContext,
25
- } from './dispatch-pipeline.js';
26
- import { buildManifest } from './manifest-builder.js';
27
- import { STATE_LABELS } from './ticketing.js';
28
-
29
- export const AGENT_DONE_LABEL = STATE_LABELS.DONE;
30
-
31
- /* node:coverage ignore next */
32
- export function ensureBranch(branchName, baseBranch) {
33
- ensureLocalBranch(branchName, baseBranch, PROJECT_ROOT, {
34
- log: (msg) => Logger.info(msg),
35
- });
36
- }
37
-
38
- /**
39
- * Resolve a single ticket ID, detect its type, and delegate to the
40
- * appropriate execution pipeline. Single entry point shared by the CLI
41
- * wrapper and the MCP `dispatch_wave` tool.
42
- */
43
- export async function resolveAndDispatch(options) {
44
- const { ticketId, dryRun = false } = options;
45
- const config = resolveConfig();
46
- const provider = options.provider ?? createProvider(config);
47
-
48
- const ticket = await provider.getTicket(ticketId);
49
- const labels = ticket.labels || [];
50
-
51
- const typeLabels = labels.filter((l) => l.startsWith('type::'));
52
- if (typeLabels.length > 1) {
53
- throw new ConflictingTypeLabelsError(
54
- `Ticket #${ticketId} has conflicting type labels: ${typeLabels.join(', ')}. Exactly one type::* label is required.`,
55
- );
56
- }
57
-
58
- const isStory = labels.includes(TYPE_LABELS.STORY);
59
- const isEpic = labels.includes(TYPE_LABELS.EPIC);
60
-
61
- if (isStory) {
62
- throw new Error(
63
- `[Dispatcher] Ticket #${ticketId} is a **Story**. Stories are dispatched ` +
64
- 'through the Story delivery path, not directly via the dispatcher. ' +
65
- `Run \`/deliver ${ticketId}\` to execute this Story, ` +
66
- `or dispatch its parent Epic with \`/deliver #<epicId>\`.`,
67
- );
68
- }
69
-
70
- if (isEpic) {
71
- return dispatch({ epicId: ticketId, dryRun, provider });
72
- }
73
-
74
- const typeLabel = labels.find((l) => l.startsWith('type::')) || 'unknown';
75
- throw new Error(
76
- `[Dispatcher] Ticket #${ticketId} has type "${typeLabel.replace('type::', '')}". ` +
77
- `Only "epic" or "story" tickets can be dispatched. ` +
78
- `Please ensure the ticket is correctly categorized before execution.`,
79
- );
80
- }
81
-
82
- /**
83
- * Main dispatcher. Orchestrates one dispatch cycle for an Epic.
84
- * Primary public export of the orchestration SDK.
85
- */
86
- export async function dispatch(options) {
87
- const ctx = resolveDispatchContext(options, ensureBranch);
88
- const { epicId, dryRun } = ctx;
89
-
90
- const fetched = await fetchEpicContext(ctx);
91
-
92
- // Every Epic is 2-tier (Epic → Story). Compute Story-level
93
- // waves directly from the Story tickets and emit a 2-tier-shaped
94
- // manifest with `waves[].stories[]` so downstream consumers (manifest
95
- // renderer, /deliver wave planner) see the correct execution plan.
96
- // Per-Story execution is owned by `/deliver` (story-init →
97
- // story-close), not by this dispatcher.
98
- if (isTwoTierDispatch(fetched.allTickets)) {
99
- Logger.info(
100
- 'Detected 2-tier hierarchy — computing Story-level execution waves.',
101
- );
102
- const { allWaves: storyWaves } = buildStoryDispatchGraph(
103
- fetched.allTickets,
104
- );
105
- return buildManifest({
106
- epicId,
107
- epic: fetched.epic,
108
- tasks: [],
109
- allTickets: fetched.allTickets,
110
- waves: storyWaves,
111
- dispatched: [],
112
- dryRun,
113
- hierarchy: '2-tier',
114
- });
115
- }
116
-
117
- // No Story tickets under the Epic — throw loudly rather than emit an
118
- // empty manifest, matching the wave-loop's behavior (build-wave-dag.js
119
- // throws the same message shape on this input). A silently-empty
120
- // manifest masks a pre-cutover Epic whose children are legacy Features.
121
- const typedChildren = (fetched.allTickets ?? [])
122
- .map((t) => (t.labels ?? []).find((l) => l.startsWith('type::')))
123
- .filter(Boolean);
124
- const legacyHint =
125
- typedChildren.length > 0
126
- ? ` Found ${typedChildren.length} non-Story child ticket(s) ` +
127
- `(${[...new Set(typedChildren)].join(', ')}) — this Epic looks ` +
128
- `pre-cutover (legacy Feature children) and needs migration to the ` +
129
- `2-tier (Epic → Story) hierarchy before dispatch.`
130
- : '';
131
- throw new Error(
132
- `Epic #${epicId} has no child stories to dispatch.${legacyHint}`,
133
- );
134
- }
@@ -1,183 +0,0 @@
1
- /**
2
- * dispatch-pipeline.js
3
- *
4
- * Internal pipeline helpers composed by `dispatch-engine.js::dispatch()`.
5
- * Keeping these out of the coordinator keeps the public entry point compact
6
- * and focused on the 2-tier flow: resolve → fetch → Story-graph.
7
- */
8
-
9
- import { PROJECT_ROOT, resolveConfig } from '../config-resolver.js';
10
- import { getEpicBranch } from '../git-utils.js';
11
- import { Logger } from '../Logger.js';
12
- import { TYPE_LABELS } from '../label-constants.js';
13
- import { createProvider } from '../provider-factory.js';
14
- import { buildStoryAdjacency } from '../story-adjacency.js';
15
- import { WorktreeManager } from '../worktree-manager.js';
16
- import { computeStoryWaves } from './dependency-analyzer.js';
17
-
18
- /**
19
- * Runtime context for a single dispatch cycle.
20
- *
21
- * Produced by {@link resolveDispatchContext} and consumed by every pipeline
22
- * stage (fetch → graph → scaffold → GC → dispatch). All fields
23
- * are resolved once up-front so downstream helpers can stay free of
24
- * configuration look-ups.
25
- *
26
- * @typedef {object} DispatchContext
27
- * @property {number} epicId Epic ticket number under dispatch.
28
- * @property {boolean} dryRun When true, mutating side-effects are skipped.
29
- * @property {object} config Resolved canonical `.agentrc.json` (with `project`, `github`, `planning`, `delivery` blocks).
30
- * @property {import('../ITicketingProvider.js').ITicketingProvider} provider Ticketing provider (may come from cache).
31
- * @property {import('../worktree-manager.js').WorktreeManager | undefined} worktreeManager Optional worktree manager (only when isolation is enabled and not dry-run).
32
- * @property {string} baseBranch Trunk branch the Epic branches from (default `main`).
33
- * @property {string} epicBranch Epic branch name (`epic/<epicId>`).
34
- * @property {(branchName: string, baseBranch: string) => void} ensureBranch Caller-supplied branch-creation helper.
35
- */
36
-
37
- /**
38
- * The output of {@link fetchEpicContext}.
39
- *
40
- * @typedef {object} FetchedEpic
41
- * @property {object} epic The Epic ticket record.
42
- * @property {object[]} allTickets Every ticket under the Epic (stories + health).
43
- * @property {Map<number, object>} allTicketsById Index of `allTickets` by ticket id.
44
- */
45
-
46
- /**
47
- * Resolve the runtime context for a dispatch: canonical config, provider, adapter,
48
- * worktree manager, base/epic branch names, and the `ensureBranch` bound
49
- * helper supplied by the caller.
50
- *
51
- * @param {object} options Dispatch entry options.
52
- * @param {number} options.epicId Epic ticket number.
53
- * @param {boolean} [options.dryRun=false] When true, skip branch creation and worktree setup.
54
- * @param {import('../ITicketingProvider.js').ITicketingProvider} [options.provider] Pre-constructed provider (overrides factory).
55
- * @param {import('../worktree-manager.js').WorktreeManager} [options.worktreeManager] Pre-constructed worktree manager.
56
- * @param {(branchName: string, baseBranch: string) => void} ensureBranch Branch-creation helper bound by caller (keeps engine ↔ git-lifecycle coupling at the edge).
57
- * @returns {DispatchContext} Fully resolved dispatch context.
58
- */
59
- export function resolveDispatchContext(options, ensureBranch) {
60
- const { epicId, dryRun = false } = options;
61
-
62
- const config = resolveConfig();
63
- const provider = options.provider ?? createProvider(config);
64
-
65
- const wtConfig = config?.delivery?.worktreeIsolation;
66
- let worktreeManager = options.worktreeManager;
67
- if (!worktreeManager && wtConfig?.enabled && !dryRun) {
68
- worktreeManager = new WorktreeManager({
69
- repoRoot: PROJECT_ROOT,
70
- config: wtConfig,
71
- });
72
- }
73
-
74
- return {
75
- epicId,
76
- dryRun,
77
- config,
78
- provider,
79
- worktreeManager,
80
- baseBranch: config?.project?.baseBranch ?? 'main',
81
- epicBranch: getEpicBranch(epicId),
82
- ensureBranch,
83
- };
84
- }
85
-
86
- /**
87
- * Fetch Epic + all tickets and prime the provider cache.
88
- *
89
- * @param {DispatchContext} ctx Dispatch context.
90
- * @returns {Promise<FetchedEpic>} Epic + ticket graph.
91
- */
92
- export async function fetchEpicContext(ctx) {
93
- const { provider, epicId } = ctx;
94
-
95
- Logger.info(`\nFetching Epic #${epicId}...`);
96
- const epic = await provider.getEpic(epicId);
97
-
98
- Logger.info(`Fetching all tickets under Epic #${epicId}...`);
99
- const allTickets = await provider.getTickets(epicId);
100
- const allTicketsById = new Map(allTickets.map((t) => [t.id, t]));
101
-
102
- provider.primeTicketCache(allTickets);
103
-
104
- return { epic, allTickets, allTicketsById };
105
- }
106
-
107
- /**
108
- * Detect 2-tier hierarchy from the fetched ticket graph. After Epic #3163's
109
- * hard cutover deleted the `type::task` ticket layer, shape selection is
110
- * purely structural: any Epic carrying at least one `type::story` ticket
111
- * resolves to 2-tier.
112
- *
113
- * @param {object[]} allTickets
114
- * @returns {boolean}
115
- */
116
- export function isTwoTierDispatch(allTickets) {
117
- if (!Array.isArray(allTickets) || allTickets.length === 0) return false;
118
- return allTickets.some((t) =>
119
- (t.labelSet ?? new Set(t.labels ?? [])).has(TYPE_LABELS.STORY),
120
- );
121
- }
122
-
123
- /**
124
- * Build the Story-level dispatch graph for a 2-tier Epic. Reads story
125
- * tickets from `allTickets`, parses cross-Story `blocked by` references
126
- * from each Story body (also honoring an optional `dependencies[]`
127
- * field set by fixture providers), and computes wave indices via
128
- * {@link computeStoryWaves}.
129
- *
130
- * The returned `allWaves` is an array of Story-ticket arrays, ordered by
131
- * wave index. `storyMap` indexes the same Story tickets by id for downstream
132
- * lookups (mirrors the `taskMap` returned by {@link buildDispatchGraph}).
133
- *
134
- * Stories with no resolvable wave (cycle pre-filter, missing in groups)
135
- * are placed in their own trailing wave so they remain visible in the
136
- * manifest output.
137
- *
138
- * @param {object[]} allTickets Fetched ticket graph (Epic + Stories).
139
- * @returns {{ allWaves: object[][], storyMap: Map<number, object> }}
140
- * @throws {Error} When the Story dependency graph contains a cycle.
141
- */
142
- export function buildStoryDispatchGraph(allTickets) {
143
- const stories = (allTickets ?? []).filter((t) =>
144
- (t.labelSet ?? new Set(t.labels ?? [])).has(TYPE_LABELS.STORY),
145
- );
146
- const storyMap = new Map(stories.map((s) => [s.id, s]));
147
-
148
- // Shared story-level adjacency builder (lib/story-adjacency.js) owns the
149
- // dependency-source ordering contract: body `blocked by` references via
150
- // `parseBlockedBy`, then explicit `dependencies[]`, foreign edges dropped.
151
- const explicitDeps = buildStoryAdjacency(stories);
152
-
153
- // computeStoryWaves expects a Map<storyId, { tasks: [] }>; with no Tasks
154
- // present, only explicitDeps + focus-area rollup (no-op for empty
155
- // task lists) drive wave assignment.
156
- const storyGroups = new Map(
157
- stories.map((s) => [s.id, { storyId: s.id, tasks: [] }]),
158
- );
159
- const waveAssignment = computeStoryWaves(storyGroups, explicitDeps);
160
-
161
- // Bucket stories by wave index. `computeStoryWaves` returns -1 for any
162
- // story it could not place; route those into a trailing bucket so they
163
- // still surface in the manifest.
164
- const byWave = new Map();
165
- let maxWave = -1;
166
- for (const story of stories) {
167
- const wave = waveAssignment.get(story.id) ?? -1;
168
- if (wave > maxWave) maxWave = wave;
169
- if (!byWave.has(wave)) byWave.set(wave, []);
170
- byWave.get(wave).push(story);
171
- }
172
-
173
- const allWaves = [];
174
- for (let i = 0; i <= maxWave; i++) {
175
- if (byWave.has(i)) allWaves.push(byWave.get(i));
176
- }
177
- if (byWave.has(-1)) allWaves.push(byWave.get(-1));
178
-
179
- Logger.info(
180
- `Computed ${allWaves.length} Story-level execution wave(s) (2-tier).`,
181
- );
182
- return { allWaves, storyMap };
183
- }