mandrel 1.94.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (560) hide show
  1. package/.agents/README.md +116 -99
  2. package/.agents/agents/acceptance-critic.md +9 -7
  3. package/.agents/agents/story-worker.md +45 -51
  4. package/.agents/audit-checklists/performance.md +1 -1
  5. package/.agents/docs/SDLC.md +498 -1287
  6. package/.agents/docs/agentrc-reference.json +185 -80
  7. package/.agents/docs/configuration.md +132 -190
  8. package/.agents/docs/execution-reference.md +51 -25
  9. package/.agents/docs/quality-gates.md +25 -33
  10. package/.agents/docs/workflows.md +8 -8
  11. package/.agents/instructions.md +113 -139
  12. package/.agents/rules/ci-remediation.md +11 -15
  13. package/.agents/rules/git-conventions-reference.md +48 -58
  14. package/.agents/rules/git-conventions.md +16 -22
  15. package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
  16. package/.agents/schemas/agentrc.schema.json +83 -254
  17. package/.agents/schemas/audit-rules.json +59 -1
  18. package/.agents/schemas/audit-rules.schema.json +33 -1
  19. package/.agents/schemas/lifecycle/README.md +1 -2
  20. package/.agents/schemas/lifecycle/ledger-record.schema.json +1 -1
  21. package/.agents/schemas/lifecycle/merge.flip-failed.schema.json +33 -0
  22. package/.agents/schemas/lifecycle/merge.unlanded.schema.json +1 -0
  23. package/.agents/schemas/lifecycle/retro.end.schema.json +1 -1
  24. package/.agents/schemas/lifecycle/story.merged.schema.json +1 -1
  25. package/.agents/schemas/signal-event.schema.json +3 -3
  26. package/.agents/schemas/story-deliver-terminal.schema.json +152 -0
  27. package/.agents/schemas/validation-evidence.schema.json +1 -1
  28. package/.agents/scripts/acceptance-eval.js +22 -66
  29. package/.agents/scripts/agents-bootstrap-github.js +1 -1
  30. package/.agents/scripts/audit-to-stories.js +7 -7
  31. package/.agents/scripts/boot-sweep.js +1 -1
  32. package/.agents/scripts/bootstrap.js +3 -3
  33. package/.agents/scripts/check-dead-exports.js +43 -104
  34. package/.agents/scripts/check-doc-links.js +2 -2
  35. package/.agents/scripts/check-lifecycle-lint.js +7 -10
  36. package/.agents/scripts/check-workflow-cli-lint.js +91 -0
  37. package/.agents/scripts/cleanup-repo-test-temp.js +6 -1
  38. package/.agents/scripts/deliver-recover.js +122 -0
  39. package/.agents/scripts/drain-pending-cleanup.js +1 -1
  40. package/.agents/scripts/evidence-gate.js +20 -50
  41. package/.agents/scripts/generate-skills-index.js +17 -1
  42. package/.agents/scripts/generate-workflows-doc.js +4 -4
  43. package/.agents/scripts/lib/ITicketingProvider.js +1 -19
  44. package/.agents/scripts/lib/Logger.js +6 -10
  45. package/.agents/scripts/lib/audit-suite/runner.js +2 -2
  46. package/.agents/scripts/lib/audit-suite/selector.js +328 -28
  47. package/.agents/scripts/lib/audit-to-stories/{seed-epic-from-findings.js → seed-from-findings.js} +9 -9
  48. package/.agents/scripts/lib/baselines/kernel.js +206 -18
  49. package/.agents/scripts/lib/baselines/kinds/maintainability.js +0 -15
  50. package/.agents/scripts/lib/baselines/reader.js +1 -6
  51. package/.agents/scripts/lib/bdd-runner-detect.js +5 -9
  52. package/.agents/scripts/lib/bootstrap/ci-workflow-template.js +28 -33
  53. package/.agents/scripts/lib/bootstrap/issue-forms-template.js +32 -33
  54. package/.agents/scripts/lib/bootstrap/manifest.js +8 -11
  55. package/.agents/scripts/lib/bootstrap/project-bootstrap.js +30 -53
  56. package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +0 -2
  57. package/.agents/scripts/lib/checks/core-bare-clean.js +6 -3
  58. package/.agents/scripts/lib/checks/index.js +3 -2
  59. package/.agents/scripts/lib/checks/loop-health.js +12 -11
  60. package/.agents/scripts/lib/checks/state.js +17 -248
  61. package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +26 -24
  62. package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +3 -4
  63. package/.agents/scripts/lib/checks/worktree-bootstrap-env.js +2 -2
  64. package/.agents/scripts/lib/checks/worktree-residue-biome.js +3 -3
  65. package/.agents/scripts/lib/cli/standard-args.js +13 -22
  66. package/.agents/scripts/lib/cli-args.js +39 -9
  67. package/.agents/scripts/lib/close-validation/gates.js +15 -15
  68. package/.agents/scripts/lib/close-validation/projections/inputs.js +7 -7
  69. package/.agents/scripts/lib/close-validation/projections/maintainability.js +12 -12
  70. package/.agents/scripts/lib/close-validation/runner.js +13 -21
  71. package/.agents/scripts/lib/close-validation/telemetry.js +17 -8
  72. package/.agents/scripts/lib/config/ci.js +6 -31
  73. package/.agents/scripts/lib/config/delivery-routing.js +52 -35
  74. package/.agents/scripts/lib/config/explain.js +61 -48
  75. package/.agents/scripts/lib/config/github.js +7 -5
  76. package/.agents/scripts/lib/config/limits.js +29 -80
  77. package/.agents/scripts/lib/config/paths.js +0 -2
  78. package/.agents/scripts/lib/config/quality.js +12 -15
  79. package/.agents/scripts/lib/config/runners.js +20 -66
  80. package/.agents/scripts/lib/config/temp-paths.js +30 -63
  81. package/.agents/scripts/lib/config/worktree-isolation.js +0 -5
  82. package/.agents/scripts/lib/config-resolver.js +2 -7
  83. package/.agents/scripts/lib/config-settings-schema-delivery.js +55 -161
  84. package/.agents/scripts/lib/config-settings-schema-quality.js +17 -16
  85. package/.agents/scripts/lib/config-settings-schema.js +100 -60
  86. package/.agents/scripts/lib/dead-exports-knip.js +105 -0
  87. package/.agents/scripts/lib/dead-exports-mode.js +51 -0
  88. package/.agents/scripts/lib/dependency-parser.js +3 -2
  89. package/.agents/scripts/lib/doc-tiers.js +2 -2
  90. package/.agents/scripts/lib/duplicate-search.js +242 -41
  91. package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +1 -1
  92. package/.agents/scripts/lib/findings/promote-finding.js +23 -14
  93. package/.agents/scripts/lib/format-generated-json.js +97 -0
  94. package/.agents/scripts/lib/framework-version.js +19 -190
  95. package/.agents/scripts/lib/gh-exec.js +8 -0
  96. package/.agents/scripts/lib/git-branch-cleanup.js +1 -10
  97. package/.agents/scripts/lib/git-branch-lifecycle.js +17 -180
  98. package/.agents/scripts/lib/git-utils.js +32 -20
  99. package/.agents/scripts/lib/github/framework-repo.js +6 -0
  100. package/.agents/scripts/lib/json-utils.js +1 -2
  101. package/.agents/scripts/lib/label-constants.js +10 -38
  102. package/.agents/scripts/lib/label-taxonomy.js +10 -55
  103. package/.agents/scripts/lib/observability/active-story-env.js +44 -165
  104. package/.agents/scripts/lib/observability/runtime-friction.js +243 -0
  105. package/.agents/scripts/lib/observability/signal-validator.js +4 -4
  106. package/.agents/scripts/lib/observability/signals-writer.js +6 -82
  107. package/.agents/scripts/lib/observability/source-classifier.js +5 -5
  108. package/.agents/scripts/lib/observability/tool-trace-hook.js +2 -12
  109. package/.agents/scripts/lib/onboard/init-tail.js +1 -3
  110. package/.agents/scripts/lib/orchestration/acceptance-clusters.js +1 -1
  111. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +2 -2
  112. package/.agents/scripts/lib/orchestration/ceremony-routing.js +105 -44
  113. package/.agents/scripts/lib/orchestration/code-review.js +78 -436
  114. package/.agents/scripts/lib/orchestration/column-sync.js +1 -1
  115. package/.agents/scripts/lib/orchestration/consolidation-precondition.js +4 -4
  116. package/.agents/scripts/lib/orchestration/context-envelope.js +2 -5
  117. package/.agents/scripts/lib/orchestration/deliver-recover.js +328 -0
  118. package/.agents/scripts/lib/orchestration/detectors-phase.js +12 -6
  119. package/.agents/scripts/lib/orchestration/docs-digest.js +8 -8
  120. package/.agents/scripts/lib/orchestration/file-assumptions.js +7 -13
  121. package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +1 -1
  122. package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +34 -0
  123. package/.agents/scripts/lib/orchestration/lease-guard-shared.js +3 -2
  124. package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +142 -0
  125. package/.agents/scripts/lib/orchestration/lifecycle/emit-loop-tick.js +17 -19
  126. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +86 -0
  127. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +37 -103
  128. package/.agents/scripts/lib/orchestration/lifecycle/ledger-writer.js +6 -3
  129. package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +21 -43
  130. package/.agents/scripts/lib/orchestration/lifecycle/listeners/watcher.js +50 -85
  131. package/.agents/scripts/lib/orchestration/lifecycle/trace-logger.js +3 -14
  132. package/.agents/scripts/lib/orchestration/lint-baseline-service.js +4 -4
  133. package/.agents/scripts/lib/orchestration/merge-block-class.js +77 -21
  134. package/.agents/scripts/lib/orchestration/merge-poll.js +104 -0
  135. package/.agents/scripts/lib/orchestration/phase-runner.js +3 -2
  136. package/.agents/scripts/lib/orchestration/plan-context.js +354 -282
  137. package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +11 -22
  138. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +4 -8
  139. package/.agents/scripts/lib/orchestration/plan-metrics.js +38 -6
  140. package/.agents/scripts/lib/orchestration/plan-navigation.js +92 -0
  141. package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +71 -0
  142. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +245 -0
  143. package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +116 -0
  144. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +432 -858
  145. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +778 -0
  146. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +47 -115
  147. package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +509 -0
  148. package/.agents/scripts/lib/orchestration/plan-reachability.js +9 -14
  149. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +1 -1
  150. package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/authoring-context.js +52 -51
  151. package/.agents/scripts/lib/orchestration/planning/decomposer-context.js +27 -0
  152. package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/spec-authoring-grounding.js +1 -1
  153. package/.agents/scripts/lib/orchestration/pr-base-guard.js +18 -28
  154. package/.agents/scripts/lib/orchestration/remote-verifier.js +1 -1
  155. package/.agents/scripts/lib/orchestration/resolve-stories.js +344 -0
  156. package/.agents/scripts/lib/orchestration/resolves-token.js +1 -1
  157. package/.agents/scripts/lib/orchestration/retro-proposals.js +140 -79
  158. package/.agents/scripts/lib/orchestration/review-depth.js +126 -47
  159. package/.agents/scripts/lib/orchestration/review-providers/codex.js +2 -2
  160. package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +3 -13
  161. package/.agents/scripts/lib/orchestration/review-providers/native.js +1 -154
  162. package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +3 -2
  163. package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +21 -56
  164. package/.agents/scripts/lib/orchestration/review-providers/security-review.js +1 -1
  165. package/.agents/scripts/lib/orchestration/review-providers/types.js +5 -4
  166. package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +1 -1
  167. package/.agents/scripts/lib/orchestration/run-epilogue.js +784 -0
  168. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +25 -1
  169. package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +11 -9
  170. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +4 -4
  171. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +86 -41
  172. package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +608 -152
  173. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +77 -32
  174. package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +305 -0
  175. package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +1 -1
  176. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +44 -0
  177. package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +37 -4
  178. package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +2 -2
  179. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +275 -46
  180. package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +1 -1
  181. package/.agents/scripts/lib/orchestration/spec-freshness.js +14 -205
  182. package/.agents/scripts/lib/orchestration/spec-section-validator.js +4 -5
  183. package/.agents/scripts/lib/orchestration/spec-spill.js +60 -0
  184. package/.agents/scripts/lib/orchestration/split-policy-validator.js +188 -0
  185. package/.agents/scripts/lib/orchestration/story-close/emit-blocked.js +49 -0
  186. package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +10 -10
  187. package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +28 -42
  188. package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +360 -0
  189. package/.agents/scripts/lib/orchestration/story-follow-ups.js +298 -0
  190. package/.agents/scripts/lib/orchestration/story-init-remote.js +51 -0
  191. package/.agents/scripts/lib/orchestration/story-plan-state.js +33 -0
  192. package/.agents/scripts/lib/orchestration/structured-comment-parser.js +1 -1
  193. package/.agents/scripts/lib/orchestration/task-body-validator.js +60 -25
  194. package/.agents/scripts/lib/orchestration/ticket-lease.js +27 -74
  195. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +130 -75
  196. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +192 -377
  197. package/.agents/scripts/lib/orchestration/ticket-validator.js +123 -25
  198. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +14 -72
  199. package/.agents/scripts/lib/orchestration/ticketing/reads.js +45 -55
  200. package/.agents/scripts/lib/orchestration/ticketing/transition.js +66 -6
  201. package/.agents/scripts/lib/orchestration/ticketing.js +0 -1
  202. package/.agents/scripts/lib/plan-phase-cleanup.js +12 -14
  203. package/.agents/scripts/lib/planning-corpus.js +12 -281
  204. package/.agents/scripts/lib/preflight-runner.js +4 -4
  205. package/.agents/scripts/lib/qa/coverage-verdict.js +5 -5
  206. package/.agents/scripts/lib/qa/qa-context-hydrator.js +5 -5
  207. package/.agents/scripts/lib/signals/index.js +4 -17
  208. package/.agents/scripts/lib/signals/read.js +35 -35
  209. package/.agents/scripts/lib/signals/schema.js +8 -11
  210. package/.agents/scripts/lib/signals/span-tree.js +7 -7
  211. package/.agents/scripts/lib/signals/write.js +0 -1
  212. package/.agents/scripts/lib/single-story/story-merged-notify.js +13 -2
  213. package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +1 -1
  214. package/.agents/scripts/lib/skills/parse-skill.js +16 -3
  215. package/.agents/scripts/lib/story-adjacency.js +17 -19
  216. package/.agents/scripts/lib/story-body/story-body.js +130 -75
  217. package/.agents/scripts/lib/story-plan.js +2 -4
  218. package/.agents/scripts/lib/templates/decomposer-prompts.js +51 -46
  219. package/.agents/scripts/lib/templates/spec-author-prompts.js +47 -45
  220. package/.agents/scripts/lib/test-env.js +14 -1
  221. package/.agents/scripts/lib/test-tiers.js +0 -3
  222. package/.agents/scripts/lib/{epic-body-sections.js → ticket-body-sections.js} +25 -39
  223. package/.agents/scripts/lib/validation-evidence.js +32 -60
  224. package/.agents/scripts/lib/wave-runner/ready-set.js +38 -12
  225. package/.agents/scripts/lib/workspace-provisioner.js +1 -1
  226. package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +1 -1
  227. package/.agents/scripts/lib/worktree/lifecycle/reap.js +72 -25
  228. package/.agents/scripts/lib/worktree/lifecycle-manager.js +1 -2
  229. package/.agents/scripts/lint-issue-body.js +71 -40
  230. package/.agents/scripts/mandrel-update-preflight.js +1 -1
  231. package/.agents/scripts/notify.js +4 -3
  232. package/.agents/scripts/plan-context.js +102 -80
  233. package/.agents/scripts/plan-persist.js +230 -279
  234. package/.agents/scripts/plan-run-epilogue.js +142 -0
  235. package/.agents/scripts/post-structured-comment.js +0 -38
  236. package/.agents/scripts/pr-watch-with-update.js +43 -22
  237. package/.agents/scripts/providers/github/compose.js +0 -1
  238. package/.agents/scripts/providers/github/errors.js +0 -19
  239. package/.agents/scripts/providers/github/issues.js +13 -39
  240. package/.agents/scripts/providers/github/mappers.js +5 -12
  241. package/.agents/scripts/providers/github/sub-issues.js +0 -47
  242. package/.agents/scripts/providers/github/tickets.js +33 -156
  243. package/.agents/scripts/providers/github.js +17 -6
  244. package/.agents/scripts/resolve-stories.js +236 -0
  245. package/.agents/scripts/run-coverage.js +4 -1
  246. package/.agents/scripts/run-lint.js +2 -2
  247. package/.agents/scripts/run-verify.js +31 -2
  248. package/.agents/scripts/signals-view.js +25 -21
  249. package/.agents/scripts/single-story-close.js +178 -26
  250. package/.agents/scripts/single-story-confirm-merge.js +313 -24
  251. package/.agents/scripts/single-story-init.js +35 -30
  252. package/.agents/scripts/stories-wave-tick.js +85 -10
  253. package/.agents/scripts/story-plan.js +28 -49
  254. package/.agents/scripts/update-ticket-state.js +14 -65
  255. package/.agents/skills/core/code-review-and-quality/SKILL.md +28 -450
  256. package/.agents/skills/core/code-review-and-quality/reference.md +458 -0
  257. package/.agents/skills/core/debugging-and-error-recovery/SKILL.md +22 -315
  258. package/.agents/skills/core/debugging-and-error-recovery/reference.md +323 -0
  259. package/.agents/skills/core/diagnose-friction/SKILL.md +14 -18
  260. package/.agents/skills/core/documentation-and-adrs/SKILL.md +25 -397
  261. package/.agents/skills/core/documentation-and-adrs/reference.md +403 -0
  262. package/.agents/skills/core/gates-and-baselines/SKILL.md +12 -12
  263. package/.agents/skills/core/idea-refinement/SKILL.md +9 -9
  264. package/.agents/skills/core/scope-triage/SKILL.md +31 -172
  265. package/.agents/skills/core/security-and-hardening/SKILL.md +22 -367
  266. package/.agents/skills/core/security-and-hardening/reference.md +375 -0
  267. package/.agents/skills/skills.index.json +3 -53
  268. package/.agents/skills/stack/qa/playwright-bdd/SKILL.md +2 -4
  269. package/.agents/skills/stack/qa/qa-explore-driving/SKILL.md +1 -1
  270. package/.agents/skills/stack/qa/qa-harness/SKILL.md +1 -3
  271. package/.agents/starter-agentrc.json +0 -5
  272. package/.agents/templates/agent-protocol.md +9 -10
  273. package/.agents/workflows/audit-architecture.md +6 -7
  274. package/.agents/workflows/audit-clean-code.md +7 -7
  275. package/.agents/workflows/audit-dependencies.md +3 -3
  276. package/.agents/workflows/audit-devops.md +3 -3
  277. package/.agents/workflows/audit-documentation.md +9 -10
  278. package/.agents/workflows/audit-lighthouse.md +11 -3
  279. package/.agents/workflows/audit-navigability.md +13 -2
  280. package/.agents/workflows/audit-performance.md +5 -6
  281. package/.agents/workflows/audit-privacy.md +3 -3
  282. package/.agents/workflows/audit-quality.md +11 -12
  283. package/.agents/workflows/audit-security.md +4 -5
  284. package/.agents/workflows/audit-seo.md +13 -3
  285. package/.agents/workflows/audit-sre.md +3 -3
  286. package/.agents/workflows/audit-to-stories.md +20 -20
  287. package/.agents/workflows/audit-ux-ui.md +10 -3
  288. package/.agents/workflows/deliver.md +177 -176
  289. package/.agents/workflows/git-cleanup.md +5 -6
  290. package/.agents/workflows/git-deliver.md +1 -1
  291. package/.agents/workflows/helpers/_merge-conflict-template.md +1 -1
  292. package/.agents/workflows/helpers/acceptance-self-eval.md +35 -40
  293. package/.agents/workflows/helpers/code-quality-guardrails.md +7 -7
  294. package/.agents/workflows/helpers/code-review.md +75 -196
  295. package/.agents/workflows/helpers/{single-story-deliver-reference.md → deliver-story-reference.md} +83 -44
  296. package/.agents/workflows/helpers/deliver-story.md +606 -0
  297. package/.agents/workflows/helpers/diagnose.md +10 -10
  298. package/.agents/workflows/helpers/parallel-tooling.md +3 -3
  299. package/.agents/workflows/helpers/signals.md +16 -16
  300. package/.agents/workflows/helpers/worktree-lifecycle.md +66 -86
  301. package/.agents/workflows/mandrel-update.md +2 -1
  302. package/.agents/workflows/plan.md +277 -145
  303. package/.agents/workflows/qa-assist.md +27 -33
  304. package/.agents/workflows/qa-explore.md +29 -38
  305. package/.agents/workflows/qa-run.md +2 -6
  306. package/README.md +9 -8
  307. package/bin/mandrel.js +12 -1
  308. package/docs/CHANGELOG.md +70 -0
  309. package/lib/cli/registry.js +262 -19
  310. package/lib/cli/sync-agents.js +157 -0
  311. package/lib/cli/sync-commands.js +115 -6
  312. package/lib/cli/sync.js +168 -6
  313. package/lib/cli/update.js +105 -8
  314. package/lib/cli/version-helpers.js +131 -0
  315. package/lib/migrations/README.md +7 -5
  316. package/lib/migrations/index.js +12 -8
  317. package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +100 -0
  318. package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +101 -0
  319. package/package.json +2 -2
  320. package/.agents/agents/retro.md +0 -42
  321. package/.agents/personas/architect.md +0 -113
  322. package/.agents/personas/devops-engineer.md +0 -38
  323. package/.agents/personas/engineer.md +0 -33
  324. package/.agents/personas/project-manager.md +0 -114
  325. package/.agents/personas/qa-engineer.md +0 -95
  326. package/.agents/personas/security-engineer.md +0 -111
  327. package/.agents/personas/technical-writer.md +0 -101
  328. package/.agents/schemas/dispatch-manifest.json +0 -232
  329. package/.agents/schemas/epic-perf-report.schema.json +0 -89
  330. package/.agents/schemas/epic-spec.schema.json +0 -153
  331. package/.agents/schemas/lifecycle/acceptance.reconcile.failed.schema.json +0 -13
  332. package/.agents/schemas/lifecycle/acceptance.reconcile.ok.schema.json +0 -13
  333. package/.agents/schemas/lifecycle/acceptance.reconcile.skipped.schema.json +0 -13
  334. package/.agents/schemas/lifecycle/acceptance.reconcile.start.schema.json +0 -12
  335. package/.agents/schemas/lifecycle/acceptance.reconcile.waived.schema.json +0 -13
  336. package/.agents/schemas/lifecycle/epic.automerge.end.schema.json +0 -15
  337. package/.agents/schemas/lifecycle/epic.automerge.start.schema.json +0 -13
  338. package/.agents/schemas/lifecycle/epic.blocked.schema.json +0 -13
  339. package/.agents/schemas/lifecycle/epic.cleanup.end.schema.json +0 -12
  340. package/.agents/schemas/lifecycle/epic.cleanup.start.schema.json +0 -12
  341. package/.agents/schemas/lifecycle/epic.close.end.schema.json +0 -12
  342. package/.agents/schemas/lifecycle/epic.complete.schema.json +0 -13
  343. package/.agents/schemas/lifecycle/epic.finalize.end.schema.json +0 -13
  344. package/.agents/schemas/lifecycle/epic.finalize.start.schema.json +0 -12
  345. package/.agents/schemas/lifecycle/epic.merge.armed.schema.json +0 -13
  346. package/.agents/schemas/lifecycle/epic.merge.blocked.schema.json +0 -14
  347. package/.agents/schemas/lifecycle/epic.merge.confirmed.schema.json +0 -17
  348. package/.agents/schemas/lifecycle/epic.merge.ready.schema.json +0 -15
  349. package/.agents/schemas/lifecycle/epic.plan.end.schema.json +0 -18
  350. package/.agents/schemas/lifecycle/epic.plan.start.schema.json +0 -12
  351. package/.agents/schemas/lifecycle/epic.snapshot.end.schema.json +0 -16
  352. package/.agents/schemas/lifecycle/epic.snapshot.start.schema.json +0 -12
  353. package/.agents/schemas/lifecycle/epic.watch.end.schema.json +0 -29
  354. package/.agents/schemas/lifecycle/epic.watch.start.schema.json +0 -16
  355. package/.agents/schemas/lifecycle/slice.end.schema.json +0 -21
  356. package/.agents/schemas/lifecycle/slice.heartbeat.schema.json +0 -20
  357. package/.agents/schemas/lifecycle/slice.start.schema.json +0 -17
  358. package/.agents/schemas/lifecycle/story.heartbeat.schema.json +0 -20
  359. package/.agents/schemas/risk-verdict.schema.json +0 -66
  360. package/.agents/schemas/story-perf-summary.schema.json +0 -73
  361. package/.agents/scripts/acceptance-spec-reconciler.js +0 -642
  362. package/.agents/scripts/analyze-execution.js +0 -444
  363. package/.agents/scripts/bookkeeping-reconcile.js +0 -117
  364. package/.agents/scripts/check-prepush-recovery.js +0 -90
  365. package/.agents/scripts/dispatcher.js +0 -295
  366. package/.agents/scripts/epic-audit-prepare.js +0 -497
  367. package/.agents/scripts/epic-audit-recheck.js +0 -274
  368. package/.agents/scripts/epic-deliver-note-intervention.js +0 -192
  369. package/.agents/scripts/epic-deliver-preflight.js +0 -462
  370. package/.agents/scripts/epic-deliver-prepare.js +0 -852
  371. package/.agents/scripts/epic-execute-record-wave.js +0 -449
  372. package/.agents/scripts/epic-plan-clarity.js +0 -211
  373. package/.agents/scripts/epic-plan-healthcheck.js +0 -581
  374. package/.agents/scripts/epic-reconcile.js +0 -625
  375. package/.agents/scripts/lib/baseline-snapshot.js +0 -979
  376. package/.agents/scripts/lib/checks/epic-merge-lock-stale.js +0 -54
  377. package/.agents/scripts/lib/checks/stale-origin-epic.js +0 -49
  378. package/.agents/scripts/lib/config/lifecycle.js +0 -40
  379. package/.agents/scripts/lib/config/preflight.js +0 -58
  380. package/.agents/scripts/lib/config/retro.js +0 -77
  381. package/.agents/scripts/lib/epic-merge-lock.js +0 -322
  382. package/.agents/scripts/lib/epic-plan-clarity.js +0 -181
  383. package/.agents/scripts/lib/epic-plan-ideation.js +0 -261
  384. package/.agents/scripts/lib/git-merge-orchestrator.js +0 -261
  385. package/.agents/scripts/lib/observability/baseline-refresh-rate.js +0 -221
  386. package/.agents/scripts/lib/observability/hook-heartbeat.js +0 -219
  387. package/.agents/scripts/lib/observability/perf-aggregator.js +0 -813
  388. package/.agents/scripts/lib/observability/perf-report-readers.js +0 -328
  389. package/.agents/scripts/lib/observability/perf-report-render.js +0 -182
  390. package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +0 -270
  391. package/.agents/scripts/lib/orchestration/context-hydration-engine.js +0 -539
  392. package/.agents/scripts/lib/orchestration/deliver-route.js +0 -173
  393. package/.agents/scripts/lib/orchestration/dispatch-engine.js +0 -134
  394. package/.agents/scripts/lib/orchestration/dispatch-pipeline.js +0 -183
  395. package/.agents/scripts/lib/orchestration/epic-cleanup.js +0 -801
  396. package/.agents/scripts/lib/orchestration/epic-deliver-lease-guard.js +0 -310
  397. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/context.js +0 -163
  398. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/creation.js +0 -140
  399. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/dag.js +0 -64
  400. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/diagnostics.js +0 -72
  401. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +0 -156
  402. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist.js +0 -345
  403. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +0 -41
  404. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/reconcile-spawn.js +0 -86
  405. package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +0 -391
  406. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/drain.js +0 -94
  407. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +0 -236
  408. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/risk-verdict.js +0 -105
  409. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +0 -307
  410. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-freshness.js +0 -117
  411. package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +0 -117
  412. package/.agents/scripts/lib/orchestration/epic-run-state-store.js +0 -621
  413. package/.agents/scripts/lib/orchestration/epic-runner/concurrency-gate.js +0 -186
  414. package/.agents/scripts/lib/orchestration/epic-runner/deliver-phases.js +0 -50
  415. package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +0 -129
  416. package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +0 -103
  417. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/composition.js +0 -267
  418. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/signals.js +0 -210
  419. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/transport.js +0 -238
  420. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/_bullet-format.js +0 -32
  421. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/component-drift.js +0 -203
  422. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/crap-drift.js +0 -227
  423. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/maintainability-drift.js +0 -117
  424. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/stalled-worktree.js +0 -37
  425. package/.agents/scripts/lib/orchestration/epic-runner/story-launcher.js +0 -127
  426. package/.agents/scripts/lib/orchestration/epic-runner/story-run-progress-writer.js +0 -400
  427. package/.agents/scripts/lib/orchestration/epic-runner/sub-agent-return.js +0 -276
  428. package/.agents/scripts/lib/orchestration/epic-runner/wave-scheduler.js +0 -66
  429. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-apply.js +0 -789
  430. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +0 -676
  431. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-discriminator.js +0 -389
  432. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-format.js +0 -230
  433. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-ops.js +0 -361
  434. package/.agents/scripts/lib/orchestration/error-journal.js +0 -139
  435. package/.agents/scripts/lib/orchestration/finalize/open-or-locate-pr.js +0 -306
  436. package/.agents/scripts/lib/orchestration/finalize/post-handoff-comment.js +0 -489
  437. package/.agents/scripts/lib/orchestration/finalize/sanitize-skip-ci.js +0 -88
  438. package/.agents/scripts/lib/orchestration/lifecycle/emit-slice-lifecycle.js +0 -270
  439. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-dispatch-end.js +0 -147
  440. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +0 -155
  441. package/.agents/scripts/lib/orchestration/lifecycle/ledger-diff.js +0 -140
  442. package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +0 -465
  443. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +0 -501
  444. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +0 -984
  445. package/.agents/scripts/lib/orchestration/lifecycle/listeners/branch-cleaner.js +0 -264
  446. package/.agents/scripts/lib/orchestration/lifecycle/listeners/checkpoint-pointer-writer.js +0 -284
  447. package/.agents/scripts/lib/orchestration/lifecycle/listeners/cleaner.js +0 -355
  448. package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +0 -673
  449. package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +0 -378
  450. package/.agents/scripts/lib/orchestration/lifecycle/listeners/intervention-recorder.js +0 -140
  451. package/.agents/scripts/lib/orchestration/lifecycle/listeners/label-transitioner.js +0 -144
  452. package/.agents/scripts/lib/orchestration/lifecycle/listeners/merge-watcher.js +0 -665
  453. package/.agents/scripts/lib/orchestration/lifecycle/listeners/notify-dispatcher.js +0 -174
  454. package/.agents/scripts/lib/orchestration/manifest-builder.js +0 -222
  455. package/.agents/scripts/lib/orchestration/plan-persist/amend.js +0 -359
  456. package/.agents/scripts/lib/orchestration/plan-persist/delivery-mode.js +0 -127
  457. package/.agents/scripts/lib/orchestration/plan-review-routing.js +0 -63
  458. package/.agents/scripts/lib/orchestration/planning-context-budget.js +0 -213
  459. package/.agents/scripts/lib/orchestration/planning-risk.js +0 -194
  460. package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +0 -56
  461. package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +0 -33
  462. package/.agents/scripts/lib/orchestration/post-merge/phases/notification.js +0 -78
  463. package/.agents/scripts/lib/orchestration/post-merge/phases/temp-cleanup.js +0 -68
  464. package/.agents/scripts/lib/orchestration/post-merge/phases/ticket-closure.js +0 -118
  465. package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +0 -396
  466. package/.agents/scripts/lib/orchestration/post-merge-pipeline.js +0 -205
  467. package/.agents/scripts/lib/orchestration/preflight-cache.js +0 -187
  468. package/.agents/scripts/lib/orchestration/recurring-failure-detector.js +0 -152
  469. package/.agents/scripts/lib/orchestration/retro/phases/checks.js +0 -94
  470. package/.agents/scripts/lib/orchestration/retro/phases/compose-body.js +0 -571
  471. package/.agents/scripts/lib/orchestration/retro/phases/gather-signals.js +0 -450
  472. package/.agents/scripts/lib/orchestration/retro/phases/post-and-mirror.js +0 -191
  473. package/.agents/scripts/lib/orchestration/retro-heuristics.js +0 -57
  474. package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +0 -275
  475. package/.agents/scripts/lib/orchestration/retro-runner.js +0 -197
  476. package/.agents/scripts/lib/orchestration/spec-renderer.js +0 -447
  477. package/.agents/scripts/lib/orchestration/story-close/auto-refresh-runner.js +0 -747
  478. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/gate-failure.js +0 -211
  479. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/pre-merge-attribution.js +0 -158
  480. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +0 -446
  481. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/regression-projection.js +0 -297
  482. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/scope-discovery.js +0 -48
  483. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution-wiring.js +0 -67
  484. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution.js +0 -161
  485. package/.agents/scripts/lib/orchestration/story-close/baseline-friction-body.js +0 -117
  486. package/.agents/scripts/lib/orchestration/story-close/cd-out-guard.js +0 -86
  487. package/.agents/scripts/lib/orchestration/story-close/cleanup-reconciler.js +0 -147
  488. package/.agents/scripts/lib/orchestration/story-close/close-inputs.js +0 -142
  489. package/.agents/scripts/lib/orchestration/story-close/comment-bodies.js +0 -62
  490. package/.agents/scripts/lib/orchestration/story-close/merge-runner.js +0 -658
  491. package/.agents/scripts/lib/orchestration/story-close/merge-subject.js +0 -198
  492. package/.agents/scripts/lib/orchestration/story-close/phases/branch-restore.js +0 -105
  493. package/.agents/scripts/lib/orchestration/story-close/phases/close.js +0 -222
  494. package/.agents/scripts/lib/orchestration/story-close/phases/gates.js +0 -292
  495. package/.agents/scripts/lib/orchestration/story-close/phases/locked-pipeline.js +0 -270
  496. package/.agents/scripts/lib/orchestration/story-close/phases/preflight.js +0 -110
  497. package/.agents/scripts/lib/orchestration/story-close/phases/refresh.js +0 -86
  498. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked-emitter.js +0 -112
  499. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked.js +0 -157
  500. package/.agents/scripts/lib/orchestration/story-close/post-merge-close.js +0 -421
  501. package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +0 -302
  502. package/.agents/scripts/lib/orchestration/story-close/shared-checkout-guard.js +0 -163
  503. package/.agents/scripts/lib/orchestration/story-close-recovery.js +0 -690
  504. package/.agents/scripts/lib/orchestration/wave-marker.js +0 -28
  505. package/.agents/scripts/lib/orchestration/wave-record-io.js +0 -218
  506. package/.agents/scripts/lib/orchestration/wave-record-notifications.js +0 -145
  507. package/.agents/scripts/lib/orchestration/wave-record-projection.js +0 -212
  508. package/.agents/scripts/lib/presentation/dispatch-manifest-render.js +0 -111
  509. package/.agents/scripts/lib/presentation/manifest-builder.js +0 -239
  510. package/.agents/scripts/lib/presentation/manifest-formatter.js +0 -242
  511. package/.agents/scripts/lib/presentation/manifest-helpers.js +0 -213
  512. package/.agents/scripts/lib/presentation/manifest-persistence.js +0 -261
  513. package/.agents/scripts/lib/presentation/manifest-procedures.js +0 -55
  514. package/.agents/scripts/lib/presentation/manifest-render-waves.js +0 -306
  515. package/.agents/scripts/lib/presentation/manifest-renderer.js +0 -188
  516. package/.agents/scripts/lib/presentation/manifest-story-views.js +0 -110
  517. package/.agents/scripts/lib/push-epic-retry.js +0 -209
  518. package/.agents/scripts/lib/spec/index.js +0 -36
  519. package/.agents/scripts/lib/spec/loader.js +0 -425
  520. package/.agents/scripts/lib/spec/state.js +0 -208
  521. package/.agents/scripts/lib/story-init/blocker-validator.js +0 -68
  522. package/.agents/scripts/lib/story-init/branch-initializer.js +0 -408
  523. package/.agents/scripts/lib/story-init/context-resolver.js +0 -92
  524. package/.agents/scripts/lib/story-init/donor-precheck.js +0 -207
  525. package/.agents/scripts/lib/story-init/state-transitioner.js +0 -80
  526. package/.agents/scripts/lib/story-init/task-graph-builder.js +0 -124
  527. package/.agents/scripts/lib/story-init/transition-summary.js +0 -34
  528. package/.agents/scripts/lib/test-reserved-epic-temp-ids.js +0 -35
  529. package/.agents/scripts/lib/wave-runner/tick.js +0 -754
  530. package/.agents/scripts/lib/wave-runner/wave-runner-error.js +0 -20
  531. package/.agents/scripts/lifecycle-emit-story-dispatch.js +0 -194
  532. package/.agents/scripts/lifecycle-emit.js +0 -510
  533. package/.agents/scripts/retro-run.js +0 -218
  534. package/.agents/scripts/slice-phase.js +0 -361
  535. package/.agents/scripts/standalone-feedback-rollup.js +0 -188
  536. package/.agents/scripts/story-close.js +0 -294
  537. package/.agents/scripts/story-init.js +0 -599
  538. package/.agents/scripts/story-phase.js +0 -369
  539. package/.agents/scripts/wave-tick.js +0 -464
  540. package/.agents/skills/core/analyze-execution/SKILL.md +0 -98
  541. package/.agents/skills/core/epic-plan-consolidate/SKILL.md +0 -172
  542. package/.agents/skills/core/epic-plan-consolidate/examples.md +0 -51
  543. package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +0 -441
  544. package/.agents/skills/core/epic-plan-decompose-author/examples.md +0 -47
  545. package/.agents/skills/core/epic-plan-premortem/SKILL.md +0 -146
  546. package/.agents/skills/core/epic-plan-premortem/examples.md +0 -53
  547. package/.agents/skills/core/epic-plan-spec-author/SKILL.md +0 -383
  548. package/.agents/skills/core/epic-plan-spec-author/examples.md +0 -91
  549. package/.agents/workflows/helpers/deliver-epic-reference.md +0 -547
  550. package/.agents/workflows/helpers/deliver-epic-single.md +0 -331
  551. package/.agents/workflows/helpers/deliver-epic.md +0 -998
  552. package/.agents/workflows/helpers/deliver-stories.md +0 -450
  553. package/.agents/workflows/helpers/epic-audit.md +0 -189
  554. package/.agents/workflows/helpers/epic-deliver-story.md +0 -436
  555. package/.agents/workflows/helpers/epic-testing.md +0 -125
  556. package/.agents/workflows/helpers/plan-epic-reference.md +0 -160
  557. package/.agents/workflows/helpers/plan-epic.md +0 -353
  558. package/.agents/workflows/helpers/plan-story.md +0 -251
  559. package/.agents/workflows/helpers/scope-triage-gate.md +0 -108
  560. package/.agents/workflows/helpers/single-story-deliver.md +0 -557
@@ -1,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
- * 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
12
+ * Scope: 'story-close', 'retro'. The check runs at every
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(...)',
@@ -144,7 +146,7 @@ const FIX_COMMAND = [
144
146
  export default {
145
147
  id: 'story-init-not-backgrounded',
146
148
  severity: 'blocker',
147
- scope: ['epic-deliver', 'story-close', 'retro'],
149
+ scope: ['story-close', 'retro'],
148
150
  autoCorrect: 'refuse-and-print',
149
151
 
150
152
  detect(state) {
@@ -176,8 +178,8 @@ export default {
176
178
  return {
177
179
  id: 'story-init-not-backgrounded',
178
180
  severity: 'blocker',
179
- scope: state?.scope ?? 'epic-deliver',
180
- summary: `${offences.length} orchestration call site(s) invoke story-init.js with Monitor backgrounding`,
181
+ scope: state?.scope ?? 'story-close',
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,
@@ -22,8 +22,7 @@
22
22
  * catches an over-deep fan-out. The self-healing surface is preserved — it is
23
23
  * re-scoped, not removed.
24
24
  *
25
- * Scope: 'epic-deliver', 'retro'. Surfaces as a blocker at preflight for
26
- * `epic-deliver` (the fan-out site) and as audit signal at retro.
25
+ * Scope: 'retro'. Surfaces as audit signal at retro.
27
26
  *
28
27
  * The check is `refuse-and-print` — auto-rewriting a workflow's declared
29
28
  * depth or tool list would silently change runtime behavior in ways the
@@ -208,7 +207,7 @@ const FIX_COMMAND = [
208
207
  export default {
209
208
  id: 'subagent-agent-tool-required',
210
209
  severity: 'blocker',
211
- scope: ['epic-deliver', 'retro'],
210
+ scope: ['retro'],
212
211
  autoCorrect: 'refuse-and-print',
213
212
 
214
213
  detect(state) {
@@ -249,7 +248,7 @@ export default {
249
248
  return {
250
249
  id: 'subagent-agent-tool-required',
251
250
  severity: 'blocker',
252
- scope: state?.scope ?? 'epic-deliver',
251
+ scope: state?.scope ?? 'retro',
253
252
  summary: `${offences.length} sub-agent workflow(s) declare an Agent fan-out deeper than the supported nesting ceiling (${ceiling})`,
254
253
  detail,
255
254
  fixCommand: FIX_COMMAND,
@@ -8,7 +8,7 @@
8
8
  * tests that read environment variables silently take a different code
9
9
  * path.
10
10
  *
11
- * Surface: `epic-deliver` preflight and the `/diagnose` CLI. Surfaced as a
11
+ * Surface: the `/diagnose` CLI. Surfaced as a
12
12
  * warning rather than a blocker — the missing file may be a deliberate
13
13
  * choice (e.g. a worktree that doesn't need MCP), but the operator should
14
14
  * see the divergence from the main checkout.
@@ -28,7 +28,7 @@ const ID = 'worktree-bootstrap-env';
28
28
  export default {
29
29
  id: ID,
30
30
  severity: 'warning',
31
- scope: ['epic-deliver', 'diagnose'],
31
+ scope: ['diagnose'],
32
32
  autoCorrect: 'refuse-and-print',
33
33
  detect(state) {
34
34
  const status = state?.fs?.worktreeBootstrapStatus ?? {};
@@ -6,8 +6,8 @@
6
6
  * root `npm run lint` walks into the orphan tree, hits the nested config,
7
7
  * and fails. The close-time biome block is the canonical symptom.
8
8
  *
9
- * Surface: `epic-deliver` preflight, `story-close` preflight, and the
10
- * `/diagnose` CLI. Surfaced as a blocker so the operator clears the residue
9
+ * Surface: `story-close` preflight, the `/diagnose` CLI, and retro.
10
+ * Surfaced as a blocker so the operator clears the residue
11
11
  * with `rm -rf` before close re-runs the validation chain.
12
12
  *
13
13
  * AutoCorrect is `refuse-and-print`. Recursive deletion under `.worktrees/`
@@ -21,7 +21,7 @@ const ID = 'worktree-residue-biome';
21
21
  export default {
22
22
  id: ID,
23
23
  severity: 'blocker',
24
- scope: ['epic-deliver', 'story-close', 'diagnose', 'retro'],
24
+ scope: ['story-close', 'diagnose', 'retro'],
25
25
  autoCorrect: 'refuse-and-print',
26
26
  detect(state) {
27
27
  const orphans = state?.fs?.worktreeBiomeOrphans ?? [];
@@ -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,28 @@ 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
+
49
+ /**
50
+ * Parse a positive-integer flag, preserving `undefined` when the flag is
51
+ * absent so a caller can distinguish "not supplied" (fall back to config)
52
+ * from an explicit value. A non-numeric or non-positive value is treated as
53
+ * absent rather than coerced to 0 — a `--max-wait-seconds=abc` typo must not
54
+ * silently become a zero-second wait.
55
+ *
56
+ * @param {unknown} value
57
+ * @returns {number|undefined}
58
+ */
59
+ function parsePositiveInt(value) {
60
+ if (value === undefined || value === null) return undefined;
61
+ const parsed = Number.parseInt(String(value), 10);
62
+ return Number.isInteger(parsed) && parsed > 0 ? parsed : undefined;
63
+ }
64
+
43
65
  /**
44
66
  * Standardized CLI argument parser for sprint scripts.
45
67
  * Supports options like --epic, --story, --dry-run, --skip-dashboard.
@@ -57,9 +79,12 @@ export function parseSprintArgs(args = process.argv) {
57
79
  'skip-validation': { type: 'boolean', default: false },
58
80
  'skip-sync': { type: 'boolean', default: false },
59
81
  'no-auto-merge': { type: 'boolean', default: false },
60
- 'no-full-scope-crap': { type: 'boolean', default: false },
61
- 'wait-merge': { type: 'boolean', default: false },
82
+ // No default absent means "use delivery.routing.closeAndLand".
83
+ 'wait-merge': { type: 'boolean' },
62
84
  'no-wait-merge': { type: 'boolean', default: false },
85
+ // Story #4543 — per-run override of `delivery.mergeWatch.maxWaitSeconds`
86
+ // (the merge wait's per-invocation bound). Absent means "use the config".
87
+ 'max-wait-seconds': { type: 'string' },
63
88
  executor: { type: 'string' },
64
89
  cwd: { type: 'string' },
65
90
  'recut-of': { type: 'string' },
@@ -80,13 +105,16 @@ export function parseSprintArgs(args = process.argv) {
80
105
  skipValidation: coerceBooleanFlag(values['skip-validation']),
81
106
  skipSync: coerceBooleanFlag(values['skip-sync']),
82
107
  noAutoMerge: coerceBooleanFlag(values['no-auto-merge']),
83
- 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']),
108
+ // Close-and-land: `--wait-merge` forces land-in-close; `--no-wait-merge`
109
+ // opts out. When neither flag is present (`undefined`),
110
+ // `parseCloseOptions` applies `delivery.routing.closeAndLand` (default
111
+ // true) so attended and headless delivers share the same happy path.
112
+ waitForMerge: optionalBooleanFlag(values['wait-merge']),
89
113
  noWaitForMerge: coerceBooleanFlag(values['no-wait-merge']),
114
+ // Story #4543 — raise the merge wait's per-invocation bound for a
115
+ // headless caller with no host tool-invocation ceiling, so it lands in
116
+ // one block instead of returning `pending` at the default 300s.
117
+ maxWaitSeconds: parsePositiveInt(values['max-wait-seconds']),
90
118
  executor: values.executor ?? null,
91
119
  // Resolve worktree cwd from flag or env. Empty string/whitespace → null.
92
120
  cwd:
@@ -95,7 +123,9 @@ export function parseSprintArgs(args = process.argv) {
95
123
  null,
96
124
  recutOf: parseTicketId(values['recut-of']),
97
125
  // 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.
126
+ // fan-out so `single-story-init.js` can skip redundant Epic lookups when
127
+ // the parent already threaded Epic context (pre-v2; field retained for
128
+ // CLI compatibility).
99
129
  resume: values.resume ?? false,
100
130
  restart: values.restart ?? false,
101
131
  noEvidence: values['no-evidence'] ?? false,
@@ -54,22 +54,22 @@ function buildChangedFileScope(baseRef) {
54
54
  *
55
55
  * The baselines gate resolves its compare ref through `resolveScope`,
56
56
  * whose environment layer reads `BASELINE_REF`. Threading
57
- * `origin/<epicBranch>` here makes the gate diff head against the epic
57
+ * `origin/<baseBranch>` here makes the gate diff head against the epic
58
58
  * integration branch instead of the framework-default `origin/main`, so
59
59
  * drift that already landed on `main` but is outside the Story's own diff
60
60
  * does not surface as a phantom regression. The same convention
61
- * (`origin/<epicBranch>`) is used by the baseline-attribution and
61
+ * (`origin/<baseBranch>`) is used by the baseline-attribution and
62
62
  * auto-refresh paths, keeping read/compare bases aligned.
63
63
  *
64
64
  * Returns `null` when no integration branch is supplied (the gate then
65
65
  * keeps its existing default-ref / consumer-config behaviour untouched).
66
66
  *
67
- * @param {string|undefined|null} epicBranch
67
+ * @param {string|undefined|null} baseBranch
68
68
  * @returns {{ BASELINE_REF: string } | null}
69
69
  */
70
- function buildBaselinesGateEnv(epicBranch) {
71
- if (typeof epicBranch !== 'string' || epicBranch.length === 0) return null;
72
- return { BASELINE_REF: `origin/${epicBranch}` };
70
+ function buildBaselinesGateEnv(baseBranch) {
71
+ if (typeof baseBranch !== 'string' || baseBranch.length === 0) return null;
72
+ return { BASELINE_REF: `origin/${baseBranch}` };
73
73
  }
74
74
 
75
75
  /**
@@ -146,7 +146,7 @@ function enabledBaselineKinds(config) {
146
146
  * `delivery.quality.requireBaselines: true`. Default false — a consumer that
147
147
  * enables baseline gates but has not committed baseline artifacts gets a
148
148
  * clean skip (see `probeBaselinesGate`) rather than a deterministic first-try
149
- * close failure. Mirrors the `delivery.ci.requireChecks` escape hatch (#4472).
149
+ * close failure. Fail-closed baseline posture (#4495).
150
150
  *
151
151
  * @param {object|undefined|null} config
152
152
  * @returns {boolean}
@@ -240,11 +240,11 @@ function probeBaselinesGate({ config, cwd, presentBaselines } = {}) {
240
240
  * shared in-process runner. The unified `check-baselines` gate is now the
241
241
  * single source of truth for per-kind regression enforcement
242
242
  * (attribution-wired floor + tolerance + schema).
243
- * The `epicBranch` parameter threads the close run's integration branch
243
+ * The `baseBranch` parameter threads the close run's integration branch
244
244
  * into two gates: the `format` gate's `changedFileScope` (existing) and —
245
245
  * since Story #3890 — the `check-baselines` gate's `BASELINE_REF` env, so
246
246
  * the baselines regression compare diffs head against the epic integration
247
- * branch (`origin/<epicBranch>`) rather than the framework-default
247
+ * branch (`origin/<baseBranch>`) rather than the framework-default
248
248
  * `origin/main`. Without this, every child Story on an `epic/<id>` branch
249
249
  * re-discovered inherited main-vs-epic drift in untouched files as phantom
250
250
  * regressions and worked around it by hand-setting `BASELINE_REF`.
@@ -268,10 +268,10 @@ function probeBaselinesGate({ config, cwd, presentBaselines } = {}) {
268
268
  * none are required, the gate is skipped with a logged reason (via `log`)
269
269
  * instead of a blocking failure.
270
270
  *
271
- * @param {{ config?: object, epicBranch?: string, cwd?: string, packageScripts?: Record<string, string>, presentBaselines?: string[]|Set<string>, log?: (message: string) => void }} [opts]
271
+ * @param {{ config?: object, baseBranch?: string, cwd?: string, packageScripts?: Record<string, string>, presentBaselines?: string[]|Set<string>, log?: (message: string) => void }} [opts]
272
272
  * `config` is the canonical resolved config (`{ project, delivery, ... }`);
273
273
  * gate commands resolve from `project.commands` and the CRAP toggle from
274
- * `delivery.quality.gates.crap.enabled`. `epicBranch` is the close run's
274
+ * `delivery.quality.gates.crap.enabled`. `baseBranch` is the close run's
275
275
  * integration branch (`epic/<id>` for Epic-attached Stories, the base
276
276
  * branch for standalone Stories). `cwd` is where the `package.json`
277
277
  * coverage-script probe and the `baselines/<kind>.json` presence probe
@@ -285,7 +285,7 @@ function probeBaselinesGate({ config, cwd, presentBaselines } = {}) {
285
285
  */
286
286
  export function buildDefaultGates({
287
287
  config,
288
- epicBranch,
288
+ baseBranch,
289
289
  cwd,
290
290
  packageScripts,
291
291
  presentBaselines,
@@ -305,9 +305,9 @@ export function buildDefaultGates({
305
305
  const formatWriteString = resolveFormatWriteCommand(config);
306
306
  const formatChangedFileScope =
307
307
  formatCheckString === FORMAT_CHECK_FALLBACK
308
- ? buildChangedFileScope(epicBranch)
308
+ ? buildChangedFileScope(baseBranch)
309
309
  : null;
310
- const baselinesGateEnv = buildBaselinesGateEnv(epicBranch);
310
+ const baselinesGateEnv = buildBaselinesGateEnv(baseBranch);
311
311
  const baselinesDecision = probeBaselinesGate({
312
312
  config,
313
313
  cwd,
@@ -379,7 +379,7 @@ export function buildDefaultGates({
379
379
  /**
380
380
  * Default gate list resolved with no consumer config — uses the
381
381
  * `npm run typecheck` fallback for the typecheck gate. Call sites that have a
382
- * resolved config object in scope (e.g. `story-close.js`) should
382
+ * resolved config object in scope (e.g. `single-story-close.js`) should
383
383
  * prefer `buildDefaultGates({ config })` so a configured
384
384
  * `project.commands.typecheck` is honoured.
385
385
  *
@@ -3,7 +3,7 @@
3
3
  * inputs.js — shared input validator for close-validation projection helpers.
4
4
  *
5
5
  * Used by `projections/maintainability.js` (and any future projection that
6
- * shares the same `{ cwd, epicBranch, storyBranch, baselinePath }` argument
6
+ * shares the same `{ cwd, baseBranch, storyBranch, baselinePath }` argument
7
7
  * shape) to collapse the inline guard cascade into a single predicate that
8
8
  * returns a typed `reason` on failure.
9
9
  *
@@ -16,7 +16,7 @@
16
16
  /**
17
17
  * @typedef {Object} ProjectionInputs
18
18
  * @property {string} [cwd]
19
- * @property {string} [epicBranch]
19
+ * @property {string} [baseBranch]
20
20
  * @property {string} [storyBranch]
21
21
  * @property {string} [baselinePath]
22
22
  */
@@ -32,7 +32,7 @@
32
32
  /**
33
33
  * @typedef {Object} ValidationFail
34
34
  * @property {false} ok
35
- * @property {'missing-cwd'|'missing-epic-branch'|'missing-story-branch'|'missing-baseline-path'|'no-baseline'} reason
35
+ * @property {'missing-cwd'|'missing-base-branch'|'missing-story-branch'|'missing-baseline-path'|'no-baseline'} reason
36
36
  */
37
37
 
38
38
  /**
@@ -40,7 +40,7 @@
40
40
  *
41
41
  * Reason branches (in order):
42
42
  * - `missing-cwd` — cwd is falsy
43
- * - `missing-epic-branch` — epicBranch is falsy
43
+ * - `missing-base-branch` — baseBranch is falsy
44
44
  * - `missing-story-branch` — storyBranch is falsy
45
45
  * - `missing-baseline-path` — baselinePath is falsy
46
46
  * - `no-baseline` — loadBaseline returned null/undefined/empty
@@ -54,9 +54,9 @@
54
54
  * @returns {ValidationOk | ValidationFail}
55
55
  */
56
56
  export function validateProjectionInputs(inputs, opts = {}) {
57
- const { cwd, epicBranch, storyBranch, baselinePath } = inputs ?? {};
57
+ const { cwd, baseBranch, storyBranch, baselinePath } = inputs ?? {};
58
58
  if (!cwd) return { ok: false, reason: 'missing-cwd' };
59
- if (!epicBranch) return { ok: false, reason: 'missing-epic-branch' };
59
+ if (!baseBranch) return { ok: false, reason: 'missing-base-branch' };
60
60
  if (!storyBranch) return { ok: false, reason: 'missing-story-branch' };
61
61
  if (!baselinePath) return { ok: false, reason: 'missing-baseline-path' };
62
62
 
@@ -80,7 +80,7 @@ export function validateProjectionInputs(inputs, opts = {}) {
80
80
  */
81
81
  export const MISSING_ARG_REASONS = new Set([
82
82
  'missing-cwd',
83
- 'missing-epic-branch',
83
+ 'missing-base-branch',
84
84
  'missing-story-branch',
85
85
  'missing-baseline-path',
86
86
  ]);
@@ -41,18 +41,18 @@ function normaliseSkipReason(reason) {
41
41
  }
42
42
 
43
43
  /**
44
- * Refresh `origin/<epicBranch>` so the diff range resolves even when the
44
+ * Refresh `origin/<baseBranch>` so the diff range resolves even when the
45
45
  * close script hasn't reached its own pull/rebase step yet. Routed through
46
46
  * the shared `(cwd, ref, windowMs)` cache so a story-init fetch in the same
47
47
  * wave satisfies the projection without re-hitting origin.
48
48
  *
49
49
  * @param {string} cwd
50
- * @param {string} epicBranch
50
+ * @param {string} baseBranch
51
51
  * @param {{ gitSpawn: typeof defaultGitSpawn }} git
52
52
  * @returns {{ ok: true } | { ok: false, detail: string }}
53
53
  */
54
- function refreshEpicRef(cwd, epicBranch, git) {
55
- const fetchRes = cachedGitFetchSync(cwd, epicBranch, {
54
+ function refreshEpicRef(cwd, baseBranch, git) {
55
+ const fetchRes = cachedGitFetchSync(cwd, baseBranch, {
56
56
  gitSpawn: git.gitSpawn,
57
57
  });
58
58
  if (fetchRes.status !== 0) {
@@ -69,13 +69,13 @@ function refreshEpicRef(cwd, epicBranch, git) {
69
69
  * the changed-files list. Normalises Windows-style backslash paths to
70
70
  * forward slashes so the baseline lookup is platform-agnostic.
71
71
  *
72
- * @param {{ cwd: string, epicBranch: string, storyBranch: string, git: { gitSpawn: typeof defaultGitSpawn } }} opts
72
+ * @param {{ cwd: string, baseBranch: string, storyBranch: string, git: { gitSpawn: typeof defaultGitSpawn } }} opts
73
73
  * @returns {{ ok: true, files: string[] } | { ok: false, detail: string }}
74
74
  */
75
- function diffChangedFiles({ cwd, epicBranch, storyBranch, git }) {
75
+ function diffChangedFiles({ cwd, baseBranch, storyBranch, git }) {
76
76
  try {
77
77
  const files = diffNameOnly({
78
- range: `origin/${epicBranch}...${storyBranch}`,
78
+ range: `origin/${baseBranch}...${storyBranch}`,
79
79
  cwd,
80
80
  gitSpawn: git.gitSpawn,
81
81
  });
@@ -190,7 +190,7 @@ function collectRegressions({
190
190
  *
191
191
  * @param {{
192
192
  * cwd: string,
193
- * epicBranch: string,
193
+ * baseBranch: string,
194
194
  * storyBranch: string,
195
195
  * baselinePath: string,
196
196
  * tolerance?: number,
@@ -207,7 +207,7 @@ function collectRegressions({
207
207
  */
208
208
  export function projectMaintainabilityRegressions({
209
209
  cwd,
210
- epicBranch,
210
+ baseBranch,
211
211
  storyBranch,
212
212
  baselinePath,
213
213
  tolerance = DEFAULT_MI_TOLERANCE,
@@ -216,7 +216,7 @@ export function projectMaintainabilityRegressions({
216
216
  loadBaseline = getBaseline,
217
217
  } = {}) {
218
218
  const validation = validateProjectionInputs(
219
- { cwd, epicBranch, storyBranch, baselinePath },
219
+ { cwd, baseBranch, storyBranch, baselinePath },
220
220
  { loadBaseline },
221
221
  );
222
222
  if (!validation.ok) {
@@ -227,7 +227,7 @@ export function projectMaintainabilityRegressions({
227
227
  };
228
228
  }
229
229
 
230
- const fetchOutcome = refreshEpicRef(cwd, epicBranch, git);
230
+ const fetchOutcome = refreshEpicRef(cwd, baseBranch, git);
231
231
  if (!fetchOutcome.ok) {
232
232
  return {
233
233
  ok: true,
@@ -237,7 +237,7 @@ export function projectMaintainabilityRegressions({
237
237
  };
238
238
  }
239
239
 
240
- const diffOutcome = diffChangedFiles({ cwd, epicBranch, storyBranch, git });
240
+ const diffOutcome = diffChangedFiles({ cwd, baseBranch, storyBranch, git });
241
241
  if (!diffOutcome.ok) {
242
242
  return {
243
243
  ok: true,
@@ -72,21 +72,19 @@ function applyChangedFileScope({ gate, spawnCwd, log }) {
72
72
  * Worktree locality (Story #1120): when `worktreePath` is supplied, every
73
73
  * gate runner is spawned with `cwd: worktreePath` so the gate sees the
74
74
  * Story branch's post-rebase tree. Evidence reads/writes still key against
75
- * `cwd` (the main checkout) because the per-Epic temp tree lives under
76
- * the main `.git/`. Failure messages name the worktree path.
75
+ * `cwd` (the main checkout) because the temp tree lives under the main
76
+ * `.git/`. Failure messages name the worktree path.
77
77
  *
78
- * Evidence-aware: when `storyId` is provided alongside either `epicId` or
79
- * `standalone: true`, and `useEvidence !== false`, each gate consults
78
+ * Evidence-aware: when `storyId` is provided alongside `standalone: true`,
79
+ * and `useEvidence !== false`, each gate consults
80
80
  * `validation-evidence.shouldSkip()` against current HEAD + the gate's
81
81
  * command-config hash. A matching record skips the gate; a successful run
82
82
  * is recorded so the next caller in the local hot path can skip in turn.
83
83
  *
84
- * Standalone keyspace (Story #4250): the standalone path has no parent
85
- * Epic, so it passes `standalone: true` (and leaves `epicId` null) to route
86
- * the evidence file to the storyId-anchored
84
+ * Standalone keyspace (Story #4250): `standalone: true` routes the evidence
85
+ * file to the storyId-anchored
87
86
  * `<tempRoot>/standalone/stories/story-<id>/validation-evidence.json`
88
- * keyspace instead of feeding a null `epicId` into the Epic-keyed path
89
- * (which structurally disabled the cache before).
87
+ * keyspace. v2.0.0 removed the Epic tier and its Epic-keyed keyspace.
90
88
  *
91
89
  * `onGateStart` is invoked immediately before each gate's runner spawn.
92
90
  * story-close uses it to drive `phaseTimer.mark(...)` for per-gate
@@ -100,7 +98,6 @@ function applyChangedFileScope({ gate, spawnCwd, log }) {
100
98
  * log?: (m: string) => void,
101
99
  * onGateStart?: (gate: Gate) => void,
102
100
  * storyId?: number|null,
103
- * epicId?: number|null,
104
101
  * standalone?: boolean,
105
102
  * useEvidence?: boolean,
106
103
  * evidenceClock?: () => number,
@@ -118,7 +115,6 @@ export async function runCloseValidation({
118
115
  log = () => {},
119
116
  onGateStart,
120
117
  storyId = null,
121
- epicId = null,
122
118
  standalone = false,
123
119
  useEvidence = true,
124
120
  evidenceClock = () => Date.now(),
@@ -129,16 +125,12 @@ export async function runCloseValidation({
129
125
  const failed = [];
130
126
  const skipped = [];
131
127
  // Evidence is active when a Story id is present AND there is a keyspace to
132
- // anchor on: either a real Epic id (Epic path) or `standalone: true`
133
- // (Story #4250 standalone storyId-anchored keyspace). A bare `epicId:
134
- // null` without `standalone` keeps the cache off, as before.
135
- const evidenceActive =
136
- useEvidence && storyId != null && (epicId != null || standalone);
137
- // The evidence-store opts: `standalone` routes to the storyId-anchored
138
- // keyspace; otherwise the Epic-keyed path resolves under `epicId`.
139
- const evidenceStoreOpts = { cwd, epicId, standalone };
140
- // Evidence keys against the main checkout's HEAD because the per-Epic
141
- // evidence file lives under the main `.git/`. Gate spawn, in contrast,
128
+ // anchor on (`standalone: true` — Story #4250's storyId-anchored
129
+ // keyspace, now the only one).
130
+ const evidenceActive = useEvidence && storyId != null && standalone;
131
+ const evidenceStoreOpts = { cwd, standalone };
132
+ // Evidence keys against the main checkout's HEAD because the evidence
133
+ // file lives under the main `.git/`. Gate spawn, in contrast,
142
134
  // runs in the worktree when one is supplied — that's the whole point of
143
135
  // Story #1120.
144
136
  const spawnCwd = worktreePath ?? cwd;