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,590 +0,0 @@
1
- #!/usr/bin/env node
2
- /* node:coverage ignore file */
3
-
4
- /**
5
- * epic-deliver-prepare.js — Step 0/1 of the operator-driven `/deliver`.
6
- *
7
- * Composes the existing engine phases that the in-process epic-runner used to
8
- * call sequentially, but does NOT dispatch any Stories. The CLI is the single
9
- * point at which the slash-command captures:
10
- *
11
- * 1. The Epic ticket snapshot (`runSnapshotPhase`).
12
- * 2. The story DAG (`runBuildWaveDagPhase`) computed from every child Story —
13
- * used here only to enumerate the open Story set and run the
14
- * concurrency-hazard gate; the ready-set runtime re-derives readiness
15
- * from live labels on every `tick`, so the prepare no longer persists a
16
- * wave grouping.
17
- * 3. The seeded `epic-run-state` checkpoint (`epic-run-state-store.initialize`)
18
- * in the per-Story-status shape (Story #4155): a flat
19
- * `stories: { [storyId]: { status: 'pending' } }` map plus the GLOBAL
20
- * in-flight `concurrencyCap`. Idempotent — re-running prepare against a
21
- * partially-driven Epic preserves the original `startedAt` and every
22
- * already-recorded Story status (it never resets recorded progress).
23
- * 4. The dispatch hint (`StoryLauncher.planWave`) — a deterministic list of
24
- * `{ storyId, worktree }` entries the slash command uses to resolve
25
- * per-Story worktree paths. The ready-set `tick` selects which of these
26
- * to dispatch on each beat; the prepare only enumerates the set.
27
- *
28
- * Stdout is a single JSON envelope so the slash command can parse without
29
- * re-reading any tickets.
30
- *
31
- * Usage:
32
- * node .agents/scripts/epic-deliver-prepare.js --epic <epicId>
33
- */
34
-
35
- import fs from 'node:fs';
36
- import path from 'node:path';
37
- import { parseArgs } from 'node:util';
38
-
39
- import { runBootSweep } from './boot-sweep.js';
40
- import { buildChecklistPayload } from './lib/audit-suite/index.js';
41
- import { runAsCli } from './lib/cli-utils.js';
42
- import { getPaths, getRunners, resolveConfig } from './lib/config-resolver.js';
43
- import { currentBranch as gitCurrentBranch } from './lib/git-branch-lifecycle.js';
44
- import { getEpicBranch, gitSpawn } from './lib/git-utils.js';
45
- import { Logger } from './lib/Logger.js';
46
- import { ensureDocsDigest } from './lib/orchestration/docs-digest.js';
47
- import {
48
- resolveOperator,
49
- runPrepareGuards,
50
- } from './lib/orchestration/epic-deliver-lease-guard.js';
51
- import {
52
- initialize as initializeEpicRunState,
53
- write as writeEpicRunState,
54
- } from './lib/orchestration/epic-run-state-store.js';
55
- import {
56
- collectPendingStoryKeys,
57
- evaluateConcurrencyGate,
58
- filterFindingsToPending,
59
- renderGateErrorMessage,
60
- } from './lib/orchestration/epic-runner/concurrency-gate.js';
61
- import { runBuildWaveDagPhase } from './lib/orchestration/epic-runner/phases/build-wave-dag.js';
62
- import { runSnapshotPhase } from './lib/orchestration/epic-runner/phases/snapshot.js';
63
- import { StoryLauncher } from './lib/orchestration/epic-runner/story-launcher.js';
64
- import { collectStoryAssumptionEntries } from './lib/orchestration/file-assumptions.js';
65
- import {
66
- computeBaseSha,
67
- readPreflightCache,
68
- } from './lib/orchestration/preflight-cache.js';
69
- import {
70
- latestHeartbeatForOwner,
71
- currentOwner as leaseCurrentOwner,
72
- } from './lib/orchestration/ticket-lease.js';
73
- import { createProvider } from './lib/provider-factory.js';
74
-
75
- const HELP = `Usage: node .agents/scripts/epic-deliver-prepare.js --epic <epicId> [--ignore-concurrency-hazards] [--steal] [--as <handle>]
76
-
77
- Snapshots Epic #<id>, builds the wave DAG, initializes the epic-run-state
78
- checkpoint, and prints the per-wave dispatch plan as JSON. Before any of that,
79
- runs two fail-closed preflight guards (Story #3482): a checkout-safety check
80
- (refuse on a dirty tree or an unexpected branch) and an Epic-lease acquisition
81
- (refuse on a live foreign claim).
82
-
83
- Options:
84
- --ignore-concurrency-hazards Bypass the cross-Story concurrency-hazard
85
- gate (Story #2297). The flag's use is
86
- recorded on the Epic checkpoint so retro
87
- tooling can flag a run that shipped
88
- despite an outstanding hazard.
89
- --steal Forcibly transfer a live foreign Epic lease
90
- to this operator instead of refusing. The
91
- takeover is logged for auditability.
92
- --as <handle> Operator identity to claim the Epic lease as.
93
- Defaults to github.operatorHandle, then the
94
- local git config user.email.
95
- `;
96
-
97
- /**
98
- * Build the production git shim the checkout-safety guard reads through. Pure
99
- * `git` subprocess wrappers over `cwd`; injected as a seam so the unit suite
100
- * can substitute an in-memory shim.
101
- *
102
- * @param {string} cwd
103
- * @returns {{ statusPorcelain: () => { dirty: boolean, entries: string }, currentBranch: () => string|null }}
104
- */
105
- function createGitShim(cwd) {
106
- return {
107
- statusPorcelain() {
108
- const res = gitSpawn(cwd, 'status', '--porcelain');
109
- if (res.status !== 0) {
110
- throw new Error(
111
- `[epic-deliver] Failed to read git status: ${res.stderr || '(no stderr)'}`,
112
- );
113
- }
114
- const entries = res.stdout ?? '';
115
- return { dirty: entries.length > 0, entries };
116
- },
117
- currentBranch() {
118
- return gitCurrentBranch(cwd);
119
- },
120
- };
121
- }
122
-
123
- /**
124
- * Resolve the local `git config user.email` as the last-resort operator
125
- * identity. Returns null when git is unavailable or the value is unset.
126
- *
127
- * @param {string} cwd
128
- * @returns {string|null}
129
- */
130
- function resolveGitUserEmail(cwd) {
131
- const res = gitSpawn(cwd, 'config', 'user.email');
132
- if (res.status !== 0) return null;
133
- const value = (res.stdout ?? '').trim();
134
- return value.length > 0 ? value : null;
135
- }
136
-
137
- /**
138
- * End-to-end prepare. DI-friendly: tests pass `injectedProvider` and skip the
139
- * real GitHub round-trips.
140
- *
141
- * @param {{
142
- * epicId: number,
143
- * cwd?: string,
144
- * injectedProvider?: object,
145
- * injectedConfig?: object,
146
- * }} args
147
- * @returns {Promise<{
148
- * epicId: number,
149
- * storyCount: number,
150
- * concurrencyCap: number,
151
- * stories: Array<{ storyId: number, title: string, worktree?: string }>,
152
- * checkpointInitializedAt: string,
153
- * }>}
154
- */
155
- /**
156
- * Run the fail-closed preflight guards (Story #3482): refuse on a
157
- * dirty/foreign-branch checkout and on a live foreign Epic lease, BEFORE any
158
- * snapshot or git mutation. No-op when guards are suppressed. The guards are
159
- * skipped when `skipPreflightGuards` is set, OR — implicitly — when a caller
160
- * injects a provider but no git seam (the signature of the prepare-runner
161
- * unit tests that drive an in-memory provider and never stand up a tree). The
162
- * real CLI path injects neither, so the guards always run for an
163
- * operator-driven invocation. Story #4075 — extracted from
164
- * `runEpicDeliverPrepare`.
165
- */
166
- async function runPreflightGuardsForPrepare({
167
- epicId,
168
- cwd,
169
- config,
170
- provider,
171
- injectedProvider,
172
- injectedGit,
173
- asOperator,
174
- steal,
175
- leaseHeartbeatAt,
176
- leaseNow,
177
- skipPreflightGuards,
178
- }) {
179
- const guardsSuppressed =
180
- skipPreflightGuards || (Boolean(injectedProvider) && !injectedGit);
181
- if (guardsSuppressed) return;
182
-
183
- const guardCwd = cwd ?? process.cwd();
184
- const git = injectedGit ?? createGitShim(guardCwd);
185
- const baseBranch = config.project?.baseBranch ?? 'main';
186
- const expectedBranch = [getEpicBranch(epicId), baseBranch];
187
- const operator =
188
- resolveOperator({
189
- asFlag: asOperator,
190
- config,
191
- gitUserEmail: injectedGit ? undefined : resolveGitUserEmail(guardCwd),
192
- }) ?? null;
193
-
194
- // Liveness seam: a foreign claim is only "live" (and so refuses) when the
195
- // claim *owner* has a recent `story.heartbeat`. Without this the lease
196
- // guard is inert — every foreign claim looks stale and gets silently
197
- // reclaimed (audit #3513). Read the Epic's current assignee (the claim
198
- // owner) and resolve that owner's latest heartbeat from the Epic lifecycle
199
- // ledger via the shared resolver. Tests may inject `leaseHeartbeatAt`
200
- // directly (any value, including null) to bypass the ledger read.
201
- let heartbeatAt = leaseHeartbeatAt;
202
- if (heartbeatAt === undefined) {
203
- const epicTicket = await provider.getTicket(epicId);
204
- const claimOwner = leaseCurrentOwner(epicTicket?.assignees);
205
- heartbeatAt = claimOwner
206
- ? latestHeartbeatForOwner({ epicId, owner: claimOwner, config })
207
- : null;
208
- }
209
-
210
- await runPrepareGuards({
211
- epicId,
212
- expectedBranch,
213
- git,
214
- provider,
215
- operator,
216
- heartbeatAt,
217
- steal,
218
- config,
219
- now: leaseNow,
220
- logger: Logger,
221
- });
222
- }
223
-
224
- /**
225
- * Route the Epic boot cleanup through the shared protected boot-sweep
226
- * engine (Story #4373). Reaps merged, done `story-*` branches left over
227
- * from prior runs — the protection partition skips any branch with
228
- * unpushed work, a dirty worktree, or a still-open parent Story, so an
229
- * in-flight Story is never touched. Fast-forward is off: the prepare may
230
- * run on the Epic branch, and the fast-forward phase would otherwise
231
- * check out the base branch.
232
- *
233
- * Best-effort — a sweep failure (lock contention, git/gh error) is
234
- * swallowed and never blocks or fails the prepare. Skipped in the same
235
- * injected-test shape the preflight guards use (a provider injected with
236
- * no git seam) so unit tests never spawn real git/gh.
237
- */
238
- async function runBootSweepForPrepare({
239
- cwd,
240
- config,
241
- provider,
242
- injectedProvider,
243
- injectedGit,
244
- injectedSweep,
245
- skipPreflightGuards,
246
- }) {
247
- const suppressed =
248
- skipPreflightGuards || (Boolean(injectedProvider) && !injectedGit);
249
- if (suppressed) return;
250
- try {
251
- await runBootSweep({
252
- cwd,
253
- include: ['story-*'],
254
- fastForward: false,
255
- injectedConfig: config,
256
- injectedProvider: provider,
257
- injectedSweep,
258
- logger: Logger,
259
- });
260
- } catch (err) {
261
- Logger.warn(
262
- `[epic-deliver-prepare] ⚠️ boot sweep threw (prepare continues): ${err?.message ?? err}`,
263
- );
264
- }
265
- }
266
-
267
- /**
268
- * Resolve the Epic state, preferring the preflight cache (Story #3027) and
269
- * falling back to a fresh snapshot + wave-DAG pass on miss or baseSha
270
- * mismatch. Returns `{ state, cacheStatus }`. Story #4075 — extracted from
271
- * `runEpicDeliverPrepare`.
272
- */
273
- async function resolvePrepareState({ epicId, cwd, provider }) {
274
- const cached = await readPreflightCache({ epicId, cwd });
275
- if (cached) {
276
- const freshEpic = await provider.getTicket(epicId);
277
- const cachedStoryIds = cached.stories
278
- .map((s) => Number(s?.id ?? s?.number))
279
- .filter((id) => Number.isInteger(id) && id > 0);
280
- const freshStories = await Promise.all(
281
- cachedStoryIds.map((id) => provider.getTicket(id)),
282
- );
283
- const freshBaseSha = computeBaseSha(freshEpic, freshStories);
284
- if (freshBaseSha === cached.baseSha) {
285
- return {
286
- state: {
287
- epic: cached.epic,
288
- stories: cached.stories,
289
- waves: cached.waves,
290
- },
291
- cacheStatus: 'hit',
292
- };
293
- }
294
- }
295
- const ctx = { epicId, provider };
296
- let state = await runSnapshotPhase(ctx, {}, {});
297
- state = await runBuildWaveDagPhase(ctx, {}, state);
298
- return { state, cacheStatus: cached ? 'stale' : 'miss' };
299
- }
300
-
301
- /**
302
- * Evaluate the cross-Story concurrency-hazard gate (Story #2297). Throws on a
303
- * tripped, non-bypassed gate; warns (and returns `gate`) on a bypassed trip.
304
- * Story #4075 — extracted from `runEpicDeliverPrepare`.
305
- */
306
- function evaluatePrepareConcurrencyGate({
307
- config,
308
- waves,
309
- injectedFindings,
310
- ignoreConcurrencyHazards,
311
- }) {
312
- const findings = Array.isArray(injectedFindings) ? injectedFindings : [];
313
- const pendingKeys = collectPendingStoryKeys(waves);
314
- const pendingFindings = filterFindingsToPending(findings, pendingKeys);
315
- const gate = evaluateConcurrencyGate({
316
- findings: pendingFindings,
317
- policy: {
318
- failOnConcurrencyHazards:
319
- config?.delivery?.failOnConcurrencyHazards === true,
320
- },
321
- ignore: ignoreConcurrencyHazards === true,
322
- });
323
- if (gate.tripped && !gate.bypassed) {
324
- const ownerRepo =
325
- config?.github?.owner && config?.github?.repo
326
- ? `${config.github.owner}/${config.github.repo}`
327
- : undefined;
328
- throw new Error(renderGateErrorMessage(gate.findings, ownerRepo));
329
- }
330
- if (gate.tripped && gate.bypassed) {
331
- Logger.warn(
332
- `[epic-deliver-prepare] ⚠️ Concurrency-hazard gate bypassed via --ignore-concurrency-hazards (reason=${gate.reason}, count=${gate.findings.length}).`,
333
- );
334
- }
335
- return gate;
336
- }
337
-
338
- /**
339
- * Build the per-Epic docs digest and write it to
340
- * `<tempRoot>/epic-<id>/docs-digest.md`, returning its repo-relative path.
341
- * Story #4338 — the parent threads this path into every child prompt so
342
- * delivery sub-agents read one compact outline instead of re-ingesting the
343
- * full `project.docsContextFiles` set per Story.
344
- *
345
- * Keyed off the **un-defaulted** config (`config.raw`): when the operator has
346
- * not configured `project.docsContextFiles`, this returns `null` (no file
347
- * written) rather than digesting the resolver's built-in default set — the
348
- * digest is an opt-in surface for projects that curate their docs context.
349
- *
350
- * @param {{ epicId: number, cwd?: string, config: object }} args
351
- * @returns {Promise<string|null>} repo-relative digest path, or null when
352
- * `project.docsContextFiles` is empty/unset (or every file is missing).
353
- */
354
- async function writeDocsDigest({ epicId, cwd, config }) {
355
- const rawFiles = config?.raw?.project?.docsContextFiles;
356
- const docsContextFiles = Array.isArray(rawFiles) ? rawFiles : [];
357
- if (docsContextFiles.length === 0) return null;
358
-
359
- const paths = getPaths(config);
360
- const root = path.resolve(cwd ?? process.cwd());
361
- const docsRoot = path.resolve(root, paths.docsRoot);
362
- const relPath = path.join(paths.tempRoot, `epic-${epicId}`, 'docs-digest.md');
363
- const absPath = path.resolve(root, relPath);
364
- const result = await ensureDocsDigest({
365
- docsContextFiles,
366
- docsRoot,
367
- outputPath: absPath,
368
- });
369
- return result ? relPath : null;
370
- }
371
-
372
- /**
373
- * Thread footprint-matched **local**-lens authoring checklists into the
374
- * per-Story dispatch entries (Epic #4405, Story #4410). For each planned Story,
375
- * derive its predicted footprint from the full ticket body's `changes[]` /
376
- * `references[]` entries, build the budget-capped checklist payload (matched by
377
- * `resolveLensTier(lens) === 'local'` + `matchesAnyFilePattern` — NOT
378
- * `selectAudits`, so no provider or git diff runs here), and write it to
379
- * `<tempRoot>/epic-<id>/checklists/story-<sid>.md`. The parent threads the
380
- * returned repo-relative `checklistPath` into that child's maker prompt, next
381
- * to `docsDigestPath`; a Story that matches no local lens gets a `null` path
382
- * and no file.
383
- *
384
- * @param {{
385
- * epicId: number,
386
- * cwd?: string,
387
- * config: object,
388
- * stories: Array<{ storyId: number, worktree?: string, title?: string }>,
389
- * storyById: Map<number, object>,
390
- * }} args
391
- * @returns {Promise<Array<{ storyId: number, worktree?: string, title?: string, checklistPath: string|null }>>}
392
- */
393
- export async function writeStoryChecklists({
394
- epicId,
395
- cwd,
396
- config,
397
- stories,
398
- storyById,
399
- buildPayload = buildChecklistPayload,
400
- }) {
401
- const paths = getPaths(config);
402
- const root = path.resolve(cwd ?? process.cwd());
403
-
404
- return Promise.all(
405
- stories.map(async (entry) => {
406
- const ticket = storyById.get(Number(entry.storyId));
407
- const footprint = ticket
408
- ? collectStoryAssumptionEntries(ticket).map((e) => e.path)
409
- : [];
410
- const { payload } = buildPayload({ footprint, logger: Logger });
411
- if (!payload) return { ...entry, checklistPath: null };
412
-
413
- const relPath = path.join(
414
- paths.tempRoot,
415
- `epic-${epicId}`,
416
- 'checklists',
417
- `story-${entry.storyId}.md`,
418
- );
419
- const absPath = path.resolve(root, relPath);
420
- await fs.promises.mkdir(path.dirname(absPath), { recursive: true });
421
- await fs.promises.writeFile(absPath, payload, 'utf-8');
422
- return { ...entry, checklistPath: relPath };
423
- }),
424
- );
425
- }
426
-
427
- export async function runEpicDeliverPrepare({
428
- epicId,
429
- cwd,
430
- injectedProvider,
431
- injectedConfig,
432
- injectedFindings,
433
- ignoreConcurrencyHazards = false,
434
- steal = false,
435
- asOperator,
436
- injectedGit,
437
- injectedSweep,
438
- leaseHeartbeatAt,
439
- leaseNow,
440
- skipPreflightGuards = false,
441
- } = {}) {
442
- if (!Number.isInteger(epicId) || epicId <= 0) {
443
- throw new TypeError(
444
- 'runEpicDeliverPrepare: --epic must be a positive integer',
445
- );
446
- }
447
-
448
- const config = injectedConfig ?? resolveConfig({ cwd });
449
- if (!config.github) {
450
- throw new Error('runEpicDeliverPrepare: no github block in .agentrc.json');
451
- }
452
- const provider = injectedProvider ?? createProvider(config);
453
- const { deliverRunner } = getRunners(config);
454
- const concurrencyCap = deliverRunner.concurrencyCap;
455
-
456
- await runPreflightGuardsForPrepare({
457
- epicId,
458
- cwd,
459
- config,
460
- provider,
461
- injectedProvider,
462
- injectedGit,
463
- asOperator,
464
- steal,
465
- leaseHeartbeatAt,
466
- leaseNow,
467
- skipPreflightGuards,
468
- });
469
-
470
- await runBootSweepForPrepare({
471
- cwd,
472
- config,
473
- provider,
474
- injectedProvider,
475
- injectedGit,
476
- injectedSweep,
477
- skipPreflightGuards,
478
- });
479
-
480
- const { state, cacheStatus } = await resolvePrepareState({
481
- epicId,
482
- cwd,
483
- provider,
484
- });
485
-
486
- const gate = evaluatePrepareConcurrencyGate({
487
- config,
488
- waves: state.waves,
489
- injectedFindings,
490
- ignoreConcurrencyHazards,
491
- });
492
-
493
- // Flatten the wave-DAG into the open Story set. The ready-set runtime
494
- // re-derives readiness from live labels on every tick, so the checkpoint
495
- // stores only the Story set in scope (seeded at `pending`) and the global
496
- // in-flight cap — no wave grouping, no `currentWave`, no `totalWaves`.
497
- const openStories = state.waves.flat();
498
- const checkpointState = await initializeEpicRunState({
499
- provider,
500
- epicId,
501
- storyIds: openStories,
502
- concurrencyCap,
503
- });
504
-
505
- // Resolve per-Story worktree paths via the launcher so the slash command
506
- // has a deterministic `{ storyId, worktree, title }` list to seed Agent
507
- // dispatch from. This is a dispatch *hint* — the ready-set tick decides
508
- // which Stories to dispatch on each beat; the prepare only enumerates them.
509
- const launcher = new StoryLauncher({ concurrencyCap });
510
- const plannedStories = launcher.planWave(openStories).map((entry, i) => ({
511
- ...entry,
512
- title: openStories[i]?.title ?? '',
513
- }));
514
-
515
- // Thread footprint-matched local-lens authoring checklists into each Story's
516
- // dispatch entry (Story #4410). Keyed off the full discovered tickets (which
517
- // carry the `changes[]`/`references[]` bodies the footprint is derived from);
518
- // a Story that matches no local lens gets a `null` checklistPath.
519
- const storyById = new Map(
520
- (state.stories ?? []).map((t) => [Number(t.id ?? t.number), t]),
521
- );
522
- const stories = await writeStoryChecklists({
523
- epicId,
524
- cwd,
525
- config,
526
- stories: plannedStories,
527
- storyById,
528
- });
529
-
530
- // Persist the `--ignore-concurrency-hazards` flag on the checkpoint so
531
- // retro tooling can flag a run that shipped despite an outstanding hazard
532
- // (the warning above is one-shot; the checkpoint is durable).
533
- if (gate.bypassed) {
534
- await writeEpicRunState({
535
- provider,
536
- epicId,
537
- state: { ...checkpointState, ignoreConcurrencyHazards: true },
538
- });
539
- }
540
-
541
- const docsDigestPath = await writeDocsDigest({ epicId, cwd, config });
542
-
543
- return {
544
- epicId,
545
- storyCount: openStories.length,
546
- concurrencyCap,
547
- stories,
548
- checkpointInitializedAt:
549
- checkpointState.startedAt ??
550
- checkpointState.lastUpdatedAt ??
551
- new Date().toISOString(),
552
- concurrencyHazardsBypassed: gate.bypassed,
553
- preflightCache: cacheStatus,
554
- docsDigestPath,
555
- };
556
- }
557
-
558
- async function main() {
559
- const { values } = parseArgs({
560
- options: {
561
- epic: { type: 'string' },
562
- help: { type: 'boolean', short: 'h' },
563
- 'ignore-concurrency-hazards': { type: 'boolean', default: false },
564
- steal: { type: 'boolean', default: false },
565
- as: { type: 'string' },
566
- },
567
- strict: false,
568
- });
569
-
570
- if (values.help) {
571
- Logger.info(HELP);
572
- return;
573
- }
574
- const epicId = Number.parseInt(values.epic ?? '', 10);
575
- if (Number.isNaN(epicId) || epicId <= 0) {
576
- Logger.error('[epic-deliver-prepare] ERROR: --epic <epicId> is required.');
577
- Logger.error(HELP);
578
- process.exit(2);
579
- }
580
-
581
- const result = await runEpicDeliverPrepare({
582
- epicId,
583
- ignoreConcurrencyHazards: values['ignore-concurrency-hazards'] === true,
584
- steal: values.steal === true,
585
- asOperator: typeof values.as === 'string' ? values.as : undefined,
586
- });
587
- Logger.info(JSON.stringify(result, null, 2));
588
- }
589
-
590
- runAsCli(import.meta.url, main, { source: 'epic-deliver-prepare' });