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
@@ -11,6 +11,8 @@
11
11
  * ```js
12
12
  * {
13
13
  * goal: string, // one-sentence purpose
14
+ * slicing: string, // v2 intra-Story delivery slice plan (optional; '' when absent)
15
+ * spec: string, // folded Tech Spec text block (optional; '' when absent)
14
16
  * changes: PathEntry[], // files/globs this Story touches
15
17
  * acceptance: string[], // observable criteria
16
18
  * verify: string[], // exact commands / tier annotation
@@ -23,10 +25,9 @@
23
25
  * }
24
26
  * ```
25
27
  *
26
- * Where `PathEntry` is one of:
28
+ * Where `PathEntry` is:
27
29
  * - `{ path: string, assumption: "creates"|"refactors-existing"|"exists"|"deletes" }`
28
- * (canonical form)
29
- * - `string` (legacy form — emits a `legacy-path-entry` warning)
30
+ * (canonical form — string bullets are rejected at parse time)
30
31
  *
31
32
  * ## Round-trip contract
32
33
  *
@@ -61,16 +62,15 @@ import { FILE_ASSUMPTION_VALUES } from '../orchestration/file-assumption-enum.js
61
62
  */
62
63
 
63
64
  /**
64
- * @typedef {PathEntry | string} ChangeEntry
65
- * Canonical: PathEntry object.
66
- * Legacy: bare string bullet (emits a `legacy-path-entry` warning via
67
- * the `warnings` array on {@link ParseResult}).
65
+ * @typedef {PathEntry} ChangeEntry
68
66
  */
69
67
 
70
68
  /**
71
69
  * @typedef {object} StoryBody
72
70
  * @property {string} goal - One-sentence purpose statement.
73
- * @property {ChangeEntry[]} changes - Files / globs this Story modifies.
71
+ * @property {string} slicing - Optional v2 intra-Story delivery slice plan text block; '' when absent.
72
+ * @property {string} spec - Optional folded Tech Spec text block; '' when absent.
73
+ * @property {PathEntry[]} changes - Files / globs this Story modifies.
74
74
  * @property {string[]} acceptance - Observable acceptance criteria.
75
75
  * @property {string[]} verify - Exact commands with tier annotation.
76
76
  * @property {PathEntry[]} references - Read-only paths (may be empty).
@@ -86,7 +86,7 @@ import { FILE_ASSUMPTION_VALUES } from '../orchestration/file-assumption-enum.js
86
86
  /**
87
87
  * @typedef {object} ParseResult
88
88
  * @property {StoryBody} body - The parsed structured body.
89
- * @property {string[]} warnings - Non-fatal issues (e.g. legacy-path-entry).
89
+ * @property {string[]} warnings - Non-fatal issues (e.g. unstructured-body).
90
90
  * @property {ParseInfo} info - Metadata about the parse.
91
91
  */
92
92
 
@@ -98,15 +98,16 @@ import { FILE_ASSUMPTION_VALUES } from '../orchestration/file-assumption-enum.js
98
98
  * @property {boolean} hasVerifySection - Whether a `## Verify` section was found.
99
99
  * @property {boolean} hasReferencesSection - Whether a `## References` section was found.
100
100
  * @property {boolean} hasNonGoalsSection - Whether a `## Non-Goals` section was found.
101
- * @property {boolean} isLegacyStringBody - True when no structured sections were found.
101
+ * @property {boolean} hasSlicingSection - Whether a `## Slicing` section was found (v2 folded slice plan).
102
+ * @property {boolean} hasSpecSection - Whether a `## Spec` section was found (folded Tech Spec).
103
+ * @property {boolean} isUnstructuredBody - True when no structured sections were found.
102
104
  */
103
105
 
104
106
  /**
105
107
  * @typedef {object} SerializeOptions
106
- * @property {boolean} [includeFooter=false] - Include `---\nparent/epic/blocked-by` footer.
108
+ * @property {boolean} [includeFooter=false] - Include `---\nparent/blocked-by` footer.
107
109
  * @property {object} [footer] - Footer fields when `includeFooter` is true.
108
110
  * @property {number} [footer.parent] - Parent feature issue number.
109
- * @property {number} [footer.epic] - Epic issue number.
110
111
  */
111
112
 
112
113
  // ---------------------------------------------------------------------------
@@ -139,12 +140,15 @@ export class StoryBodyParseError extends Error {
139
140
  // maps to the `non_goals` field.
140
141
  const HEADING_TO_FIELD = new Map([
141
142
  ['goal', 'goal'],
143
+ ['slicing', 'slicing'],
144
+ ['spec', 'spec'],
142
145
  ['changes', 'changes'],
143
146
  ['acceptance', 'acceptance'],
144
147
  ['verify', 'verify'],
145
148
  ['references', 'references'],
146
149
  ['non_goals', 'non_goals'],
147
150
  ]);
151
+ const TEXT_BLOCK_FIELDS = new Set(['slicing', 'spec']);
148
152
 
149
153
  // ---------------------------------------------------------------------------
150
154
  // Helpers
@@ -162,19 +166,16 @@ function stripListMarker(line) {
162
166
  }
163
167
 
164
168
  /**
165
- * Parse a single `changes` / `references` bullet into a `PathEntry` or
166
- * legacy string. Emits a `legacy-path-entry` warning for string form.
169
+ * Parse a single `changes` / `references` bullet into a `PathEntry`.
167
170
  *
168
171
  * Object form: `{ path: "...", assumption: "creates" }` (stored as
169
172
  * `- { "path": "...", "assumption": "..." }` or just recognized from the
170
173
  * structured body directly — when deserializing from a structured object
171
174
  * that was never serialized to markdown, the entry arrives as-is).
172
175
  *
173
- * String form: `src/foo.js: create handleSubmit`
174
- *
175
176
  * @param {string|object} raw
176
177
  * @param {string[]} warnings
177
- * @returns {PathEntry | string}
178
+ * @returns {PathEntry}
178
179
  */
179
180
  function parsePathEntry(raw, warnings) {
180
181
  // Already a structured object (from a parsed JSON body, not markdown).
@@ -218,15 +219,14 @@ function parsePathEntry(raw, warnings) {
218
219
  } catch (err) {
219
220
  // Re-throw StoryBodyParseError so it propagates.
220
221
  if (err instanceof StoryBodyParseError) throw err;
221
- // JSON parse failed — fall through to legacy string handling.
222
+ // JSON parse failed — fall through to reject plain-string form.
222
223
  }
223
224
  }
224
225
 
225
- // Legacy string form — warn but accept.
226
- warnings.push(
227
- `legacy-path-entry: change entry "${str.slice(0, 80)}" is a plain string; prefer { path, assumption } object form.`,
226
+ throw new StoryBodyParseError(
227
+ `changes/references entry must be a { path, assumption } object; plain string bullets are no longer accepted: ${str.slice(0, 120)}`,
228
+ { field: 'changes', raw: str },
228
229
  );
229
- return str;
230
230
  }
231
231
 
232
232
  /**
@@ -245,8 +245,11 @@ function extractBlockedBy(footerBlock) {
245
245
  return deps;
246
246
  }
247
247
 
248
- // Matches the trailing `<!-- meta: {...} -->` block serialize() emits.
249
- const META_BLOCK_RE = /<!--\s*meta:\s*(\{[\s\S]*?\})\s*-->/;
248
+ // Matches any trailing `<!-- meta: -->` block. Object payloads are the
249
+ // canonical serialize() shape; non-object / malformed payloads are still
250
+ // recognized so section parsing can skip them and extractMeta can degrade.
251
+ const META_BLOCK_RE = /<!--\s*meta:\s*([\s\S]*?)\s*-->/;
252
+ const META_OBJECT_RE = /<!--\s*meta:\s*(\{[\s\S]*?\})\s*-->/;
250
253
 
251
254
  /**
252
255
  * Extract the `wide` / `estimated_test_files` fields from the trailing
@@ -275,7 +278,7 @@ function extractMeta(markdown) {
275
278
  mandrel_version: null,
276
279
  authored_at: null,
277
280
  };
278
- const match = markdown.match(META_BLOCK_RE);
281
+ const match = markdown.match(META_OBJECT_RE) ?? markdown.match(META_BLOCK_RE);
279
282
  if (!match) return result;
280
283
 
281
284
  let parsed;
@@ -285,7 +288,10 @@ function extractMeta(markdown) {
285
288
  // Malformed meta comment — degrade to defaults rather than corrupt the body.
286
289
  return result;
287
290
  }
288
- if (parsed === null || typeof parsed !== 'object') return result;
291
+ // Non-object JSON (array / scalar / null) is treated as absent meta.
292
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
293
+ return result;
294
+ }
289
295
 
290
296
  result.wide = normalizeWide(parsed.wide);
291
297
  result.reason_to_exist = normalizeReasonToExist(parsed.reason_to_exist);
@@ -385,27 +391,11 @@ function splitSections(markdown) {
385
391
  // below, which closes the open section. The chosen canonical spelling is
386
392
  // therefore the hyphenated single token `## Non-Goals`.
387
393
  const fieldHeadingMatch = line.match(/^#{2,3}\s+([\w-]+)\s*$/i);
388
- if (fieldHeadingMatch) {
389
- const name = fieldHeadingMatch[1].toLowerCase().replace(/-/g, '_');
390
- if (HEADING_TO_FIELD.has(name)) {
391
- inPreamble = false;
392
- currentSection = name;
393
- if (!sections.has(currentSection)) sections.set(currentSection, []);
394
- continue;
395
- }
396
- // A heading that matches the canonical `## Word` shape but is not a
397
- // recognized field name (e.g. a trailing free-form `## Notes`) closes
398
- // the currently-open section. Without this reset, the unknown heading
399
- // and its bullets bleed into the previously-recognized section,
400
- // silently corrupting `verify[]` / `acceptance[]`. We do NOT re-enter
401
- // the preamble (`inPreamble` stays false), so a later recognized
402
- // heading still registers normally; we only stop appending to the
403
- // closed section. The heading line and its body are dropped from all
404
- // sections. (Multi-word free-form headings like `## Out of Scope` —
405
- // with internal spaces — do not match the `[\w-]+` single-token shape
406
- // and reach this branch too. The hyphenated single-token canonical
407
- // negative-scope heading is `## Non-Goals`, which IS recognized above.)
408
- currentSection = null;
394
+ const fieldName = fieldHeadingMatch?.[1]?.toLowerCase().replace(/-/g, '_');
395
+ if (HEADING_TO_FIELD.has(fieldName)) {
396
+ inPreamble = false;
397
+ currentSection = fieldName;
398
+ if (!sections.has(currentSection)) sections.set(currentSection, []);
409
399
  continue;
410
400
  }
411
401
 
@@ -418,7 +408,11 @@ function splitSections(markdown) {
418
408
  // lines were silently absorbed into `verify[]` / `acceptance[]`. The
419
409
  // heading and everything under it is dropped from structured parsing
420
410
  // (it is extended, non-canonical markdown).
421
- if (!inPreamble && /^#{1,6}\s+\S/.test(line)) {
411
+ if (
412
+ !inPreamble &&
413
+ /^#{1,6}\s+\S/.test(line) &&
414
+ !TEXT_BLOCK_FIELDS.has(currentSection)
415
+ ) {
422
416
  currentSection = null;
423
417
  continue;
424
418
  }
@@ -442,10 +436,7 @@ function splitSections(markdown) {
442
436
  if (inPreamble) {
443
437
  preambleLines.push(line);
444
438
  } else if (currentSection !== null) {
445
- const trimmed = line.trim();
446
- if (trimmed.length > 0) {
447
- sections.get(currentSection).push(line);
448
- }
439
+ sections.get(currentSection).push(line);
449
440
  }
450
441
  }
451
442
 
@@ -460,7 +451,7 @@ function splitSections(markdown) {
460
451
  // ---------------------------------------------------------------------------
461
452
 
462
453
  /**
463
- * Build the minimal {@link ParseResult} returned for a legacy string body —
454
+ * Build the minimal {@link ParseResult} returned for an unstructured body —
464
455
  * markdown that carries no recognised structured section. The goal falls
465
456
  * back to the preamble text (or the whole trimmed input), `depends_on` is
466
457
  * still recovered from the footer, and all section arrays are empty.
@@ -470,13 +461,15 @@ function splitSections(markdown) {
470
461
  * @param {string} footer - Footer block text (from splitSections).
471
462
  * @returns {ParseResult}
472
463
  */
473
- function parseLegacyStringBody(input, preamble, footer) {
464
+ function parseUnstructuredBody(input, preamble, footer) {
474
465
  const warnings = [
475
- 'legacy-string-body: no structured sections found; returning minimal body from preamble text.',
466
+ 'unstructured-body: no structured sections found; returning minimal body from preamble text.',
476
467
  'test-surface-unestimated: estimated_test_files not present.',
477
468
  ];
478
469
  const body = {
479
470
  goal: preamble || input.trim(),
471
+ slicing: '',
472
+ spec: '',
480
473
  changes: [],
481
474
  acceptance: [],
482
475
  verify: [],
@@ -499,7 +492,9 @@ function parseLegacyStringBody(input, preamble, footer) {
499
492
  hasVerifySection: false,
500
493
  hasReferencesSection: false,
501
494
  hasNonGoalsSection: false,
502
- isLegacyStringBody: true,
495
+ hasSlicingSection: false,
496
+ hasSpecSection: false,
497
+ isUnstructuredBody: true,
503
498
  },
504
499
  };
505
500
  }
@@ -518,15 +513,30 @@ function parseGoalSection(lines) {
518
513
  .join(' ');
519
514
  }
520
515
 
516
+ /**
517
+ * Parse a verbatim text-block section (`## Slicing` or `## Spec`) into a
518
+ * newline-joined string. Unlike {@link parseGoalSection}, line breaks are
519
+ * preserved so a bullet list, compact table, or folded Tech Spec survives the
520
+ * round-trip; only blank lines and trailing whitespace are normalized.
521
+ *
522
+ * @param {string[]} lines
523
+ * @returns {string}
524
+ */
525
+ function parseTextBlockSection(lines) {
526
+ return lines
527
+ .map((line) => line.replace(/\s+$/, ''))
528
+ .join('\n')
529
+ .replace(/^\n+|\n+$/g, '');
530
+ }
531
+
521
532
  /**
522
533
  * Parse a `## Changes` / `## References` section into a list of
523
- * `PathEntry | string` entries. List markers are stripped, blank entries are
524
- * dropped, and each surviving entry is normalized via {@link parsePathEntry}
525
- * (which appends `legacy-path-entry` warnings for bare-string bullets).
534
+ * `PathEntry` entries. List markers are stripped, blank entries are
535
+ * dropped, and each surviving entry is normalized via {@link parsePathEntry}.
526
536
  *
527
537
  * @param {string[]} lines - Raw content lines under the heading.
528
538
  * @param {string[]} warnings - Mutable warnings sink.
529
- * @returns {Array<PathEntry|string>}
539
+ * @returns {PathEntry[]}
530
540
  */
531
541
  function parsePathEntrySection(lines, warnings) {
532
542
  const entries = [];
@@ -601,19 +611,28 @@ export function parse(input) {
601
611
  const hasVerifySection = sections.has('verify');
602
612
  const hasReferencesSection = sections.has('references');
603
613
  const hasNonGoalsSection = sections.has('non_goals');
614
+ const hasSlicingSection = sections.has('slicing');
615
+ const hasSpecSection = sections.has('spec');
604
616
 
605
- // If no structured sections found, treat as legacy string body.
606
- const isLegacyStringBody =
617
+ // If no structured sections found, treat as unstructured body.
618
+ const isUnstructuredBody =
607
619
  !hasGoalSection &&
608
620
  !hasChangesSection &&
609
621
  !hasAcceptanceSection &&
610
622
  !hasVerifySection;
611
623
 
612
- if (isLegacyStringBody) {
613
- return parseLegacyStringBody(input, preamble, footer);
624
+ if (isUnstructuredBody) {
625
+ return parseUnstructuredBody(input, preamble, footer);
614
626
  }
615
627
 
616
628
  const goal = parseGoalSection(sections.get('goal') ?? []);
629
+ // Optional v2 intra-Story delivery slice plan (`## Slicing`). Preserved as
630
+ // a verbatim text block — a large Story (what v1 called an Epic) folds its
631
+ // Delivery Slicing here instead of fanning out into sibling Stories; a
632
+ // trivial Story omits it entirely. Parsed as a text block so a bullet list
633
+ // or compact table round-trips.
634
+ const slicing = parseTextBlockSection(sections.get('slicing') ?? []);
635
+ const spec = parseTextBlockSection(sections.get('spec') ?? []);
617
636
  const changes = parsePathEntrySection(
618
637
  sections.get('changes') ?? [],
619
638
  warnings,
@@ -644,6 +663,8 @@ export function parse(input) {
644
663
 
645
664
  const body = {
646
665
  goal,
666
+ slicing,
667
+ spec,
647
668
  changes,
648
669
  acceptance,
649
670
  verify,
@@ -667,7 +688,9 @@ export function parse(input) {
667
688
  hasVerifySection,
668
689
  hasReferencesSection,
669
690
  hasNonGoalsSection,
670
- isLegacyStringBody: false,
691
+ hasSlicingSection,
692
+ hasSpecSection,
693
+ isUnstructuredBody: false,
671
694
  },
672
695
  };
673
696
  }
@@ -685,6 +708,12 @@ function parseStructuredObject(obj) {
685
708
 
686
709
  const goal = typeof obj.goal === 'string' ? obj.goal.trim() : '';
687
710
 
711
+ // slicing — optional v2 intra-Story delivery slice plan (verbatim text).
712
+ const slicing = typeof obj.slicing === 'string' ? obj.slicing.trim() : '';
713
+
714
+ // spec — optional folded Tech Spec (verbatim text).
715
+ const spec = typeof obj.spec === 'string' ? obj.spec.trim() : '';
716
+
688
717
  // changes
689
718
  const rawChanges = Array.isArray(obj.changes) ? obj.changes : [];
690
719
  const changes = [];
@@ -747,6 +776,8 @@ function parseStructuredObject(obj) {
747
776
 
748
777
  const body = {
749
778
  goal,
779
+ slicing,
780
+ spec,
750
781
  changes,
751
782
  acceptance,
752
783
  verify,
@@ -770,7 +801,9 @@ function parseStructuredObject(obj) {
770
801
  hasVerifySection: 'verify' in obj,
771
802
  hasReferencesSection: 'references' in obj,
772
803
  hasNonGoalsSection: 'non_goals' in obj,
773
- isLegacyStringBody: false,
804
+ hasSlicingSection: 'slicing' in obj,
805
+ hasSpecSection: 'spec' in obj,
806
+ isUnstructuredBody: false,
774
807
  },
775
808
  };
776
809
  }
@@ -793,10 +826,10 @@ function serializePathEntry(entry) {
793
826
 
794
827
  /**
795
828
  * Descriptor table for the human-readable Story-body sections, in canonical
796
- * emit order (`## Goal`, `## Changes`, `## Acceptance`, `## Verify`,
797
- * `## References`, `## Non-Goals`). Each descriptor reads one body field and returns the
798
- * section's markdown block when the field is present and non-empty, or `null`
799
- * to omit the section.
829
+ * emit order (`## Goal`, `## Slicing`, `## Spec`, `## Changes`,
830
+ * `## Acceptance`, `## Verify`, `## References`, `## Non-Goals`). Each
831
+ * descriptor reads one body field and returns the section's markdown block
832
+ * when the field is present and non-empty, or `null` to omit the section.
800
833
  *
801
834
  * Standardising the section ladder as a single data table makes adding a new
802
835
  * optional section a one-line edit here rather than a new control-flow branch
@@ -812,6 +845,26 @@ const SERIALIZE_SECTIONS = [
812
845
  ? `## Goal\n${goal.trim()}`
813
846
  : null,
814
847
  },
848
+ {
849
+ // Optional v2 intra-Story delivery slice plan. Single-token `## Slicing`
850
+ // heading (recognized by the `[\w-]+` field-heading regex). Verbatim text
851
+ // block. Render-when-non-empty: an absent/empty `slicing` emits nothing,
852
+ // so every pre-v2 body round-trips byte-identically.
853
+ field: 'slicing',
854
+ render: (slicing) =>
855
+ typeof slicing === 'string' && slicing.trim().length > 0
856
+ ? `## Slicing\n${slicing.trim()}`
857
+ : null,
858
+ },
859
+ {
860
+ // Optional folded Tech Spec. Like `## Slicing`, this is a verbatim text
861
+ // block and emits nothing for absent/empty pre-v2 bodies.
862
+ field: 'spec',
863
+ render: (spec) =>
864
+ typeof spec === 'string' && spec.trim().length > 0
865
+ ? `## Spec\n${spec.trim()}`
866
+ : null,
867
+ },
815
868
  {
816
869
  field: 'changes',
817
870
  render: (changes) =>
@@ -913,8 +966,8 @@ function serializeAuthoredMarker(body) {
913
966
  }
914
967
 
915
968
  /**
916
- * Build the optional `---` footer block (`parent` / `Epic` / `blocked by`
917
- * lines). Returns the empty string when `opts.includeFooter` is falsy.
969
+ * Build the optional `---` footer block (`parent` / `blocked by` lines).
970
+ * Returns the empty string when `opts.includeFooter` is falsy.
918
971
  *
919
972
  * @param {StoryBody} body
920
973
  * @param {SerializeOptions} opts
@@ -924,7 +977,9 @@ function serializeFooter(body, opts) {
924
977
  if (!opts.includeFooter) return '';
925
978
  const footerLines = ['---'];
926
979
  if (opts.footer?.parent) footerLines.push(`parent: #${opts.footer.parent}`);
927
- if (opts.footer?.epic) footerLines.push(`Epic: #${opts.footer.epic}`);
980
+ // Story #4545 — no `Epic: #N` branch. `pr-base-guard.js` hard-refuses a
981
+ // Story body carrying that footer, so composing one here would let the
982
+ // framework generate work it would then reject at delivery.
928
983
  if (Array.isArray(body.depends_on)) {
929
984
  for (const dep of body.depends_on) {
930
985
  footerLines.push(`blocked by ${dep}`);
@@ -938,8 +993,8 @@ function serializeFooter(body, opts) {
938
993
  * format written to GitHub issue bodies.
939
994
  *
940
995
  * The output matches the section order the spec-renderer uses:
941
- * `## Goal`, `## Changes`, `## Acceptance`, `## Verify`, `## References`,
942
- * `## Non-Goals` (each omitted when empty).
996
+ * `## Goal`, `## Slicing`, `## Spec`, `## Changes`, `## Acceptance`,
997
+ * `## Verify`, `## References`, `## Non-Goals` (each omitted when empty).
943
998
  *
944
999
  * `wide`, `reason_to_exist`, and `estimated_test_files` are emitted as a
945
1000
  * fenced `<!-- meta -->` comment block so round-trips preserve them without
@@ -200,7 +200,6 @@ export async function loadBodyTemplate(projectRoot) {
200
200
  export function buildContextEnvelope({
201
201
  seed,
202
202
  refine,
203
- persona,
204
203
  bodyTemplate,
205
204
  duplicateCandidates,
206
205
  techStack = null,
@@ -212,7 +211,6 @@ export function buildContextEnvelope({
212
211
  version: 1,
213
212
  seed,
214
213
  refine,
215
- persona,
216
214
  bodyTemplate,
217
215
  requiredSections: [...REQUIRED_SECTIONS],
218
216
  duplicateCandidates: {
@@ -222,8 +220,8 @@ export function buildContextEnvelope({
222
220
  techStack,
223
221
  corpusContext,
224
222
  deliverContract: {
225
- workflow: '.agents/workflows/helpers/single-story-deliver.md',
226
- requiredLabels: ['type::story', `persona::${persona}`],
223
+ workflow: '.agents/workflows/helpers/deliver-story.md',
224
+ requiredLabels: ['type::story'],
227
225
  forbidden: ['Epic: #N references in the body'],
228
226
  },
229
227
  };