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,17 +1,17 @@
1
1
  /**
2
2
  * story-init-not-backgrounded — refuse-and-print check.
3
3
  *
4
- * Detects orchestration call sites that invoke `story-init.js` via the
5
- * Bash tool's `run_in_background: true` mode (with subsequent `Monitor`
4
+ * Detects orchestration call sites that invoke `single-story-init.js` via
5
+ * the Bash tool's `run_in_background: true` mode (with subsequent `Monitor`
6
6
  * waiting on completion) instead of a synchronous Bash call with a
7
7
  * 10-minute timeout. This guards the failure mode where `Monitor`'s wait
8
8
  * is not equivalent to script exit — a sub-agent that exits during a
9
- * Monitor wait kills `story-init.js` mid-batch, leaving a half-initialized
10
- * worktree and a failed wave aggregator.
9
+ * Monitor wait kills `single-story-init.js` mid-run, leaving a
10
+ * half-initialized worktree.
11
11
  *
12
12
  * Scope: 'epic-deliver', 'story-close', 'retro'. The check runs at every
13
- * preflight surface that has the opportunity to invoke story-init —
14
- * primarily `epic-deliver`'s wave loop — and surfaces as a retro audit
13
+ * preflight surface that has the opportunity to invoke Story init —
14
+ * primarily `/deliver`'s init step — and surfaces as a retro audit
15
15
  * signal if the failure mode resurfaces during a sprint.
16
16
  *
17
17
  * The check is `refuse-and-print`. Auto-rewriting an orchestration call
@@ -20,7 +20,8 @@
20
20
  * synchronous-call replacement pattern so they can apply it deliberately.
21
21
  *
22
22
  * Implementation note: we scan `.agents/` (markdown + js) for the
23
- * juxtaposition of a `story-init.js` reference and a backgrounding token
23
+ * juxtaposition of a `story-init.js` reference (which also matches
24
+ * `single-story-init.js` as a suffix) and a backgrounding token
24
25
  * (`run_in_background: true`, the literal `Monitor` tool name as a
25
26
  * fan-out target, or `&` shell backgrounding) within a small line window.
26
27
  */
@@ -39,7 +40,8 @@ const WINDOW_LINES = 20;
39
40
  * - `run_in_background: true` — Bash tool's backgrounding flag.
40
41
  * - `detached: true` — child_process.spawn options that detach the
41
42
  * subprocess from the parent's lifecycle, equivalent to backgrounding.
42
- * - `story-init.js &` — POSIX shell ampersand backgrounding.
43
+ * - `single-story-init.js &` — POSIX shell ampersand backgrounding
44
+ * (the pattern matches the `story-init.js` suffix of both names).
43
45
  */
44
46
  const BACKGROUND_TOKENS = [
45
47
  /run_in_background\s*:\s*true/,
@@ -85,12 +87,12 @@ function walkSources(dir) {
85
87
 
86
88
  /**
87
89
  * For one file, return an array of `{ line, kind }` offences: every line
88
- * referencing `story-init.js` that has a backgrounding token in the same
89
- * ±WINDOW_LINES window.
90
+ * referencing `story-init.js` (including `single-story-init.js`) that has
91
+ * a backgrounding token in the same ±WINDOW_LINES window.
90
92
  *
91
- * The check explicitly excludes the `story-init.js` file itself and any
92
- * dedicated check module (this file): the source-of-truth implementation
93
- * legitimately mentions itself.
93
+ * The check explicitly excludes the `single-story-init.js` file itself and
94
+ * any dedicated check module (this file): the source-of-truth
95
+ * implementation legitimately mentions itself.
94
96
  *
95
97
  * @param {string} file
96
98
  * @param {string} src
@@ -100,12 +102,12 @@ function scanFile(file, src) {
100
102
  const offences = [];
101
103
  // Don't flag the actual story-init script, self-references, or the
102
104
  // parallel-tooling helper — the helper documents both Rule 2
103
- // (run_in_background) and the story-init.js anti-pattern in adjacent
104
- // bullets, which collides with the scanner's ±20-line window even
105
- // though there is no real invocation in the prose.
105
+ // (run_in_background) and the story-init backgrounding anti-pattern in
106
+ // adjacent bullets, which collides with the scanner's ±20-line window
107
+ // even though there is no real invocation in the prose.
106
108
  const basename = path.basename(file);
107
109
  if (
108
- basename === 'story-init.js' ||
110
+ basename === 'single-story-init.js' ||
109
111
  basename === 'story-init-not-backgrounded.js' ||
110
112
  basename === 'story-init-not-backgrounded.test.js' ||
111
113
  basename === 'parallel-tooling.md'
@@ -129,13 +131,13 @@ function scanFile(file, src) {
129
131
  }
130
132
 
131
133
  const FIX_COMMAND = [
132
- '# Invoke story-init.js synchronously with a 10-minute timeout. The',
133
- '# script is idempotent on partial state, so re-running after a',
134
+ '# Invoke single-story-init.js synchronously with a 10-minute timeout.',
135
+ '# The script is idempotent on partial state, so re-running after a',
134
136
  '# half-initialized worktree is safe — but blocking on the Bash call',
135
137
  '# is what prevents the half-init state in the first place.',
136
138
  '#',
137
139
  '# Replacement pattern (Bash tool):',
138
- '# Bash(timeout: 600000, command: "node .agents/scripts/story-init.js --story <id>")',
140
+ '# Bash(timeout: 600000, command: "node .agents/scripts/single-story-init.js --story <id>")',
139
141
  '#',
140
142
  '# Do NOT use:',
141
143
  '# Bash(run_in_background: true, ...) + Monitor(...)',
@@ -177,7 +179,7 @@ export default {
177
179
  id: 'story-init-not-backgrounded',
178
180
  severity: 'blocker',
179
181
  scope: state?.scope ?? 'epic-deliver',
180
- summary: `${offences.length} orchestration call site(s) invoke story-init.js with Monitor backgrounding`,
182
+ summary: `${offences.length} orchestration call site(s) invoke single-story-init.js with Monitor backgrounding`,
181
183
  detail,
182
184
  fixCommand: FIX_COMMAND,
183
185
  autoCorrectable: false,
@@ -13,7 +13,6 @@
13
13
  *
14
14
  * Contract
15
15
  * --------
16
- * parseStandardCliArgs(argv, schema?) → { values, positionals }
17
16
  * parseStandardCliArgs({ argv, schema?, extras? }) → { values, positionals }
18
17
  *
19
18
  * - `argv` — `process.argv.slice(2)` shape; the helper does NOT strip
@@ -99,24 +98,20 @@ function camelCase(name) {
99
98
  }
100
99
 
101
100
  /**
102
- * Normalize the call signature. Accepts either positional
103
- * `(argv, schema)` (backward compat) or the object form
104
- * `({ argv, schema, extras })`.
101
+ * Validate the call signature. Only the object form
102
+ * `({ argv, schema, extras })` is accepted.
105
103
  *
106
- * @param {unknown} argvOrOpts
107
- * @param {unknown} maybeSchema
104
+ * @param {unknown} opts
108
105
  * @returns {{ argv: string[], schema: object | undefined, extras: object | undefined }}
109
106
  */
110
- function normaliseCallSignature(argvOrOpts, maybeSchema) {
111
- if (
112
- argvOrOpts !== null &&
113
- typeof argvOrOpts === 'object' &&
114
- !Array.isArray(argvOrOpts)
115
- ) {
116
- const { argv, schema, extras } = argvOrOpts;
117
- return { argv: argv ?? [], schema, extras };
107
+ function normaliseCallSignature(opts) {
108
+ if (opts === null || typeof opts !== 'object' || Array.isArray(opts)) {
109
+ throw new Error(
110
+ 'parseStandardCliArgs: options must be a plain object ({ argv, schema?, extras? })',
111
+ );
118
112
  }
119
- return { argv: argvOrOpts ?? [], schema: maybeSchema, extras: undefined };
113
+ const { argv, schema, extras } = opts;
114
+ return { argv: argv ?? [], schema, extras };
120
115
  }
121
116
 
122
117
  /**
@@ -313,15 +308,11 @@ function normaliseValues(raw, extras) {
313
308
  * Parse the dispatcher's shared CLI flag surface. See module docstring
314
309
  * for the full contract.
315
310
  *
316
- * @param {string[]|{argv?: string[], schema?: object, extras?: object}} argvOrOpts
317
- * @param {Record<string, { required?: boolean }>} [maybeSchema]
311
+ * @param {{ argv?: string[], schema?: object, extras?: object }} [opts]
318
312
  * @returns {{ values: Record<string, unknown>, positionals: string[] }}
319
313
  */
320
- export function parseStandardCliArgs(argvOrOpts = [], maybeSchema) {
321
- const { argv, schema, extras } = normaliseCallSignature(
322
- argvOrOpts,
323
- maybeSchema,
324
- );
314
+ export function parseStandardCliArgs(opts = {}) {
315
+ const { argv, schema, extras } = normaliseCallSignature(opts);
325
316
  if (!Array.isArray(argv)) {
326
317
  throw new Error('parseStandardCliArgs: argv must be an array');
327
318
  }
@@ -40,6 +40,12 @@ function coerceBooleanFlag(value) {
40
40
  return Boolean(value);
41
41
  }
42
42
 
43
+ /** Like coerceBooleanFlag, but preserves `undefined` (flag absent). */
44
+ function optionalBooleanFlag(value) {
45
+ if (value === undefined) return undefined;
46
+ return coerceBooleanFlag(value);
47
+ }
48
+
43
49
  /**
44
50
  * Standardized CLI argument parser for sprint scripts.
45
51
  * Supports options like --epic, --story, --dry-run, --skip-dashboard.
@@ -58,7 +64,8 @@ export function parseSprintArgs(args = process.argv) {
58
64
  'skip-sync': { type: 'boolean', default: false },
59
65
  'no-auto-merge': { type: 'boolean', default: false },
60
66
  'no-full-scope-crap': { type: 'boolean', default: false },
61
- 'wait-merge': { type: 'boolean', default: false },
67
+ // No default absent means "use delivery.routing.closeAndLand".
68
+ 'wait-merge': { type: 'boolean' },
62
69
  'no-wait-merge': { type: 'boolean', default: false },
63
70
  executor: { type: 'string' },
64
71
  cwd: { type: 'string' },
@@ -81,11 +88,11 @@ export function parseSprintArgs(args = process.argv) {
81
88
  skipSync: coerceBooleanFlag(values['skip-sync']),
82
89
  noAutoMerge: coerceBooleanFlag(values['no-auto-merge']),
83
90
  noFullScopeCrap: coerceBooleanFlag(values['no-full-scope-crap']),
84
- // Story #4428 — headless must-land signal for `single-story-close.js`:
85
- // `--wait-merge` opts a headless run into polling to merge confirmation
86
- // instead of resting at `agent::closing`; `--no-wait-merge` is the
87
- // explicit opt-out (see `single-story-close/phases/options.js`).
88
- waitForMerge: coerceBooleanFlag(values['wait-merge']),
91
+ // Close-and-land: `--wait-merge` forces land-in-close; `--no-wait-merge`
92
+ // opts out. When neither flag is present (`undefined`),
93
+ // `parseCloseOptions` applies `delivery.routing.closeAndLand` (default
94
+ // true) so attended and headless delivers share the same happy path.
95
+ waitForMerge: optionalBooleanFlag(values['wait-merge']),
89
96
  noWaitForMerge: coerceBooleanFlag(values['no-wait-merge']),
90
97
  executor: values.executor ?? null,
91
98
  // Resolve worktree cwd from flag or env. Empty string/whitespace → null.
@@ -95,7 +102,9 @@ export function parseSprintArgs(args = process.argv) {
95
102
  null,
96
103
  recutOf: parseTicketId(values['recut-of']),
97
104
  // Story #4253: pre-resolved Epic linkage threaded by the /deliver
98
- // fan-out so `story-init.js` can skip the per-Story `getEpic` round-trip.
105
+ // fan-out so `single-story-init.js` can skip redundant Epic lookups when
106
+ // the parent already threaded Epic context (pre-v2; field retained for
107
+ // CLI compatibility).
99
108
  resume: values.resume ?? false,
100
109
  restart: values.restart ?? false,
101
110
  noEvidence: values['no-evidence'] ?? false,
@@ -6,7 +6,12 @@
6
6
  * runner (`INDEPENDENT_GATE_NAMES` / `partitionGates`).
7
7
  */
8
8
 
9
+ import { existsSync } from 'node:fs';
10
+
11
+ import { _internals as baselineReaderInternals } from '../baselines/reader.js';
12
+ import { getQuality } from '../config/quality.js';
9
13
  import { hasNpmScript, readPackageScripts } from '../npm-scripts.js';
14
+ import { KNOWN_KINDS } from '../orchestration/check-baselines/phases/parse-args.js';
10
15
  import {
11
16
  buildFormatHint,
12
17
  FORMAT_CHECK_FALLBACK,
@@ -115,6 +120,106 @@ function buildTestGateEntry(coverageCaptureActive) {
115
120
  return [{ name: 'test', cmd: 'npm', args: ['test'] }];
116
121
  }
117
122
 
123
+ const CHECK_BASELINES_HINT =
124
+ 'Unified baselines gate breached. Inspect the JSON report (`node .agents/scripts/check-baselines.js`) to see which kind/component/axis fell below floor; remediate the underlying file(s) or — when the regression is intentional — refresh the relevant baseline through its per-kind update script and commit with a `baseline-refresh:` tagged subject.';
125
+
126
+ /**
127
+ * Baseline kinds the resolved config enables for the unified
128
+ * `check-baselines` gate. Mirrors `selectEnabledGates` in the check-baselines
129
+ * pipeline (a kind runs when its `gates.<kind>` block is present and not
130
+ * explicitly disabled) so the registration probe's view of "what will run"
131
+ * matches the gate's own view exactly.
132
+ *
133
+ * @param {object|undefined|null} config canonical resolved config
134
+ * @returns {string[]}
135
+ */
136
+ function enabledBaselineKinds(config) {
137
+ const gates = getQuality(config)?.gates ?? {};
138
+ return KNOWN_KINDS.filter((kind) => {
139
+ const block = gates[kind];
140
+ return block && typeof block === 'object' && block.enabled !== false;
141
+ });
142
+ }
143
+
144
+ /**
145
+ * Whether the consumer opted into fail-closed baseline enforcement via
146
+ * `delivery.quality.requireBaselines: true`. Default false — a consumer that
147
+ * enables baseline gates but has not committed baseline artifacts gets a
148
+ * clean skip (see `probeBaselinesGate`) rather than a deterministic first-try
149
+ * close failure. Fail-closed baseline posture (#4495).
150
+ *
151
+ * @param {object|undefined|null} config
152
+ * @returns {boolean}
153
+ */
154
+ function baselinesRequiredByConfig(config) {
155
+ return config?.delivery?.quality?.requireBaselines === true;
156
+ }
157
+
158
+ function toKindSet(presentBaselines) {
159
+ if (presentBaselines instanceof Set) return presentBaselines;
160
+ if (Array.isArray(presentBaselines)) return new Set(presentBaselines);
161
+ return new Set();
162
+ }
163
+
164
+ /**
165
+ * Probe whether the `check-baselines` consumer contract is satisfied before
166
+ * registering the gate (#4495 — mirrors the #4473/#4480 coverage-capture
167
+ * remedy). The contract: every enabled baseline kind carries a committed
168
+ * baseline artifact on disk (the same path the gate's reader resolves).
169
+ *
170
+ * Decision shape:
171
+ * - `{ register: false, reason }` — skip (caller logs the reason). Baseline
172
+ * gates ARE enabled but none of the enabled kinds carry a committed
173
+ * baseline artifact and the consumer has not set `requireBaselines`. This
174
+ * is the bench/greenfield case: the gate would otherwise fail
175
+ * deterministically on first try reading a non-existent
176
+ * `baselines/<kind>.json`.
177
+ * - `{ register: true }` — at least one committed baseline artifact is
178
+ * present, OR no baseline kinds are enabled at all (the gate then self-
179
+ * skips every kind and exits a clean empty PASS — no failure to avoid, so
180
+ * the gate stays registered exactly as pre-#4495); run the gate.
181
+ * - `{ register: true, hint }` — baselines are required-by-config
182
+ * (`requireBaselines: true`) but absent; keep the gate registered so it
183
+ * fails, with a preflight hint naming the fix.
184
+ *
185
+ * @param {{ config?: object, cwd?: string, presentBaselines?: string[]|Set<string> }} opts
186
+ * `presentBaselines` injects the set of kinds whose baseline artifact
187
+ * exists (tests), short-circuiting the on-disk probe.
188
+ * @returns {{ register: boolean, reason?: string, hint?: string }}
189
+ */
190
+ function probeBaselinesGate({ config, cwd, presentBaselines } = {}) {
191
+ const enabled = enabledBaselineKinds(config);
192
+ if (enabled.length === 0) {
193
+ // No enabled baseline kinds → `check-baselines.js` self-skips every kind
194
+ // and exits clean (an empty PASS). There is no deterministic-failure risk
195
+ // to avoid, so keep the gate registered exactly as it was pre-#4495; the
196
+ // #4495 skip is confined strictly to the read-miss-would-fail case below.
197
+ return { register: true };
198
+ }
199
+ const injected =
200
+ presentBaselines != null ? toKindSet(presentBaselines) : null;
201
+ const present = enabled.filter((kind) =>
202
+ injected
203
+ ? injected.has(kind)
204
+ : existsSync(baselineReaderInternals.resolveBaselinePath(kind, { cwd })),
205
+ );
206
+ if (present.length > 0) return { register: true };
207
+ if (baselinesRequiredByConfig(config)) {
208
+ return {
209
+ register: true,
210
+ hint:
211
+ `Baselines are required (delivery.quality.requireBaselines) but no committed baseline artifact was found for enabled kind(s): ${enabled.join(', ')}. ` +
212
+ 'Generate the baseline(s) with the per-kind update script (e.g. `npm run crap:update`, `npm run maintainability:update`) and commit them, or unset requireBaselines to skip the gate until baselines exist.',
213
+ };
214
+ }
215
+ return {
216
+ register: false,
217
+ reason:
218
+ `check-baselines skipped — enabled kind(s) ${enabled.join(', ')} have no committed baseline artifact under baselines/ ` +
219
+ 'and delivery.quality.requireBaselines is not set. Commit baseline artifacts (or set requireBaselines to enforce them) to activate the gate.',
220
+ };
221
+ }
222
+
118
223
  /**
119
224
  * Build the canonical close-validation gate list.
120
225
  *
@@ -152,15 +257,30 @@ function buildTestGateEntry(coverageCaptureActive) {
152
257
  * instead of a deterministic close failure with no test gate at all. The
153
258
  * probe reads `package.json` at `cwd` (the gate execution directory).
154
259
  *
155
- * @param {{ config?: object, epicBranch?: string, cwd?: string, packageScripts?: Record<string, string> }} [opts]
260
+ * Story #4495 the unified `check-baselines` gate reads a committed
261
+ * `baselines/<kind>.json` for each enabled kind; a consumer that enables
262
+ * baseline gates but ships no `baselines/` tree (every bench sandbox, any
263
+ * greenfield consumer) failed the gate deterministically on first try. The
264
+ * gate is now registered only when its consumer contract is satisfied
265
+ * (`probeBaselinesGate`): at least one enabled kind carries a committed
266
+ * baseline, OR the consumer opted into fail-closed enforcement via
267
+ * `delivery.quality.requireBaselines`. When no baselines are committed and
268
+ * none are required, the gate is skipped with a logged reason (via `log`)
269
+ * instead of a blocking failure.
270
+ *
271
+ * @param {{ config?: object, epicBranch?: string, cwd?: string, packageScripts?: Record<string, string>, presentBaselines?: string[]|Set<string>, log?: (message: string) => void }} [opts]
156
272
  * `config` is the canonical resolved config (`{ project, delivery, ... }`);
157
273
  * gate commands resolve from `project.commands` and the CRAP toggle from
158
274
  * `delivery.quality.gates.crap.enabled`. `epicBranch` is the close run's
159
275
  * integration branch (`epic/<id>` for Epic-attached Stories, the base
160
276
  * branch for standalone Stories). `cwd` is where the `package.json`
161
- * coverage-script probe reads from (defaults to `process.cwd()`);
162
- * `packageScripts` injects the scripts map directly (tests) and short-
163
- * circuits the disk read.
277
+ * coverage-script probe and the `baselines/<kind>.json` presence probe
278
+ * read from (defaults to `process.cwd()`); `packageScripts` injects the
279
+ * scripts map directly (tests) and short-circuits the coverage-script disk
280
+ * read; `presentBaselines` injects the set of kinds whose baseline artifact
281
+ * exists (tests) and short-circuits the baseline-presence disk read; `log`
282
+ * receives the skip reason when the `check-baselines` gate is not
283
+ * registered.
164
284
  * @returns {Gate[]}
165
285
  */
166
286
  export function buildDefaultGates({
@@ -168,6 +288,8 @@ export function buildDefaultGates({
168
288
  epicBranch,
169
289
  cwd,
170
290
  packageScripts,
291
+ presentBaselines,
292
+ log,
171
293
  } = {}) {
172
294
  const scripts = packageScripts ?? readPackageScripts(cwd);
173
295
  const coverageCaptureActive =
@@ -186,6 +308,14 @@ export function buildDefaultGates({
186
308
  ? buildChangedFileScope(epicBranch)
187
309
  : null;
188
310
  const baselinesGateEnv = buildBaselinesGateEnv(epicBranch);
311
+ const baselinesDecision = probeBaselinesGate({
312
+ config,
313
+ cwd,
314
+ presentBaselines,
315
+ });
316
+ if (!baselinesDecision.register && baselinesDecision.reason) {
317
+ log?.(`[close-validation] ${baselinesDecision.reason}`);
318
+ }
189
319
  return [
190
320
  {
191
321
  name: 'typecheck',
@@ -218,30 +348,38 @@ export function buildDefaultGates({
218
348
  },
219
349
  ]
220
350
  : []),
221
- {
222
- // Story #2210 unified `check-baselines` gate is the only path for
223
- // per-kind regression enforcement. The legacy per-kind in-process
224
- // gates were retired because their regression-compare semantics are
225
- // fully subsumed by this gate's attribution-wired floor + tolerance +
226
- // schema enforcement, and running both paths in series was redundant
227
- // and conflict-prone.
228
- //
229
- // `check-baselines.js` self-skips per-kind gates whose
230
- // `enabled === false` is configured, so registering it
231
- // unconditionally is safe.
232
- name: 'check-baselines',
233
- cmd: 'node',
234
- args: ['.agents/scripts/check-baselines.js', '--format', 'text'],
235
- hint: 'Unified baselines gate breached. Inspect the JSON report (`node .agents/scripts/check-baselines.js`) to see which kind/component/axis fell below floor; remediate the underlying file(s) or — when the regression is intentional — refresh the relevant baseline through its per-kind update script and commit with a `baseline-refresh:` tagged subject.',
236
- ...(baselinesGateEnv ? { env: baselinesGateEnv } : {}),
237
- },
351
+ // Story #2210 — unified `check-baselines` gate is the only path for
352
+ // per-kind regression enforcement. The legacy per-kind in-process gates
353
+ // were retired because their regression-compare semantics are fully
354
+ // subsumed by this gate's attribution-wired floor + tolerance + schema
355
+ // enforcement, and running both paths in series was redundant and
356
+ // conflict-prone.
357
+ //
358
+ // `check-baselines.js` self-skips per-kind gates whose `enabled === false`
359
+ // is configured. Story #4495: it is now also skipped entirely when the
360
+ // consumer enables baseline gates but ships no committed baseline artifact
361
+ // (and has not set `delivery.quality.requireBaselines`) — otherwise the
362
+ // gate fails deterministically on first try reading a non-existent
363
+ // `baselines/<kind>.json` (`probeBaselinesGate`). When required-by-config
364
+ // but absent, it stays registered with a preflight hint naming the fix.
365
+ ...(baselinesDecision.register
366
+ ? [
367
+ {
368
+ name: 'check-baselines',
369
+ cmd: 'node',
370
+ args: ['.agents/scripts/check-baselines.js', '--format', 'text'],
371
+ hint: baselinesDecision.hint ?? CHECK_BASELINES_HINT,
372
+ ...(baselinesGateEnv ? { env: baselinesGateEnv } : {}),
373
+ },
374
+ ]
375
+ : []),
238
376
  ];
239
377
  }
240
378
 
241
379
  /**
242
380
  * Default gate list resolved with no consumer config — uses the
243
381
  * `npm run typecheck` fallback for the typecheck gate. Call sites that have a
244
- * resolved config object in scope (e.g. `story-close.js`) should
382
+ * resolved config object in scope (e.g. `single-story-close.js`) should
245
383
  * prefer `buildDefaultGates({ config })` so a configured
246
384
  * `project.commands.typecheck` is honoured.
247
385
  *
@@ -38,6 +38,7 @@
38
38
  */
39
39
  export const ACCEPTANCE_EVAL_DEFAULTS = Object.freeze({
40
40
  maxRounds: 2,
41
+ clusterCeiling: 4,
41
42
  });
42
43
 
43
44
  /**
@@ -50,6 +51,22 @@ export const ACCEPTANCE_EVAL_DEFAULTS = Object.freeze({
50
51
  */
51
52
  export const ACCEPTANCE_EVAL_MAX_ROUNDS_CEILING = 5;
52
53
 
54
+ /**
55
+ * Hard, undisableable ceiling on `clusterCeiling` — the max ACs one
56
+ * single-delivery acceptance critic scores in a single fresh-context pass
57
+ * (Epic #4475, M4-B, design §S2a). It is the **acceptance-dilution guard**:
58
+ * single delivery collapses the whole Epic into one session, so the only
59
+ * acceptance coverage left is the per-AC-cluster critic fan-out
60
+ * (`ceil(totalACs / clusterCeiling)` independent maker-blind passes). A
61
+ * pathologically large `clusterCeiling` would collapse that fan-out to a
62
+ * single critic scoring every AC at once — exactly the dilution the design
63
+ * forecloses — so a configured value above this ceiling is clamped down to
64
+ * it. Kept small on purpose.
65
+ *
66
+ * @type {number}
67
+ */
68
+ export const ACCEPTANCE_EVAL_CLUSTER_CEILING_MAX = 8;
69
+
53
70
  /**
54
71
  * Clamp a candidate round count into the inviolable `[1, ceiling]` range.
55
72
  * Non-integer / non-finite inputs fall back to the documented default.
@@ -68,19 +85,43 @@ function clampRounds(value, fallback) {
68
85
  return candidate;
69
86
  }
70
87
 
88
+ /**
89
+ * Clamp a candidate cluster ceiling into the inviolable
90
+ * `[1, ACCEPTANCE_EVAL_CLUSTER_CEILING_MAX]` range. Non-integer / non-finite
91
+ * inputs fall back to the documented default. Mirrors `clampRounds` — the
92
+ * anti-dilution guard cannot be disabled (`clusterCeiling: 0` or a negative
93
+ * clamps up to 1; an over-max value clamps down to the hard cap).
94
+ *
95
+ * @param {unknown} value
96
+ * @param {number} fallback
97
+ * @returns {number}
98
+ */
99
+ function clampClusterCeiling(value, fallback) {
100
+ const candidate =
101
+ typeof value === 'number' && Number.isInteger(value) ? value : fallback;
102
+ if (candidate < 1) return 1;
103
+ if (candidate > ACCEPTANCE_EVAL_CLUSTER_CEILING_MAX) {
104
+ return ACCEPTANCE_EVAL_CLUSTER_CEILING_MAX;
105
+ }
106
+ return candidate;
107
+ }
108
+
71
109
  /**
72
110
  * Read the merged acceptance-eval block. Returns the canonical shape:
73
111
  *
74
112
  * {
75
- * maxRounds: number, // clamped into [1, ceiling]
76
- * ceiling: number, // the undisableable hard cap
113
+ * maxRounds: number, // clamped into [1, roundsCeiling]
114
+ * ceiling: number, // the undisableable hard cap on rounds
115
+ * clusterCeiling: number, // clamped into [1, clusterCeilingMax]
116
+ * clusterCeilingMax: number // the undisableable hard cap on cluster size
77
117
  * }
78
118
  *
79
- * `maxRounds` is always a positive integer no greater than `ceiling`,
80
- * regardless of what the resolved config carried.
119
+ * `maxRounds` is always a positive integer no greater than `ceiling`;
120
+ * `clusterCeiling` is always a positive integer no greater than
121
+ * `clusterCeilingMax`, regardless of what the resolved config carried.
81
122
  *
82
123
  * @param {object | null | undefined} config
83
- * @returns {{ maxRounds: number, ceiling: number }}
124
+ * @returns {{ maxRounds: number, ceiling: number, clusterCeiling: number, clusterCeilingMax: number }}
84
125
  */
85
126
  export function getAcceptanceEval(config) {
86
127
  const user = config?.delivery?.acceptanceEval ?? {};
@@ -88,8 +129,14 @@ export function getAcceptanceEval(config) {
88
129
  user.maxRounds,
89
130
  ACCEPTANCE_EVAL_DEFAULTS.maxRounds,
90
131
  );
132
+ const clusterCeiling = clampClusterCeiling(
133
+ user.clusterCeiling,
134
+ ACCEPTANCE_EVAL_DEFAULTS.clusterCeiling,
135
+ );
91
136
  return {
92
137
  maxRounds,
93
138
  ceiling: ACCEPTANCE_EVAL_MAX_ROUNDS_CEILING,
139
+ clusterCeiling,
140
+ clusterCeilingMax: ACCEPTANCE_EVAL_CLUSTER_CEILING_MAX,
94
141
  };
95
142
  }
@@ -1,30 +1,17 @@
1
1
  /**
2
- * `delivery.ci` accessor + framework defaults — Story #2899 (Epic #2880, F13)
3
- * and Story #4356 (Epic #4355).
2
+ * `delivery.ci` accessor + framework defaults — Story #4356 (Epic #4355).
4
3
  *
5
- * `delivery.ci.skipForStoryPushes` defaults to `true` so per-Task Story-branch
6
- * commits append a `[skip ci]` trailer out of the box. The Epic-branch merge
7
- * commit produced by `story-close.js`'s merge runner never carries the
8
- * marker — that path is the one consumers actually want CI to evaluate.
9
- *
10
- * Story #4356 adds the CI-aware delivery knobs: `earlyPr` (default `true`)
11
- * gates whether /deliver opens the Epic PR early so CI warms while later
12
- * waves run; `watch` tunes the merge/CI watch poll loop; and `autoMerge`
4
+ * Surviving knobs: `watch` tunes the merge/CI watch poll loop; `autoMerge`
13
5
  * (default `"trust-ci"`) selects the merge posture — `"trust-ci"` merges once
14
6
  * required checks pass, `"strict"` additionally requires a clean review gate.
15
7
  *
16
- * Story #4472 adds `requireChecks` (default `false`): when `true` the
17
- * AutomergePredicate treats a checks-less repo ("no checks reported") as a
18
- * hard block rather than green, so a consumer that wants fail-closed-without-
19
- * checks as policy opts into it explicitly instead of the framework blocking
20
- * implicitly.
8
+ * Retired (no production readers on v2 Story-only delivery): `earlyPr`
9
+ * (Epic early-PR warmup) and `requireChecks` (AutomergePredicate escape hatch
10
+ * whose listener was never landed).
21
11
  */
22
12
 
23
13
  export const CI_DELIVERY_DEFAULTS = Object.freeze({
24
- skipForStoryPushes: true,
25
- earlyPr: true,
26
14
  autoMerge: 'trust-ci',
27
- requireChecks: false,
28
15
  });
29
16
 
30
17
  /**
@@ -35,27 +22,15 @@ export const CI_DELIVERY_DEFAULTS = Object.freeze({
35
22
  * defaults; only the scalar knobs carry framework defaults here.
36
23
  *
37
24
  * @param {object | null | undefined} config
38
- * @returns {{ skipForStoryPushes: boolean, earlyPr: boolean, autoMerge: 'trust-ci' | 'strict', requireChecks: boolean, watch: object | undefined }}
25
+ * @returns {{ autoMerge: 'trust-ci' | 'strict', watch: object | undefined }}
39
26
  */
40
27
  export function getCiDelivery(config) {
41
28
  const ci = config?.delivery?.ci ?? config?.ci ?? config ?? {};
42
29
  return {
43
- skipForStoryPushes:
44
- typeof ci.skipForStoryPushes === 'boolean'
45
- ? ci.skipForStoryPushes
46
- : CI_DELIVERY_DEFAULTS.skipForStoryPushes,
47
- earlyPr:
48
- typeof ci.earlyPr === 'boolean'
49
- ? ci.earlyPr
50
- : CI_DELIVERY_DEFAULTS.earlyPr,
51
30
  autoMerge:
52
31
  ci.autoMerge === 'trust-ci' || ci.autoMerge === 'strict'
53
32
  ? ci.autoMerge
54
33
  : CI_DELIVERY_DEFAULTS.autoMerge,
55
- requireChecks:
56
- typeof ci.requireChecks === 'boolean'
57
- ? ci.requireChecks
58
- : CI_DELIVERY_DEFAULTS.requireChecks,
59
34
  watch:
60
35
  ci.watch && typeof ci.watch === 'object' ? { ...ci.watch } : undefined,
61
36
  };