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,359 +0,0 @@
1
- /**
2
- * amend.js — the `--amend` change-request delta path of the collapsed
3
- * persist surface (Epic #4474 PR4, design §2 mode matrix, amend row).
4
- *
5
- * An amend run receives the full ticket set with every ticket carrying an
6
- * `op` field:
7
- *
8
- * - `add` — a new Story; created fresh.
9
- * - `modify` — an existing Story whose contract changed; closed and
10
- * recreated (close-and-recreate is scoped to modify/close
11
- * slugs ONLY — never the whole tree, which is `--force`'s
12
- * semantics).
13
- * - `keep` — an existing Story left byte-untouched; it participates in
14
- * the merged-set DAG validation but no provider mutation
15
- * ever targets it.
16
- * - `close` — an existing Story dropped from the plan; closed.
17
- *
18
- * The DAG (and the full ticket validator) runs over the MERGED set —
19
- * keeps + adds + modifies, closes excluded — so a cycle introduced by an
20
- * add that depends on a kept Story that depends on a modify is caught
21
- * before any GitHub call, and a dependency pointing at a closed slug fails
22
- * the unknown-slug check.
23
- *
24
- * Close ops are destructive, so they are gated behind the same explicit
25
- * confirmation contract as `epic-reconcile.js`: without `--explicit-delete`
26
- * the run stops BEFORE any mutation, prints the dry-run op diff, and exits
27
- * 2 ({@link AmendExplicitCloseError} carries the rendered diff; the CLI
28
- * maps it onto the exit code). Non-interactive callers pass the flag.
29
- *
30
- * Slug → issue resolution: an explicit `id` on the ticket (the authoring
31
- * envelope's open-children listing carries issue numbers) wins; otherwise
32
- * the reconciler state ledger (`.agents/epics/<id>.state.json`) resolves
33
- * the slug. A modify/keep/close slug that resolves nowhere is a hard error
34
- * — the amend never guesses which Story it is about to close.
35
- *
36
- * @module lib/orchestration/plan-persist/amend
37
- */
38
-
39
- import { Logger } from '../../Logger.js';
40
-
41
- /** Valid `op` values on an amend ticket. */
42
- const AMEND_OPS = Object.freeze(['add', 'modify', 'keep', 'close']);
43
-
44
- /**
45
- * Error carrying the rendered dry-run diff for the exit-2 confirmation
46
- * path (mirrors `epic-reconcile.js` EXIT_CODES.EXPLICIT_DELETE_REQUIRED).
47
- */
48
- export class AmendExplicitCloseError extends Error {
49
- /**
50
- * @param {string} message
51
- * @param {{ diff: string }} detail
52
- */
53
- constructor(message, { diff }) {
54
- super(message);
55
- this.name = 'AmendExplicitCloseError';
56
- this.code = 'PLAN_AMEND_EXPLICIT_DELETE_REQUIRED';
57
- this.diff = diff;
58
- }
59
- }
60
-
61
- /**
62
- * Partition an amend ticket set by `op`, validating the op vocabulary and
63
- * slug uniqueness. Every ticket MUST carry an op — a missing op on one
64
- * ticket of an amend payload is an authoring defect, not a default.
65
- *
66
- * @param {Array<{ slug?: string, op?: string }>} tickets
67
- * @returns {{ add: object[], modify: object[], keep: object[], close: object[] }}
68
- */
69
- export function partitionAmendTickets(tickets) {
70
- const partition = { add: [], modify: [], keep: [], close: [] };
71
- const seen = new Set();
72
- for (const ticket of tickets) {
73
- const slug = ticket?.slug;
74
- if (typeof slug !== 'string' || slug.length === 0) {
75
- throw new Error(
76
- '[plan-persist] amend ticket without a slug — every amend ticket ' +
77
- 'must carry both slug and op.',
78
- );
79
- }
80
- if (seen.has(slug)) {
81
- throw new Error(
82
- `[plan-persist] duplicate slug "${slug}" in the amend payload.`,
83
- );
84
- }
85
- seen.add(slug);
86
- const op = ticket?.op;
87
- if (!AMEND_OPS.includes(op)) {
88
- throw new Error(
89
- `[plan-persist] amend ticket "${slug}" carries invalid op ` +
90
- `"${op}" — expected one of ${AMEND_OPS.join(', ')}.`,
91
- );
92
- }
93
- partition[op].push(ticket);
94
- }
95
- return partition;
96
- }
97
-
98
- /**
99
- * Project the MERGED ticket set for validation and spec rendering:
100
- * keeps + adds + modifies in original authoring order, closes excluded,
101
- * with the amend-only `op`/`id` carrier fields stripped so the ticket
102
- * validator and `renderSpec` see the exact fan-out ticket shape.
103
- *
104
- * @param {Array<{ op?: string }>} tickets the full amend payload
105
- * @returns {object[]} merged set, op/id stripped
106
- */
107
- export function buildMergedTicketSet(tickets) {
108
- return tickets
109
- .filter((t) => t?.op !== 'close')
110
- .map(({ op: _op, id: _id, ...rest }) => rest);
111
- }
112
-
113
- /**
114
- * Resolve every modify/keep/close slug to its live issue number and
115
- * hard-error on any ambiguity (the "closing the wrong stories" risk):
116
- *
117
- * - modify/keep/close must resolve via explicit `id` or the state
118
- * ledger mapping — no resolution is a hard error;
119
- * - an add slug must NOT already resolve to an issue (a collision means
120
- * the author meant modify, or picked a stale slug);
121
- * - resolved modify/close targets are fetched and must exist; a target
122
- * already closed on GitHub is surfaced (skipped close, not an error —
123
- * re-running an interrupted amend must stay safe).
124
- *
125
- * @param {{
126
- * partition: ReturnType<typeof partitionAmendTickets>,
127
- * stateMapping: Record<string, { issueNumber?: number }>,
128
- * provider: { getTicket: (id: number) => Promise<object|null> },
129
- * }} args
130
- * @returns {Promise<{
131
- * modify: Array<{ ticket: object, issueNumber: number, alreadyClosed: boolean }>,
132
- * keep: Array<{ ticket: object, issueNumber: number }>,
133
- * close: Array<{ ticket: object, issueNumber: number, alreadyClosed: boolean }>,
134
- * }>}
135
- */
136
- export async function resolveAmendTargets({
137
- partition,
138
- stateMapping,
139
- provider,
140
- }) {
141
- const mapping = stateMapping ?? {};
142
- const resolveSlug = (ticket) => {
143
- if (Number.isInteger(ticket.id)) return ticket.id;
144
- const entry = mapping[ticket.slug];
145
- if (Number.isInteger(entry?.issueNumber)) return entry.issueNumber;
146
- return null;
147
- };
148
-
149
- for (const ticket of partition.add) {
150
- const collision = resolveSlug(ticket);
151
- if (collision !== null) {
152
- throw new Error(
153
- `[plan-persist] amend op "add" for slug "${ticket.slug}" collides ` +
154
- `with existing issue #${collision} — use op "modify" to replace ` +
155
- 'it, or pick a fresh slug.',
156
- );
157
- }
158
- }
159
-
160
- const resolveExisting = async (ticket, op) => {
161
- const issueNumber = resolveSlug(ticket);
162
- if (issueNumber === null) {
163
- throw new Error(
164
- `[plan-persist] amend op "${op}" for slug "${ticket.slug}" resolves ` +
165
- 'to no existing issue (no `id` on the ticket, no state-ledger ' +
166
- 'mapping). Refusing to guess — carry the issue number as `id`.',
167
- );
168
- }
169
- const issue = await provider.getTicket(issueNumber);
170
- if (!issue) {
171
- throw new Error(
172
- `[plan-persist] amend op "${op}" for slug "${ticket.slug}" points ` +
173
- `at issue #${issueNumber}, which does not exist.`,
174
- );
175
- }
176
- return { ticket, issueNumber, alreadyClosed: issue.state === 'closed' };
177
- };
178
-
179
- const modify = [];
180
- for (const t of partition.modify)
181
- modify.push(await resolveExisting(t, 'modify'));
182
- const close = [];
183
- for (const t of partition.close)
184
- close.push(await resolveExisting(t, 'close'));
185
- const keep = [];
186
- for (const t of partition.keep) {
187
- const { ticket, issueNumber } = await resolveExisting(t, 'keep');
188
- keep.push({ ticket, issueNumber });
189
- }
190
- return { modify, keep, close };
191
- }
192
-
193
- /**
194
- * Render the operator-facing dry-run diff of the amend plan — printed on
195
- * the exit-2 confirmation path and logged before an `--explicit-delete`
196
- * apply so the destructive set is always visible.
197
- *
198
- * @param {{
199
- * epicId: number,
200
- * targets: Awaited<ReturnType<typeof resolveAmendTargets>>,
201
- * adds: Array<{ slug: string, title?: string }>,
202
- * }} args
203
- * @returns {string}
204
- */
205
- export function renderAmendPlanDiff({ epicId, targets, adds }) {
206
- const rows = [
207
- ...targets.close.map(
208
- (t) =>
209
- `| close | \`${t.ticket.slug}\` | #${t.issueNumber} | closed${t.alreadyClosed ? ' (already closed)' : ''} |`,
210
- ),
211
- ...targets.modify.map(
212
- (t) =>
213
- `| modify | \`${t.ticket.slug}\` | #${t.issueNumber} | closed + recreated |`,
214
- ),
215
- ...adds.map((t) => `| add | \`${t.slug}\` | — | created |`),
216
- ...targets.keep.map(
217
- (t) => `| keep | \`${t.ticket.slug}\` | #${t.issueNumber} | untouched |`,
218
- ),
219
- ];
220
- return [
221
- `Amend plan for Epic #${epicId} (dry-run):`,
222
- '',
223
- '| Op | Slug | Issue | Effect |',
224
- '| --- | --- | --- | --- |',
225
- ...rows,
226
- ].join('\n');
227
- }
228
-
229
- /**
230
- * Enforce the close-op confirmation gate: when the amend plan carries
231
- * close ops (including the close half of modify) affecting live issues and
232
- * `--explicit-delete` was not passed, throw {@link AmendExplicitCloseError}
233
- * with the rendered diff — BEFORE any mutation. Mirrors the
234
- * `epic-reconcile.js` exit-2 contract.
235
- *
236
- * @param {{
237
- * epicId: number,
238
- * targets: Awaited<ReturnType<typeof resolveAmendTargets>>,
239
- * adds: object[],
240
- * explicitDelete: boolean,
241
- * }} args
242
- */
243
- export function enforceAmendCloseGate({
244
- epicId,
245
- targets,
246
- adds,
247
- explicitDelete,
248
- }) {
249
- const liveCloses = [
250
- ...targets.close.filter((t) => !t.alreadyClosed),
251
- ...targets.modify.filter((t) => !t.alreadyClosed),
252
- ];
253
- if (liveCloses.length === 0 || explicitDelete) return;
254
- const diff = renderAmendPlanDiff({ epicId, targets, adds });
255
- const named = liveCloses
256
- .map((t) => `#${t.issueNumber} (\`${t.ticket.slug}\`)`)
257
- .join(', ');
258
- throw new AmendExplicitCloseError(
259
- `[plan-persist] amend plan would close ${liveCloses.length} live ` +
260
- `issue(s): ${named}. Review the dry-run diff and re-run with ` +
261
- '--explicit-delete to apply.',
262
- { diff },
263
- );
264
- }
265
-
266
- /**
267
- * Apply the amend ops against the provider, in destructive-last order per
268
- * slug class: closes first (their disappearance is what the operator
269
- * confirmed), then modify (close old + create new), then adds. Keeps are
270
- * never touched by construction — no code path here receives them.
271
- *
272
- * @param {{
273
- * epicId: number,
274
- * provider: {
275
- * updateTicket: (id: number, patch: object) => Promise<object>,
276
- * createTicket: (parentId: number, payload: object) => Promise<{ id: number }>,
277
- * },
278
- * targets: Awaited<ReturnType<typeof resolveAmendTargets>>,
279
- * validatedBySlug: Map<string, { slug: string, title: string, body?: string, labels?: string[] }>,
280
- * }} args
281
- * @returns {Promise<{
282
- * closed: Array<{ slug: string, issueNumber: number }>,
283
- * recreated: Array<{ slug: string, oldIssueNumber: number, issueNumber: number }>,
284
- * created: Array<{ slug: string, issueNumber: number }>,
285
- * mapping: Record<string, { entity: 'story', issueNumber: number }>,
286
- * closedSlugs: string[],
287
- * }>}
288
- */
289
- export async function applyAmendOps({
290
- epicId,
291
- provider,
292
- targets,
293
- validatedBySlug,
294
- }) {
295
- const closed = [];
296
- const recreated = [];
297
- const created = [];
298
- const mapping = {};
299
- const closedSlugs = [];
300
-
301
- const createFromValidated = async (slug) => {
302
- const validated = validatedBySlug.get(slug);
303
- if (!validated) {
304
- throw new Error(
305
- `[plan-persist] amend apply: no validated ticket for slug "${slug}".`,
306
- );
307
- }
308
- const result = await provider.createTicket(epicId, {
309
- title: validated.title,
310
- body: validated.body ?? '',
311
- labels: validated.labels ?? [],
312
- });
313
- return result.id;
314
- };
315
-
316
- for (const target of targets.close) {
317
- if (!target.alreadyClosed) {
318
- await provider.updateTicket(target.issueNumber, { state: 'closed' });
319
- } else {
320
- Logger.info(
321
- `[plan-persist] amend close: #${target.issueNumber} ` +
322
- `(${target.ticket.slug}) already closed — skipping.`,
323
- );
324
- }
325
- closed.push({ slug: target.ticket.slug, issueNumber: target.issueNumber });
326
- closedSlugs.push(target.ticket.slug);
327
- }
328
-
329
- for (const target of targets.modify) {
330
- if (!target.alreadyClosed) {
331
- await provider.updateTicket(target.issueNumber, { state: 'closed' });
332
- }
333
- const newId = await createFromValidated(target.ticket.slug);
334
- recreated.push({
335
- slug: target.ticket.slug,
336
- oldIssueNumber: target.issueNumber,
337
- issueNumber: newId,
338
- });
339
- mapping[target.ticket.slug] = { entity: 'story', issueNumber: newId };
340
- }
341
-
342
- for (const [slug] of validatedBySlug) {
343
- const isModify = targets.modify.some((t) => t.ticket.slug === slug);
344
- const isKeep = targets.keep.some((t) => t.ticket.slug === slug);
345
- if (isModify || isKeep) continue;
346
- const newId = await createFromValidated(slug);
347
- created.push({ slug, issueNumber: newId });
348
- mapping[slug] = { entity: 'story', issueNumber: newId };
349
- }
350
-
351
- for (const target of targets.keep) {
352
- mapping[target.ticket.slug] = {
353
- entity: 'story',
354
- issueNumber: target.issueNumber,
355
- };
356
- }
357
-
358
- return { closed, recreated, created, mapping, closedSlugs };
359
- }
@@ -1,127 +0,0 @@
1
- /**
2
- * delivery-mode.js — delivery-shape mode resolution for the collapsed
3
- * persist surface (Epic #4474 PR4, design §2 mode matrix).
4
- *
5
- * The risk verdict's optional `deliveryShape` field ("fan-out" | "single",
6
- * absent → fan-out so every existing verdict stays valid) selects between
7
- * the three persist modes:
8
- *
9
- * - `fan-out` — the full mode: ticket validator + DAG + budget gates,
10
- * Story-tree creation via the structural reconciler.
11
- * - `single` — the spec-only single-delivery mode: NO tickets are
12
- * authored, the ticket validator + DAG are skipped (fenced by
13
- * construction — {@link resolveDeliveryMode} hard-refuses the
14
- * combination of `deliveryShape: "single"` with a tickets payload, so
15
- * the skip branch is unreachable when tickets are present), and the
16
- * persist applies the `delivery::single` routing marker instead of a
17
- * Story tree. Inert until #4475 lands the deliver-side reader.
18
- * - `amend` — the change-request delta path (`--amend`): tickets carry
19
- * `op: add|modify|keep|close` and the persist maps the ops onto the
20
- * existing Story tree (see `plan-persist/amend.js`).
21
- *
22
- * @module lib/orchestration/plan-persist/delivery-mode
23
- */
24
-
25
- import { parseDeliverySlicingTable } from '../consolidation-precondition.js';
26
-
27
- /** Canonical delivery-shape values the risk-verdict schema admits. */
28
- const DELIVERY_SHAPES = Object.freeze(['fan-out', 'single']);
29
-
30
- /**
31
- * Mode-coherence hard error (design §1 step 3 item 3, extended for PR4).
32
- *
33
- * Resolves the persist mode from the risk verdict's `deliveryShape` (absent
34
- * → `fan-out`), the tickets payload, and the `--amend` flag — and refuses
35
- * every incoherent combination loudly instead of silently coercing:
36
- *
37
- * - unknown `deliveryShape` values;
38
- * - `deliveryShape: "single"` WITH a tickets payload (the DAG-skip
39
- * leakage risk — the single mode's validator/DAG skip is only sound
40
- * when there are no tickets to validate);
41
- * - fan-out without a non-empty tickets array;
42
- * - `--amend` combined with `deliveryShape: "single"` (the delta path is
43
- * fan-out-shaped by definition — a single-delivery re-plan is a
44
- * `--force` re-persist);
45
- * - `--amend` without tickets (the delta IS the tickets-with-ops
46
- * payload);
47
- * - `op` fields present without `--amend` (a full persist must never
48
- * silently reinterpret an amend delta as a fresh tree).
49
- *
50
- * @param {{ deliveryShape?: string }} riskVerdict schema-validated verdict
51
- * @param {unknown} tickets parsed tickets payload (null when no file)
52
- * @param {{ amend?: boolean }} [opts]
53
- * @returns {'fan-out'|'single'|'amend'} the resolved persist mode
54
- */
55
- export function resolveDeliveryMode(riskVerdict, tickets, opts = {}) {
56
- const { amend = false } = opts;
57
- const shape = riskVerdict?.deliveryShape ?? 'fan-out';
58
- if (!DELIVERY_SHAPES.includes(shape)) {
59
- throw new Error(
60
- `[plan-persist] unknown deliveryShape "${shape}" — expected one of ` +
61
- `${DELIVERY_SHAPES.join(', ')} (or omit the field for fan-out).`,
62
- );
63
- }
64
- const hasTickets = Array.isArray(tickets) && tickets.length > 0;
65
-
66
- if (amend) {
67
- if (shape === 'single') {
68
- throw new Error(
69
- '[plan-persist] --amend is incoherent with deliveryShape "single" — ' +
70
- 'the amend delta maps ops onto an existing Story tree, and a ' +
71
- 'single-delivery plan has none. Re-author the verdict as fan-out, ' +
72
- 'or re-persist the single plan with --force.',
73
- );
74
- }
75
- if (!hasTickets) {
76
- throw new Error(
77
- '[plan-persist] --amend requires a tickets payload carrying ' +
78
- '`op: add|modify|keep|close` on every ticket — the delta IS the ' +
79
- 'tickets file (--tickets <file>).',
80
- );
81
- }
82
- return 'amend';
83
- }
84
-
85
- if (shape === 'single') {
86
- if (hasTickets) {
87
- throw new Error(
88
- '[plan-persist] mode-coherence: deliveryShape "single" with a ' +
89
- 'tickets payload is contradictory — the single-delivery mode ' +
90
- 'authors NO tickets (the Delivery Slicing table is the audit ' +
91
- 'trail). Remove the tickets file, or re-author the risk verdict ' +
92
- 'as fan-out.',
93
- );
94
- }
95
- return 'single';
96
- }
97
-
98
- if (!hasTickets) {
99
- throw new Error(
100
- '[plan-persist] fan-out persist requires a non-empty tickets array ' +
101
- '(--tickets <file>). A ticket-less spec-only plan must declare ' +
102
- 'deliveryShape: "single" in the risk verdict.',
103
- );
104
- }
105
- if (tickets.some((t) => t && typeof t === 'object' && 'op' in t)) {
106
- throw new Error(
107
- '[plan-persist] tickets carry `op` fields but --amend was not passed ' +
108
- '— refusing to reinterpret an amend delta as a full persist. Pass ' +
109
- '--amend, or strip the op fields for a fresh fan-out.',
110
- );
111
- }
112
- return 'fan-out';
113
- }
114
-
115
- /**
116
- * Count the slices of the authored Tech Spec's `## Delivery Slicing` table
117
- * — the single-mode plan summary's `sliceCount` (design §2: the slicing
118
- * table IS the single mode's audit trail). Returns `null` when the table
119
- * is absent or unparseable (fail-open, mirroring the parser's contract).
120
- *
121
- * @param {string} techSpecContent
122
- * @returns {number|null}
123
- */
124
- export function countDeliverySlices(techSpecContent) {
125
- const rows = parseDeliverySlicingTable(techSpecContent ?? '');
126
- return Array.isArray(rows) ? rows.length : null;
127
- }
@@ -1,63 +0,0 @@
1
- /**
2
- * plan-review-routing.js — resolve Phase 7 review-stop vs auto-proceed.
3
- *
4
- * Pure ESM, no I/O. Consumes the shared planningRisk envelope (derived
5
- * from the planner-authored risk verdict via `deriveRiskEnvelope`) and
6
- * optional operator overrides to decide whether the plan wrapper should
7
- * STOP for human review before Phase 8.
8
- */
9
-
10
- /**
11
- * @typedef {import('./planning-risk.js').PlanningRiskEnvelope} PlanningRiskEnvelope
12
- * @typedef {'review-required' | 'auto-proceed' | 'operator-override-review'} ReviewRoutingDecision
13
- */
14
-
15
- /**
16
- * @typedef {Object} ReviewRoutingEnvelope
17
- * @property {ReviewRoutingDecision} decision
18
- * @property {boolean} requiresStop
19
- * @property {boolean} forceReviewApplied
20
- * @property {string} operatorMessage
21
- */
22
-
23
- const AUTO_PROCEED_MESSAGE =
24
- 'Planning risk is low — auto-proceeding to Phase 8 decomposition after spec validation. Context tickets remain open until Epic delivery finalizes.';
25
-
26
- const REVIEW_REQUIRED_MESSAGE =
27
- 'Planning risk requires operator review — STOP before Phase 8. Review the Tech Spec sections and the Acceptance Table — both managed sections of the Epic body — on GitHub and confirm in this session before decomposition.';
28
-
29
- const FORCE_REVIEW_MESSAGE =
30
- 'Operator override — forcing review stop before Phase 8 despite low planning risk.';
31
-
32
- /**
33
- * Resolve whether Phase 7 should STOP for operator review before Phase 8.
34
- *
35
- * @param {{ planningRisk: PlanningRiskEnvelope, forceReview?: boolean }} input
36
- * @returns {ReviewRoutingEnvelope}
37
- */
38
- export function resolveReviewRouting({ planningRisk, forceReview = false }) {
39
- if (forceReview) {
40
- return {
41
- decision: 'operator-override-review',
42
- requiresStop: true,
43
- forceReviewApplied: true,
44
- operatorMessage: FORCE_REVIEW_MESSAGE,
45
- };
46
- }
47
-
48
- if (planningRisk.requiresReview) {
49
- return {
50
- decision: 'review-required',
51
- requiresStop: true,
52
- forceReviewApplied: false,
53
- operatorMessage: REVIEW_REQUIRED_MESSAGE,
54
- };
55
- }
56
-
57
- return {
58
- decision: 'auto-proceed',
59
- requiresStop: false,
60
- forceReviewApplied: false,
61
- operatorMessage: AUTO_PROCEED_MESSAGE,
62
- };
63
- }