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
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/ledger-record.schema.json",
4
4
  "title": "Lifecycle ledger record (emitted | completed | failed)",
5
- "description": "Append-only NDJSON record shape for temp/epic-<id>/lifecycle.ndjson. Three discriminated kinds; consumers (LedgerWriter, the ledger-diff assertion helpers, TraceLogger) discriminate on `kind`.",
5
+ "description": "Append-only NDJSON record shape for temp/run-<id>/lifecycle.ndjson. Three discriminated kinds; consumers (LedgerWriter, the ledger-diff assertion helpers, TraceLogger) discriminate on `kind`.",
6
6
  "oneOf": [
7
7
  { "$ref": "#/$defs/emitted" },
8
8
  { "$ref": "#/$defs/completed" },
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://github.com/dsj1984/mandrel/blob/main/.agents/schemas/lifecycle/retro.end.schema.json",
4
4
  "title": "retro.end",
5
- "description": "Emitted at the end of the retro sub-phase. `posted` indicates whether the retro structured comment was upserted onto the Epic; `retroPath` is the local mirror path under temp/epic-<id>/ when written. Story #2252.",
5
+ "description": "Emitted at the end of the retro sub-phase. `posted` indicates whether the retro structured comment was upserted onto the Epic; `retroPath` is the local mirror path under temp/run-<id>/ when written. Story #2252.",
6
6
  "type": "object",
7
7
  "required": ["epicId", "posted"],
8
8
  "properties": {
@@ -47,20 +47,7 @@
47
47
  "type": "string",
48
48
  "minLength": 1,
49
49
  "description": "One-paragraph overall risk narrative for the audit trail (the rationale the retired regex classifier could never produce)."
50
- },
51
- "deliveryShape": {
52
- "type": "string",
53
- "enum": ["fan-out", "single"],
54
- "description": "Planner-judged delivery shape for the Epic (Epic #4474 PR4, design §2 mode matrix). 'fan-out' persists a Story tree (the default when the field is absent — existing verdicts stay valid); 'single' is the spec-only single-delivery mode: no tickets are authored, the ticket validator + DAG are skipped, and plan-persist applies the delivery::single routing marker instead of a Story tree. The marker is inert until #4475 lands the deliver-side reader."
55
- },
56
- "deliveryShapeRationale": {
57
- "type": "string",
58
- "minLength": 1,
59
- "description": "Concrete justification for the declared deliveryShape, grounded in the Delivery Slicing table (slice count / chain shape). Required whenever deliveryShape is present; surfaced as the routingReasons of the single-mode plan summary."
60
50
  }
61
51
  },
62
- "dependentRequired": {
63
- "deliveryShape": ["deliveryShapeRationale"]
64
- },
65
52
  "additionalProperties": false
66
53
  }
@@ -32,9 +32,20 @@
32
32
  * — this CLI is the decision + signal boundary, mirroring how the existing
33
33
  * gates separate decision from ticket mutation.
34
34
  *
35
+ * Two invocation shapes (Epic #4475, M4-B):
36
+ * - Per-Story (fan-out): the diff is one Story's; round scoping is per
37
+ * Story off the Story's `signals.ndjson`.
38
+ * - Per-AC-cluster (single delivery): `--epic <id> --cluster <clusterId>`
39
+ * with NO `--story`. The verdict scores one AC cluster of the Epic's
40
+ * `## Acceptance Table` against the cumulative `main..epic/<id>` diff;
41
+ * round scoping is per cluster off the Epic's `signals.ndjson`. This is
42
+ * the acceptance-dilution guard — `ceil(totalACs / clusterCeiling)`
43
+ * independent maker-blind critic passes, one per cluster.
44
+ *
35
45
  * CLI:
36
- * --story <id> Story ID (required).
37
- * --epic <id> Parent Epic ID (omit for standalone Stories).
46
+ * --story <id> Story ID (required unless --cluster is given).
47
+ * --epic <id> Parent Epic ID (required with --cluster).
48
+ * --cluster <id> AC-cluster id for the single-delivery critic.
38
49
  * --verdict <path> Path to the round's verdict JSON (required).
39
50
  * --no-signal Suppress the signal emit (tests).
40
51
  *
@@ -57,7 +68,10 @@ import addFormats from 'ajv-formats';
57
68
  import { runAsCli } from './lib/cli-utils.js';
58
69
  import { getAcceptanceEval, resolveConfig } from './lib/config-resolver.js';
59
70
  import { Logger } from './lib/Logger.js';
60
- import { appendSignal } from './lib/observability/signals-writer.js';
71
+ import {
72
+ appendEpicSignal,
73
+ appendSignal,
74
+ } from './lib/observability/signals-writer.js';
61
75
  import {
62
76
  buildAcceptanceEvalSignal,
63
77
  decideAcceptanceEval,
@@ -126,6 +140,7 @@ function parseCliArgs(argv) {
126
140
  options: {
127
141
  story: { type: 'string' },
128
142
  epic: { type: 'string' },
143
+ cluster: { type: 'string' },
129
144
  verdict: { type: 'string' },
130
145
  'no-signal': { type: 'boolean', default: false },
131
146
  },
@@ -136,6 +151,10 @@ function parseCliArgs(argv) {
136
151
  return {
137
152
  storyId: Number.isInteger(storyId) && storyId > 0 ? storyId : null,
138
153
  epicId: Number.isInteger(epicRaw) && epicRaw > 0 ? epicRaw : null,
154
+ clusterId:
155
+ typeof values.cluster === 'string' && values.cluster.length > 0
156
+ ? values.cluster
157
+ : null,
139
158
  verdictPath: values.verdict ?? null,
140
159
  emitSignal: values['no-signal'] !== true,
141
160
  };
@@ -163,18 +182,23 @@ function parseCliArgs(argv) {
163
182
  * @returns {Promise<{ envelope: object, exitCode: number }>}
164
183
  */
165
184
  export async function runAcceptanceEval(
166
- { storyId, epicId, verdict, config, emitSignal, round },
185
+ { storyId, epicId, clusterId = null, verdict, config, emitSignal, round },
167
186
  deps = {},
168
187
  ) {
169
188
  const {
170
189
  appendSignalFn = appendSignal,
190
+ appendEpicSignalFn = appendEpicSignal,
171
191
  deriveRoundFn = deriveAcceptanceEvalRound,
172
192
  } = deps;
193
+ const clusterMode =
194
+ typeof clusterId === 'string' &&
195
+ clusterId.length > 0 &&
196
+ Number.isInteger(epicId);
173
197
  const { maxRounds } = getAcceptanceEval(config);
174
198
  const resolvedRound =
175
199
  Number.isInteger(round) && round >= 1
176
200
  ? round
177
- : deriveRoundFn({ epicId: epicId ?? null, storyId, config });
201
+ : deriveRoundFn({ epicId: epicId ?? null, storyId, clusterId, config });
178
202
  const outcome = decideAcceptanceEval({
179
203
  verdict,
180
204
  maxRounds,
@@ -184,16 +208,21 @@ export async function runAcceptanceEval(
184
208
  let signalEmitted = false;
185
209
  if (emitSignal) {
186
210
  const signal = {
187
- ...buildAcceptanceEvalSignal({ storyId, epicId, outcome }),
211
+ ...buildAcceptanceEvalSignal({ storyId, epicId, outcome, clusterId }),
188
212
  ts: new Date().toISOString(),
189
213
  };
190
214
  try {
191
- signalEmitted = await appendSignalFn({
192
- epicId,
193
- storyId,
194
- signal,
195
- config,
196
- });
215
+ // Cluster mode (single delivery) writes to the epic-level signals
216
+ // stream so per-cluster round counts survive resume; the per-Story
217
+ // path writes to the Story stream (unchanged).
218
+ signalEmitted = clusterMode
219
+ ? await appendEpicSignalFn({ epicId, signal, config })
220
+ : await appendSignalFn({
221
+ epicId,
222
+ storyId,
223
+ signal,
224
+ config,
225
+ });
197
226
  } catch (err) {
198
227
  // Observability is best-effort — a failed signal write must never
199
228
  // take down the gate. The decision still stands.
@@ -206,8 +235,9 @@ export async function runAcceptanceEval(
206
235
  }
207
236
 
208
237
  const envelope = {
209
- storyId,
238
+ storyId: storyId ?? null,
210
239
  epicId: epicId ?? null,
240
+ ...(clusterMode ? { clusterId } : {}),
211
241
  decision: outcome.decision,
212
242
  round: outcome.round,
213
243
  cap: outcome.cap,
@@ -231,11 +261,19 @@ export async function runAcceptanceEval(
231
261
  }
232
262
 
233
263
  export async function main(argv = process.argv.slice(2)) {
234
- const { storyId, epicId, verdictPath, emitSignal } = parseCliArgs(argv);
264
+ const { storyId, epicId, clusterId, verdictPath, emitSignal } =
265
+ parseCliArgs(argv);
235
266
 
236
- if (!storyId) {
267
+ // Epic #4475 (M4-B): two invocation shapes.
268
+ // - Per-Story (fan-out): --story <id> [--epic <id>].
269
+ // - Per-AC-cluster (single delivery): --epic <id> --cluster <id> (no
270
+ // --story); the verdict scores one AC cluster of the Epic's Acceptance
271
+ // Table against the cumulative main..epic/<id> diff.
272
+ const clusterMode = Boolean(clusterId) && Number.isInteger(epicId);
273
+ if (!storyId && !clusterMode) {
237
274
  throw new Error(
238
- 'Usage: node acceptance-eval.js --story <id> [--epic <id>] --verdict <path> [--no-signal]',
275
+ 'Usage: node acceptance-eval.js --story <id> [--epic <id>] --verdict <path> [--no-signal]\n' +
276
+ ' or: node acceptance-eval.js --epic <id> --cluster <clusterId> --verdict <path> [--no-signal]',
239
277
  );
240
278
  }
241
279
  if (!verdictPath) {
@@ -267,8 +305,13 @@ export async function main(argv = process.argv.slice(2)) {
267
305
  const verdict = validateVerdict(parsed);
268
306
 
269
307
  // A verdict whose embedded storyId disagrees with the CLI flag is a
270
- // wiring error worth failing on, not a silent mismatch.
271
- if (Number.isInteger(verdict.storyId) && verdict.storyId !== storyId) {
308
+ // wiring error worth failing on, not a silent mismatch. Skipped in cluster
309
+ // mode (no --story; the verdict scores an AC cluster, not a Story).
310
+ if (
311
+ !clusterMode &&
312
+ Number.isInteger(verdict.storyId) &&
313
+ verdict.storyId !== storyId
314
+ ) {
272
315
  throw new Error(
273
316
  `acceptance-eval: verdict storyId (${verdict.storyId}) does not match --story ${storyId}.`,
274
317
  );
@@ -278,6 +321,7 @@ export async function main(argv = process.argv.slice(2)) {
278
321
  const { envelope, exitCode } = await runAcceptanceEval({
279
322
  storyId,
280
323
  epicId,
324
+ clusterId,
281
325
  verdict,
282
326
  config,
283
327
  emitSignal,
@@ -237,7 +237,7 @@ async function ensureProjectFields(provider, project, log) {
237
237
  *
238
238
  * Accepts the canonical resolved config (output of `resolveConfig()` —
239
239
  * `config.github` holds the GitHub provider block). Epic #2880 removed the
240
- * legacy shim parameters; see `.agents/rules/git-conventions.md#contract-cutovers-—-no-shim-layer`.
240
+ * legacy shim parameters; see `.agents/rules/git-conventions-reference.md#contract-cutovers-—-no-shim-layer`.
241
241
  *
242
242
  * Consent-first install (Story #3526, Feature #3515, Epic #3438): every
243
243
  * mutation this function performs — labels, Projects V2, branch protection,
@@ -27,7 +27,7 @@
27
27
  * NDJSON for a Story, no children for an Epic) so the close pipelines
28
28
  * never block on observability output. Hard failures (bad CLI args,
29
29
  * provider error, schema-violating payload) exit non-zero — the call
30
- * sites in post-merge-pipeline / `/deliver` Phase 5 treat that
30
+ * sites in `single-story-close.js` / `helpers/deliver-story.md` treat that
31
31
  * as a non-fatal warning.
32
32
  *
33
33
  * This file is a thin CLI: it wires the I/O readers from
@@ -12,8 +12,8 @@
12
12
  * Emits a single `audit-to-stories-plan.json` envelope to --out (or
13
13
  * stdout when --json is set).
14
14
  *
15
- * --emit-epic-seed --plan <plan.json> --out <path>
16
- * Read the plan envelope from disk, render the `/plan --idea`
15
+ * --emit-plan-seed --plan <plan.json> --out <path>
16
+ * Read the plan envelope from disk, render the `/plan --seed`
17
17
  * seed markdown, persist to --out.
18
18
  *
19
19
  * --emit-stories --plan <plan.json>
@@ -37,7 +37,7 @@ import { classifyGroupsAgainstGitHub } from './lib/audit-to-stories/dedupe-again
37
37
  import { withFingerprints } from './lib/audit-to-stories/finding-adapter.js';
38
38
  import { groupFindings } from './lib/audit-to-stories/group-findings.js';
39
39
  import { parseAuditReports } from './lib/audit-to-stories/parse-audit-md.js';
40
- import { buildEpicSeedMarkdown } from './lib/audit-to-stories/seed-epic-from-findings.js';
40
+ import { buildPlanSeedMarkdown } from './lib/audit-to-stories/seed-from-findings.js';
41
41
  import { runAsCli } from './lib/cli-utils.js';
42
42
  import { Logger } from './lib/Logger.js';
43
43
  import { parse as parseStoryBody } from './lib/story-body/story-body.js';
@@ -291,7 +291,7 @@ async function main() {
291
291
  args: process.argv.slice(2),
292
292
  options: {
293
293
  scan: { type: 'boolean' },
294
- 'emit-epic-seed': { type: 'boolean' },
294
+ 'emit-plan-seed': { type: 'boolean' },
295
295
  'emit-stories': { type: 'boolean' },
296
296
  glob: { type: 'string' },
297
297
  severity: { type: 'string' },
@@ -315,9 +315,9 @@ async function main() {
315
315
  return;
316
316
  }
317
317
 
318
- if (values['emit-epic-seed']) {
318
+ if (values['emit-plan-seed']) {
319
319
  const plan = loadPlan(values.plan);
320
- const md = buildEpicSeedMarkdown({
320
+ const md = buildPlanSeedMarkdown({
321
321
  groups: plan.groups ?? [],
322
322
  findings: plan.findings ?? [],
323
323
  sourceReports: plan.sourceReports ?? [],
@@ -346,7 +346,7 @@ async function main() {
346
346
  }
347
347
 
348
348
  throw new Error(
349
- 'Usage: node audit-to-stories.js (--scan | --emit-epic-seed | --emit-stories) [options]',
349
+ 'Usage: node audit-to-stories.js (--scan | --emit-plan-seed | --emit-stories) [options]',
350
350
  );
351
351
  }
352
352
 
@@ -72,7 +72,7 @@ Options:
72
72
  * returns the sweep envelope so no caller can be blocked by a failure.
73
73
  *
74
74
  * DI-friendly: `injectedConfig` / `injectedProvider` let a caller (e.g.
75
- * `epic-deliver-prepare.js`) reuse an already-resolved config + provider,
75
+ * `single-story-init.js`) reuse an already-resolved config + provider,
76
76
  * and `injectedSweep` swaps the engine for unit tests.
77
77
  *
78
78
  * @param {{
@@ -12,7 +12,13 @@
12
12
  * session and every subagent spawn (instructions.md § 4).
13
13
  * - `mandatoryRead` — the resolved `project.docsContextFiles` set.
14
14
  *
15
- * A tier that resolves **empty** is skipped silently (the `docsContextFiles`
15
+ * It additionally enforces a **per-file** ceiling on the role-scoped agent-boot
16
+ * tier (`.agents/agents/*.md`, #4478): no single boot context may exceed
17
+ * `agentBoot.ceilingBytes` (default 8192). This is a per-agent cap, not a sum
18
+ * ratchet — each role def is a standalone system prompt a converted spawn boots
19
+ * on, and adding another role def is legitimate.
20
+ *
21
+ * A read-tier that resolves **empty** is skipped silently (the `docsContextFiles`
16
22
  * half skips when unconfigured / its files are absent), so a repo with no
17
23
  * `CLAUDE.md` and no context docs is a clean no-op.
18
24
  *
@@ -60,6 +66,31 @@ export const GATED_TIERS = ['alwaysLoaded', 'mandatoryRead'];
60
66
  */
61
67
  export const DEFAULT_TOLERANCE_BYTES = 2048;
62
68
 
69
+ /**
70
+ * Per-file ceiling (bytes) for the role-scoped agent-boot tier (#4478). Unlike
71
+ * the read-tiers (gated by a total-byte ratchet), each `.agents/agents/*.md`
72
+ * boot context is a **standalone** system prompt a converted spawn boots on, so
73
+ * the meaningful budget is per-agent, not the sum: no single role def may
74
+ * exceed this ceiling. Adding another role def is legitimate — a per-file gate
75
+ * (rather than a sum ratchet) does not false-positive on that.
76
+ * @type {number}
77
+ */
78
+ export const AGENT_BOOT_CEILING_BYTES = 8192;
79
+
80
+ /**
81
+ * Return the agent-boot files that exceed the per-file ceiling.
82
+ *
83
+ * @param {{ tiers: Record<string, Array<{ path: string, bytes: number }>> }} tierMap
84
+ * @param {number} ceiling
85
+ * @returns {Array<{ path: string, bytes: number, ceiling: number }>}
86
+ */
87
+ export function agentBootOverflow(tierMap, ceiling = AGENT_BOOT_CEILING_BYTES) {
88
+ const files = tierMap?.tiers?.agentBoot ?? [];
89
+ return files
90
+ .filter((f) => Number.isFinite(f?.bytes) && f.bytes > ceiling)
91
+ .map((f) => ({ path: f.path, bytes: f.bytes, ceiling }));
92
+ }
93
+
63
94
  /**
64
95
  * Parse argv for `--baseline <path>`, `--root <path>`, `--update`, `--json`.
65
96
  * Exported so unit tests can pin the parser.
@@ -127,11 +158,19 @@ export function buildBaseline(tierMap, toleranceBytes) {
127
158
  const files = tierMap.tiers[name] ?? [];
128
159
  tiers[name] = { totalBytes: tierTotalBytes(files), files };
129
160
  }
161
+ // The agent-boot tier is recorded top-level (not under `tiers`) because it is
162
+ // gated by a per-file ceiling, not the total-byte ratchet the `tiers` entries
163
+ // use — keeping it out of `tiers` keeps the ratchet diff loop unambiguous.
164
+ const agentBootFiles = tierMap.tiers.agentBoot ?? [];
130
165
  return {
131
166
  $schema: 'https://mandrel.dev/baselines/context-budget.schema.json',
132
167
  generatedAt: new Date().toISOString(),
133
168
  toleranceBytes,
134
169
  tiers,
170
+ agentBoot: {
171
+ ceilingBytes: AGENT_BOOT_CEILING_BYTES,
172
+ files: agentBootFiles,
173
+ },
135
174
  };
136
175
  }
137
176
 
@@ -278,7 +317,11 @@ export async function runCli({
278
317
  }
279
318
 
280
319
  const diff = diffBudget(tierMap, baseline);
281
- const exitCode = diff.grown.length > 0 ? 1 : 0;
320
+ const ceiling = Number.isFinite(baseline?.agentBoot?.ceilingBytes)
321
+ ? baseline.agentBoot.ceilingBytes
322
+ : AGENT_BOOT_CEILING_BYTES;
323
+ const bootOverflow = agentBootOverflow(tierMap, ceiling);
324
+ const exitCode = diff.grown.length > 0 || bootOverflow.length > 0 ? 1 : 0;
282
325
 
283
326
  if (json) {
284
327
  const envelope = {
@@ -293,17 +336,31 @@ export async function runCli({
293
336
  grown: diff.grown,
294
337
  shrunk: diff.shrunk,
295
338
  skipped: diff.skipped,
339
+ agentBootCeilingBytes: ceiling,
340
+ agentBootOverflow: bootOverflow,
296
341
  exitCode,
297
342
  };
298
343
  stdout.write(`${JSON.stringify(envelope, null, 2)}\n`);
299
344
  } else {
300
345
  stdout.write(`\n--- context-budget preview ---\n`);
301
346
  stdout.write(`${renderDiff(diff)}\n`);
302
- if (exitCode === 1) {
303
- stderr.write(
304
- `[context-budget] a documentation tier grew beyond tolerance — refresh the budget consciously with \`node .agents/scripts/check-context-budget.js --update\` once the growth is intentional\n`,
347
+ for (const o of bootOverflow) {
348
+ stdout.write(
349
+ `+ agentBoot: ${o.path} is ${o.bytes} bytes, over the ${o.ceiling}-byte per-agent ceiling\n`,
305
350
  );
306
351
  }
352
+ if (exitCode === 1) {
353
+ if (bootOverflow.length > 0) {
354
+ stderr.write(
355
+ `[context-budget] ❌ a role-agent boot context exceeds the ${ceiling}-byte per-agent ceiling — trim the role def (the ceiling is a hard cap, not a starve target)\n`,
356
+ );
357
+ }
358
+ if (diff.grown.length > 0) {
359
+ stderr.write(
360
+ `[context-budget] ❌ a documentation tier grew beyond tolerance — refresh the budget consciously with \`node .agents/scripts/check-context-budget.js --update\` once the growth is intentional\n`,
361
+ );
362
+ }
363
+ }
307
364
  }
308
365
 
309
366
  return exitCode;
@@ -80,17 +80,14 @@ const SCRIPTS_DIR = path.join(REPO_ROOT, '.agents', 'scripts');
80
80
  * auto-merge call could re-enter the codebase.
81
81
  */
82
82
  const MERGE_LOCKOUT_ALLOWED_SUFFIXES = Object.freeze([
83
- // Story #2256 / #2336 — the predicate-gated AutomergeArmer listener is
84
- // now the SOLE production code path authorized to call `gh pr merge`.
85
- // The legacy `.agents/scripts/epic-deliver-automerge.js` exemption was
86
- // removed in Story #2336 / Task #2340 once the CLI was reduced to a
87
- // pure `epic.automerge.start` emit shim.
83
+ // v2 Story close path — the sole production code path authorized to
84
+ // call `gh pr merge` after the Epic AutomergeArmer listener was removed.
88
85
  path.join(
89
86
  'lib',
90
87
  'orchestration',
91
- 'lifecycle',
92
- 'listeners',
93
- 'automerge-armer.js',
88
+ 'single-story-close',
89
+ 'phases',
90
+ 'auto-merge.js',
94
91
  ),
95
92
  ]);
96
93
 
@@ -339,7 +336,7 @@ export function findMergeLockoutViolations(
339
336
  violations.push({
340
337
  file,
341
338
  line: i + 1,
342
- hint: `String literal containing '${FORBIDDEN}' is forbidden outside automerge-armer.js (Story #2253 review High-1). Auto-merge enablement must flow through the AutomergeArmer listener so blocker/review predicates gate the call.`,
339
+ hint: `String literal containing '${FORBIDDEN}' is forbidden outside single-story-close/phases/auto-merge.js. Auto-merge enablement must flow through the Story close path.`,
343
340
  });
344
341
  break; // one violation per line is enough
345
342
  }
@@ -3,7 +3,7 @@
3
3
  * check-prepush-recovery.js — gate decision for the pre-push coverage step.
4
4
  *
5
5
  * Story #3162. The pre-push hook normally runs `coverage-capture.js` +
6
- * `crap:check` on every push. During a `story-close.js` recovery (operator
6
+ * `crap:check` on every push. During a pre-v2 `story-close.js` recovery (operator
7
7
  * pushing `epic/<id>` to unblock a run after a merge-orchestrator failure),
8
8
  * a pre-existing coverage regression on `epic/<id>` — unrelated to the
9
9
  * Story under recovery — hard-blocks the push and forces a `--no-verify`
@@ -20,7 +20,12 @@
20
20
  import { existsSync, readdirSync, rmSync } from 'node:fs';
21
21
  import path from 'node:path';
22
22
  import { runAsCli } from './lib/cli-utils.js';
23
- import { isReservedTestEpicTempDirName } from './lib/test-reserved-epic-temp-ids.js';
23
+
24
+ const RESERVED_TEST_EPIC_TEMP_DIR = /^epic-999\d{3}$/;
25
+
26
+ function isReservedTestEpicTempDirName(name) {
27
+ return RESERVED_TEST_EPIC_TEMP_DIR.test(name);
28
+ }
24
29
 
25
30
  /**
26
31
  * @param {object} [opts]
@@ -81,12 +81,6 @@ const FRICTION_RULES = [
81
81
  remediation:
82
82
  ' - Syntax/parsing error. Check recently modified files for missing brackets, quotes, or invalid structures.',
83
83
  },
84
- {
85
- markers: ['Astro', 'astro'],
86
- category: 'Missing Skill',
87
- remediation:
88
- ' - Framework error: Refer to `.agents/skills/stack/frontend/astro/SKILL.md` for Astro rules.',
89
- },
90
84
  ];
91
85
 
92
86
  const FRICTION_DEFAULT = {
@@ -18,7 +18,6 @@
18
18
  * - `silent` → only `fatal` emits.
19
19
  * - `info` → default. Emits `info` and above; suppresses `debug`.
20
20
  * - `verbose` → emits everything (including `debug`).
21
- * - `debug` → alias for `verbose` (backward compatible).
22
21
  */
23
22
  /**
24
23
  * Recognized log levels, lowest-noise first. Anything outside this set
@@ -26,9 +25,7 @@
26
25
  *
27
26
  * @type {ReadonlySet<string>}
28
27
  */
29
- const VALID_LEVELS = Object.freeze(
30
- new Set(['silent', 'info', 'verbose', 'debug']),
31
- );
28
+ const VALID_LEVELS = Object.freeze(new Set(['silent', 'info', 'verbose']));
32
29
 
33
30
  /**
34
31
  * Process-wide level override. `null` means "no explicit override — read
@@ -50,7 +47,7 @@ let levelOverride = null;
50
47
  * the level branches react in-process, without a child process per level
51
48
  * (Story #3329).
52
49
  *
53
- * @returns {'silent'|'info'|'verbose'|'debug'}
50
+ * @returns {'silent'|'info'|'verbose'}
54
51
  */
55
52
  export function resolveLevel() {
56
53
  const raw = (
@@ -63,12 +60,12 @@ export function resolveLevel() {
63
60
 
64
61
  /**
65
62
  * Pin the process-wide log level, bypassing `AGENT_LOG_LEVEL`. Pass a
66
- * recognized level (`silent` / `info` / `verbose` / `debug`) to force it,
63
+ * recognized level (`silent` / `info` / `verbose`) to force it,
67
64
  * or `null` to clear the pin and restore env-driven resolution. An
68
65
  * unrecognized non-null value throws so callers cannot silently pin a
69
66
  * level that resolves to `info`.
70
67
  *
71
- * @param {('silent'|'info'|'verbose'|'debug')|null} level
68
+ * @param {('silent'|'info'|'verbose')|null} level
72
69
  * @returns {void}
73
70
  */
74
71
  export function setLevel(level) {
@@ -78,15 +75,14 @@ export function setLevel(level) {
78
75
  }
79
76
  if (typeof level !== 'string' || !VALID_LEVELS.has(level.toLowerCase())) {
80
77
  throw new RangeError(
81
- `setLevel: level must be one of silent|info|verbose|debug or null (got ${level})`,
78
+ `setLevel: level must be one of silent|info|verbose or null (got ${level})`,
82
79
  );
83
80
  }
84
81
  levelOverride = level.toLowerCase();
85
82
  }
86
83
 
87
84
  function debugEnabled() {
88
- const level = resolveLevel();
89
- return level === 'verbose' || level === 'debug';
85
+ return resolveLevel() === 'verbose';
90
86
  }
91
87
 
92
88
  function infoEnabled() {
@@ -189,8 +189,8 @@ export async function runAuditSuite({
189
189
  injectedRules,
190
190
  injectedWriteArtifact,
191
191
  }) {
192
- const { agentSettings } = resolveConfig();
193
- const paths = getPaths({ agentSettings });
192
+ const config = resolveConfig();
193
+ const paths = getPaths(config);
194
194
  const callerSubstitutions = substitutions ?? {};
195
195
  const rules = injectedRules ?? (await loadRules(paths));
196
196
 
@@ -109,10 +109,10 @@ export const LENS_TIERS = Object.freeze(['local', 'cumulative', 'global']);
109
109
  * @throws {Error} When the manifest cannot be read or parsed.
110
110
  */
111
111
  function readAuditRulesSync() {
112
- const { agentSettings } = resolveConfig();
112
+ const config = resolveConfig();
113
113
  const rulesPath = path.join(
114
114
  PROJECT_ROOT,
115
- getPaths({ agentSettings }).schemasRoot,
115
+ getPaths(config).schemasRoot,
116
116
  'audit-rules.json',
117
117
  );
118
118
  try {
@@ -160,7 +160,7 @@ export function resolveLensTier(lens) {
160
160
  * every path) matches every change set here, so its concern is verified at
161
161
  * BOTH innermost tiers — the
162
162
  * write-time checklist threading and this Story-scope lens pass — and excluded
163
- * from Epic close (a local lens is dropped by {@link selectEpicCloseLenses}).
163
+ * from the retired Epic-close roster (local lenses stay Story-scope only).
164
164
  * A local lens with an empty `filePatterns` list matches nothing here, so a
165
165
  * diff matching no local lens's patterns yields an empty roster and adds no
166
166
  * lens work.
@@ -300,12 +300,12 @@ export async function selectAudits({
300
300
  gitTimeoutMsOverride,
301
301
  gateModeOpts,
302
302
  }) {
303
- const { agentSettings } = resolveConfig();
303
+ const config = resolveConfig();
304
304
  const timeoutMs = gitTimeoutMsOverride ?? DEFAULT_GIT_TIMEOUT_MS;
305
305
 
306
306
  const rulesPath = path.join(
307
307
  PROJECT_ROOT,
308
- getPaths({ agentSettings }).schemasRoot,
308
+ getPaths(config).schemasRoot,
309
309
  'audit-rules.json',
310
310
  );
311
311
  let rulesData;
@@ -1,17 +1,17 @@
1
1
  /**
2
- * lib/audit-to-stories/seed-epic-from-findings.js
2
+ * lib/audit-to-stories/seed-from-findings.js
3
3
  *
4
- * Build the `--idea`-shaped seed markdown that `/plan` Phase 1
5
- * consumes when the operator picks the Single-Epic grouping mode.
4
+ * Build the `/plan --seed`-shaped one-pager markdown that the audit-to-
5
+ * stories Single-plan grouping path emits for `/plan` to consume.
6
6
  *
7
- * The seed renders the canonical one-pager sections so the idea-refinement
8
- * skill can sharpen it without having to invent context:
7
+ * The seed renders the canonical one-pager sections so the authoring
8
+ * pass can sharpen it without having to invent context:
9
9
  * - Problem Statement (aggregated severity profile)
10
10
  * - Recommended Direction (rollup of recommendations by dimension)
11
11
  * - Key Assumptions (carries the source-report links forward)
12
12
  * - MVP Scope (the proposed Stories, one bullet per group)
13
- * - Key Files (explicit file paths so /plan Phase 7 decompose
14
- * has concrete anchors)
13
+ * - Key Files (explicit file paths so `/plan` authoring has concrete
14
+ * anchors)
15
15
  * - Not Doing (out-of-scope items by convention)
16
16
  *
17
17
  * Pure: returns a string. The caller decides where to persist it.
@@ -112,14 +112,14 @@ function formatKeyAssumptions(sourceReports) {
112
112
  * @param {string[]} params.sourceReports — list of source report paths.
113
113
  * @returns {string}
114
114
  */
115
- export function buildEpicSeedMarkdown({ groups, findings, sourceReports }) {
115
+ export function buildPlanSeedMarkdown({ groups, findings, sourceReports }) {
116
116
  if (
117
117
  !Array.isArray(groups) ||
118
118
  !Array.isArray(findings) ||
119
119
  !Array.isArray(sourceReports)
120
120
  ) {
121
121
  throw new Error(
122
- 'buildEpicSeedMarkdown: groups, findings, sourceReports must all be arrays',
122
+ 'buildPlanSeedMarkdown: groups, findings, sourceReports must all be arrays',
123
123
  );
124
124
  }
125
125
  const problem = formatProblemStatement(findings);