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,449 +0,0 @@
1
- #!/usr/bin/env node
2
- /* node:coverage ignore file */
3
-
4
- /**
5
- * epic-execute-record-wave.js — record one recorder beat's per-Story
6
- * returns, splice each Story's terminal status into the `epic-run-state`
7
- * checkpoint's flat per-Story `stories` map, and re-render the unified
8
- * `epic-run-progress` rollup on the Epic.
9
- *
10
- * Story #4155 (Epic #4151) — the Epic `/deliver` runtime cut over from the
11
- * wave-batch scheduler to the continuous ready-set core. This recorder lost
12
- * its wave semantics with it: there is no `--wave` flag, no wave-level
13
- * status aggregation, no `currentWave` advance, and no `waves[]` history. The
14
- * tick (`lib/wave-runner/tick.js`) re-derives readiness from live labels on
15
- * every beat, so the checkpoint only records terminal Story outcomes (for the
16
- * auto-merge predicate, branch cleanup, and the operator rollup). The
17
- * recorder also emits one `story.dispatch.end` per recorded Story so the
18
- * tick's ledger-derived in-flight set and the `--check-idle` watchdog can
19
- * clear the dispatch start/end pairing.
20
- *
21
- * 1. Parse / reconcile / verify the per-Story returns.
22
- * 2. Record each Story's terminal status onto the checkpoint `stories` map.
23
- * 3. Emit `story.dispatch.end` per recorded Story.
24
- * 4. Re-render `epic-run-progress` from the checkpoint `stories` map.
25
- * 5. Print the next action for the slash-command (`dispatch-next` |
26
- * `halt-blocked` | `halt-failed`).
27
- *
28
- * The implementation is split across three modules so the parent stays a
29
- * thin runner shell:
30
- *
31
- * - `lib/orchestration/wave-record-projection.js` — pure helpers
32
- * (per-Story validation / normalization, rollup-row shaping). Re-exported
33
- * from this file so existing callers see an unchanged public surface.
34
- * - `lib/orchestration/wave-record-io.js` — impure helpers (ticket
35
- * verification, manifest title lookup, returns reconciliation).
36
- * - `lib/orchestration/wave-record-notifications.js` — curated webhook
37
- * emit chain for the recorder beat.
38
- */
39
-
40
- import { readFileSync } from 'node:fs';
41
-
42
- import { defineFlags } from './lib/cli-args.js';
43
- import { runAsCli } from './lib/cli-utils.js';
44
- import { getRunners } from './lib/config/runners.js';
45
- import { resolveConfig } from './lib/config-resolver.js';
46
- import { Logger } from './lib/Logger.js';
47
- import * as epicRunStateStore from './lib/orchestration/epic-run-state-store.js';
48
- import { upsertEpicRunProgress } from './lib/orchestration/epic-runner/progress-reporter/composition.js';
49
- import {
50
- emitStoryDispatchEnd,
51
- storyStatusToDispatchOutcome,
52
- } from './lib/orchestration/lifecycle/emit-story-dispatch-end.js';
53
- import {
54
- loadManifestTitleMap,
55
- resolveResolvedResults,
56
- verifyWaveResults,
57
- } from './lib/orchestration/wave-record-io.js';
58
- import { emitRecordNotifications } from './lib/orchestration/wave-record-notifications.js';
59
- import {
60
- selectInputFlag,
61
- validateEpic,
62
- validateResults,
63
- } from './lib/orchestration/wave-record-projection.js';
64
- import { createProvider } from './lib/provider-factory.js';
65
- import { notify } from './notify.js';
66
-
67
- export {
68
- loadManifestTitleMap,
69
- normalizeReturns,
70
- resolveResolvedResults,
71
- verifyWaveResults,
72
- } from './lib/orchestration/wave-record-io.js';
73
- // Re-export the pure projection surface so tests and downstream consumers
74
- // can keep importing from `epic-execute-record-wave.js` after the extract.
75
- export {
76
- classifyParsedReturn,
77
- normalizeReturnsPure,
78
- STORY_STATUS_TO_ROW_STATE,
79
- selectInputFlag,
80
- toRollupRow,
81
- VALID_STORY_STATUSES,
82
- validateEpic,
83
- validateResults,
84
- validateReturnsEntry,
85
- } from './lib/orchestration/wave-record-projection.js';
86
-
87
- const HELP = `Usage: node .agents/scripts/epic-execute-record-wave.js \\
88
- --epic <epicId> \\
89
- (--returns @<file>|<inline-json> | --results @<file>|<inline-json>)
90
-
91
- Records this recorder beat's per-Story outcomes onto the epic-run-state
92
- checkpoint's flat per-Story status map and upserts the unified
93
- epic-run-progress rollup on the Epic. Prints the next action for the
94
- /deliver slash command.
95
- `;
96
-
97
- /**
98
- * Parse a `--results` / `--returns` argv value, supporting both `@<file>`
99
- * and inline JSON. `flag` controls which CLI name appears in error messages.
100
- *
101
- * @param {string} value
102
- * @param {{ readFile?: (path: string) => string, flag?: string }} [deps]
103
- */
104
- export function parseInputArg(value, deps = {}) {
105
- const flag = deps.flag ?? '--results';
106
- if (typeof value !== 'string' || value.length === 0) {
107
- throw new TypeError(
108
- `epic-execute-record-wave: ${flag} is required (use \`@<file>\` or an inline JSON array).`,
109
- );
110
- }
111
- const reader = deps.readFile ?? ((p) => readFileSync(p, 'utf8'));
112
- let raw;
113
- if (value.startsWith('@')) {
114
- const filePath = value.slice(1);
115
- if (!filePath) {
116
- throw new TypeError(
117
- `epic-execute-record-wave: ${flag} @<file> requires a path after \`@\`.`,
118
- );
119
- }
120
- raw = reader(filePath);
121
- } else {
122
- raw = value;
123
- }
124
- try {
125
- return JSON.parse(raw);
126
- } catch (err) {
127
- throw new SyntaxError(
128
- `epic-execute-record-wave: ${flag} value is not valid JSON: ${err.message}`,
129
- );
130
- }
131
- }
132
-
133
- /**
134
- * Classify the recorder beat's next action from the verified rows. Pure.
135
- * Any failed Story → `halt-failed`; else any blocked Story → `halt-blocked`;
136
- * else → `dispatch-next` (the host re-ticks to pick up the next ready set).
137
- *
138
- * @param {Array<{ status: string }>} verified
139
- * @returns {{ status: 'complete'|'blocked'|'failed', nextAction: string, blockedStoryIds: number[] }}
140
- */
141
- export function classifyRecordOutcome(verified) {
142
- const rows = Array.isArray(verified) ? verified : [];
143
- const failed = rows.some((r) => r.status === 'failed');
144
- const blockedStoryIds = rows
145
- .filter((r) => r.status === 'blocked')
146
- .map((r) => r.storyId);
147
- if (failed) {
148
- return { status: 'failed', nextAction: 'halt-failed', blockedStoryIds };
149
- }
150
- if (blockedStoryIds.length > 0) {
151
- return { status: 'blocked', nextAction: 'halt-blocked', blockedStoryIds };
152
- }
153
- return { status: 'complete', nextAction: 'dispatch-next', blockedStoryIds };
154
- }
155
-
156
- /**
157
- * End-to-end record beat. DI-friendly: tests pass `injectedProvider` and a
158
- * fully-formed `results` (or `returns`) array to skip real network reads.
159
- *
160
- * @param {{
161
- * epicId: number,
162
- * results?: unknown,
163
- * returns?: unknown,
164
- * cwd?: string,
165
- * injectedProvider?: object,
166
- * injectedConfig?: object,
167
- * injectedNotify?: (ticketId: number, payload: object) => Promise<void>,
168
- * now?: () => Date,
169
- * }} args
170
- */
171
- export async function runEpicExecuteRecordWave({
172
- epicId,
173
- results,
174
- returns,
175
- cwd,
176
- injectedProvider,
177
- injectedConfig,
178
- injectedNotify,
179
- now = () => new Date(),
180
- } = {}) {
181
- validateEpic(epicId);
182
- if (results == null && returns == null) {
183
- throw new TypeError(
184
- 'runEpicExecuteRecordWave: either `results` or `returns` is required',
185
- );
186
- }
187
- if (results != null && returns != null) {
188
- throw new TypeError(
189
- 'runEpicExecuteRecordWave: pass `results` OR `returns`, not both',
190
- );
191
- }
192
-
193
- const config = injectedConfig ?? resolveConfig({ cwd });
194
- const provider = injectedProvider ?? createProvider(config);
195
-
196
- const existing = await epicRunStateStore.read({ provider, epicId });
197
- if (!existing) {
198
- throw new Error(
199
- `runEpicExecuteRecordWave: no epic-run-state checkpoint found on Epic #${epicId}; ` +
200
- 'run `node .agents/scripts/epic-deliver-prepare.js --epic <id>` first.',
201
- );
202
- }
203
- const firstRecord = !hasRecordedStory(existing.stories);
204
-
205
- const deliverRunner = getRunners(config).deliverRunner ?? {};
206
-
207
- // 1. Parse / reconcile the per-Story returns.
208
- const { resolvedResults, parseFailures } = await resolveResolvedResults({
209
- provider,
210
- epicId,
211
- results,
212
- returns,
213
- });
214
-
215
- const validated = validateResults(resolvedResults);
216
-
217
- // 2. Verify every `done` claim against the live ticket label.
218
- const { verified, discrepancies } = await verifyWaveResults({
219
- provider,
220
- results: validated,
221
- concurrencyCap: deliverRunner.verifyConcurrencyCap,
222
- });
223
-
224
- // 3. Cross-look manifest titles for the rollup rows.
225
- const titleById = await loadManifestTitleMap({ provider, epicId });
226
-
227
- // 4. Record each Story's terminal status onto the checkpoint `stories`
228
- // map. Recorded serially so the upserts do not race the same comment.
229
- let state = existing;
230
- for (const row of verified) {
231
- state = await epicRunStateStore.recordStoryStatus({
232
- provider,
233
- epicId,
234
- storyId: row.storyId,
235
- status: row.status,
236
- title: titleById.get(row.storyId),
237
- blockerCommentId: row.blockerCommentId,
238
- });
239
- }
240
-
241
- // 5. Emit one `story.dispatch.end` per recorded Story. Closes the
242
- // start/end pairing the tick reconciler and the `--check-idle`
243
- // watchdog use to derive in-flight Stories. Best-effort: a failed
244
- // append must not block the loop.
245
- emitWaveDispatchEnds({ epicId, verified, config });
246
-
247
- // 6. Re-render the unified `epic-run-progress` rollup from the checkpoint
248
- // `stories` map. The single operator-facing summary.
249
- const { body: renderedBody } = await upsertEpicRunProgress({
250
- provider,
251
- epicId,
252
- stories: state.stories,
253
- startedAt: existing.startedAt,
254
- now,
255
- });
256
-
257
- const { status, nextAction, blockedStoryIds } =
258
- classifyRecordOutcome(verified);
259
-
260
- // 7. Fire the curated webhook events for this recorder beat. Each helper
261
- // is fire-and-forget — webhook misconfig or a transient Slack outage
262
- // must not block the loop.
263
- await emitRecordNotifications({
264
- injectedNotify,
265
- defaultNotify: notify,
266
- config,
267
- provider,
268
- epicId,
269
- firstRecord,
270
- stories: state.stories,
271
- verified,
272
- blockedStoryIds,
273
- });
274
-
275
- const envelope = {
276
- epicId,
277
- recorded: true,
278
- status,
279
- stories: verified.map((r) => ({ id: r.storyId, status: r.status })),
280
- blockedStoryIds,
281
- nextAction,
282
- renderedBody,
283
- };
284
- if (discrepancies.length > 0) {
285
- envelope.discrepancies = discrepancies;
286
- }
287
- if (parseFailures.length > 0) {
288
- envelope.parseFailures = parseFailures.map((f) => ({
289
- storyId: f.storyId,
290
- error: f.error,
291
- }));
292
- }
293
- return envelope;
294
- }
295
-
296
- /**
297
- * Whether the checkpoint's per-Story `stories` map already carries a
298
- * non-`pending` (recorded) status — used to fire `epic-started` exactly
299
- * once, on the first recorder beat. Pure helper.
300
- *
301
- * @param {Record<string, { status?: string }>|undefined} stories
302
- * @returns {boolean}
303
- */
304
- function hasRecordedStory(stories) {
305
- const map = stories && typeof stories === 'object' ? stories : {};
306
- for (const rec of Object.values(map)) {
307
- if (rec?.status && rec.status !== 'pending') return true;
308
- }
309
- return false;
310
- }
311
-
312
- /**
313
- * Append one `story.dispatch.end` lifecycle record per recorded Story
314
- * (Story #3900). Each emit is independent and best-effort: a single failed
315
- * append is logged and swallowed so one bad record never aborts the loop.
316
- * The Story status taxonomy (`done`/`blocked`/`failed`) maps directly onto
317
- * the `story.dispatch.end` outcome enum.
318
- *
319
- * Exported for unit testing.
320
- *
321
- * @param {{
322
- * epicId: number,
323
- * verified: Array<{ storyId: number, status: string }>,
324
- * config?: object,
325
- * emit?: typeof emitStoryDispatchEnd,
326
- * }} args
327
- * @returns {number} count of records successfully appended.
328
- */
329
- export function emitWaveDispatchEnds({
330
- epicId,
331
- verified,
332
- config,
333
- emit = emitStoryDispatchEnd,
334
- }) {
335
- let emitted = 0;
336
- for (const result of verified ?? []) {
337
- const storyId = result?.storyId;
338
- const status = result?.status;
339
- if (!Number.isInteger(storyId) || storyId <= 0) continue;
340
- try {
341
- emit({
342
- epicId,
343
- storyId,
344
- outcome: storyStatusToDispatchOutcome(status),
345
- config,
346
- });
347
- emitted += 1;
348
- } catch (err) {
349
- Logger.warn(
350
- `[record-wave] Non-fatal: could not emit story.dispatch.end for Story #${storyId} — ${err?.message ?? 'unknown error'}`,
351
- );
352
- }
353
- }
354
- return emitted;
355
- }
356
-
357
- /**
358
- * Resolve the parsed `--results` / `--returns` argv into the input shape
359
- * `runEpicExecuteRecordWave` expects.
360
- *
361
- * @param {{ resultsRaw?: string, returnsRaw?: string }} parsed
362
- */
363
- export function resolveRecordInput(parsed) {
364
- const flag = selectInputFlag(
365
- Boolean(parsed?.resultsRaw),
366
- Boolean(parsed?.returnsRaw),
367
- );
368
- if (flag === 'results') {
369
- return { results: parseInputArg(parsed.resultsRaw, { flag: '--results' }) };
370
- }
371
- return { returns: parseInputArg(parsed.returnsRaw, { flag: '--returns' }) };
372
- }
373
-
374
- /**
375
- * Parse argv into the runner contract.
376
- *
377
- * @param {string[]} argv
378
- */
379
- export function parseArgv(argv) {
380
- const { values } = defineFlags(
381
- {
382
- epic: { type: 'integer', alias: 'epicId' },
383
- results: { type: 'string', alias: 'resultsRaw' },
384
- returns: { type: 'string', alias: 'returnsRaw' },
385
- help: { type: 'boolean', short: 'h' },
386
- },
387
- argv,
388
- );
389
- return values;
390
- }
391
-
392
- /**
393
- * Orchestration body of `main` extracted as a sibling exported function so
394
- * the validate / dispatch / envelope-shape ladder is unit-testable without
395
- * spawning a process. `main` becomes a thin shell: parse → call this →
396
- * render → exit.
397
- *
398
- * @param {ReturnType<typeof parseArgv>} values
399
- * @param {{
400
- * runRecordWave?: typeof runEpicExecuteRecordWave,
401
- * resolveRecordInput?: typeof resolveRecordInput,
402
- * help?: string,
403
- * }} [deps]
404
- * @returns {Promise<{ exitCode: number, result: object }>}
405
- * `result.kind` is one of: `'help'`, `'validation-error'`, `'envelope'`.
406
- */
407
- export async function runRecordWaveCli(values, deps = {}) {
408
- const helpText = deps.help ?? HELP;
409
- if (values.help) {
410
- return { exitCode: 0, result: { kind: 'help', text: helpText } };
411
- }
412
- if (!Number.isInteger(values.epicId) || values.epicId <= 0) {
413
- return {
414
- exitCode: 2,
415
- result: {
416
- kind: 'validation-error',
417
- message:
418
- '[epic-execute-record-wave] ERROR: --epic <epicId> is required.',
419
- help: helpText,
420
- },
421
- };
422
- }
423
- const resolveInput = deps.resolveRecordInput ?? resolveRecordInput;
424
- const runner = deps.runRecordWave ?? runEpicExecuteRecordWave;
425
- const envelope = await runner({
426
- epicId: values.epicId,
427
- ...resolveInput(values),
428
- });
429
- return { exitCode: 0, result: { kind: 'envelope', envelope } };
430
- }
431
-
432
- export async function main(argv = process.argv.slice(2)) {
433
- const values = parseArgv(argv);
434
- const { exitCode, result } = await runRecordWaveCli(values);
435
-
436
- if (result.kind === 'help') {
437
- process.stdout.write(result.text);
438
- return;
439
- }
440
- if (result.kind === 'validation-error') {
441
- Logger.error(result.message);
442
- Logger.error(result.help);
443
- process.exit(exitCode);
444
- }
445
- process.stdout.write(`${JSON.stringify(result.envelope, null, 2)}\n`);
446
- if (exitCode !== 0) process.exit(exitCode);
447
- }
448
-
449
- runAsCli(import.meta.url, main, { source: 'epic-execute-record-wave' });
@@ -1,211 +0,0 @@
1
- #!/usr/bin/env node
2
- /* node:coverage ignore file */
3
-
4
- /**
5
- * epic-plan-clarity.js — Phase 6 Epic Clarity Gate CLI.
6
- *
7
- * Two modes:
8
- *
9
- * 1. --emit-context --epic <id> [--pretty]
10
- * Fetches the Epic body via the resolved ticketing provider, scores
11
- * it against the five canonical sections from
12
- * `.agents/templates/epic-from-idea.md`, and prints a JSON envelope
13
- * to stdout: `{ epicId, epicBody, verdict, sections, missingOrPlaceholder }`.
14
- * Read-only — no state mutations.
15
- *
16
- * 2. --epic <id> --updated-body <path>
17
- * Reads the sharpened body from disk, compares it to the current
18
- * Epic body, and (when different) persists via
19
- * `provider.updateTicket(epicId, { body })`. Posts a
20
- * `clarity-gate-update` structured audit comment recording the
21
- * change. Idempotent: identical body → no-op (`changed: false`).
22
- *
23
- * Exit codes:
24
- * 0 — mode completed.
25
- * 1 — fatal error (see stderr).
26
- */
27
-
28
- import { readFile } from 'node:fs/promises';
29
- import { parseArgs } from 'node:util';
30
- import { runAsCli } from './lib/cli-utils.js';
31
- import {
32
- resolveConfig,
33
- validateOrchestrationConfig,
34
- } from './lib/config-resolver.js';
35
- import { scoreEpicBody } from './lib/epic-plan-clarity.js';
36
- import { Logger, routeAllOutputToStderr } from './lib/Logger.js';
37
- import { recordPlanInvocation } from './lib/orchestration/plan-metrics.js';
38
- import { upsertStructuredComment } from './lib/orchestration/ticketing.js';
39
- import { createProvider } from './lib/provider-factory.js';
40
-
41
- /**
42
- * Build the read-only emit-context envelope for an Epic.
43
- *
44
- * @param {{ epicId: number, provider: object }} args
45
- * @returns {Promise<{ epicId: number, epicBody: string, verdict: string, sections: Array<{name:string,status:string}>, missingOrPlaceholder: string[] }>}
46
- */
47
- export async function buildClarityContext({ epicId, provider }) {
48
- const epic = await provider.getEpic(epicId);
49
- if (!epic) {
50
- throw new Error(`[epic-plan-clarity] Epic #${epicId} not found.`);
51
- }
52
- const body = epic.body ?? '';
53
- const score = scoreEpicBody({ body });
54
- return {
55
- epicId,
56
- epicBody: body,
57
- verdict: score.verdict,
58
- sections: score.sections,
59
- missingOrPlaceholder: score.missingOrPlaceholder,
60
- };
61
- }
62
-
63
- /**
64
- * Persist a sharpened Epic body. Wraps `provider.updateTicket` behind the
65
- * `updateEpicFromOnePager`-style port and posts the `clarity-gate-update`
66
- * audit comment on success.
67
- *
68
- * @param {{
69
- * epicId: number,
70
- * updatedBody: string,
71
- * provider: object,
72
- * }} args
73
- * @returns {Promise<{ epicId: number, changed: boolean, currentLength: number, updatedLength: number }>}
74
- */
75
- export async function persistClarityUpdate({ epicId, updatedBody, provider }) {
76
- const epic = await provider.getEpic(epicId);
77
- if (!epic) {
78
- throw new Error(`[epic-plan-clarity] Epic #${epicId} not found.`);
79
- }
80
- const currentBody = epic.body ?? '';
81
-
82
- if (currentBody === updatedBody) {
83
- Logger.info(
84
- `[epic-plan-clarity] Epic #${epicId} body matches submitted update — no-op.`,
85
- );
86
- return {
87
- epicId,
88
- changed: false,
89
- currentLength: currentBody.length,
90
- updatedLength: updatedBody.length,
91
- };
92
- }
93
-
94
- await provider.updateTicket(epicId, { body: updatedBody });
95
- Logger.info(`[epic-plan-clarity] Updated Epic #${epicId} body.`);
96
-
97
- // Audit comment. Skip silently with a stderr warn when the provider does
98
- // not implement comment surfacing — keeps the gate functional in stripped
99
- // test doubles.
100
- const timestamp = new Date().toISOString();
101
- const auditBody = [
102
- '```json',
103
- JSON.stringify(
104
- {
105
- epicId,
106
- timestamp,
107
- changed: true,
108
- currentLength: currentBody.length,
109
- updatedLength: updatedBody.length,
110
- },
111
- null,
112
- 2,
113
- ),
114
- '```',
115
- '',
116
- 'Phase 6 Epic Clarity Gate persisted a sharpened Epic body. The previous body has been replaced; the rewrite was operator-approved via the HITL diff stop.',
117
- ].join('\n');
118
-
119
- try {
120
- await upsertStructuredComment(
121
- provider,
122
- epicId,
123
- 'clarity-gate-update',
124
- auditBody,
125
- );
126
- } catch (err) {
127
- Logger.warn(
128
- `[epic-plan-clarity] Failed to post clarity-gate-update audit comment: ${err.message}`,
129
- );
130
- }
131
-
132
- return {
133
- epicId,
134
- changed: true,
135
- currentLength: currentBody.length,
136
- updatedLength: updatedBody.length,
137
- };
138
- }
139
-
140
- /* node:coverage ignore next */
141
- async function main() {
142
- const { values } = parseArgs({
143
- options: {
144
- epic: { type: 'string' },
145
- 'emit-context': { type: 'boolean', default: false },
146
- 'updated-body': { type: 'string' },
147
- pretty: { type: 'boolean', default: false },
148
- },
149
- });
150
-
151
- if (!values.epic) {
152
- throw new Error(
153
- 'Usage: epic-plan-clarity.js --epic <EpicId> (--emit-context [--pretty] | --updated-body <file>)',
154
- );
155
- }
156
-
157
- const epicId = Number.parseInt(values.epic, 10);
158
- if (!Number.isInteger(epicId) || epicId <= 0) {
159
- throw new Error(
160
- `Invalid epic ID: "${values.epic}" — must be a positive integer.`,
161
- );
162
- }
163
-
164
- let config;
165
- try {
166
- config = resolveConfig();
167
- validateOrchestrationConfig(config);
168
- } catch (err) {
169
- throw new Error(`Config schema validation failed:\n${err.message}`);
170
- }
171
- const provider = createProvider(config);
172
-
173
- // Story #2278 — in --emit-context mode stdout is reserved for the JSON
174
- // envelope. Flip Logger sinks to stderr defensively even though
175
- // buildClarityContext does not currently call Logger.info, so future
176
- // additions cannot silently corrupt the captured file.
177
- if (values['emit-context']) {
178
- routeAllOutputToStderr();
179
- // Plan-metrics ledger (#4474 PR1): stamp entry/exit + mode.
180
- const envelope = await recordPlanInvocation(
181
- { cli: 'epic-plan-clarity', mode: 'emit-context', epicId, config },
182
- () => buildClarityContext({ epicId, provider }),
183
- );
184
- const json = values.pretty
185
- ? JSON.stringify(envelope, null, 2)
186
- : JSON.stringify(envelope);
187
- process.stdout.write(`${json}\n`);
188
- return;
189
- }
190
-
191
- if (!values['updated-body']) {
192
- throw new Error(
193
- 'Missing mode flag: pass --emit-context or --updated-body <file>.',
194
- );
195
- }
196
-
197
- const updatedBody = await readFile(values['updated-body'], 'utf8');
198
- // Plan-metrics ledger (#4474 PR1): stamp entry/exit + mode.
199
- const result = await recordPlanInvocation(
200
- { cli: 'epic-plan-clarity', mode: 'persist', epicId, config },
201
- () =>
202
- persistClarityUpdate({
203
- epicId,
204
- updatedBody,
205
- provider,
206
- }),
207
- );
208
- process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
209
- }
210
-
211
- runAsCli(import.meta.url, main, { source: 'epic-plan-clarity' });