mandrel 1.93.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (463) hide show
  1. package/.agents/README.md +59 -73
  2. package/.agents/agents/acceptance-critic.md +129 -0
  3. package/.agents/agents/story-worker.md +161 -0
  4. package/.agents/docs/SDLC.md +489 -1285
  5. package/.agents/docs/agentrc-reference.json +177 -67
  6. package/.agents/docs/configuration.md +108 -136
  7. package/.agents/docs/execution-reference.md +44 -22
  8. package/.agents/docs/quality-gates.md +13 -19
  9. package/.agents/docs/workflows.md +3 -3
  10. package/.agents/instructions.md +107 -108
  11. package/.agents/rules/ci-remediation.md +8 -12
  12. package/.agents/rules/git-conventions-reference.md +224 -0
  13. package/.agents/rules/git-conventions.md +42 -223
  14. package/.agents/rules/security-baseline.md +5 -0
  15. package/.agents/rules/testing-standards.md +106 -13
  16. package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
  17. package/.agents/schemas/agentrc.schema.json +71 -201
  18. package/.agents/schemas/lifecycle/ledger-record.schema.json +1 -1
  19. package/.agents/schemas/lifecycle/retro.end.schema.json +1 -1
  20. package/.agents/schemas/risk-verdict.schema.json +0 -13
  21. package/.agents/scripts/acceptance-eval.js +62 -18
  22. package/.agents/scripts/agents-bootstrap-github.js +1 -1
  23. package/.agents/scripts/analyze-execution.js +1 -1
  24. package/.agents/scripts/audit-to-stories.js +7 -7
  25. package/.agents/scripts/boot-sweep.js +1 -1
  26. package/.agents/scripts/check-context-budget.js +62 -5
  27. package/.agents/scripts/check-lifecycle-lint.js +6 -9
  28. package/.agents/scripts/check-prepush-recovery.js +1 -1
  29. package/.agents/scripts/cleanup-repo-test-temp.js +6 -1
  30. package/.agents/scripts/diagnose-friction.js +0 -6
  31. package/.agents/scripts/lib/Logger.js +6 -10
  32. package/.agents/scripts/lib/audit-suite/runner.js +2 -2
  33. package/.agents/scripts/lib/audit-suite/selector.js +5 -5
  34. package/.agents/scripts/lib/audit-to-stories/{seed-epic-from-findings.js → seed-from-findings.js} +9 -9
  35. package/.agents/scripts/lib/baselines/kernel.js +206 -18
  36. package/.agents/scripts/lib/baselines/kinds/maintainability.js +0 -4
  37. package/.agents/scripts/lib/baselines/reader.js +1 -6
  38. package/.agents/scripts/lib/bdd-runner-detect.js +5 -9
  39. package/.agents/scripts/lib/bootstrap/issue-forms-template.js +32 -33
  40. package/.agents/scripts/lib/bootstrap/project-bootstrap.js +56 -18
  41. package/.agents/scripts/lib/checks/core-bare-clean.js +2 -2
  42. package/.agents/scripts/lib/checks/index.js +2 -1
  43. package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +23 -21
  44. package/.agents/scripts/lib/cli/standard-args.js +13 -22
  45. package/.agents/scripts/lib/cli-args.js +16 -7
  46. package/.agents/scripts/lib/close-validation/gates.js +160 -22
  47. package/.agents/scripts/lib/config/acceptance-eval.js +52 -5
  48. package/.agents/scripts/lib/config/ci.js +6 -31
  49. package/.agents/scripts/lib/config/delivery-routing.js +103 -0
  50. package/.agents/scripts/lib/config/explain.js +57 -36
  51. package/.agents/scripts/lib/config/limits.js +17 -58
  52. package/.agents/scripts/lib/config/paths.js +0 -2
  53. package/.agents/scripts/lib/config/quality.js +1 -1
  54. package/.agents/scripts/lib/config/runners.js +17 -50
  55. package/.agents/scripts/lib/config/temp-paths.js +19 -14
  56. package/.agents/scripts/lib/config/worktree-isolation.js +0 -5
  57. package/.agents/scripts/lib/config-resolver.js +3 -8
  58. package/.agents/scripts/lib/config-settings-schema-delivery.js +46 -136
  59. package/.agents/scripts/lib/config-settings-schema-quality.js +17 -14
  60. package/.agents/scripts/lib/config-settings-schema.js +52 -38
  61. package/.agents/scripts/lib/dependency-parser.js +3 -2
  62. package/.agents/scripts/lib/doc-tiers.js +39 -4
  63. package/.agents/scripts/lib/duplicate-search.js +211 -41
  64. package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +1 -1
  65. package/.agents/scripts/lib/findings/promote-finding.js +5 -5
  66. package/.agents/scripts/lib/framework-version.js +2 -3
  67. package/.agents/scripts/lib/git-branch-cleanup.js +1 -10
  68. package/.agents/scripts/lib/git-branch-lifecycle.js +17 -22
  69. package/.agents/scripts/lib/git-utils.js +32 -6
  70. package/.agents/scripts/lib/github/framework-repo.js +6 -0
  71. package/.agents/scripts/lib/label-constants.js +10 -23
  72. package/.agents/scripts/lib/label-taxonomy.js +9 -43
  73. package/.agents/scripts/lib/observability/active-story-env.js +112 -3
  74. package/.agents/scripts/lib/observability/hook-heartbeat.js +187 -0
  75. package/.agents/scripts/lib/observability/source-classifier.js +3 -3
  76. package/.agents/scripts/lib/observability/tool-trace-hook.js +15 -4
  77. package/.agents/scripts/lib/onboard/init-tail.js +1 -3
  78. package/.agents/scripts/lib/orchestration/acceptance-clusters.js +111 -0
  79. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +32 -4
  80. package/.agents/scripts/lib/orchestration/audit-lens-routing.js +128 -0
  81. package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +273 -0
  82. package/.agents/scripts/lib/orchestration/ceremony-routing.js +204 -0
  83. package/.agents/scripts/lib/orchestration/code-review.js +20 -268
  84. package/.agents/scripts/lib/orchestration/column-sync.js +1 -1
  85. package/.agents/scripts/lib/orchestration/consolidation-precondition.js +1 -1
  86. package/.agents/scripts/lib/orchestration/context-envelope.js +2 -5
  87. package/.agents/scripts/lib/orchestration/docs-digest.js +8 -8
  88. package/.agents/scripts/lib/orchestration/file-assumptions.js +7 -13
  89. package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +1 -1
  90. package/.agents/scripts/lib/orchestration/lifecycle/emit-loop-tick.js +8 -8
  91. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +2 -2
  92. package/.agents/scripts/lib/orchestration/lifecycle/ledger-writer.js +6 -3
  93. package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +17 -43
  94. package/.agents/scripts/lib/orchestration/lint-baseline-service.js +4 -4
  95. package/.agents/scripts/lib/orchestration/merge-block-class.js +1 -1
  96. package/.agents/scripts/lib/orchestration/phase-runner.js +3 -2
  97. package/.agents/scripts/lib/orchestration/plan-context.js +248 -266
  98. package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +3 -2
  99. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +1 -1
  100. package/.agents/scripts/lib/orchestration/plan-navigation.js +92 -0
  101. package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +61 -0
  102. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +97 -0
  103. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +223 -854
  104. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +361 -0
  105. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +35 -108
  106. package/.agents/scripts/lib/orchestration/plan-reachability.js +9 -14
  107. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +1 -1
  108. package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/authoring-context.js +14 -14
  109. package/.agents/scripts/lib/orchestration/planning/decomposer-context.js +27 -0
  110. package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/risk-verdict.js +3 -4
  111. package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +2 -2
  112. package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +8 -20
  113. package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +3 -2
  114. package/.agents/scripts/lib/orchestration/pr-base-guard.js +18 -28
  115. package/.agents/scripts/lib/orchestration/preflight-cache.js +5 -5
  116. package/.agents/scripts/lib/orchestration/remote-verifier.js +1 -1
  117. package/.agents/scripts/lib/orchestration/resolve-plan-run.js +155 -0
  118. package/.agents/scripts/lib/orchestration/resolves-token.js +1 -1
  119. package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +8 -8
  120. package/.agents/scripts/lib/orchestration/retro-proposals.js +140 -79
  121. package/.agents/scripts/lib/orchestration/review-depth.js +26 -12
  122. package/.agents/scripts/lib/orchestration/review-providers/codex.js +2 -2
  123. package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +21 -56
  124. package/.agents/scripts/lib/orchestration/run-epilogue.js +426 -0
  125. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +1 -1
  126. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +1 -0
  127. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +95 -41
  128. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +16 -13
  129. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +40 -0
  130. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +11 -3
  131. package/.agents/scripts/lib/orchestration/spec-freshness.js +14 -205
  132. package/.agents/scripts/lib/orchestration/spec-section-validator.js +4 -5
  133. package/.agents/scripts/lib/orchestration/spec-spill.js +60 -0
  134. package/.agents/scripts/lib/orchestration/split-policy-validator.js +188 -0
  135. package/.agents/scripts/lib/orchestration/story-close/emit-blocked.js +49 -0
  136. package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +15 -12
  137. package/.agents/scripts/lib/orchestration/story-follow-ups.js +237 -0
  138. package/.agents/scripts/lib/orchestration/story-init-remote.js +47 -0
  139. package/.agents/scripts/lib/orchestration/story-plan-state.js +48 -0
  140. package/.agents/scripts/lib/orchestration/{epic-runner → story-progress}/story-run-progress-writer.js +3 -3
  141. package/.agents/scripts/lib/orchestration/structured-comment-parser.js +1 -1
  142. package/.agents/scripts/lib/orchestration/task-body-validator.js +8 -18
  143. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +11 -61
  144. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +189 -373
  145. package/.agents/scripts/lib/orchestration/ticket-validator.js +3 -8
  146. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +0 -25
  147. package/.agents/scripts/lib/orchestration/ticketing/reads.js +29 -26
  148. package/.agents/scripts/lib/orchestration/ticketing/transition.js +5 -5
  149. package/.agents/scripts/lib/planning-corpus.js +16 -11
  150. package/.agents/scripts/lib/preflight-runner.js +2 -2
  151. package/.agents/scripts/lib/provider-factory.js +1 -1
  152. package/.agents/scripts/lib/qa/coverage-verdict.js +5 -5
  153. package/.agents/scripts/lib/single-story/confirm-merge-follow-ups.js +36 -0
  154. package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +1 -1
  155. package/.agents/scripts/lib/story-adjacency.js +11 -14
  156. package/.agents/scripts/lib/story-body/story-body.js +124 -70
  157. package/.agents/scripts/lib/story-plan.js +2 -4
  158. package/.agents/scripts/lib/templates/decomposer-prompts.js +46 -45
  159. package/.agents/scripts/lib/templates/spec-author-prompts.js +47 -45
  160. package/.agents/scripts/lib/{epic-body-sections.js → ticket-body-sections.js} +26 -26
  161. package/.agents/scripts/lib/validation-evidence.js +1 -1
  162. package/.agents/scripts/lib/wave-runner/ready-set.js +6 -6
  163. package/.agents/scripts/lib/workspace-provisioner.js +1 -1
  164. package/.agents/scripts/lib/worktree/lifecycle/reap.js +5 -7
  165. package/.agents/scripts/lint-issue-body.js +71 -40
  166. package/.agents/scripts/mandrel-update-preflight.js +1 -1
  167. package/.agents/scripts/notify.js +4 -3
  168. package/.agents/scripts/plan-context.js +64 -74
  169. package/.agents/scripts/plan-persist.js +121 -280
  170. package/.agents/scripts/plan-run-epilogue.js +97 -0
  171. package/.agents/scripts/post-structured-comment.js +38 -0
  172. package/.agents/scripts/providers/github/issues.js +17 -33
  173. package/.agents/scripts/providers/github/mappers.js +0 -12
  174. package/.agents/scripts/providers/github/tickets.js +2 -5
  175. package/.agents/scripts/resolve-plan-run.js +117 -0
  176. package/.agents/scripts/signals-view.js +24 -19
  177. package/.agents/scripts/single-story-close.js +11 -14
  178. package/.agents/scripts/single-story-confirm-merge.js +39 -23
  179. package/.agents/scripts/single-story-init.js +29 -20
  180. package/.agents/scripts/stories-wave-tick.js +6 -6
  181. package/.agents/scripts/story-plan.js +26 -47
  182. package/.agents/scripts/sync-claude-agents.js +165 -0
  183. package/.agents/scripts/update-ticket-state.js +37 -15
  184. package/.agents/skills/core/analyze-execution/SKILL.md +21 -18
  185. package/.agents/skills/core/api-and-interface-design/SKILL.md +5 -3
  186. package/.agents/skills/core/code-review-and-quality/SKILL.md +63 -7
  187. package/.agents/skills/core/debugging-and-error-recovery/SKILL.md +1 -1
  188. package/.agents/skills/core/gates-and-baselines/SKILL.md +149 -0
  189. package/.agents/skills/core/idea-refinement/SKILL.md +8 -14
  190. package/.agents/skills/core/qa-coverage-mapping/SKILL.md +7 -7
  191. package/.agents/skills/core/scope-triage/SKILL.md +28 -172
  192. package/.agents/skills/skills.index.json +8 -418
  193. package/.agents/starter-agentrc.json +0 -5
  194. package/.agents/templates/agent-protocol.md +9 -10
  195. package/.agents/workflows/audit-architecture.md +3 -3
  196. package/.agents/workflows/audit-clean-code.md +3 -3
  197. package/.agents/workflows/audit-dependencies.md +3 -3
  198. package/.agents/workflows/audit-devops.md +3 -3
  199. package/.agents/workflows/audit-documentation.md +5 -5
  200. package/.agents/workflows/audit-lighthouse.md +3 -3
  201. package/.agents/workflows/audit-navigability.md +3 -2
  202. package/.agents/workflows/audit-performance.md +3 -3
  203. package/.agents/workflows/audit-privacy.md +3 -3
  204. package/.agents/workflows/audit-quality.md +3 -3
  205. package/.agents/workflows/audit-security.md +3 -3
  206. package/.agents/workflows/audit-seo.md +3 -3
  207. package/.agents/workflows/audit-sre.md +3 -3
  208. package/.agents/workflows/audit-to-stories.md +20 -20
  209. package/.agents/workflows/audit-ux-ui.md +3 -3
  210. package/.agents/workflows/deliver.md +122 -131
  211. package/.agents/workflows/git-cleanup.md +3 -4
  212. package/.agents/workflows/helpers/_merge-conflict-template.md +1 -1
  213. package/.agents/workflows/helpers/acceptance-self-eval.md +52 -40
  214. package/.agents/workflows/helpers/code-review.md +70 -193
  215. package/.agents/workflows/helpers/{single-story-deliver-reference.md → deliver-story-reference.md} +12 -14
  216. package/.agents/workflows/helpers/{single-story-deliver.md → deliver-story.md} +113 -139
  217. package/.agents/workflows/helpers/diagnose.md +10 -10
  218. package/.agents/workflows/helpers/mandrel-sync-config.md +1 -1
  219. package/.agents/workflows/helpers/parallel-tooling.md +1 -1
  220. package/.agents/workflows/helpers/signals.md +16 -16
  221. package/.agents/workflows/helpers/worktree-lifecycle.md +48 -64
  222. package/.agents/workflows/mandrel-update.md +3 -2
  223. package/.agents/workflows/plan.md +112 -145
  224. package/.agents/workflows/qa-assist.md +24 -30
  225. package/.agents/workflows/qa-explore.md +29 -38
  226. package/.agents/workflows/qa-run.md +2 -2
  227. package/README.md +9 -8
  228. package/docs/CHANGELOG.md +46 -0
  229. package/lib/cli/registry.js +95 -0
  230. package/lib/migrations/index.js +6 -5
  231. package/package.json +5 -3
  232. package/.agents/personas/architect.md +0 -113
  233. package/.agents/personas/devops-engineer.md +0 -38
  234. package/.agents/personas/engineer-mobile.md +0 -120
  235. package/.agents/personas/engineer-web.md +0 -111
  236. package/.agents/personas/engineer.md +0 -119
  237. package/.agents/personas/product.md +0 -94
  238. package/.agents/personas/project-manager.md +0 -114
  239. package/.agents/personas/qa-engineer.md +0 -95
  240. package/.agents/personas/refactorer.md +0 -113
  241. package/.agents/personas/security-engineer.md +0 -112
  242. package/.agents/personas/sre.md +0 -86
  243. package/.agents/personas/technical-writer.md +0 -101
  244. package/.agents/personas/ux-designer.md +0 -95
  245. package/.agents/schemas/dispatch-manifest.json +0 -232
  246. package/.agents/schemas/epic-spec.schema.json +0 -153
  247. package/.agents/scripts/acceptance-spec-reconciler.js +0 -642
  248. package/.agents/scripts/dispatcher.js +0 -295
  249. package/.agents/scripts/epic-audit-prepare.js +0 -497
  250. package/.agents/scripts/epic-audit-recheck.js +0 -274
  251. package/.agents/scripts/epic-deliver-note-intervention.js +0 -192
  252. package/.agents/scripts/epic-deliver-preflight.js +0 -462
  253. package/.agents/scripts/epic-deliver-prepare.js +0 -590
  254. package/.agents/scripts/epic-execute-record-wave.js +0 -449
  255. package/.agents/scripts/epic-plan-clarity.js +0 -211
  256. package/.agents/scripts/epic-plan-decompose.js +0 -54
  257. package/.agents/scripts/epic-plan-healthcheck.js +0 -581
  258. package/.agents/scripts/epic-plan-spec.js +0 -64
  259. package/.agents/scripts/epic-reconcile.js +0 -625
  260. package/.agents/scripts/lib/baseline-snapshot.js +0 -979
  261. package/.agents/scripts/lib/checks/epic-merge-lock-stale.js +0 -54
  262. package/.agents/scripts/lib/checks/stale-origin-epic.js +0 -49
  263. package/.agents/scripts/lib/config/lifecycle.js +0 -40
  264. package/.agents/scripts/lib/config/preflight.js +0 -58
  265. package/.agents/scripts/lib/config/retro.js +0 -77
  266. package/.agents/scripts/lib/epic-merge-lock.js +0 -322
  267. package/.agents/scripts/lib/epic-plan-clarity.js +0 -181
  268. package/.agents/scripts/lib/epic-plan-ideation.js +0 -261
  269. package/.agents/scripts/lib/orchestration/context-hydration-engine.js +0 -660
  270. package/.agents/scripts/lib/orchestration/dispatch-engine.js +0 -134
  271. package/.agents/scripts/lib/orchestration/dispatch-pipeline.js +0 -183
  272. package/.agents/scripts/lib/orchestration/epic-cleanup.js +0 -801
  273. package/.agents/scripts/lib/orchestration/epic-deliver-lease-guard.js +0 -310
  274. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/context.js +0 -163
  275. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/creation.js +0 -140
  276. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/dag.js +0 -64
  277. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/diagnostics.js +0 -72
  278. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +0 -156
  279. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist.js +0 -345
  280. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +0 -41
  281. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/reconcile-spawn.js +0 -86
  282. package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +0 -391
  283. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/drain.js +0 -94
  284. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +0 -236
  285. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +0 -307
  286. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-freshness.js +0 -117
  287. package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +0 -117
  288. package/.agents/scripts/lib/orchestration/epic-run-state-store.js +0 -388
  289. package/.agents/scripts/lib/orchestration/epic-runner/concurrency-gate.js +0 -186
  290. package/.agents/scripts/lib/orchestration/epic-runner/deliver-phases.js +0 -50
  291. package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +0 -129
  292. package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +0 -103
  293. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/composition.js +0 -267
  294. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/signals.js +0 -210
  295. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/transport.js +0 -238
  296. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/_bullet-format.js +0 -32
  297. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/component-drift.js +0 -203
  298. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/crap-drift.js +0 -227
  299. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/maintainability-drift.js +0 -117
  300. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/stalled-worktree.js +0 -37
  301. package/.agents/scripts/lib/orchestration/epic-runner/story-launcher.js +0 -127
  302. package/.agents/scripts/lib/orchestration/epic-runner/sub-agent-return.js +0 -276
  303. package/.agents/scripts/lib/orchestration/epic-runner/wave-scheduler.js +0 -66
  304. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-apply.js +0 -789
  305. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +0 -676
  306. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-discriminator.js +0 -389
  307. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-format.js +0 -230
  308. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-ops.js +0 -361
  309. package/.agents/scripts/lib/orchestration/finalize/open-or-locate-pr.js +0 -306
  310. package/.agents/scripts/lib/orchestration/finalize/post-handoff-comment.js +0 -489
  311. package/.agents/scripts/lib/orchestration/finalize/sanitize-skip-ci.js +0 -88
  312. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-dispatch-end.js +0 -147
  313. package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +0 -384
  314. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +0 -501
  315. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +0 -984
  316. package/.agents/scripts/lib/orchestration/lifecycle/listeners/branch-cleaner.js +0 -264
  317. package/.agents/scripts/lib/orchestration/lifecycle/listeners/checkpoint-pointer-writer.js +0 -278
  318. package/.agents/scripts/lib/orchestration/lifecycle/listeners/cleaner.js +0 -355
  319. package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +0 -673
  320. package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +0 -378
  321. package/.agents/scripts/lib/orchestration/lifecycle/listeners/intervention-recorder.js +0 -140
  322. package/.agents/scripts/lib/orchestration/lifecycle/listeners/label-transitioner.js +0 -144
  323. package/.agents/scripts/lib/orchestration/lifecycle/listeners/notify-dispatcher.js +0 -174
  324. package/.agents/scripts/lib/orchestration/manifest-builder.js +0 -222
  325. package/.agents/scripts/lib/orchestration/plan-persist/amend.js +0 -359
  326. package/.agents/scripts/lib/orchestration/plan-persist/delivery-mode.js +0 -127
  327. package/.agents/scripts/lib/orchestration/post-merge-pipeline.js +0 -205
  328. package/.agents/scripts/lib/orchestration/recurring-failure-detector.js +0 -152
  329. package/.agents/scripts/lib/orchestration/retro/phases/checks.js +0 -94
  330. package/.agents/scripts/lib/orchestration/retro/phases/compose-body.js +0 -571
  331. package/.agents/scripts/lib/orchestration/retro/phases/gather-signals.js +0 -450
  332. package/.agents/scripts/lib/orchestration/retro/phases/post-and-mirror.js +0 -191
  333. package/.agents/scripts/lib/orchestration/retro-heuristics.js +0 -57
  334. package/.agents/scripts/lib/orchestration/retro-runner.js +0 -197
  335. package/.agents/scripts/lib/orchestration/skill-capsule-loader.js +0 -109
  336. package/.agents/scripts/lib/orchestration/spec-renderer.js +0 -447
  337. package/.agents/scripts/lib/orchestration/story-close/auto-refresh-runner.js +0 -747
  338. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/gate-failure.js +0 -211
  339. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/pre-merge-attribution.js +0 -158
  340. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +0 -446
  341. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/regression-projection.js +0 -297
  342. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/scope-discovery.js +0 -48
  343. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution-wiring.js +0 -67
  344. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution.js +0 -161
  345. package/.agents/scripts/lib/orchestration/story-close/baseline-friction-body.js +0 -117
  346. package/.agents/scripts/lib/orchestration/story-close/cd-out-guard.js +0 -86
  347. package/.agents/scripts/lib/orchestration/story-close/cleanup-reconciler.js +0 -147
  348. package/.agents/scripts/lib/orchestration/story-close/close-inputs.js +0 -142
  349. package/.agents/scripts/lib/orchestration/story-close/comment-bodies.js +0 -62
  350. package/.agents/scripts/lib/orchestration/story-close/merge-runner.js +0 -658
  351. package/.agents/scripts/lib/orchestration/story-close/merge-subject.js +0 -198
  352. package/.agents/scripts/lib/orchestration/story-close/phases/branch-restore.js +0 -105
  353. package/.agents/scripts/lib/orchestration/story-close/phases/close.js +0 -222
  354. package/.agents/scripts/lib/orchestration/story-close/phases/gates.js +0 -292
  355. package/.agents/scripts/lib/orchestration/story-close/phases/locked-pipeline.js +0 -270
  356. package/.agents/scripts/lib/orchestration/story-close/phases/preflight.js +0 -110
  357. package/.agents/scripts/lib/orchestration/story-close/phases/refresh.js +0 -86
  358. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked-emitter.js +0 -112
  359. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked.js +0 -157
  360. package/.agents/scripts/lib/orchestration/story-close/post-merge-close.js +0 -421
  361. package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +0 -301
  362. package/.agents/scripts/lib/orchestration/story-close/shared-checkout-guard.js +0 -163
  363. package/.agents/scripts/lib/orchestration/story-close-recovery.js +0 -690
  364. package/.agents/scripts/lib/orchestration/wave-marker.js +0 -28
  365. package/.agents/scripts/lib/orchestration/wave-record-io.js +0 -218
  366. package/.agents/scripts/lib/orchestration/wave-record-notifications.js +0 -145
  367. package/.agents/scripts/lib/orchestration/wave-record-projection.js +0 -212
  368. package/.agents/scripts/lib/presentation/dispatch-manifest-render.js +0 -111
  369. package/.agents/scripts/lib/presentation/manifest-builder.js +0 -239
  370. package/.agents/scripts/lib/presentation/manifest-formatter.js +0 -242
  371. package/.agents/scripts/lib/presentation/manifest-helpers.js +0 -213
  372. package/.agents/scripts/lib/presentation/manifest-persistence.js +0 -261
  373. package/.agents/scripts/lib/presentation/manifest-procedures.js +0 -55
  374. package/.agents/scripts/lib/presentation/manifest-render-waves.js +0 -306
  375. package/.agents/scripts/lib/presentation/manifest-renderer.js +0 -188
  376. package/.agents/scripts/lib/presentation/manifest-story-views.js +0 -110
  377. package/.agents/scripts/lib/push-epic-retry.js +0 -209
  378. package/.agents/scripts/lib/spec/index.js +0 -36
  379. package/.agents/scripts/lib/spec/loader.js +0 -425
  380. package/.agents/scripts/lib/spec/state.js +0 -208
  381. package/.agents/scripts/lib/story-init/blocker-validator.js +0 -68
  382. package/.agents/scripts/lib/story-init/branch-initializer.js +0 -408
  383. package/.agents/scripts/lib/story-init/context-resolver.js +0 -92
  384. package/.agents/scripts/lib/story-init/donor-precheck.js +0 -207
  385. package/.agents/scripts/lib/story-init/state-transitioner.js +0 -80
  386. package/.agents/scripts/lib/story-init/task-graph-builder.js +0 -124
  387. package/.agents/scripts/lib/story-init/transition-summary.js +0 -34
  388. package/.agents/scripts/lib/test-reserved-epic-temp-ids.js +0 -35
  389. package/.agents/scripts/lib/wave-runner/tick.js +0 -754
  390. package/.agents/scripts/lib/wave-runner/wave-runner-error.js +0 -20
  391. package/.agents/scripts/lifecycle-emit-story-dispatch.js +0 -194
  392. package/.agents/scripts/lifecycle-emit.js +0 -510
  393. package/.agents/scripts/plan-critics.js +0 -199
  394. package/.agents/scripts/retro-run.js +0 -218
  395. package/.agents/scripts/standalone-feedback-rollup.js +0 -188
  396. package/.agents/scripts/story-close.js +0 -294
  397. package/.agents/scripts/story-init.js +0 -599
  398. package/.agents/scripts/story-phase.js +0 -369
  399. package/.agents/scripts/wave-tick.js +0 -335
  400. package/.agents/skills/core/baseline-refresh/SKILL.md +0 -181
  401. package/.agents/skills/core/ci-cd-and-automation/SKILL.md +0 -274
  402. package/.agents/skills/core/ci-cd-and-automation/examples.md +0 -211
  403. package/.agents/skills/core/code-simplification/SKILL.md +0 -389
  404. package/.agents/skills/core/context-engineering/SKILL.md +0 -309
  405. package/.agents/skills/core/context-engineering/examples.md +0 -58
  406. package/.agents/skills/core/deprecation-and-migration/SKILL.md +0 -250
  407. package/.agents/skills/core/epic-plan-consolidate/SKILL.md +0 -172
  408. package/.agents/skills/core/epic-plan-consolidate/examples.md +0 -51
  409. package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +0 -441
  410. package/.agents/skills/core/epic-plan-decompose-author/examples.md +0 -47
  411. package/.agents/skills/core/epic-plan-premortem/SKILL.md +0 -146
  412. package/.agents/skills/core/epic-plan-premortem/examples.md +0 -53
  413. package/.agents/skills/core/epic-plan-spec-author/SKILL.md +0 -413
  414. package/.agents/skills/core/epic-plan-spec-author/examples.md +0 -91
  415. package/.agents/skills/core/frontend-ui-engineering/SKILL.md +0 -357
  416. package/.agents/skills/core/hydrate-context/SKILL.md +0 -123
  417. package/.agents/skills/core/idea-refinement/examples.md +0 -437
  418. package/.agents/skills/core/idea-refinement/frameworks.md +0 -135
  419. package/.agents/skills/core/incremental-implementation/SKILL.md +0 -271
  420. package/.agents/skills/core/introducing-a-baseline-gate/SKILL.md +0 -213
  421. package/.agents/skills/core/knowledge-transfer/SKILL.md +0 -180
  422. package/.agents/skills/core/mutation-survivor-remediation/SKILL.md +0 -117
  423. package/.agents/skills/core/performance-optimization/SKILL.md +0 -314
  424. package/.agents/skills/core/planning-and-task-breakdown/SKILL.md +0 -277
  425. package/.agents/skills/core/property-based-testing/SKILL.md +0 -148
  426. package/.agents/skills/core/refactoring-discipline/SKILL.md +0 -111
  427. package/.agents/skills/core/shipping-and-launch/SKILL.md +0 -328
  428. package/.agents/skills/core/spec-driven-development/SKILL.md +0 -252
  429. package/.agents/skills/core/test-driven-development/SKILL.md +0 -475
  430. package/.agents/skills/core/using-agent-skills/SKILL.md +0 -232
  431. package/.agents/skills/stack/architecture/monorepo-path-strategist/SKILL.md +0 -31
  432. package/.agents/skills/stack/architecture/structured-output-zod/SKILL.md +0 -51
  433. package/.agents/skills/stack/architecture/subagent-orchestration/SKILL.md +0 -76
  434. package/.agents/skills/stack/backend/cloudflare-hono-architect/SKILL.md +0 -31
  435. package/.agents/skills/stack/backend/cloudflare-hono-architect/examples/route-template.ts +0 -33
  436. package/.agents/skills/stack/backend/cloudflare-queue-manager/SKILL.md +0 -31
  437. package/.agents/skills/stack/backend/cloudflare-workers/SKILL.md +0 -51
  438. package/.agents/skills/stack/backend/highlevel-crm/SKILL.md +0 -54
  439. package/.agents/skills/stack/backend/sqlite-drizzle-expert/SKILL.md +0 -29
  440. package/.agents/skills/stack/backend/sqlite-drizzle-expert/examples/schema-template.ts +0 -30
  441. package/.agents/skills/stack/backend/stripe-integration/SKILL.md +0 -57
  442. package/.agents/skills/stack/backend/stripe-integration/scripts/listen-stripe.sh +0 -9
  443. package/.agents/skills/stack/backend/turso-sqlite/SKILL.md +0 -48
  444. package/.agents/skills/stack/frontend/astro/SKILL.md +0 -62
  445. package/.agents/skills/stack/frontend/astro-react-island-strategist/SKILL.md +0 -30
  446. package/.agents/skills/stack/frontend/expo-react-native-developer/SKILL.md +0 -29
  447. package/.agents/skills/stack/frontend/google-analytics-v4/SKILL.md +0 -50
  448. package/.agents/skills/stack/frontend/tailwind-v4/SKILL.md +0 -58
  449. package/.agents/skills/stack/frontend/ui-accessibility-engineer/SKILL.md +0 -34
  450. package/.agents/skills/stack/qa/audit-accessibility/SKILL.md +0 -51
  451. package/.agents/skills/stack/qa/lighthouse-baseline/SKILL.md +0 -199
  452. package/.agents/skills/stack/security/backend-security-patterns/SKILL.md +0 -68
  453. package/.agents/workflows/helpers/deliver-epic-reference.md +0 -534
  454. package/.agents/workflows/helpers/deliver-epic.md +0 -955
  455. package/.agents/workflows/helpers/deliver-stories.md +0 -440
  456. package/.agents/workflows/helpers/epic-audit.md +0 -189
  457. package/.agents/workflows/helpers/epic-deliver-story.md +0 -427
  458. package/.agents/workflows/helpers/epic-testing.md +0 -125
  459. package/.agents/workflows/helpers/plan-epic-reference.md +0 -160
  460. package/.agents/workflows/helpers/plan-epic.md +0 -351
  461. package/.agents/workflows/helpers/plan-story.md +0 -251
  462. package/.agents/workflows/helpers/scope-triage-gate.md +0 -108
  463. /package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/spec-authoring-grounding.js +0 -0
@@ -1,236 +0,0 @@
1
- /**
2
- * phases/plan-epic.js — Tech Spec / Acceptance Table persistence phase.
3
- *
4
- * Story #4324: the `context::tech-spec` / `context::acceptance-spec` ticket
5
- * classes are retired. The Epic body is the single planning document: this
6
- * phase upserts the authored Tech Spec (opening with `## Delivery Slicing`)
7
- * and the Acceptance Spec's AC-ID table (`## Acceptance Table`) as
8
- * marker-delimited managed sections of the Epic body — see
9
- * `lib/epic-body-sections.js`. Each write is **section-scoped**: only the
10
- * managed region is replaced; the rest of the body is byte-preserved.
11
- *
12
- * Idempotent against partial state: when the Epic body already carries all
13
- * requested sections, the phase short-circuits with `already-planned`.
14
- * Pass `force: true` to re-plan: the managed sections are overwritten in
15
- * place and a one-line regeneration audit comment lands on the Epic.
16
- *
17
- * The retired machine-managed `## Planning Artifacts` checklist (which
18
- * linked the old context tickets) is stripped on every persist so a
19
- * re-planned historical Epic stops advertising stale ticket links; the
20
- * legacy tickets themselves are ignored (forward-only cutover — no
21
- * backfill, no fetch).
22
- */
23
-
24
- import {
25
- hasEpicSection,
26
- stripEpicSection,
27
- stripPlanningArtifactsSection,
28
- upsertEpicSection,
29
- } from '../../../epic-body-sections.js';
30
- import { Logger } from '../../../Logger.js';
31
- import { ACCEPTANCE_NA } from '../../../label-constants.js';
32
-
33
- /**
34
- * Resolve whether Phase 7 should persist an acceptance-table section or
35
- * apply the `acceptance::n-a` waiver, from the planningRisk envelope derived
36
- * off the planner-authored risk verdict (`deriveRiskEnvelope`, Epic #3865).
37
- *
38
- * @param {import('../../planning-risk.js').PlanningRiskEnvelope|null} planningRisk
39
- * Derived envelope; `null` (direct invocations without a verdict) never
40
- * applies the waiver.
41
- * @param {string|null} acceptanceSpecContent
42
- * @returns {{ planningRisk: import('../../planning-risk.js').PlanningRiskEnvelope|null, wantsAcceptanceSpec: boolean, applyAcceptanceWaiver: boolean }}
43
- */
44
- export function resolveAcceptancePersistence(
45
- planningRisk,
46
- acceptanceSpecContent,
47
- ) {
48
- const hasAcceptanceContent =
49
- typeof acceptanceSpecContent === 'string' &&
50
- acceptanceSpecContent.trim() !== '';
51
-
52
- if (planningRisk?.acceptanceDisposition === 'not-applicable') {
53
- return {
54
- planningRisk,
55
- wantsAcceptanceSpec: false,
56
- applyAcceptanceWaiver: true,
57
- };
58
- }
59
-
60
- return {
61
- planningRisk: planningRisk ?? null,
62
- wantsAcceptanceSpec: hasAcceptanceContent,
63
- applyAcceptanceWaiver: false,
64
- };
65
- }
66
-
67
- export function validatePlanEpicInputs({
68
- techSpecContent,
69
- acceptanceSpecContent,
70
- }) {
71
- if (typeof techSpecContent !== 'string' || techSpecContent.trim() === '') {
72
- throw new Error(
73
- '[Epic Planner] techSpecContent is required and must be non-empty.',
74
- );
75
- }
76
- if (
77
- acceptanceSpecContent !== null &&
78
- (typeof acceptanceSpecContent !== 'string' ||
79
- acceptanceSpecContent.trim() === '')
80
- ) {
81
- throw new Error(
82
- '[Epic Planner] acceptanceSpecContent, when provided, must be a non-empty string.',
83
- );
84
- }
85
- }
86
-
87
- /**
88
- * Snapshot which managed planning sections the Epic body already carries.
89
- *
90
- * @param {{ body?: string }} epic
91
- * @returns {{ techSpec: boolean, acceptanceTable: boolean }}
92
- */
93
- export function getExistingSections(epic) {
94
- const body = epic?.body ?? '';
95
- return {
96
- techSpec: hasEpicSection(body, 'techSpec'),
97
- acceptanceTable: hasEpicSection(body, 'acceptanceTable'),
98
- };
99
- }
100
-
101
- export function hasAllRequestedSections({ existing, wantsAcceptanceSpec }) {
102
- return Boolean(
103
- existing.techSpec &&
104
- (wantsAcceptanceSpec ? existing.acceptanceTable : true),
105
- );
106
- }
107
-
108
- /**
109
- * Persist the host-authored Tech Spec (and optional Acceptance Table) as
110
- * managed sections of the Epic body.
111
- *
112
- * @returns {Promise<{
113
- * persisted: boolean,
114
- * reason: 'already-planned'|'persisted'|'force-replan',
115
- * techSpecPersisted: boolean,
116
- * acceptanceTable: 'persisted'|'waived'|'none',
117
- * }>}
118
- */
119
- export async function planEpic(
120
- epicId,
121
- provider,
122
- { techSpecContent, acceptanceSpecContent = null },
123
- _settings = {},
124
- { force = false, planningRisk = null } = {},
125
- ) {
126
- validatePlanEpicInputs({
127
- techSpecContent,
128
- acceptanceSpecContent,
129
- });
130
-
131
- Logger.info(`[Epic Planner] Fetching Epic #${epicId}...`);
132
- const epic = await provider.getEpic(epicId);
133
-
134
- if (!epic) {
135
- throw new Error(`Epic #${epicId} not found.`);
136
- }
137
-
138
- const { wantsAcceptanceSpec, applyAcceptanceWaiver } =
139
- resolveAcceptancePersistence(planningRisk, acceptanceSpecContent);
140
-
141
- Logger.info(
142
- `[Epic Planner] Acceptance disposition: ${planningRisk?.acceptanceDisposition ?? 'unspecified'}` +
143
- (applyAcceptanceWaiver
144
- ? ` — applying ${ACCEPTANCE_NA} waiver (no acceptance-table section).`
145
- : wantsAcceptanceSpec
146
- ? ' — persisting the ## Acceptance Table section.'
147
- : ' — no acceptance-spec content supplied.'),
148
- );
149
-
150
- const existing = getExistingSections(epic);
151
- if (!force && hasAllRequestedSections({ existing, wantsAcceptanceSpec })) {
152
- Logger.warn(
153
- `[Epic Planner] Epic #${epicId} body already carries all requested planning sections. Aborting to prevent an unintended overwrite. Use --force to re-plan.`,
154
- );
155
- return {
156
- persisted: false,
157
- reason: 'already-planned',
158
- techSpecPersisted: existing.techSpec,
159
- acceptanceTable: existing.acceptanceTable ? 'persisted' : 'none',
160
- };
161
- }
162
-
163
- // Section-scoped writes: each upsert replaces only its own managed
164
- // region; the ideation sections and any operator-authored prose are
165
- // byte-preserved. The retired `## Planning Artifacts` checklist is
166
- // stripped so re-planned historical Epics stop advertising the old
167
- // context-ticket links (the legacy tickets themselves are ignored).
168
- let newBody = stripPlanningArtifactsSection(epic.body ?? '');
169
- newBody = upsertEpicSection(newBody, 'techSpec', techSpecContent);
170
-
171
- let acceptanceTable = 'none';
172
- if (wantsAcceptanceSpec) {
173
- newBody = upsertEpicSection(
174
- newBody,
175
- 'acceptanceTable',
176
- acceptanceSpecContent,
177
- );
178
- acceptanceTable = 'persisted';
179
- } else if (applyAcceptanceWaiver) {
180
- // Acceptance transition: was present, now waived (acceptance::n-a).
181
- // Strip the stale table so the close-time reconciler cannot read a
182
- // section the planner no longer stands behind.
183
- if (existing.acceptanceTable) {
184
- Logger.info(
185
- `[Epic Planner] Acceptance disposition now waived — removing the stale ## Acceptance Table section from Epic #${epicId}.`,
186
- );
187
- newBody = stripEpicSection(newBody, 'acceptanceTable');
188
- }
189
- acceptanceTable = 'waived';
190
- }
191
-
192
- /** @type {{ add?: string[], remove?: string[] }} */
193
- const labelMutations = {};
194
- if (applyAcceptanceWaiver) {
195
- labelMutations.add = [ACCEPTANCE_NA];
196
- } else if (
197
- wantsAcceptanceSpec &&
198
- (epic.labels ?? []).includes(ACCEPTANCE_NA)
199
- ) {
200
- labelMutations.remove = [ACCEPTANCE_NA];
201
- }
202
-
203
- Logger.info(
204
- `[Epic Planner] Updating Epic #${epicId} body with the planning sections...`,
205
- );
206
- await provider.updateTicket(epicId, {
207
- body: newBody,
208
- ...(labelMutations.add || labelMutations.remove
209
- ? { labels: labelMutations }
210
- : {}),
211
- });
212
-
213
- if (force) {
214
- // Preserve the regeneration audit trail the retired per-ticket
215
- // overwrite used to leave. Best-effort — never fail the persist on a
216
- // comment post error.
217
- try {
218
- await provider.postComment(epicId, {
219
- type: 'notification',
220
- body: '♻️ **Regeneration Audit**: the Tech Spec / Acceptance Table sections of this Epic body were regenerated in place by a `/plan --force` re-plan. Content outside the managed sections was preserved.',
221
- });
222
- } catch (_err) {
223
- // Swallow: audit comment is advisory.
224
- }
225
- }
226
-
227
- Logger.info(`[Epic Planner] Epic #${epicId} updated successfully.`);
228
- Logger.info(`[Epic Planner] Planning pipeline complete!`);
229
-
230
- return {
231
- persisted: true,
232
- reason: force ? 'force-replan' : 'persisted',
233
- techSpecPersisted: true,
234
- acceptanceTable,
235
- };
236
- }
@@ -1,307 +0,0 @@
1
- /**
2
- * phases/run-spec-phase.js — orchestrator for Phase 7 (spec).
3
- *
4
- * Wires the planEpic persist phase, the Tech Spec freshness advisory, the
5
- * `agent::review-spec` label flip, the planning-state checkpoint upsert, and
6
- * the temp-file cleanup into a single sequential flow.
7
- */
8
-
9
- import path from 'node:path';
10
- import { verifyBddRunnerPendingTag } from '../../../bdd-runner-detect.js';
11
- import { Logger } from '../../../Logger.js';
12
- import { AGENT_LABELS, TYPE_LABELS } from '../../../label-constants.js';
13
- import { cleanupPhaseTempFiles } from '../../../plan-phase-cleanup.js';
14
- import { PROJECT_ROOT } from '../../../project-root.js';
15
- import { acquireEpicPlanLease } from '../../epic-plan-lease-guard.js';
16
- import {
17
- initialize as initializePlanState,
18
- read as readPlanState,
19
- write as writePlanState,
20
- } from '../../epic-plan-state-store.js';
21
- import { resolveReviewRouting } from '../../plan-review-routing.js';
22
- import { deriveRiskEnvelope } from '../../planning-risk.js';
23
- import {
24
- formatMissingSectionMessage,
25
- validateSpecSections,
26
- } from '../../spec-section-validator.js';
27
- import { upsertStructuredComment } from '../../ticketing.js';
28
- import { planEpic } from './plan-epic.js';
29
- import { runSpecFreshnessCheck } from './spec-freshness.js';
30
-
31
- /**
32
- * Render the `risk-verdict` structured-comment body: a reviewer-readable
33
- * axis table plus the canonical fenced-JSON record (verdict + derived
34
- * envelope) downstream tooling parses.
35
- *
36
- * @param {{ epicId: number, riskVerdict: import('../../planning-risk.js').RiskVerdict, planningRisk: import('../../planning-risk.js').PlanningRiskEnvelope }} input
37
- * @returns {string}
38
- */
39
- function buildRiskVerdictCommentBody({ epicId, riskVerdict, planningRisk }) {
40
- const axisRows = planningRisk.axes.map(
41
- (entry) => `| ${entry.axis} | ${entry.level} | ${entry.rationale} |`,
42
- );
43
- const axisTable =
44
- axisRows.length > 0
45
- ? ['| Axis | Level | Rationale |', '| --- | --- | --- |', ...axisRows]
46
- : ['_No risk axes apply (planner-asserted)._'];
47
- const record = {
48
- kind: 'risk-verdict',
49
- epicId,
50
- verdict: riskVerdict,
51
- planningRisk,
52
- };
53
- // Story #4145 — when the disposition was forced to not-applicable because
54
- // no BDD runner exists, make the waiver operator-visible in the rendered
55
- // comment (not just the fenced JSON record) so a reviewer sees why an
56
- // otherwise-required AC table was waived.
57
- const waiverNote = planningRisk.acceptanceWaivedReason
58
- ? ['', `> ⚠️ **Acceptance waived** — ${planningRisk.acceptanceWaivedReason}`]
59
- : [];
60
- return [
61
- `### 🧭 Planning Risk Verdict — ${planningRisk.overallLevel} · ${planningRisk.gateDecision}`,
62
- '',
63
- riskVerdict.summary,
64
- '',
65
- ...axisTable,
66
- ...waiverNote,
67
- '',
68
- '```json',
69
- JSON.stringify(record, null, 2),
70
- '```',
71
- ].join('\n');
72
- }
73
-
74
- async function setEpicLabel(provider, epicId, targetLabel) {
75
- const planningLabels = [AGENT_LABELS.REVIEW_SPEC, AGENT_LABELS.READY];
76
- await provider.updateTicket(epicId, {
77
- labels: {
78
- add: [targetLabel],
79
- remove: planningLabels.filter((l) => l !== targetLabel),
80
- },
81
- });
82
- }
83
-
84
- /**
85
- * Execute the spec phase end to end.
86
- *
87
- * @param {number} epicId
88
- * @param {import('../../../ITicketingProvider.js').ITicketingProvider} provider
89
- * @param {{ techSpecContent: string, acceptanceSpecContent?: string|null }} artifacts
90
- * @param {object} settings
91
- * @param {{ force?: boolean, forceReview?: boolean, steal?: boolean, config?: object, riskVerdict?: import('../../planning-risk.js').RiskVerdict }} [opts]
92
- * @returns {Promise<{ epicId: number, techSpecPersisted: boolean, acceptanceTable: 'persisted'|'waived'|'none', checkpoint: object, planningRisk: import('../../planning-risk.js').PlanningRiskEnvelope, reviewRouting: import('../../plan-review-routing.js').ReviewRoutingEnvelope }>}
93
- */
94
- export async function runSpecPhase(
95
- epicId,
96
- provider,
97
- { techSpecContent, acceptanceSpecContent = null },
98
- settings = {},
99
- {
100
- force = false,
101
- forceReview = false,
102
- steal = false,
103
- config,
104
- riskVerdict,
105
- } = {},
106
- ) {
107
- // Hard cutover (Epic #3865): the planner-authored risk verdict is the
108
- // sole risk source. Derive the envelope up front so a missing verdict
109
- // fails closed before any GitHub mutation.
110
- if (!riskVerdict || !Array.isArray(riskVerdict.axes)) {
111
- throw new Error(
112
- '[epic-plan-spec] risk verdict is required — author risk-verdict.json via the epic-plan-spec-author Skill and pass it with --risk-verdict.',
113
- );
114
- }
115
-
116
- // Story #4403 (Finding 3): the "## Delivery Slicing" presence gate — the
117
- // Phase 8-side anchor the Holistic Consolidation pass reconciles against —
118
- // is validated here, against the in-memory authored content, before any
119
- // GitHub mutation (lease acquisition, Epic body write, structured
120
- // comments). This replaces the retired standalone `epic-plan-spec-validate.js`
121
- // CLI / Phase 7.5 workflow step, whose documented ordering ran the check
122
- // AFTER the persist path had already written to GitHub and deleted the
123
- // temp file it read — so the "blocking gate" could never actually block.
124
- const sectionCheck = validateSpecSections({ body: techSpecContent });
125
- if (!sectionCheck.ok) {
126
- throw new Error(
127
- formatMissingSectionMessage({
128
- techspecPath: `Epic #${epicId} authored Tech Spec`,
129
- missing: sectionCheck.missing,
130
- }),
131
- );
132
- }
133
-
134
- // Story #4145 — probe the project's BDD runner. When none is detected
135
- // (`fallback === true`, e.g. a node:test repo with no tests/features/**),
136
- // the acceptance disposition is forced to not-applicable inside
137
- // deriveRiskEnvelope: an authored AC table could never be reconciled by
138
- // `@epic-<id>-ac-*` feature tags, so /deliver finalize would otherwise
139
- // abort and require a manual `acceptance::n-a`. The probe is static and
140
- // best-effort — a detection failure degrades to "runner present" (no
141
- // forced waiver), preserving the BDD-repo path, and never blocks Phase 7.
142
- let bddRunner = null;
143
- try {
144
- bddRunner = await verifyBddRunnerPendingTag({ cwd: PROJECT_ROOT });
145
- } catch (err) {
146
- Logger.warn(
147
- `[epic-plan-spec] BDD runner probe skipped (${err.message}); acceptance disposition derived from risk axes only.`,
148
- );
149
- }
150
- const planningRisk = deriveRiskEnvelope(riskVerdict, { bddRunner });
151
- if (planningRisk.acceptanceWaivedReason) {
152
- Logger.info(
153
- `[epic-plan-spec] Acceptance disposition forced to not-applicable for Epic #${epicId}: ${planningRisk.acceptanceWaivedReason}`,
154
- );
155
- }
156
-
157
- const epic = await provider.getEpic(epicId);
158
- if (!epic) {
159
- throw new Error(`[epic-plan-spec] Epic #${epicId} not found.`);
160
- }
161
- if (!epic.labels?.includes(TYPE_LABELS.EPIC)) {
162
- throw new Error(
163
- `[epic-plan-spec] Ticket #${epicId} is not a ${TYPE_LABELS.EPIC}.`,
164
- );
165
- }
166
-
167
- // Workflow-guards (Story #3481): acquire the Epic-lease before any Phase 7
168
- // mutation so two concurrent /plan runs cannot both drive this Epic. The
169
- // guard fails closed (audit #3513) — any foreign assignee refuses here and
170
- // the CLI exits non-zero naming the owner, unless `--steal` transfers it.
171
- await acquireEpicPlanLease({ provider, epicId, config, steal });
172
-
173
- await initializePlanState({ provider, epicId });
174
-
175
- const planResult = await planEpic(
176
- epicId,
177
- provider,
178
- { techSpecContent, acceptanceSpecContent },
179
- settings,
180
- {
181
- force,
182
- planningRisk,
183
- },
184
- );
185
- const specChanged = planResult?.persisted !== false;
186
-
187
- const afterPlan = await provider.getEpic(epicId);
188
-
189
- // Story #2635 — cross-validate the authored Tech Spec body against the
190
- // base branch and surface any stale path-shaped references. Story #4324:
191
- // with the Tech Spec folded into the Epic body, the advisory comment
192
- // lands on the Epic itself. Non-blocking: a missing base ref, an
193
- // unreadable temp directory, or a provider failure downgrades to a
194
- // warning so Phase 7 never fails on the advisory check.
195
- const baseBranchRef = settings?.baseBranch ?? 'main';
196
- const tempRoot = path.resolve(
197
- PROJECT_ROOT,
198
- settings?.paths?.tempRoot ?? 'temp',
199
- );
200
- const freshness = await runSpecFreshnessCheck({
201
- epicId,
202
- techSpecContent,
203
- baseBranchRef,
204
- tempRoot,
205
- provider,
206
- });
207
-
208
- // Story #1585 (Epic #1471): the baseline-snapshot fork was previously
209
- // performed here at plan-time. It now runs at first-story-init time
210
- // inside `lib/story-init/branch-initializer.js#bootstrapWorktree` so
211
- // `/plan` remains git-state-free. `forkAndCommitEpicSnapshot` and
212
- // `forkMainToEpic` remain exported for that caller.
213
-
214
- const reviewRouting = resolveReviewRouting({ planningRisk, forceReview });
215
-
216
- // Record the planner-authored verdict as a structured artifact — the
217
- // audit trail the retired regex classifier never produced (Epic #3865).
218
- await upsertStructuredComment(
219
- provider,
220
- epicId,
221
- 'risk-verdict',
222
- buildRiskVerdictCommentBody({ epicId, riskVerdict, planningRisk }),
223
- );
224
-
225
- const currentState =
226
- (await readPlanState({ provider, epicId })) ??
227
- (await initializePlanState({ provider, epicId }));
228
- const checkpoint = await writePlanState({
229
- provider,
230
- epicId,
231
- state: {
232
- ...currentState,
233
- planningRisk,
234
- riskVerdict,
235
- reviewRouting: {
236
- decision: reviewRouting.decision,
237
- requiresStop: reviewRouting.requiresStop,
238
- forceReviewApplied: reviewRouting.forceReviewApplied,
239
- },
240
- spec: {
241
- ...currentState.spec,
242
- techSpecPersisted: planResult?.techSpecPersisted === true,
243
- acceptanceTable: planResult?.acceptanceTable ?? 'none',
244
- completedAt: new Date().toISOString(),
245
- },
246
- },
247
- });
248
-
249
- Logger.info(`[epic-plan-spec] Review routing: ${reviewRouting.decision}.`);
250
- Logger.info(`[epic-plan-spec] ${reviewRouting.operatorMessage}`);
251
-
252
- // Story #4019 (refining #3905): a spec-phase rerun that changed nothing
253
- // (planEpic short-circuited on `already-planned`) MUST NOT demote a
254
- // fully-decomposed `agent::ready` Epic back to `agent::review-spec` —
255
- // there is no new spec content to review. The demotion fires only when
256
- // the spec actually persisted/changed, or when the Epic is not at
257
- // `agent::ready` (where the flip is the normal forward transition).
258
- const epicLabels = afterPlan.labels ?? [];
259
- const skipDemotion = !specChanged && epicLabels.includes(AGENT_LABELS.READY);
260
- let labelTransition;
261
- if (skipDemotion) {
262
- labelTransition = 'kept-ready';
263
- Logger.info(
264
- `[epic-plan-spec] Spec unchanged (${planResult?.reason ?? 'already-planned'}) and Epic #${epicId} is ${AGENT_LABELS.READY} — keeping ${AGENT_LABELS.READY} (no demotion to ${AGENT_LABELS.REVIEW_SPEC}).`,
265
- );
266
- } else {
267
- labelTransition = 'review-spec';
268
- Logger.info(
269
- `[epic-plan-spec] Flipping Epic #${epicId} to ${AGENT_LABELS.REVIEW_SPEC}...`,
270
- );
271
- await setEpicLabel(provider, epicId, AGENT_LABELS.REVIEW_SPEC);
272
- }
273
-
274
- const cleanup = await cleanupPhaseTempFiles({ phase: 'spec', epicId });
275
-
276
- const acceptanceSummary =
277
- planResult?.acceptanceTable === 'persisted'
278
- ? ' + ## Acceptance Table section'
279
- : planResult?.acceptanceTable === 'waived'
280
- ? ' (acceptance waived)'
281
- : '';
282
- const freshnessSummary =
283
- freshness.stale > 0 || freshness.ambiguous > 0
284
- ? ` ⚠️ Spec freshness: ${freshness.stale} stale / ${freshness.ambiguous} ambiguous reference(s) — see ${freshness.reportPath ?? 'report'}.`
285
- : '';
286
- Logger.info(
287
- `[epic-plan-spec] ✅ Spec phase complete for Epic #${epicId}. Tech Spec sections folded into the Epic body${acceptanceSummary}.${freshnessSummary}`,
288
- );
289
- if (cleanup.deleted.length > 0) {
290
- Logger.info(
291
- `[epic-plan-spec] 🧹 Cleaned up ${cleanup.deleted.length} temp file(s).`,
292
- );
293
- }
294
-
295
- return {
296
- epicId,
297
- techSpecPersisted: planResult?.techSpecPersisted === true,
298
- acceptanceTable: planResult?.acceptanceTable ?? 'none',
299
- checkpoint,
300
- cleanup,
301
- freshness,
302
- planningRisk,
303
- reviewRouting,
304
- specChanged,
305
- labelTransition,
306
- };
307
- }
@@ -1,117 +0,0 @@
1
- /**
2
- * phases/spec-freshness.js — Tech Spec freshness check phase.
3
- *
4
- * Cross-validates the authored Tech Spec body against the base branch and
5
- * surfaces any stale path-shaped references on the Epic (Story #4324: the
6
- * Tech Spec is folded into the Epic body, so the Epic is the comment
7
- * target). Two side effects, both best-effort and non-blocking:
8
- *
9
- * 1. Write the full `{ stale, fresh, ambiguous }` report to
10
- * `<tempRoot>/epic-<id>-spec-freshness.json` so downstream tooling
11
- * (the `--code-freshness` health check on the roadmap, or an
12
- * operator inspecting the run) can read it without re-probing git.
13
- * 2. When `stale.length > 0`, upsert a `spec-freshness` structured
14
- * comment on the Epic listing each suspect citation.
15
- * The comment is upserted, so re-running spec re-renders the same
16
- * comment in place rather than spamming the issue.
17
- *
18
- * Caller signals are aggressive in containment — any error in this path
19
- * is downgraded to a warning. Phase 7 must not fail because a doc-author
20
- * cited a path the validator can't probe (e.g. shallow clone, base ref
21
- * not fetched). The non-blocking contract is the load-bearing AC.
22
- */
23
-
24
- import { mkdir, writeFile } from 'node:fs/promises';
25
- import path from 'node:path';
26
- import { Logger } from '../../../Logger.js';
27
- import {
28
- renderSpecFreshnessComment,
29
- validateSpecFreshness,
30
- } from '../../spec-freshness.js';
31
- import { upsertStructuredComment } from '../../ticketing.js';
32
-
33
- /**
34
- * @param {object} opts
35
- * @param {number} opts.epicId
36
- * @param {string} opts.techSpecContent
37
- * @param {string} opts.baseBranchRef
38
- * @param {string} opts.tempRoot
39
- * @param {import('../../../ITicketingProvider.js').ITicketingProvider} opts.provider
40
- * @param {Function} [opts.validator] - Testing seam (defaults to validateSpecFreshness).
41
- * @param {Function} [opts.commentUpserter] - Testing seam (defaults to upsertStructuredComment).
42
- * @param {Function} [opts.fileWriter] - Testing seam (defaults to fs writeFile/mkdir wrapper).
43
- * @returns {Promise<{ stale: number, ambiguous: number, fresh: number, reportPath: string|null, commentPosted: boolean }>}
44
- */
45
- export async function runSpecFreshnessCheck({
46
- epicId,
47
- techSpecContent,
48
- baseBranchRef,
49
- tempRoot,
50
- provider,
51
- validator = validateSpecFreshness,
52
- commentUpserter = upsertStructuredComment,
53
- fileWriter = async (filePath, body) => {
54
- await mkdir(path.dirname(filePath), { recursive: true });
55
- await writeFile(filePath, body, 'utf8');
56
- },
57
- }) {
58
- try {
59
- const report = validator(techSpecContent, { baseBranchRef });
60
- const reportPath = path.join(
61
- tempRoot,
62
- `epic-${epicId}-spec-freshness.json`,
63
- );
64
- const payload = {
65
- epicId,
66
- baseBranchRef,
67
- generatedAt: new Date().toISOString(),
68
- summary: {
69
- stale: report.stale.length,
70
- ambiguous: report.ambiguous.length,
71
- fresh: report.fresh.length,
72
- },
73
- ...report,
74
- };
75
- await fileWriter(reportPath, `${JSON.stringify(payload, null, 2)}\n`);
76
-
77
- let commentPosted = false;
78
- if (report.stale.length > 0 && Number.isFinite(epicId)) {
79
- const body = renderSpecFreshnessComment(report, {
80
- baseBranchRef,
81
- epicId,
82
- });
83
- await commentUpserter(provider, epicId, 'spec-freshness', body);
84
- commentPosted = true;
85
- }
86
-
87
- if (report.stale.length > 0 || report.ambiguous.length > 0) {
88
- Logger.warn(
89
- `[epic-plan-spec] Tech Spec freshness: ${report.stale.length} stale, ${report.ambiguous.length} ambiguous, ${report.fresh.length} fresh against ${baseBranchRef}. Report: ${reportPath}.`,
90
- );
91
- } else {
92
- Logger.info(
93
- `[epic-plan-spec] Tech Spec freshness: ${report.fresh.length} fresh references against ${baseBranchRef}. No drift detected.`,
94
- );
95
- }
96
-
97
- return {
98
- stale: report.stale.length,
99
- ambiguous: report.ambiguous.length,
100
- fresh: report.fresh.length,
101
- reportPath,
102
- commentPosted,
103
- };
104
- } catch (err) {
105
- Logger.warn(
106
- `[epic-plan-spec] Tech Spec freshness check skipped: ${err.message}`,
107
- );
108
- return {
109
- stale: 0,
110
- ambiguous: 0,
111
- fresh: 0,
112
- reportPath: null,
113
- commentPosted: false,
114
- error: err.message,
115
- };
116
- }
117
- }