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,8 +1,9 @@
1
1
  import { LIMITS_DEFAULTS } from '../config/limits.js';
2
2
  import {
3
3
  AUTHORING_ALTITUDE_GUIDANCE,
4
- DEFAULT_TASK_SIZING,
4
+ DEFAULT_MODEL_CAPACITY,
5
5
  DELIVERABLE_GRANULARITY_GUIDANCE,
6
+ resolveCapacityCeilings,
6
7
  } from '../orchestration/ticket-validator-sizing.js';
7
8
 
8
9
  /**
@@ -18,27 +19,16 @@ import {
18
19
  * asks the planner to carry acceptance/verify as top-level ticket arrays.
19
20
  *
20
21
  * **Single source of the prompt body (Story #4162).** This module is the sole
21
- * carrier of the full decomposer system-prompt body. The
22
- * `epic-plan-decompose-author` SKILL no longer embeds a second verbatim copy —
23
- * it references this rendered prompt (delivered to the host LLM in the
24
- * `systemPrompt` field of the authoring context envelope built by
25
- * `epic-plan-decompose/phases/context.js`) instead, so the two surfaces cannot
26
- * drift. A guard test (`tests/ticket-decomposer.test.js`) fails if the SKILL
27
- * re-grows a full copy of the prompt preamble.
28
- *
29
- * **Token-budget sizing input (Story #4162).** `maxTokenBudget` is the real
30
- * one-pass delivery envelope (the task-prompt hydration cap surfaced into the
31
- * authoring envelope by `context.js`, Story #3875). It is threaded into the
32
- * rendered prompt as a sizing input so the planner sizes Stories against the
33
- * envelope a single agent can actually deliver in one pass, rather than leading
34
- * with the file-count proxy alone.
22
+ * carrier of the full decomposer system-prompt body, delivered to the host
23
+ * LLM in the `systemPrompts.decompose` field of the `/plan` context envelope
24
+ * (via `lib/orchestration/planning/decomposer-context.js`), so no second
25
+ * verbatim copy can drift.
35
26
  */
36
27
  export function renderDecomposerSystemPrompt({
37
28
  maxTickets = LIMITS_DEFAULTS.maxTickets,
38
- maxTokenBudget = LIMITS_DEFAULTS.maxTokenBudget,
39
29
  epicId = null,
40
30
  } = {}) {
41
- return render2TierPrompt({ maxTickets, maxTokenBudget, epicId });
31
+ return render2TierPrompt({ maxTickets, epicId });
42
32
  }
43
33
 
44
34
  /**
@@ -47,12 +37,16 @@ export function renderDecomposerSystemPrompt({
47
37
  * on the Story body so the executing agent has everything it needs in one
48
38
  * ticket. Thematic grouping lives as prose in the Epic body / Tech Spec.
49
39
  */
50
- function render2TierPrompt({ maxTickets, maxTokenBudget, epicId = null }) {
51
- // Sizing thresholds are sourced from the single DEFAULT_TASK_SIZING constant
52
- // (ticket-validator-sizing.js) so the prompt and the validator cannot drift.
53
- const { softFiles, hardFiles, softAcceptanceCount } = DEFAULT_TASK_SIZING;
40
+ function render2TierPrompt({ maxTickets, epicId = null }) {
41
+ // v2 Stage 3: default-single emit one Story unless the split policy clears.
42
+ // Capacity thresholds are sourced from the single DEFAULT_MODEL_CAPACITY
43
+ // constant (ticket-validator-sizing.js) so the prompt and the validator
44
+ // cannot drift.
45
+ const { softSessionTokens, hardSessionTokens } = resolveCapacityCeilings(
46
+ DEFAULT_MODEL_CAPACITY,
47
+ );
54
48
  // Deliverable-granularity definition + single-consumer merge rule + the
55
- // soft envelope-floor heuristic are sourced from the single
49
+ // thin-dependent merge heuristic are sourced from the single
56
50
  // DELIVERABLE_GRANULARITY_GUIDANCE constant (ticket-validator-sizing.js) so
57
51
  // the prompt and the authoring SKILL cannot drift (Story #3777; the
58
52
  // envelope-floor sentence added by Story #4313).
@@ -78,17 +72,20 @@ function render2TierPrompt({ maxTickets, maxTokenBudget, epicId = null }) {
78
72
  ? `@epic-${epicId}-ac-1`
79
73
  : '@epic-<id>-ac-N';
80
74
  return `You are an expert Senior Project Manager and Orchestrator.
81
- Your job is to take an Epic (including its inline User Stories) and a Technical Specification and decompose them into a flat list of Story tickets for an AI Agent to execute.
75
+ Your job is to turn a plan seed / Tech Spec into a Story ticket array for an AI Agent to execute.
82
76
 
83
- ### HIERARCHY RULES:
84
- 1. **Stories**: Specific user-facing or architectural user stories (e.g., "Implement JWT Token Exchange").
85
- - Every Story attaches directly to the Epic there is NO Feature tier and NO Task layer in this hierarchy.
86
- - **Story-Level Execution**: Each Story will be executed end-to-end on a single branch by a single agent. Acceptance criteria and verification commands live as top-level \`acceptance[]\` / \`verify[]\` arrays on the Story ticket (see STORY BODY SCHEMA below).
87
- - Thematic grouping is prose in the Epic body / Tech Spec, never a ticket.
77
+ ### HIERARCHY RULES (v2 default-single):
78
+ 1. **Emit exactly one Story by default.** Split into N>1 only when pieces have near-zero overlap or sit across an architectural seam. Coupled work stays one Story — put intra-session checkpoints in \`## Slicing\` and fold the Tech Spec into \`## Spec\`.
79
+ 2. **Stories**: Specific user-facing or architectural capabilities (e.g., "Implement JWT Token Exchange").
80
+ - There is NO Epic parent ticket, NO Feature tier, and NO Task layer.
81
+ - **Story-Level Execution**: Each Story is executed end-to-end on a single branch by a single agent. Acceptance criteria and verification commands live as top-level \`acceptance[]\` / \`verify[]\` arrays on the Story ticket (see STORY BODY SCHEMA below).
82
+ - Thematic grouping is prose in the Story's folded \`## Spec\` / \`## Slicing\`, never sibling tickets for coupled work.
88
83
 
89
84
  ### LABEL CONVENTIONS:
90
- - Every ticket must have the \`type::story\` label. No other type label is allowed the retired Feature and Task tiers have no labels under this hierarchy.
91
- - Every ticket must have a \`persona::[engineer|architect|qa-engineer|security-engineer|etc]\` label indicating WHO should execute it.
85
+ - \`type::story\` is applied automatically by persist — you do not need to emit it, and no other type label is allowed (the retired Feature and Task tiers have no labels under this hierarchy).
86
+ - \`labels[]\` is **optional**. Emit it only to request an *additional* label; persist sanitizes the list before applying it.
87
+ - Do **not** emit \`agent::*\` labels — lifecycle state is runtime-owned, and persist applies \`agent::ready\` itself once every checkpoint is on the ticket.
88
+ - Do **not** emit \`persona::*\` labels — the behavioral persona concept (and its label axis) was removed in v2.
92
89
 
93
90
  ### OUTPUT FORMAT:
94
91
  You MUST respond ONLY with a valid JSON array of objects. No prose, no markdown blocks.
@@ -102,7 +99,7 @@ You MUST respond ONLY with a valid JSON array of objects. No prose, no markdown
102
99
  "body": <string — see STORY BODY SCHEMA below>,
103
100
  "acceptance": ["<testable, observable criterion>", ...],
104
101
  "verify": ["<exact command or test path> (<tier>)", ...],
105
- "labels": ["type::story", "persona::..."],
102
+ "labels": ["<extra-label>"] (optional — type::story is applied automatically; omit this field unless you need an additional label),
106
103
  "depends_on": ["slug-of-blocking-dependency"] (optional array of Story slugs that block execution)
107
104
  }
108
105
  ]
@@ -112,12 +109,20 @@ You MUST respond ONLY with a valid JSON array of objects. No prose, no markdown
112
109
  ### STORY BODY SCHEMA (REQUIRED FOR EVERY STORY):
113
110
  \`body\` MUST be a **string** — the serialized markdown produced by \`serialize()\` from \`lib/story-body/story-body.js\`. Do NOT emit \`body\` as a JSON object: an object body throws \`StoryBodyParseError\` in the reconciler (Story #3302) and is discarded by the GitHub provider, producing an empty issue body. Stories are consumed by non-interactive sub-agents that must self-verify from the Story ticket alone — so the ticket must carry everything an agent needs to execute and self-verify.
114
111
 
115
- The \`acceptance[]\` and \`verify[]\` arrays live at the **top level** of the Story ticket object (not nested inside \`body\`). The validator reads \`story.acceptance\` and \`story.verify\` directly nesting them inside the body makes them invisible to the validator and the decompose is rejected.
112
+ The \`acceptance[]\` and \`verify[]\` arrays live at the **top level** of the Story ticket object that is the machine contract the validator reads. Author each list **once, at top level**, and **omit** the \`## Acceptance\` / \`## Verify\` sections from the authored \`body\` string: persist syncs the top-level arrays into those sections so the GitHub issue stays a complete executable document. The validator resolves both fields from the top level, so an omitted section is the expected shape, not a violation.
113
+
114
+ If you do write those sections into the \`body\` string anyway, they must mirror the top-level arrays **item for item** — persist fails closed on a disagreement rather than guessing which list is authoritative. Do **not** invent a second criteria list inside \`## Spec\`, and do not author a separate Acceptance Spec / PRD artifact.
116
115
 
117
116
  The serialized \`body\` string renders these markdown sections (in order):
118
117
 
119
118
  ## Goal
120
- <one sentence — why this Story exists within the Epic>
119
+ <one sentence — why this Story exists>
120
+
121
+ ## Slicing
122
+ <optional ordered intra-session checkpoints — not a second Spec or AC table>
123
+
124
+ ## Spec
125
+ <optional lean technical approach — do NOT restate Goal / Acceptance / Verify>
121
126
 
122
127
  ## Changes
123
128
  - {"path": "<file path>", "assumption": "creates" | "refactors-existing" | "deletes"}
@@ -141,7 +146,9 @@ The serialized \`body\` string renders these markdown sections (in order):
141
146
 
142
147
  #### STORY BODY RULES:
143
148
 
144
- - **goal** (in body string): One sentence stating WHY this story exists within the Epic.
149
+ - **goal** (in body string): One sentence stating WHY this Story exists.
150
+ - **spec** (optional, in body string as \`## Spec\`): Lean technical approach only. If the Spec is large enough to feel like its own document, the Story is probably too big — split it. Persist keeps Specs inline and rejects over-budget Specs (never writes them under \`docs/\`).
151
+ - **slicing** (optional): Ordered intra-session checkpoints for one Story. Not a fan-out table and not a duplicate of Acceptance.
145
152
  - **changes** (in body string): Each entry is an object \`{ path, assumption }\` where \`assumption\` is one of \`creates | refactors-existing | deletes\`. Acceptable path shapes include explicit files (\`src/components/Foo.tsx\`), glob patterns (\`tests/e2e/*.spec.ts\`, \`**/*.astro\`), and module identifiers that resolve to files. Use \`refactors-existing\` for in-place edits to a file already on \`main\`; \`creates\` for net-new files; \`deletes\` for removals.
146
153
  - **acceptance** (top-level array on the ticket object): Items MUST be observable from outside the agent. Acceptable shapes: a specific command exits 0, a file exists at a given path, a snapshot test matches, a \`data-testid\` resolves under a given selector, a row count in a fixture matches. UNACCEPTABLE: "verify by reading the diff", "looks good", "matches the spec" — push these down into a \`verify\` command instead.
147
154
  - **verify** (top-level array on the ticket object): Each entry MUST name a testing tier in parentheses, drawn from \`unit\` / \`contract\` / \`e2e\` / \`validate\`. Example: \`npm run test -- src/x.test.ts (unit)\`, \`npm run validate (validate)\`. Stories with zero verify entries SHOULD fail validation; if a story is genuinely unverifiable in isolation (e.g., a copy edit auditor will eyeball), the literal entry \`manual:<reason>\` is allowed so the absence is intentional, not lazy. Manual entries without a reason are rejected.
@@ -157,37 +164,35 @@ ${newFileContract}
157
164
 
158
165
  ${advisoryCaveat}
159
166
 
160
- #### STORY SIZING — COHESION FIRST (the numeric ceiling is only a backstop):
167
+ #### STORY SIZING — COHESION FIRST (session capacity is only a backstop):
161
168
 
162
169
  **Decompose at deliverable granularity, not module/task level.** ${granularityDefinition}
163
170
 
164
- The primary question is **cohesion, not count**: *is this one coherent change with one reason to exist?* File count cannot tell a trivial ${softFiles}-file rename from a hard 3-file parser+caller+config change — so lead with the change's reason, not its size.
165
-
166
- **Size against the real one-pass delivery envelope.** Each Story is delivered and self-verified by a single agent in one pass, whose context is capped by the delivery token budget \`maxTokenBudget = ${maxTokenBudget}\` tokens (the task-prompt hydration cap). Use that envelope — not the file count alone — as the leading sizing input: a Story is correctly sized when one agent can hold its full change, acceptance, and verification in a single pass within \`maxTokenBudget\`. The numeric file thresholds below are a coarse backstop on top of this envelope, not the primary signal.
171
+ The primary question is **cohesion, not count**: *is this one coherent change with one reason to exist?* File count cannot tell a trivial rename from a hard parser+caller+config change — so lead with the change's reason, not its size. Frontier models one-shot capability-sized work in a single pass — do not fragment a coherent capability into dependent slices just to stay "small."
167
172
 
168
173
  ${envelopeFloor}
169
174
 
170
175
  - **One Story = one coherent change with one reason to exist.** If you cannot state that reason in a sentence, the Story is probably two Stories — or two Stories that should be one. State that sentence explicitly in the Story's \`reason_to_exist\` meta field (see STORY BODY RULES) so the consolidate critic can check it.
171
176
  - ${singleConsumerRule}
172
177
  - **Split independent, parallelizable work** into sibling Stories — but only when the pieces genuinely have separate reasons to exist.
173
- - **Declare \`wide\` with a one-line reason when a change is legitimately broad** (a cohesive cutover that spans many files for one reason). Declaring \`wide\` lifts the hard file-width ceiling — see below.
178
+ - **Declare \`wide\` with a one-line reason when a change is legitimately broad** (a cohesive cutover whose authored ticket mass is high for one reason). Declaring \`wide\` lifts the hard session-mass ceiling — see below.
174
179
 
175
- **Numeric backstop (validator-enforced).** These thresholds are sourced from the single \`DEFAULT_TASK_SIZING\` constant in \`ticket-validator-sizing.js\` — there is no second copy to drift:
180
+ **Capacity backstop (validator-enforced).** Absolute authored-token ceilings from the single \`DEFAULT_MODEL_CAPACITY\` constant in \`ticket-validator-sizing.js\` — not operator-tunable. They catch Spec novels, not capability-sized Stories:
176
181
 
177
- - A Story touching more than **${softFiles} files** (\`softFiles\`) emits an advisory width finding a nudge to check cohesion or declare \`wide\`.
178
- - A Story touching more than **${hardFiles} files** (\`hardFiles\`) is **rejected** unless it declares \`wide\` with a reason.
179
- - Acceptance mass is **advisory only**: more than **${softAcceptanceCount} acceptance items** (\`softAcceptanceCount\`) emits an advisory warning. There is NO hard acceptance ceiling — a long binding contract is a signal to re-check cohesion, never a reason to fragment one coherent capability into dependent slices.
182
+ - Soft advisory (**${softSessionTokens} tokens**): authored session mass above this emits a nudge to check cohesion or declare \`wide\`.
183
+ - Hard ceiling (**${hardSessionTokens} tokens**): authored session mass above this is **rejected** unless the Story declares \`wide\` with a reason.
184
+ - Session mass = **authored tokens only** (goal / reason / Spec / acceptance / verify / slicing / change-path text). File count and AC count do **not** inflate mass — a long binding contract or a broad file footprint is never by itself a reason to fragment one coherent capability into dependent slices.
180
185
 
181
186
  #### DELIVERY-SCHEDULE SIMULATION — the story count must earn itself:
182
187
 
183
188
  Before emitting, simulate the delivery schedule your plan implies, and judge the plan by its schedule — not by how tidy the taxonomy looks:
184
189
 
185
190
  1. **Build the wave schedule.** A Story runs only after every \`depends_on\` completes, and two Stories that name the same file in \`changes[]\` cannot run in the same wave (the scheduler serializes file-overlapping Stories even when no \`depends_on\` edge links them).
186
- 2. **Compute the parallelism yield**: story count ÷ critical-path length in waves. A yield near 1.0 means the plan is a serial chain — N Stories that deliver no faster than one Story while paying N delivery sessions (hydration, branch, PR, review, CI).
191
+ 2. **Compute the parallelism yield**: story count ÷ critical-path length in waves. A yield near 1.0 means the plan is a serial chain — N Stories that deliver no faster than one Story while paying N delivery sessions (branch, PR, review, CI).
187
192
  3. **Every Story must earn its slot** by at least one of:
188
193
  - **(a) parallelism** — it actually runs concurrently with a sibling in the schedule you just built ("logically independent" does not count; *schedule*-independent does);
189
194
  - **(b) risk isolation** — it isolates a consumer-facing behavior change or high-risk cutover into its own reviewable, revertable unit;
190
- - **(c) envelope pressure** — merged into its neighbor it would exceed the one-pass delivery envelope (\`maxTokenBudget\`).
195
+ - **(c) cohesion break** — merged into its neighbor it would no longer be one coherent change with one reason to exist.
191
196
  4. **A dependent link with none of those justifications merges into its consumer.** This generalizes the single-consumer merge rule from pairs to chains.
192
197
  5. **Hot-file rule.** When one file appears in the \`changes[]\` of more than a third of your Stories, the slicing axis cuts across a shared seam — merge the Stories that co-edit it, or re-slice along the seam so each Story owns its files.
193
198
 
@@ -201,7 +206,7 @@ A Story whose footprint is legitimately broad declares \`wide\` carrying a one-l
201
206
  "wide": { "reason": "hard contract cutover: migrate every <X> call site in one PR" }
202
207
  \`\`\`
203
208
 
204
- Declaring \`wide\` with a non-empty reason **lifts the \`hardFiles\` rejection** — no Story is rejected for width when it states why it is broad. Omit \`wide\` for ordinary Stories; a wide footprint with no \`wide\` declaration emits only an advisory nudge (check cohesion or declare \`wide\`), never a rejection on its own.
209
+ Declaring \`wide\` with a non-empty reason **lifts the hard session-mass rejection** — no Story is rejected for width when it states why it is broad. Omit \`wide\` for ordinary Stories; a wide footprint with no \`wide\` declaration emits only an advisory nudge (check cohesion or declare \`wide\`), never a rejection on its own.
205
210
 
206
211
  **Glob entries** in \`changes[]\` (bullets containing \`*\`) mark the Story footprint as \`unknown-width\`: the numeric ceiling cannot bound a glob, so it is skipped. A Story carrying glob changes with no \`wide\` declaration emits an advisory nudge.
207
212
 
@@ -1,23 +1,14 @@
1
1
  /**
2
- * spec-author-prompts.js — single source of the Tech Spec and Acceptance
3
- * Spec authoring system prompts (Epic #4474, M3 PR2).
2
+ * spec-author-prompts.js — Story-scoped Spec / Acceptance authoring prompts.
4
3
  *
5
- * **Single source of the prompt bodies.** These two prompts were lifted
6
- * VERBATIM from the "(authoritative)" fenced blocks in
7
- * `.agents/skills/core/epic-plan-spec-author/SKILL.md` "Tech Spec system
8
- * prompt" and § "Acceptance Spec system prompt") as the M3 side of the
9
- * M3/M8 boundary handshake: the `plan-context.js` envelope renders them
10
- * into `systemPrompts.spec` / `systemPrompts.acceptance` so the envelope
11
- * is authoritative from day one, and M8 (#4479) then deletes the
12
- * skill-side copies. This mirrors the Story #4162 pattern established by
13
- * `decomposer-prompts.js` for the decompose prompt: one rendered carrier,
14
- * no second verbatim copy to drift.
4
+ * v2 keeps a single executable document per Story. These prompts used to
5
+ * author a separate Epic Tech Spec + Acceptance Spec that were folded into
6
+ * the Epic body and then restated on Stories — a duplication source. They
7
+ * now author only Story `## Spec` approach prose and remind authors that
8
+ * acceptance lives once on the Story (`acceptance[]` / `## Acceptance`).
15
9
  */
16
10
 
17
11
  /**
18
- * The Tech Spec authoring system prompt (verbatim from the
19
- * `epic-plan-spec-author` SKILL's authoritative block).
20
- *
21
12
  * @returns {string}
22
13
  */
23
14
  export function renderTechSpecSystemPrompt() {
@@ -25,9 +16,6 @@ export function renderTechSpecSystemPrompt() {
25
16
  }
26
17
 
27
18
  /**
28
- * The Acceptance Spec authoring system prompt (verbatim from the
29
- * `epic-plan-spec-author` SKILL's authoritative block).
30
- *
31
19
  * @returns {string}
32
20
  */
33
21
  export function renderAcceptanceSpecSystemPrompt() {
@@ -35,40 +23,54 @@ export function renderAcceptanceSpecSystemPrompt() {
35
23
  }
36
24
 
37
25
  const TECH_SPEC_SYSTEM_PROMPT = `You are an expert Engineering Architect.
38
- Your job is to convert an Epic into a Technical Specification for implementation.
26
+ Your job is to author the Story's \`## Spec\` approach section the technical
27
+ how for one cohesive, executable Story. There is no separate Epic Tech Spec
28
+ document and no spill-to-docs path.
39
29
 
40
- The Tech Spec should outline:
41
- 1. Delivery Slicing — propose how the Epic's enumerated capabilities cluster into shippable Stories. This count is a CEILING, not a target: the Phase 8 consolidation pass may merge below your proposed count when slices form dependent single-consumer chains, but never splits above it. Do NOT coarsen the Epic enumeration to produce this; the grouping recommendation is the granularity lever.
42
- 2. Architecture & Design
43
- 3. Data Models (if any)
44
- 4. API Changes (if any)
45
- 5. Core Components
46
- 6. Security & Privacy Considerations
30
+ The Spec should outline only what an implementing agent needs beyond Goal /
31
+ Changes / Acceptance:
32
+ 1. Architecture & Design (approach, seams, reuse)
33
+ 2. Data Models (if any)
34
+ 3. API Changes (if any)
35
+ 4. Core Components
36
+ 5. Security & Privacy Considerations
47
37
 
48
38
  CRITICAL REQUIREMENTS:
49
- - Respond ONLY with valid Markdown.
50
- - Do not use top-level <h1> (# ) tags. Open the document with the \`## Delivery Slicing\` section — it is the primary input to Phase 8 consolidation, so author it first and hang the rest of the spec off it.
51
- - Do NOT restate the Epic's Context, Goal, or Scope — your output lands as sections of the same Epic body, which travels into every downstream story agent's prompt, so any restatement is pure duplication and a drift risk. If a brief technical orientation is genuinely useful, add an optional \`## Technical Overview\` of no more than 2–3 sentences that names the *technical approach* only (which subsystems are touched and reused); never re-narrate the problem statement, goals, or scope.
39
+ - Respond ONLY with valid Markdown suitable to paste into a Story \`## Spec\`.
40
+ - Do not use top-level <h1> (# ) tags. Prefer \`##\` / \`###\` under Spec.
41
+ - Do NOT restate the Story's Goal, Acceptance, Verify, Changes, or Non-Goals
42
+ those sections already live on the same Story body. Restatement is
43
+ duplication and a drift risk. If a brief orientation helps, keep a
44
+ \`## Technical Overview\` to 2–3 sentences naming the technical approach only.
45
+ - Do NOT author a Delivery Slicing / fan-out table. If the work needs multiple
46
+ independent Stories, say so in one short note and stop — oversized Specs
47
+ mean the Story should be split, not documented elsewhere.
52
48
  - Format architectural decisions clearly with bullet points.
53
- - Author the \`## Delivery Slicing\` section as a markdown table with columns \`Slice | What ships | Independent?\`, using noun-phrase slice names (e.g. "Foundation", "Transport seam", "Send helper") that map onto Feature titles. "Independent?" answers: can this slice ship to production and provide value without the next slice landing? A slice you mark "Independent? No" MUST carry a one-line justification (parallelism, risk isolation, or delivery-envelope pressure); an unjustified dependent single-consumer slice folds into its consumer by default rather than shipping as its own Story.`;
49
+ - Keep the Spec lean enough to stay inline on the Story (persist rejects
50
+ over-budget Specs; they are never written under docs/).`;
54
51
 
55
52
  const ACCEPTANCE_SPEC_SYSTEM_PROMPT = `You are an expert Acceptance Engineer.
56
- Your job is to convert an Epic and a Tech Spec into a structured Acceptance Specification that drives features-first BDD authoring.
53
+ Your job is to help author the Story's binding acceptance contract not a
54
+ separate Acceptance Spec document.
57
55
 
58
- The Acceptance Spec should outline:
59
- 1. Acceptance Table — one row per user-visible outcome, expressed as a Markdown table with columns: AC ID | Outcome | Feature File | Scenario | Disposition
60
- 2. Stable AC IDs — assign AC-1, AC-2, ... in document order; reuse the same ID across re-plans when an Outcome is materially unchanged so scenario tags (@ac-N) stay aligned
61
- 3. Disposition tag each row with one of: new | updated | unchanged
56
+ v2 rule: acceptance lives **once**, on the Story:
57
+ - Machine contract: top-level \`acceptance[]\` (and \`verify[]\`) on the ticket JSON
58
+ - Human document: the same items rendered under \`## Acceptance\` / \`## Verify\`
59
+ on the Story body (persist syncs top-level into the body)
62
60
 
63
- The Epic body's \`## Acceptance Criteria\` bullets are the single source of truth for what the spec verifies. Your table does not re-invent criteria it anchors each one to a specific Epic AC bullet.
61
+ Do **not** author an Epic Acceptance Table, PRD restatement, or a second
62
+ criteria list inside \`## Spec\`.
64
63
 
65
64
  CRITICAL REQUIREMENTS:
66
- - Respond ONLY with valid Markdown.
67
- - Do not use top-level <h1> (# ) tags. Start with ## Acceptance Table the table lands as a section of the Epic body, so it must NOT reuse the Epic's own ## Acceptance Criteria heading.
68
- - Every AC row MUST have a stable AC ID of the form AC-<n> (AC-1, AC-2, ...) — do not reorder IDs across re-plans; new ACs get fresh sequential IDs.
69
- - Every AC row MUST carry a Disposition value from the enum: new | updated | unchanged. (At Epic close, the acceptance reconciler overwrites Disposition with the verification outcome — satisfied | pending | missing — inside this section only; on re-plan, reset each row to the authoring enum.)
70
- - Each Outcome MUST be a **terse restatement keyed to a specific Epic \`## Acceptance Criteria\` bullet** — lead the Outcome with the bullet's anchor (its quoted lead phrase or an explicit "Epic AC N" index) and keep the rest to a single user-visible behaviour. Do NOT re-elaborate the Epic bullet in independent words: a free-standing Outcome that paraphrases the criterion without naming the bullet it verifies is forbidden, because it drifts from the Epic silently. No DB assertions, no HTTP status codes, no internal implementation details.
71
- - Where one Epic AC bullet genuinely expands into several user-visible outcomes, emit one row per outcome and declare the split on each — e.g. lead with "splits Epic AC 3" — so the fan-out is explicit rather than hidden.
72
- - Anchor coverage MUST be complete and auditable: every Epic AC bullet MUST be covered by at least one row, and every row MUST anchor to an Epic AC bullet. Flag divergence in the authored spec instead of dropping it — if an Epic AC bullet has no corresponding row, or a row has no Epic anchor, call it out explicitly (a note beneath the table) rather than silently omitting the bullet or emitting an unanchored row.
73
- - Cite proposed feature file paths under tests/features/** so Phase 8 can scaffold matching scenarios.
74
- - Acceptance Outcomes MUST NOT prescribe a commit subject that begins with a non-Conventional-Commits prefix (allowed leading types: feat|fix|chore|refactor|perf|docs|style|test|build|ci|revert). The legacy \`baseline-refresh\` token used as a leading subject prescription is forbidden — commitlint will reject it at commit time, and the decompose-time validator (\`ticket-validator.js\` → \`validateAcceptanceSubjectPrefix\`) will reject the decompose with \`code: 'forbidden-subject-prefix'\`. Use a Conventional-Commits subject (e.g. \`chore(baselines): refresh ...\`) and a body trailer (e.g. \`baseline-refresh: true\` — trailer with a value, not a subject prefix) when a machine-readable marker is needed. See Epic #2501 for rationale.`;
65
+ - Respond ONLY with guidance or a draft \`acceptance[]\` / \`verify[]\` list for
66
+ one Storynever a parallel "Acceptance Spec" markdown artifact.
67
+ - Every acceptance item MUST be observable from outside the agent (command
68
+ exits 0, file exists, selector resolves, fixture count matches). Reject
69
+ vague "matches the spec" / "looks good" items.
70
+ - Every verify entry MUST name a tier in parentheses: unit | contract | e2e |
71
+ validate (or \`manual:<reason>\` when genuinely unverifiable in isolation).
72
+ - Do NOT re-elaborate Goal or Spec prose inside acceptance items bind the
73
+ outcome, not the approach.
74
+ - Acceptance Outcomes MUST NOT prescribe a commit subject that begins with a
75
+ non-Conventional-Commits prefix (allowed leading types: feat|fix|chore|
76
+ refactor|perf|docs|style|test|build|ci|revert).`;
@@ -17,12 +17,25 @@
17
17
  * the NODE_ENV band-aid was removed in Story #3342. Tests that need to
18
18
  * exercise the webhook POST inject `opts.fetchImpl` instead, so the
19
19
  * request never reaches the real network even if a URL resolves.)
20
+ * - Every `GIT_*` variable is dropped. When the suite runs inside a git
21
+ * hook (husky pre-push via the coverage-capture path), the parent git
22
+ * invocation exports `GIT_DIR` — from a linked worktree, the absolute
23
+ * `<main>/.git/worktrees/<name>` path. A test fixture's `git init`
24
+ * under that env re-initializes the shared gitdir and writes
25
+ * `core.bare=true` into the MAIN checkout's `.git/config`, breaking
26
+ * every worktree at once (#4580). Production git call sites are
27
+ * covered by `cleanGitEnv` in `git-utils.js`; this is the same scrub
28
+ * for test child processes, which may spawn git directly. Tests that
29
+ * need a `GIT_*` variable set it explicitly on their own spawn.
20
30
  *
21
31
  * @param {NodeJS.ProcessEnv} baseEnv
22
32
  * @returns {NodeJS.ProcessEnv}
23
33
  */
24
34
  export function buildWebhookSafeTestEnv(baseEnv = process.env) {
25
- const env = { ...baseEnv, NODE_ENV: baseEnv.NODE_ENV ?? 'test' };
35
+ const env = Object.fromEntries(
36
+ Object.entries(baseEnv).filter(([k]) => !k.startsWith('GIT_')),
37
+ );
38
+ env.NODE_ENV = baseEnv.NODE_ENV ?? 'test';
26
39
  if (env.MANDREL_ALLOW_TEST_WEBHOOKS !== '1') {
27
40
  delete env.NOTIFICATION_WEBHOOK_URL;
28
41
  }
@@ -12,13 +12,10 @@ import picomatch from 'picomatch';
12
12
  */
13
13
  export const INTEGRATION_INCLUDE = [
14
14
  'tests/**/*.integration.test.js',
15
- 'tests/epic-execute/epic-execute-record-wave.test.js',
16
15
  'tests/hook-chain-reflog-invariant.test.js',
17
- 'tests/push-epic-retry.test.js',
18
16
  'tests/contract/check-baselines-regression.test.js',
19
17
  'tests/contract/check-baselines-kernel-mismatch.test.js',
20
18
  'tests/integration-prime-after-sweep.test.js',
21
- 'tests/concurrency-wiring.test.js',
22
19
  'tests/scripts/git-cleanup.test.js',
23
20
  'tests/lib/checks/runner-integration.test.js',
24
21
  'tests/single-story-close-sync.test.js',
@@ -1,19 +1,19 @@
1
1
  /**
2
- * epic-body-sections.js — marker-delimited managed sections of the Epic body.
2
+ * ticket-body-sections.js — marker-delimited managed sections of a
3
+ * planning ticket body.
3
4
  *
4
5
  * Story #4324 retired the `context::tech-spec` / `context::acceptance-spec`
5
- * ticket classes: the Epic body is now the single planning document. The
6
- * Tech Spec (opening with `## Delivery Slicing`, per #4316) and the
7
- * Acceptance Spec's AC-ID table (`## Acceptance Table`, Outcomes keyed to
8
- * Epic AC bullets per #4315) land as **managed sections** of the Epic body,
9
- * delimited by invisible HTML comment markers so each writer can update
10
- * *only its own region* without rewriting the rest of the body.
6
+ * ticket classes: the planning ticket body is the single planning document.
7
+ * The Tech Spec (opening with `## Delivery Slicing`, per #4316) and the
8
+ * Acceptance Spec's AC-ID table (`## Acceptance Table`) land as **managed
9
+ * sections**, delimited by invisible HTML comment markers so each writer
10
+ * can update *only its own region* without rewriting the rest of the body.
11
11
  *
12
12
  * Section-scoped writes are the load-bearing contract (extending the
13
13
  * single-writer discipline #4303 established for the body trailer):
14
14
  *
15
- * - The Phase 7 spec persist path (`epic-plan-spec/phases/plan-epic.js`)
16
- * upserts the `techSpec` and `acceptanceTable` regions.
15
+ * - The `/plan` persist path upserts the `techSpec` and `acceptanceTable`
16
+ * regions.
17
17
  * - The close-time acceptance reconciler
18
18
  * (`acceptance-spec-reconciler.js`) reads and rewrites the
19
19
  * `acceptanceTable` region only (verification dispositions).
@@ -32,7 +32,7 @@
32
32
  *
33
33
  * @type {Readonly<Record<'techSpec'|'acceptanceTable', { start: string, end: string, label: string }>>}
34
34
  */
35
- export const EPIC_BODY_SECTIONS = Object.freeze({
35
+ export const TICKET_BODY_SECTIONS = Object.freeze({
36
36
  techSpec: Object.freeze({
37
37
  start: '<!-- mandrel:tech-spec:start -->',
38
38
  end: '<!-- mandrel:tech-spec:end -->',
@@ -47,7 +47,7 @@ export const EPIC_BODY_SECTIONS = Object.freeze({
47
47
 
48
48
  /**
49
49
  * Canonical heading the acceptance-table region opens with. Distinct from
50
- * the Epic's ideation `## Acceptance Criteria` bullets (which remain the
50
+ * the ticket's ideation `## Acceptance Criteria` bullets (which remain the
51
51
  * SSOT for *what* the table verifies — the table anchors to those bullets).
52
52
  */
53
53
  export const ACCEPTANCE_TABLE_HEADING = '## Acceptance Table';
@@ -56,7 +56,7 @@ export const ACCEPTANCE_TABLE_HEADING = '## Acceptance Table';
56
56
  * Regex matching the Tech Spec's required opening heading (same variants
57
57
  * `spec-section-validator.js` accepts). Exported so it is the single
58
58
  * source of truth for this pattern — `spec-section-validator.js`,
59
- * `epic-plan-clarity.js`, and `consolidation-precondition.js` all import
59
+ * `consolidation-precondition.js` all import
60
60
  * it rather than each carrying their own copy.
61
61
  */
62
62
  export const DELIVERY_SLICING_RE = /^##\s+(?:Delivery\s+)?Slicing\s*$/im;
@@ -66,10 +66,10 @@ export const DELIVERY_SLICING_RE = /^##\s+(?:Delivery\s+)?Slicing\s*$/im;
66
66
  * @returns {{ start: string, end: string, label: string }}
67
67
  */
68
68
  function descriptor(kind) {
69
- const d = EPIC_BODY_SECTIONS[kind];
69
+ const d = TICKET_BODY_SECTIONS[kind];
70
70
  if (!d) {
71
71
  throw new TypeError(
72
- `epic-body-sections: unknown section kind "${kind}" (expected ${Object.keys(EPIC_BODY_SECTIONS).join(' | ')})`,
72
+ `ticket-body-sections: unknown section kind "${kind}" (expected ${Object.keys(TICKET_BODY_SECTIONS).join(' | ')})`,
73
73
  );
74
74
  }
75
75
  return d;
@@ -103,24 +103,10 @@ function locate(body, kind) {
103
103
  * @param {'techSpec'|'acceptanceTable'} kind
104
104
  * @returns {boolean}
105
105
  */
106
- export function hasEpicSection(body, kind) {
106
+ export function hasTicketSection(body, kind) {
107
107
  return locate(body, kind) !== null;
108
108
  }
109
109
 
110
- /**
111
- * Extract a managed region's content (between the markers, trimmed).
112
- * Returns `null` when the region is absent.
113
- *
114
- * @param {string} body
115
- * @param {'techSpec'|'acceptanceTable'} kind
116
- * @returns {string|null}
117
- */
118
- export function extractEpicSection(body, kind) {
119
- const loc = locate(body, kind);
120
- if (!loc) return null;
121
- return body.slice(loc.contentStart, loc.contentEnd).trim();
122
- }
123
-
124
110
  /**
125
111
  * Insert or replace a managed region, preserving every byte outside it.
126
112
  *
@@ -136,7 +122,7 @@ export function extractEpicSection(body, kind) {
136
122
  * @param {string} content Section content (headings included).
137
123
  * @returns {string}
138
124
  */
139
- export function upsertEpicSection(body, kind, content) {
125
+ export function upsertTicketSection(body, kind, content) {
140
126
  const { start, end } = descriptor(kind);
141
127
  const safeBody = typeof body === 'string' ? body : '';
142
128
  const trimmedContent = typeof content === 'string' ? content.trim() : '';
@@ -179,7 +165,7 @@ export function upsertEpicSection(body, kind, content) {
179
165
  * @param {'techSpec'|'acceptanceTable'} kind
180
166
  * @returns {string}
181
167
  */
182
- export function stripEpicSection(body, kind) {
168
+ export function stripTicketSection(body, kind) {
183
169
  const { end } = descriptor(kind);
184
170
  const loc = locate(body, kind);
185
171
  if (!loc) return typeof body === 'string' ? body : '';
@@ -189,7 +175,7 @@ export function stripEpicSection(body, kind) {
189
175
  }
190
176
 
191
177
  /**
192
- * Re-plan / decompose detection: true when the Epic body carries folded
178
+ * Re-plan / decompose detection: true when the ticket body carries folded
193
179
  * Tech Spec content — the managed region, or (defence in depth for a
194
180
  * hand-authored body) a bare `## Delivery Slicing` heading.
195
181
  *
@@ -197,7 +183,7 @@ export function stripEpicSection(body, kind) {
197
183
  * @returns {boolean}
198
184
  */
199
185
  export function hasTechSpecContent(body) {
200
- if (hasEpicSection(body, 'techSpec')) return true;
186
+ if (hasTicketSection(body, 'techSpec')) return true;
201
187
  return typeof body === 'string' && DELIVERY_SLICING_RE.test(body);
202
188
  }
203
189
 
@@ -217,9 +203,9 @@ const DELIVERY_DROP_HEADINGS = new Set([
217
203
  ]);
218
204
 
219
205
  /**
220
- * Slice an Epic body down to the sections a delivery story agent acts on.
206
+ * Slice a planning ticket body down to the sections a delivery story agent acts on.
221
207
  *
222
- * KEEP: the Epic title / preamble before the first `##`, `## Goal`,
208
+ * KEEP: the ticket title / preamble before the first `##`, `## Goal`,
223
209
  * `## Non-Goals`, `## User Stories`, the `techSpec` managed region, and —
224
210
  * fail-open — any unknown / operator-authored `##` section not in the drop
225
211
  * list. DROP: `## Context`, `## Scope`, `## Acceptance Criteria`, and the
@@ -236,12 +222,12 @@ const DELIVERY_DROP_HEADINGS = new Set([
236
222
  * @param {string} body
237
223
  * @returns {string}
238
224
  */
239
- export function sliceEpicBodyForDelivery(body) {
225
+ export function sliceTicketBodyForDelivery(body) {
240
226
  if (typeof body !== 'string' || body.length === 0) return '';
241
227
 
242
228
  // 1. Drop the acceptance-table managed region outright (authoring/close
243
229
  // machinery, never delivery context).
244
- let working = stripEpicSection(body, 'acceptanceTable');
230
+ let working = stripTicketSection(body, 'acceptanceTable');
245
231
 
246
232
  // 2. Protect the techSpec managed region from heading-boundary slicing by
247
233
  // lifting it out behind an opaque placeholder, then restoring it after
@@ -261,7 +247,7 @@ export function sliceEpicBodyForDelivery(body) {
261
247
 
262
248
  // 3. Slice plain `##` sections by heading boundaries, dropping only the
263
249
  // known ideation/authoring headings. The preamble before the first
264
- // `##` (Epic title / lede) is always kept.
250
+ // `##` (ticket title / lede) is always kept.
265
251
  const kept = [];
266
252
  let dropping = false;
267
253
  for (const line of working.split('\n')) {
@@ -291,7 +277,7 @@ export function sliceEpicBodyForDelivery(body) {
291
277
 
292
278
  /**
293
279
  * Strip the retired machine-managed `## Planning Artifacts` checklist from
294
- * an Epic body (the section that linked the now-retired context tickets).
280
+ * a planning ticket body (the section that linked the now-retired context tickets).
295
281
  * The slice ends at the next `## ` heading, a managed-region marker, or
296
282
  * EOF. Historical bodies without the section pass through untouched.
297
283
  *