mandrel 1.94.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (393) hide show
  1. package/.agents/README.md +59 -73
  2. package/.agents/agents/story-worker.md +12 -13
  3. package/.agents/docs/SDLC.md +489 -1285
  4. package/.agents/docs/agentrc-reference.json +177 -67
  5. package/.agents/docs/configuration.md +104 -138
  6. package/.agents/docs/execution-reference.md +17 -20
  7. package/.agents/docs/quality-gates.md +13 -19
  8. package/.agents/docs/workflows.md +3 -3
  9. package/.agents/instructions.md +70 -81
  10. package/.agents/rules/ci-remediation.md +8 -12
  11. package/.agents/rules/git-conventions-reference.md +6 -7
  12. package/.agents/rules/git-conventions.md +16 -22
  13. package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
  14. package/.agents/schemas/agentrc.schema.json +54 -214
  15. package/.agents/schemas/lifecycle/ledger-record.schema.json +1 -1
  16. package/.agents/schemas/lifecycle/retro.end.schema.json +1 -1
  17. package/.agents/schemas/risk-verdict.schema.json +0 -13
  18. package/.agents/scripts/analyze-execution.js +1 -1
  19. package/.agents/scripts/audit-to-stories.js +7 -7
  20. package/.agents/scripts/boot-sweep.js +1 -1
  21. package/.agents/scripts/check-lifecycle-lint.js +6 -9
  22. package/.agents/scripts/check-prepush-recovery.js +1 -1
  23. package/.agents/scripts/cleanup-repo-test-temp.js +6 -1
  24. package/.agents/scripts/lib/Logger.js +6 -10
  25. package/.agents/scripts/lib/audit-suite/runner.js +2 -2
  26. package/.agents/scripts/lib/audit-suite/selector.js +5 -5
  27. package/.agents/scripts/lib/audit-to-stories/{seed-epic-from-findings.js → seed-from-findings.js} +9 -9
  28. package/.agents/scripts/lib/baselines/kernel.js +206 -18
  29. package/.agents/scripts/lib/baselines/kinds/maintainability.js +0 -4
  30. package/.agents/scripts/lib/baselines/reader.js +1 -6
  31. package/.agents/scripts/lib/bdd-runner-detect.js +5 -9
  32. package/.agents/scripts/lib/bootstrap/issue-forms-template.js +32 -33
  33. package/.agents/scripts/lib/checks/core-bare-clean.js +2 -2
  34. package/.agents/scripts/lib/checks/index.js +2 -1
  35. package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +23 -21
  36. package/.agents/scripts/lib/cli/standard-args.js +13 -22
  37. package/.agents/scripts/lib/cli-args.js +16 -7
  38. package/.agents/scripts/lib/close-validation/gates.js +2 -2
  39. package/.agents/scripts/lib/config/ci.js +6 -31
  40. package/.agents/scripts/lib/config/delivery-routing.js +45 -29
  41. package/.agents/scripts/lib/config/explain.js +55 -36
  42. package/.agents/scripts/lib/config/limits.js +17 -58
  43. package/.agents/scripts/lib/config/paths.js +0 -2
  44. package/.agents/scripts/lib/config/quality.js +1 -1
  45. package/.agents/scripts/lib/config/runners.js +17 -50
  46. package/.agents/scripts/lib/config/temp-paths.js +19 -14
  47. package/.agents/scripts/lib/config/worktree-isolation.js +0 -5
  48. package/.agents/scripts/lib/config-resolver.js +2 -7
  49. package/.agents/scripts/lib/config-settings-schema-delivery.js +24 -148
  50. package/.agents/scripts/lib/config-settings-schema-quality.js +8 -14
  51. package/.agents/scripts/lib/config-settings-schema.js +52 -38
  52. package/.agents/scripts/lib/dependency-parser.js +3 -2
  53. package/.agents/scripts/lib/doc-tiers.js +2 -2
  54. package/.agents/scripts/lib/duplicate-search.js +211 -41
  55. package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +1 -1
  56. package/.agents/scripts/lib/findings/promote-finding.js +5 -5
  57. package/.agents/scripts/lib/framework-version.js +2 -3
  58. package/.agents/scripts/lib/git-branch-cleanup.js +1 -10
  59. package/.agents/scripts/lib/git-branch-lifecycle.js +17 -22
  60. package/.agents/scripts/lib/git-utils.js +32 -6
  61. package/.agents/scripts/lib/github/framework-repo.js +6 -0
  62. package/.agents/scripts/lib/label-constants.js +10 -23
  63. package/.agents/scripts/lib/label-taxonomy.js +9 -43
  64. package/.agents/scripts/lib/observability/active-story-env.js +1 -1
  65. package/.agents/scripts/lib/observability/hook-heartbeat.js +20 -52
  66. package/.agents/scripts/lib/observability/source-classifier.js +3 -3
  67. package/.agents/scripts/lib/onboard/init-tail.js +1 -3
  68. package/.agents/scripts/lib/orchestration/audit-lens-routing.js +128 -0
  69. package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +8 -5
  70. package/.agents/scripts/lib/orchestration/ceremony-routing.js +83 -20
  71. package/.agents/scripts/lib/orchestration/code-review.js +20 -268
  72. package/.agents/scripts/lib/orchestration/column-sync.js +1 -1
  73. package/.agents/scripts/lib/orchestration/consolidation-precondition.js +1 -1
  74. package/.agents/scripts/lib/orchestration/context-envelope.js +2 -5
  75. package/.agents/scripts/lib/orchestration/docs-digest.js +8 -8
  76. package/.agents/scripts/lib/orchestration/file-assumptions.js +7 -13
  77. package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +1 -1
  78. package/.agents/scripts/lib/orchestration/lifecycle/emit-loop-tick.js +8 -8
  79. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +2 -2
  80. package/.agents/scripts/lib/orchestration/lifecycle/ledger-writer.js +6 -3
  81. package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +17 -43
  82. package/.agents/scripts/lib/orchestration/lint-baseline-service.js +4 -4
  83. package/.agents/scripts/lib/orchestration/merge-block-class.js +1 -1
  84. package/.agents/scripts/lib/orchestration/phase-runner.js +3 -2
  85. package/.agents/scripts/lib/orchestration/plan-context.js +248 -266
  86. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +1 -1
  87. package/.agents/scripts/lib/orchestration/plan-navigation.js +92 -0
  88. package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +61 -0
  89. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +97 -0
  90. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +223 -854
  91. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +361 -0
  92. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +35 -108
  93. package/.agents/scripts/lib/orchestration/plan-reachability.js +9 -14
  94. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +1 -1
  95. package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/authoring-context.js +13 -13
  96. package/.agents/scripts/lib/orchestration/planning/decomposer-context.js +27 -0
  97. package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/risk-verdict.js +3 -4
  98. package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +2 -2
  99. package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +8 -20
  100. package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +3 -2
  101. package/.agents/scripts/lib/orchestration/pr-base-guard.js +18 -28
  102. package/.agents/scripts/lib/orchestration/preflight-cache.js +5 -5
  103. package/.agents/scripts/lib/orchestration/remote-verifier.js +1 -1
  104. package/.agents/scripts/lib/orchestration/resolve-plan-run.js +155 -0
  105. package/.agents/scripts/lib/orchestration/resolves-token.js +1 -1
  106. package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +8 -8
  107. package/.agents/scripts/lib/orchestration/retro-proposals.js +140 -79
  108. package/.agents/scripts/lib/orchestration/review-depth.js +26 -12
  109. package/.agents/scripts/lib/orchestration/review-providers/codex.js +2 -2
  110. package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +21 -56
  111. package/.agents/scripts/lib/orchestration/run-epilogue.js +426 -0
  112. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +1 -1
  113. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +95 -41
  114. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +16 -13
  115. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +40 -0
  116. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +11 -3
  117. package/.agents/scripts/lib/orchestration/spec-freshness.js +14 -205
  118. package/.agents/scripts/lib/orchestration/spec-section-validator.js +4 -5
  119. package/.agents/scripts/lib/orchestration/spec-spill.js +60 -0
  120. package/.agents/scripts/lib/orchestration/split-policy-validator.js +188 -0
  121. package/.agents/scripts/lib/orchestration/story-close/emit-blocked.js +49 -0
  122. package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +15 -12
  123. package/.agents/scripts/lib/orchestration/story-follow-ups.js +237 -0
  124. package/.agents/scripts/lib/orchestration/story-init-remote.js +47 -0
  125. package/.agents/scripts/lib/orchestration/story-plan-state.js +48 -0
  126. package/.agents/scripts/lib/orchestration/{epic-runner → story-progress}/story-run-progress-writer.js +3 -3
  127. package/.agents/scripts/lib/orchestration/structured-comment-parser.js +1 -1
  128. package/.agents/scripts/lib/orchestration/task-body-validator.js +8 -18
  129. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +11 -61
  130. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +189 -373
  131. package/.agents/scripts/lib/orchestration/ticket-validator.js +2 -7
  132. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +0 -25
  133. package/.agents/scripts/lib/orchestration/ticketing/reads.js +29 -26
  134. package/.agents/scripts/lib/orchestration/ticketing/transition.js +5 -5
  135. package/.agents/scripts/lib/planning-corpus.js +16 -11
  136. package/.agents/scripts/lib/preflight-runner.js +2 -2
  137. package/.agents/scripts/lib/qa/coverage-verdict.js +5 -5
  138. package/.agents/scripts/lib/single-story/confirm-merge-follow-ups.js +36 -0
  139. package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +1 -1
  140. package/.agents/scripts/lib/story-adjacency.js +11 -14
  141. package/.agents/scripts/lib/story-body/story-body.js +124 -70
  142. package/.agents/scripts/lib/story-plan.js +2 -4
  143. package/.agents/scripts/lib/templates/decomposer-prompts.js +46 -45
  144. package/.agents/scripts/lib/templates/spec-author-prompts.js +47 -45
  145. package/.agents/scripts/lib/{epic-body-sections.js → ticket-body-sections.js} +26 -26
  146. package/.agents/scripts/lib/validation-evidence.js +1 -1
  147. package/.agents/scripts/lib/wave-runner/ready-set.js +6 -6
  148. package/.agents/scripts/lib/workspace-provisioner.js +1 -1
  149. package/.agents/scripts/lib/worktree/lifecycle/reap.js +5 -7
  150. package/.agents/scripts/lint-issue-body.js +71 -40
  151. package/.agents/scripts/mandrel-update-preflight.js +1 -1
  152. package/.agents/scripts/notify.js +4 -3
  153. package/.agents/scripts/plan-context.js +64 -74
  154. package/.agents/scripts/plan-persist.js +121 -280
  155. package/.agents/scripts/plan-run-epilogue.js +97 -0
  156. package/.agents/scripts/providers/github/issues.js +17 -33
  157. package/.agents/scripts/providers/github/mappers.js +0 -12
  158. package/.agents/scripts/providers/github/tickets.js +2 -5
  159. package/.agents/scripts/resolve-plan-run.js +117 -0
  160. package/.agents/scripts/signals-view.js +24 -19
  161. package/.agents/scripts/single-story-close.js +11 -14
  162. package/.agents/scripts/single-story-confirm-merge.js +39 -23
  163. package/.agents/scripts/single-story-init.js +29 -20
  164. package/.agents/scripts/stories-wave-tick.js +6 -6
  165. package/.agents/scripts/story-plan.js +26 -47
  166. package/.agents/scripts/update-ticket-state.js +6 -15
  167. package/.agents/skills/core/analyze-execution/SKILL.md +21 -18
  168. package/.agents/skills/core/idea-refinement/SKILL.md +6 -6
  169. package/.agents/skills/core/scope-triage/SKILL.md +28 -172
  170. package/.agents/skills/skills.index.json +3 -43
  171. package/.agents/starter-agentrc.json +0 -5
  172. package/.agents/templates/agent-protocol.md +9 -10
  173. package/.agents/workflows/audit-architecture.md +3 -3
  174. package/.agents/workflows/audit-clean-code.md +3 -3
  175. package/.agents/workflows/audit-dependencies.md +3 -3
  176. package/.agents/workflows/audit-devops.md +3 -3
  177. package/.agents/workflows/audit-documentation.md +5 -5
  178. package/.agents/workflows/audit-lighthouse.md +3 -3
  179. package/.agents/workflows/audit-navigability.md +3 -2
  180. package/.agents/workflows/audit-performance.md +3 -3
  181. package/.agents/workflows/audit-privacy.md +3 -3
  182. package/.agents/workflows/audit-quality.md +3 -3
  183. package/.agents/workflows/audit-security.md +3 -3
  184. package/.agents/workflows/audit-seo.md +3 -3
  185. package/.agents/workflows/audit-sre.md +3 -3
  186. package/.agents/workflows/audit-to-stories.md +20 -20
  187. package/.agents/workflows/audit-ux-ui.md +3 -3
  188. package/.agents/workflows/deliver.md +122 -174
  189. package/.agents/workflows/git-cleanup.md +3 -4
  190. package/.agents/workflows/helpers/_merge-conflict-template.md +1 -1
  191. package/.agents/workflows/helpers/acceptance-self-eval.md +16 -29
  192. package/.agents/workflows/helpers/code-review.md +70 -193
  193. package/.agents/workflows/helpers/{single-story-deliver-reference.md → deliver-story-reference.md} +12 -14
  194. package/.agents/workflows/helpers/{single-story-deliver.md → deliver-story.md} +113 -139
  195. package/.agents/workflows/helpers/diagnose.md +10 -10
  196. package/.agents/workflows/helpers/parallel-tooling.md +1 -1
  197. package/.agents/workflows/helpers/signals.md +16 -16
  198. package/.agents/workflows/helpers/worktree-lifecycle.md +48 -64
  199. package/.agents/workflows/mandrel-update.md +2 -1
  200. package/.agents/workflows/plan.md +112 -145
  201. package/.agents/workflows/qa-assist.md +24 -30
  202. package/.agents/workflows/qa-explore.md +29 -38
  203. package/.agents/workflows/qa-run.md +2 -2
  204. package/README.md +9 -8
  205. package/docs/CHANGELOG.md +30 -0
  206. package/lib/migrations/index.js +6 -5
  207. package/package.json +2 -2
  208. package/.agents/agents/retro.md +0 -42
  209. package/.agents/personas/architect.md +0 -113
  210. package/.agents/personas/devops-engineer.md +0 -38
  211. package/.agents/personas/engineer.md +0 -33
  212. package/.agents/personas/project-manager.md +0 -114
  213. package/.agents/personas/qa-engineer.md +0 -95
  214. package/.agents/personas/security-engineer.md +0 -111
  215. package/.agents/personas/technical-writer.md +0 -101
  216. package/.agents/schemas/dispatch-manifest.json +0 -232
  217. package/.agents/schemas/epic-spec.schema.json +0 -153
  218. package/.agents/schemas/lifecycle/slice.end.schema.json +0 -21
  219. package/.agents/schemas/lifecycle/slice.heartbeat.schema.json +0 -20
  220. package/.agents/schemas/lifecycle/slice.start.schema.json +0 -17
  221. package/.agents/scripts/acceptance-spec-reconciler.js +0 -642
  222. package/.agents/scripts/bookkeeping-reconcile.js +0 -117
  223. package/.agents/scripts/dispatcher.js +0 -295
  224. package/.agents/scripts/epic-audit-prepare.js +0 -497
  225. package/.agents/scripts/epic-audit-recheck.js +0 -274
  226. package/.agents/scripts/epic-deliver-note-intervention.js +0 -192
  227. package/.agents/scripts/epic-deliver-preflight.js +0 -462
  228. package/.agents/scripts/epic-deliver-prepare.js +0 -852
  229. package/.agents/scripts/epic-execute-record-wave.js +0 -449
  230. package/.agents/scripts/epic-plan-clarity.js +0 -211
  231. package/.agents/scripts/epic-plan-healthcheck.js +0 -581
  232. package/.agents/scripts/epic-reconcile.js +0 -625
  233. package/.agents/scripts/lib/baseline-snapshot.js +0 -979
  234. package/.agents/scripts/lib/checks/epic-merge-lock-stale.js +0 -54
  235. package/.agents/scripts/lib/checks/stale-origin-epic.js +0 -49
  236. package/.agents/scripts/lib/config/lifecycle.js +0 -40
  237. package/.agents/scripts/lib/config/preflight.js +0 -58
  238. package/.agents/scripts/lib/config/retro.js +0 -77
  239. package/.agents/scripts/lib/epic-merge-lock.js +0 -322
  240. package/.agents/scripts/lib/epic-plan-clarity.js +0 -181
  241. package/.agents/scripts/lib/epic-plan-ideation.js +0 -261
  242. package/.agents/scripts/lib/orchestration/context-hydration-engine.js +0 -539
  243. package/.agents/scripts/lib/orchestration/deliver-route.js +0 -173
  244. package/.agents/scripts/lib/orchestration/dispatch-engine.js +0 -134
  245. package/.agents/scripts/lib/orchestration/dispatch-pipeline.js +0 -183
  246. package/.agents/scripts/lib/orchestration/epic-cleanup.js +0 -801
  247. package/.agents/scripts/lib/orchestration/epic-deliver-lease-guard.js +0 -310
  248. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/context.js +0 -163
  249. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/creation.js +0 -140
  250. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/dag.js +0 -64
  251. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/diagnostics.js +0 -72
  252. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +0 -156
  253. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist.js +0 -345
  254. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +0 -41
  255. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/reconcile-spawn.js +0 -86
  256. package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +0 -391
  257. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/drain.js +0 -94
  258. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +0 -236
  259. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +0 -307
  260. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-freshness.js +0 -117
  261. package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +0 -117
  262. package/.agents/scripts/lib/orchestration/epic-run-state-store.js +0 -621
  263. package/.agents/scripts/lib/orchestration/epic-runner/concurrency-gate.js +0 -186
  264. package/.agents/scripts/lib/orchestration/epic-runner/deliver-phases.js +0 -50
  265. package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +0 -129
  266. package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +0 -103
  267. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/composition.js +0 -267
  268. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/signals.js +0 -210
  269. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/transport.js +0 -238
  270. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/_bullet-format.js +0 -32
  271. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/component-drift.js +0 -203
  272. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/crap-drift.js +0 -227
  273. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/maintainability-drift.js +0 -117
  274. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/stalled-worktree.js +0 -37
  275. package/.agents/scripts/lib/orchestration/epic-runner/story-launcher.js +0 -127
  276. package/.agents/scripts/lib/orchestration/epic-runner/sub-agent-return.js +0 -276
  277. package/.agents/scripts/lib/orchestration/epic-runner/wave-scheduler.js +0 -66
  278. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-apply.js +0 -789
  279. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +0 -676
  280. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-discriminator.js +0 -389
  281. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-format.js +0 -230
  282. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-ops.js +0 -361
  283. package/.agents/scripts/lib/orchestration/finalize/open-or-locate-pr.js +0 -306
  284. package/.agents/scripts/lib/orchestration/finalize/post-handoff-comment.js +0 -489
  285. package/.agents/scripts/lib/orchestration/finalize/sanitize-skip-ci.js +0 -88
  286. package/.agents/scripts/lib/orchestration/lifecycle/emit-slice-lifecycle.js +0 -270
  287. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-dispatch-end.js +0 -147
  288. package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +0 -465
  289. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +0 -501
  290. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +0 -984
  291. package/.agents/scripts/lib/orchestration/lifecycle/listeners/branch-cleaner.js +0 -264
  292. package/.agents/scripts/lib/orchestration/lifecycle/listeners/checkpoint-pointer-writer.js +0 -284
  293. package/.agents/scripts/lib/orchestration/lifecycle/listeners/cleaner.js +0 -355
  294. package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +0 -673
  295. package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +0 -378
  296. package/.agents/scripts/lib/orchestration/lifecycle/listeners/intervention-recorder.js +0 -140
  297. package/.agents/scripts/lib/orchestration/lifecycle/listeners/label-transitioner.js +0 -144
  298. package/.agents/scripts/lib/orchestration/lifecycle/listeners/notify-dispatcher.js +0 -174
  299. package/.agents/scripts/lib/orchestration/manifest-builder.js +0 -222
  300. package/.agents/scripts/lib/orchestration/plan-persist/amend.js +0 -359
  301. package/.agents/scripts/lib/orchestration/plan-persist/delivery-mode.js +0 -127
  302. package/.agents/scripts/lib/orchestration/post-merge-pipeline.js +0 -205
  303. package/.agents/scripts/lib/orchestration/recurring-failure-detector.js +0 -152
  304. package/.agents/scripts/lib/orchestration/retro/phases/checks.js +0 -94
  305. package/.agents/scripts/lib/orchestration/retro/phases/compose-body.js +0 -571
  306. package/.agents/scripts/lib/orchestration/retro/phases/gather-signals.js +0 -450
  307. package/.agents/scripts/lib/orchestration/retro/phases/post-and-mirror.js +0 -191
  308. package/.agents/scripts/lib/orchestration/retro-heuristics.js +0 -57
  309. package/.agents/scripts/lib/orchestration/retro-runner.js +0 -197
  310. package/.agents/scripts/lib/orchestration/spec-renderer.js +0 -447
  311. package/.agents/scripts/lib/orchestration/story-close/auto-refresh-runner.js +0 -747
  312. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/gate-failure.js +0 -211
  313. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/pre-merge-attribution.js +0 -158
  314. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +0 -446
  315. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/regression-projection.js +0 -297
  316. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/scope-discovery.js +0 -48
  317. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution-wiring.js +0 -67
  318. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution.js +0 -161
  319. package/.agents/scripts/lib/orchestration/story-close/baseline-friction-body.js +0 -117
  320. package/.agents/scripts/lib/orchestration/story-close/cd-out-guard.js +0 -86
  321. package/.agents/scripts/lib/orchestration/story-close/cleanup-reconciler.js +0 -147
  322. package/.agents/scripts/lib/orchestration/story-close/close-inputs.js +0 -142
  323. package/.agents/scripts/lib/orchestration/story-close/comment-bodies.js +0 -62
  324. package/.agents/scripts/lib/orchestration/story-close/merge-runner.js +0 -658
  325. package/.agents/scripts/lib/orchestration/story-close/merge-subject.js +0 -198
  326. package/.agents/scripts/lib/orchestration/story-close/phases/branch-restore.js +0 -105
  327. package/.agents/scripts/lib/orchestration/story-close/phases/close.js +0 -222
  328. package/.agents/scripts/lib/orchestration/story-close/phases/gates.js +0 -292
  329. package/.agents/scripts/lib/orchestration/story-close/phases/locked-pipeline.js +0 -270
  330. package/.agents/scripts/lib/orchestration/story-close/phases/preflight.js +0 -110
  331. package/.agents/scripts/lib/orchestration/story-close/phases/refresh.js +0 -86
  332. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked-emitter.js +0 -112
  333. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked.js +0 -157
  334. package/.agents/scripts/lib/orchestration/story-close/post-merge-close.js +0 -421
  335. package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +0 -302
  336. package/.agents/scripts/lib/orchestration/story-close/shared-checkout-guard.js +0 -163
  337. package/.agents/scripts/lib/orchestration/story-close-recovery.js +0 -690
  338. package/.agents/scripts/lib/orchestration/wave-marker.js +0 -28
  339. package/.agents/scripts/lib/orchestration/wave-record-io.js +0 -218
  340. package/.agents/scripts/lib/orchestration/wave-record-notifications.js +0 -145
  341. package/.agents/scripts/lib/orchestration/wave-record-projection.js +0 -212
  342. package/.agents/scripts/lib/presentation/dispatch-manifest-render.js +0 -111
  343. package/.agents/scripts/lib/presentation/manifest-builder.js +0 -239
  344. package/.agents/scripts/lib/presentation/manifest-formatter.js +0 -242
  345. package/.agents/scripts/lib/presentation/manifest-helpers.js +0 -213
  346. package/.agents/scripts/lib/presentation/manifest-persistence.js +0 -261
  347. package/.agents/scripts/lib/presentation/manifest-procedures.js +0 -55
  348. package/.agents/scripts/lib/presentation/manifest-render-waves.js +0 -306
  349. package/.agents/scripts/lib/presentation/manifest-renderer.js +0 -188
  350. package/.agents/scripts/lib/presentation/manifest-story-views.js +0 -110
  351. package/.agents/scripts/lib/push-epic-retry.js +0 -209
  352. package/.agents/scripts/lib/spec/index.js +0 -36
  353. package/.agents/scripts/lib/spec/loader.js +0 -425
  354. package/.agents/scripts/lib/spec/state.js +0 -208
  355. package/.agents/scripts/lib/story-init/blocker-validator.js +0 -68
  356. package/.agents/scripts/lib/story-init/branch-initializer.js +0 -408
  357. package/.agents/scripts/lib/story-init/context-resolver.js +0 -92
  358. package/.agents/scripts/lib/story-init/donor-precheck.js +0 -207
  359. package/.agents/scripts/lib/story-init/state-transitioner.js +0 -80
  360. package/.agents/scripts/lib/story-init/task-graph-builder.js +0 -124
  361. package/.agents/scripts/lib/story-init/transition-summary.js +0 -34
  362. package/.agents/scripts/lib/test-reserved-epic-temp-ids.js +0 -35
  363. package/.agents/scripts/lib/wave-runner/tick.js +0 -754
  364. package/.agents/scripts/lib/wave-runner/wave-runner-error.js +0 -20
  365. package/.agents/scripts/lifecycle-emit-story-dispatch.js +0 -194
  366. package/.agents/scripts/lifecycle-emit.js +0 -510
  367. package/.agents/scripts/retro-run.js +0 -218
  368. package/.agents/scripts/slice-phase.js +0 -361
  369. package/.agents/scripts/standalone-feedback-rollup.js +0 -188
  370. package/.agents/scripts/story-close.js +0 -294
  371. package/.agents/scripts/story-init.js +0 -599
  372. package/.agents/scripts/story-phase.js +0 -369
  373. package/.agents/scripts/wave-tick.js +0 -464
  374. package/.agents/skills/core/epic-plan-consolidate/SKILL.md +0 -172
  375. package/.agents/skills/core/epic-plan-consolidate/examples.md +0 -51
  376. package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +0 -441
  377. package/.agents/skills/core/epic-plan-decompose-author/examples.md +0 -47
  378. package/.agents/skills/core/epic-plan-premortem/SKILL.md +0 -146
  379. package/.agents/skills/core/epic-plan-premortem/examples.md +0 -53
  380. package/.agents/skills/core/epic-plan-spec-author/SKILL.md +0 -383
  381. package/.agents/skills/core/epic-plan-spec-author/examples.md +0 -91
  382. package/.agents/workflows/helpers/deliver-epic-reference.md +0 -547
  383. package/.agents/workflows/helpers/deliver-epic-single.md +0 -331
  384. package/.agents/workflows/helpers/deliver-epic.md +0 -998
  385. package/.agents/workflows/helpers/deliver-stories.md +0 -450
  386. package/.agents/workflows/helpers/epic-audit.md +0 -189
  387. package/.agents/workflows/helpers/epic-deliver-story.md +0 -436
  388. package/.agents/workflows/helpers/epic-testing.md +0 -125
  389. package/.agents/workflows/helpers/plan-epic-reference.md +0 -160
  390. package/.agents/workflows/helpers/plan-epic.md +0 -353
  391. package/.agents/workflows/helpers/plan-story.md +0 -251
  392. package/.agents/workflows/helpers/scope-triage-gate.md +0 -108
  393. /package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/spec-authoring-grounding.js +0 -0
@@ -1,462 +0,0 @@
1
- #!/usr/bin/env node
2
- /* node:coverage ignore file */
3
-
4
- /**
5
- * epic-deliver-preflight.js — Story #2899 (Epic #2880, F13).
6
- *
7
- * Estimates the cost of an upcoming `/deliver` run *before* Story
8
- * fan-out and surfaces the result to the operator on two channels:
9
- *
10
- * 1. A JSON envelope on stdout (always) with the keys
11
- * `storyCount`, `installCostSeconds`, `dependencyDepth`,
12
- * `githubApiRequests`, `claudeQuotaTokens`, plus `breaches`
13
- * (the non-empty subset of `delivery.preflight.max*` thresholds the
14
- * estimate exceeds), plus `remoteVerified` / `remoteProbe` — the
15
- * issue #4483 deterministic remote evidence (`git remote get-url
16
- * origin` + bounded `git ls-remote origin HEAD`). On
17
- * `remoteVerified: false` the workflow MUST flip the Epic to
18
- * `agent::blocked` quoting `remoteProbe.detail` — inline delivery to
19
- * local `main` is never a sanctioned fallback.
20
- * 2. When `--post` is set (and `--dry-run` is not), an upserted
21
- * `delivery-preflight` structured comment on the Epic ticket so
22
- * reviewers reading the Epic discover the same numbers without
23
- * shelling out.
24
- *
25
- * The CLI is intentionally side-effect-light when `--dry-run` is set: no
26
- * comment write, no lifecycle emit. The slash-command workflow
27
- * (`/deliver` Phase 1) calls the CLI without `--dry-run` so the
28
- * comment is upserted; if any threshold is breached, the workflow flips
29
- * the Epic to `agent::blocked` and surfaces the envelope in chat for
30
- * operator review. The CLI itself does NOT flip labels — the workflow
31
- * owns the HITL transition so a re-invocation against a recovered Epic
32
- * does not double-flip.
33
- *
34
- * Estimate model (kept simple and deterministic so a sub-agent reviewing
35
- * the comment can reason about the numbers):
36
- *
37
- * - `storyCount` = number of child `type::story` tickets.
38
- * - `dependencyDepth` = longest dependency chain through the Story
39
- * DAG (Story #4155). The ready-set runtime has
40
- * no wave barrier, so wall-clock is bounded
41
- * below by this depth, not by a wave count: a
42
- * depth-1 Epic (all Stories independent) can run
43
- * fully parallel, while a depth-N chain forces N
44
- * sequential beats regardless of cap. Computed
45
- * as the dependency-DAG layer count.
46
- * - `installCostSeconds` = `storyCount * perStoryInstallSeconds`
47
- * (default 45s, override via
48
- * `--per-story-install-seconds`). Models a
49
- * per-worktree `npm ci`.
50
- * - `githubApiRequests` = base 30 (snapshot + plan) +
51
- * `storyCount * perStoryApiRequests`
52
- * (default 25 — story-init + per-Task label
53
- * transitions + close-validation).
54
- * - `claudeQuotaTokens` = `storyCount * perStoryClaudeTokens`
55
- * (default 200000 — covers full Story loop
56
- * hydration + 4-Task implementation).
57
- *
58
- * Operators tune the per-Story constants on the CLI when their project's
59
- * empirical numbers diverge; the defaults are framework guidance, not
60
- * physics.
61
- */
62
-
63
- import { parseArgs } from 'node:util';
64
-
65
- import { runAsCli } from './lib/cli-utils.js';
66
- import { getPreflight, resolveConfig } from './lib/config-resolver.js';
67
- import { Logger } from './lib/Logger.js';
68
- import { runBuildWaveDagPhase } from './lib/orchestration/epic-runner/phases/build-wave-dag.js';
69
- import { runSnapshotPhase } from './lib/orchestration/epic-runner/phases/snapshot.js';
70
- import {
71
- computeBaseSha,
72
- writePreflightCache,
73
- } from './lib/orchestration/preflight-cache.js';
74
- import { verifyRemote } from './lib/orchestration/remote-verifier.js';
75
- import { upsertStructuredComment } from './lib/orchestration/ticketing.js';
76
- import { createProvider } from './lib/provider-factory.js';
77
-
78
- const HELP = `Usage: node .agents/scripts/epic-deliver-preflight.js \\
79
- --epic <epicId> [--dry-run] [--post] \\
80
- [--per-story-install-seconds <n>] \\
81
- [--per-story-api-requests <n>] \\
82
- [--per-story-claude-tokens <n>]
83
-
84
- Estimates Story count, install cost, wave count, GitHub API request volume,
85
- and Claude Max quota burn for an Epic *before* /deliver fan-out.
86
-
87
- Flags:
88
- --dry-run Compute the estimate and print the JSON
89
- envelope on stdout. Does NOT upsert the
90
- delivery-preflight comment.
91
- --post Upsert the delivery-preflight structured
92
- comment on the Epic ticket. Required when
93
- --dry-run is absent and the caller wants
94
- side effects on the ticket.
95
- --per-story-install-seconds <n> Override the per-Story install-cost
96
- constant (default 45).
97
- --per-story-api-requests <n> Override the per-Story API-request
98
- estimate (default 25).
99
- --per-story-claude-tokens <n> Override the per-Story Claude-token
100
- estimate (default 200000).
101
- --help Show this message.
102
-
103
- Output (stdout, always): JSON envelope with the estimate plus a 'breaches'
104
- array describing any \`delivery.preflight.max*\` thresholds the estimate
105
- exceeds. A non-empty 'breaches' array does NOT cause the CLI to exit
106
- non-zero — the slash-command workflow owns the agent::blocked transition.
107
-
108
- Exit codes:
109
- 0 — estimate computed; stdout carries the envelope.
110
- 1 — provider, config, or wave-DAG failure (no envelope written).
111
- `;
112
-
113
- const DEFAULTS = Object.freeze({
114
- perStoryInstallSeconds: 45,
115
- perStoryApiRequests: 25,
116
- perStoryClaudeTokens: 200_000,
117
- // Base GH API budget: snapshot getTicket + getSubTickets + plan/manifest
118
- // reads/writes that happen once per /deliver run regardless of
119
- // Story count. Empirical observation from a 5-Story Epic shows ~30
120
- // requests for the non-per-Story floor.
121
- baseApiRequests: 30,
122
- });
123
-
124
- /**
125
- * Pure estimate calculator. Exported for unit tests so the math is
126
- * exercised without spinning up a provider.
127
- *
128
- * @param {{
129
- * storyCount: number,
130
- * dependencyDepth: number,
131
- * perStoryInstallSeconds?: number,
132
- * perStoryApiRequests?: number,
133
- * perStoryClaudeTokens?: number,
134
- * baseApiRequests?: number,
135
- * }} input
136
- * @returns {{
137
- * storyCount: number,
138
- * installCostSeconds: number,
139
- * dependencyDepth: number,
140
- * githubApiRequests: number,
141
- * claudeQuotaTokens: number,
142
- * }}
143
- */
144
- export function computeEstimate({
145
- storyCount,
146
- dependencyDepth,
147
- perStoryInstallSeconds = DEFAULTS.perStoryInstallSeconds,
148
- perStoryApiRequests = DEFAULTS.perStoryApiRequests,
149
- perStoryClaudeTokens = DEFAULTS.perStoryClaudeTokens,
150
- baseApiRequests = DEFAULTS.baseApiRequests,
151
- }) {
152
- if (!Number.isInteger(storyCount) || storyCount < 0) {
153
- throw new TypeError(
154
- 'computeEstimate: storyCount must be a non-negative integer',
155
- );
156
- }
157
- if (!Number.isInteger(dependencyDepth) || dependencyDepth < 0) {
158
- throw new TypeError(
159
- 'computeEstimate: dependencyDepth must be a non-negative integer',
160
- );
161
- }
162
- return {
163
- storyCount,
164
- installCostSeconds: storyCount * perStoryInstallSeconds,
165
- dependencyDepth,
166
- githubApiRequests: baseApiRequests + storyCount * perStoryApiRequests,
167
- claudeQuotaTokens: storyCount * perStoryClaudeTokens,
168
- };
169
- }
170
-
171
- /**
172
- * Compare the estimate against the resolved `delivery.preflight.max*`
173
- * thresholds. A `null` floor is treated as "no cap" and skipped.
174
- *
175
- * @param {ReturnType<typeof computeEstimate>} estimate
176
- * @param {ReturnType<typeof getPreflight>} thresholds
177
- * @returns {Array<{ key: string, observed: number, max: number }>}
178
- */
179
- export function detectBreaches(estimate, thresholds) {
180
- const mapping = [
181
- { key: 'storyCount', observedKey: 'storyCount', maxKey: 'maxStories' },
182
- // Story #4155 — `dependencyDepth` replaces the retired `waveCount`
183
- // estimate; it is still gated by the `maxWaves` config threshold (the
184
- // published config key is left unchanged for contract stability).
185
- {
186
- key: 'dependencyDepth',
187
- observedKey: 'dependencyDepth',
188
- maxKey: 'maxWaves',
189
- },
190
- {
191
- key: 'installCostSeconds',
192
- observedKey: 'installCostSeconds',
193
- maxKey: 'maxInstallCostSeconds',
194
- },
195
- {
196
- key: 'githubApiRequests',
197
- observedKey: 'githubApiRequests',
198
- maxKey: 'maxGithubApiRequests',
199
- },
200
- {
201
- key: 'claudeQuotaTokens',
202
- observedKey: 'claudeQuotaTokens',
203
- maxKey: 'maxClaudeQuotaTokens',
204
- },
205
- ];
206
- const breaches = [];
207
- for (const m of mapping) {
208
- const max = thresholds[m.maxKey];
209
- if (max === null || max === undefined) continue;
210
- const observed = estimate[m.observedKey];
211
- if (observed > max) {
212
- breaches.push({ key: m.key, observed, max });
213
- }
214
- }
215
- return breaches;
216
- }
217
-
218
- /**
219
- * Render the markdown body of the `delivery-preflight` structured
220
- * comment. Pure helper — exported for tests.
221
- */
222
- export function renderPreflightBody({
223
- epicId,
224
- estimate,
225
- breaches,
226
- thresholds,
227
- remote,
228
- }) {
229
- const lines = [];
230
- lines.push(`### 🛫 Delivery preflight — Epic #${epicId}`);
231
- lines.push('');
232
- // Issue #4483 — verified remote evidence at entry. Rendered before the
233
- // metric table so a reviewer (and the orchestrating agent) sees the
234
- // land-or-block fact first. Omitted when the caller has no probe result
235
- // (legacy callers / tests that only exercise the estimate math).
236
- if (remote) {
237
- lines.push(
238
- remote.remoteVerified
239
- ? `✅ **remoteVerified: true** — ${remote.detail}`
240
- : `⛔ **remoteVerified: false** — ${remote.detail} — \`/deliver\` MUST transition the Epic to \`agent::blocked\` quoting this probe; inline delivery to local \`main\` is forbidden.`,
241
- );
242
- lines.push('');
243
- }
244
- lines.push('| Metric | Estimate | Threshold |');
245
- lines.push('| --- | ---: | ---: |');
246
- const rows = [
247
- ['storyCount', estimate.storyCount, thresholds.maxStories],
248
- ['dependencyDepth', estimate.dependencyDepth, thresholds.maxWaves],
249
- [
250
- 'installCostSeconds',
251
- estimate.installCostSeconds,
252
- thresholds.maxInstallCostSeconds,
253
- ],
254
- [
255
- 'githubApiRequests',
256
- estimate.githubApiRequests,
257
- thresholds.maxGithubApiRequests,
258
- ],
259
- [
260
- 'claudeQuotaTokens',
261
- estimate.claudeQuotaTokens,
262
- thresholds.maxClaudeQuotaTokens,
263
- ],
264
- ];
265
- for (const [k, v, t] of rows) {
266
- lines.push(`| ${k} | ${v} | ${t == null ? '—' : t} |`);
267
- }
268
- lines.push('');
269
- if (breaches.length === 0) {
270
- lines.push(
271
- '✅ All metrics within configured `delivery.preflight.*` thresholds.',
272
- );
273
- } else {
274
- lines.push(
275
- '⛔ **Threshold breaches** — `/deliver` will flip the Epic to `agent::blocked` for operator review:',
276
- );
277
- for (const b of breaches) {
278
- lines.push(`- \`${b.key}\` = ${b.observed} (max ${b.max})`);
279
- }
280
- }
281
- return lines.join('\n');
282
- }
283
-
284
- /**
285
- * End-to-end preflight. DI-friendly so tests can swap the provider and
286
- * config without shelling out.
287
- *
288
- * @param {{
289
- * epicId: number,
290
- * dryRun?: boolean,
291
- * post?: boolean,
292
- * cwd?: string,
293
- * perStoryInstallSeconds?: number,
294
- * perStoryApiRequests?: number,
295
- * perStoryClaudeTokens?: number,
296
- * injectedProvider?: object,
297
- * injectedConfig?: object,
298
- * verifyRemoteFn?: typeof verifyRemote,
299
- * }} args
300
- */
301
- export async function runPreflight({
302
- epicId,
303
- dryRun = false,
304
- post = false,
305
- cwd,
306
- perStoryInstallSeconds,
307
- perStoryApiRequests,
308
- perStoryClaudeTokens,
309
- injectedProvider,
310
- injectedConfig,
311
- verifyRemoteFn = verifyRemote,
312
- }) {
313
- if (!Number.isInteger(epicId) || epicId <= 0) {
314
- throw new TypeError('runPreflight: --epic must be a positive integer');
315
- }
316
-
317
- const config = injectedConfig ?? resolveConfig({ cwd });
318
- const provider = injectedProvider ?? createProvider(config);
319
- const thresholds = getPreflight(config);
320
-
321
- // Issue #4483 — deterministic remote evidence at entry. Probe BEFORE any
322
- // provider work so the envelope always carries verified fact (not the
323
- // agent's perception) about whether a live, pushable `origin` exists.
324
- // The CLI records; the `/deliver` workflow owns the `agent::blocked`
325
- // transition on `remoteVerified: false` (same split as breach handling).
326
- const remote = verifyRemoteFn({ cwd });
327
-
328
- // Compose the same two phases /deliver Phase 1 runs so the
329
- // preflight numbers match the actual dispatch plan.
330
- const ctx = { epicId, provider };
331
- let state = {};
332
- state = await runSnapshotPhase(ctx, {}, state);
333
- state = await runBuildWaveDagPhase(ctx, {}, state);
334
-
335
- const storyCount = Array.isArray(state.stories) ? state.stories.length : 0;
336
- // Dependency depth = the dependency-DAG layer count (the longest chain of
337
- // `blocked by` edges). `runBuildWaveDagPhase` already computes this layering
338
- // as `state.waves`, so its length is the depth even though the ready-set
339
- // runtime no longer dispatches by wave (Story #4155).
340
- const dependencyDepth = Array.isArray(state.waves) ? state.waves.length : 0;
341
-
342
- // Persist the snapshot/DAG envelope so `epic-deliver-prepare.js` can
343
- // reuse it instead of re-walking the hierarchy. The cache key is a
344
- // deterministic fingerprint of the Epic ticket returned by the same
345
- // `getTicket(epicId)` call that drove `runSnapshotPhase` **plus** the
346
- // Story snapshots that drove the wave DAG (Story #4019), so any drift —
347
- // Epic label/body/updatedAt or a Story-dependency edit — forces a cache
348
- // miss in prepare.
349
- const baseSha = computeBaseSha(state.epic, state.stories);
350
- let cacheWritten = false;
351
- if (!dryRun) {
352
- await writePreflightCache({
353
- epicId,
354
- baseSha,
355
- epic: state.epic,
356
- stories: state.stories,
357
- waves: state.waves,
358
- cwd,
359
- });
360
- cacheWritten = true;
361
- }
362
-
363
- const estimate = computeEstimate({
364
- storyCount,
365
- dependencyDepth,
366
- perStoryInstallSeconds,
367
- perStoryApiRequests,
368
- perStoryClaudeTokens,
369
- });
370
- const breaches = detectBreaches(estimate, thresholds);
371
-
372
- const envelope = {
373
- epicId,
374
- ...estimate,
375
- breaches,
376
- thresholds,
377
- baseSha,
378
- cacheWritten,
379
- // Issue #4483 — verified remote evidence. `remoteVerified: false`
380
- // REQUIRES the workflow to block explicitly (never build inline).
381
- remoteVerified: remote.remoteVerified,
382
- remoteProbe: {
383
- remoteUrl: remote.remoteUrl,
384
- detail: remote.detail,
385
- },
386
- };
387
-
388
- if (post && !dryRun) {
389
- const body = renderPreflightBody({
390
- epicId,
391
- estimate,
392
- breaches,
393
- thresholds,
394
- remote,
395
- });
396
- await upsertStructuredComment(provider, epicId, 'delivery-preflight', body);
397
- envelope.commentUpserted = true;
398
- } else {
399
- envelope.commentUpserted = false;
400
- }
401
- return envelope;
402
- }
403
-
404
- export function parseArgv(argv) {
405
- const { values } = parseArgs({
406
- args: argv,
407
- options: {
408
- epic: { type: 'string' },
409
- 'dry-run': { type: 'boolean' },
410
- post: { type: 'boolean' },
411
- 'per-story-install-seconds': { type: 'string' },
412
- 'per-story-api-requests': { type: 'string' },
413
- 'per-story-claude-tokens': { type: 'string' },
414
- help: { type: 'boolean', short: 'h' },
415
- },
416
- strict: false,
417
- });
418
- return values;
419
- }
420
-
421
- function parseIntOrDefault(raw) {
422
- if (raw == null) return undefined;
423
- const n = Number.parseInt(raw, 10);
424
- if (!Number.isInteger(n) || n < 0) {
425
- throw new RangeError(
426
- `expected non-negative integer, got ${JSON.stringify(raw)}`,
427
- );
428
- }
429
- return n;
430
- }
431
-
432
- export async function main(argv = process.argv.slice(2)) {
433
- const values = parseArgv(argv);
434
- if (values.help) {
435
- process.stdout.write(HELP);
436
- return;
437
- }
438
- const epicId = Number.parseInt(values.epic ?? '', 10);
439
- if (!Number.isInteger(epicId) || epicId <= 0) {
440
- process.stderr.write(
441
- '[epic-deliver-preflight] ERROR: --epic <epicId> is required.\n',
442
- );
443
- process.stderr.write(HELP);
444
- process.exit(2);
445
- }
446
- const envelope = await runPreflight({
447
- epicId,
448
- dryRun: values['dry-run'] === true,
449
- post: values.post === true,
450
- perStoryInstallSeconds: parseIntOrDefault(
451
- values['per-story-install-seconds'],
452
- ),
453
- perStoryApiRequests: parseIntOrDefault(values['per-story-api-requests']),
454
- perStoryClaudeTokens: parseIntOrDefault(values['per-story-claude-tokens']),
455
- });
456
- Logger.info(JSON.stringify(envelope, null, 2));
457
- }
458
-
459
- // Re-export for tests that want to inspect the framework defaults.
460
- export const PREFLIGHT_DEFAULTS = DEFAULTS;
461
-
462
- runAsCli(import.meta.url, main, { source: 'epic-deliver-preflight' });