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,955 +0,0 @@
1
- ---
2
- description: >-
3
- Drive an Epic from `agent::ready` to a merged pull request against `main`.
4
- The ten-phase flow runs the wave loop, close-validation, the Epic-close
5
- lens-roster resolve, the code-review pass (which walks the cumulative diff
6
- once with the lens roster folded in), retro, finalize, watch-and-iterate,
7
- conditional auto-merge,
8
- and local branch cleanup. When the run is end-to-end clean (zero manual
9
- interventions, zero 🔴/🟠 review findings, compact retro) the PR
10
- auto-merges via `gh pr merge --squash --delete-branch`; otherwise the
11
- workflow falls back to the operator-merges-button path so a human
12
- inspects the surface area.
13
- ---
14
-
15
- # helpers/deliver-epic — Epic delivery path (invoked by /deliver)
16
-
17
- > **Runtime core.** This file is the always-ingested Epic-delivery path:
18
- > phase flow, commands, gate contracts, and return shapes. The recovery
19
- > procedures, historical rationale, and troubleshooting detail live in the
20
- > sibling [`deliver-epic-reference.md`](deliver-epic-reference.md); each
21
- > moved procedure keeps a one-line pointer at its trigger point below. The
22
- > reference is not projected to `.claude/commands/` — it is consulted on
23
- > demand.
24
-
25
- ## Overview
26
-
27
- This helper is the **Epic delivery path** behind `/deliver` — the router
28
- delegates to it once per Epic ID, either as the sole route (single-Epic
29
- input) or as one **Epic segment** of the sequential segment plan `/deliver`
30
- composes over mixed Epic / standalone-Story input (Epic segments run in
31
- input order, after the standalone segment; see
32
- [`deliver.md`](../deliver.md)). Each invocation opens a PR against `main`
33
- and auto-merges when every signal certifies a clean run; otherwise it falls
34
- back to the operator-merges-button path.
35
-
36
- ```text
37
- /deliver <epicId>
38
- → Phase 1 — prepare (epic-deliver-prepare.js)
39
- → Phase 2 — ready-set loop (wave-tick.js → dispatch ready set → observe → re-tick)
40
- → Phase 3 — close-validation (lint + test + ratchets on epic/<id>)
41
- → Phase 4 — epic-close lens roster (helpers/epic-audit.md — resolve the slim cumulative+global+risk-routed roster)
42
- → Phase 5 — code-review (helpers/code-review.md scope: epic — walks the cumulative diff once, lens roster folded in)
43
- → Phase 6 — retro (.agents/scripts/lib/orchestration/retro-runner.js)
44
- → Phase 6.5 — integration gate (whole-product navigability + journey suite; @pending ≠ green for surface-adding Epics — blocks finalize)
45
- → Phase 7 — finalize (lifecycle-emit → epic.close.end → open PR to main)
46
- → Phase 8 — watch-and-iterate (poll `gh pr checks`; fix locally until green)
47
- → Phase 8.5 — auto-merge gate (lifecycle-emit → epic.automerge.start)
48
- → Phase 9 — cleanup (BranchCleaner + Cleaner lifecycle listeners on epic.cleanup.start / epic.merge.armed; fire via lifecycle-emit → epic.merge.armed)
49
- ```
50
-
51
- The argument is always a single Epic ID (`type::epic`) — multi-Epic or
52
- mixed input is segmented by the `/deliver` router before this helper runs.
53
- Story IDs go to
54
- [`helpers/deliver-stories`](deliver-stories.md) (standalone) or the
55
- [`helpers/epic-deliver-story`](epic-deliver-story.md) helper
56
- (Epic-attached, invoked by this workflow's fan-out); Tasks are not directly
57
- executable.
58
- Story dispatch is in-session via the Agent tool — no subprocess is
59
- spawned.
60
-
61
- ---
62
-
63
- ## Arguments
64
-
65
- ```text
66
- /deliver <epicId> [--skip-epic-audit] [--skip-code-review] [--skip-retro] [--full-retro] [--skip-integration-gate]
67
- ```
68
-
69
- - `epicId` — must carry `type::epic`. Otherwise STOP and tell the operator
70
- to use `/deliver <id>` (standalone Story) or open the parent Epic.
71
- - `--skip-epic-audit` — skip Phase 4 (log the override). Use only when the
72
- change-set audits are known to be irrelevant (e.g., docs-only Epic).
73
- - `--skip-code-review` — skip Phase 5 (log the override).
74
- - `--skip-retro` — skip Phase 6 (use sparingly).
75
- - `--full-retro` — force the six-section retro regardless of manifest
76
- cleanliness. `--skip-retro` wins over `--full-retro`.
77
- - `--skip-integration-gate` — skip Phase 6.5 (log the override). The
78
- explicit operator override for the post-wave integration gate,
79
- consistent with `--skip-epic-audit`. Skipping the gate is recorded as a
80
- manual intervention and disqualifies auto-merge, exactly like the other
81
- `--skip-*` overrides.
82
-
83
- Every other runtime modifier is sourced from the Epic's labels or from
84
- `delivery.deliverRunner` in `.agentrc.json`.
85
-
86
- - `--yes` — the top-level `/deliver` unattended flag (suppresses the
87
- operator confirmation gate; see [`deliver.md`](../deliver.md)). This
88
- helper reads it as the **headless signal** for Phase 8.5's must-land
89
- terminal step (Story #4427): when `/deliver` was invoked with `--yes`,
90
- thread `--headless true` into the Phase 8.5
91
- `epic.automerge.start` `lifecycle-emit.js` call (omit the flag, or
92
- pass `--headless false`, for an attended run). The runtime reads this
93
- as an explicit `headless` input threaded through
94
- `runLifecycleEmit` → `buildDefaultListenerChain` →
95
- `MergeWatcher({ headless })` — never an ambient/undefined global.
96
- Attended-mode behavior (no `--headless` flag) is byte-for-byte
97
- unchanged: `MergeWatcher` defaults `headless` to `false`.
98
-
99
- ---
100
-
101
- ## Contract
102
-
103
- - **Idempotent by checkpoint.** Re-runs resume from `epic-run-state`.
104
- - **Single pause point.** Only `agent::blocked` halts execution. No
105
- clarifying questions — if stuck, flip to `agent::blocked`, post a
106
- friction comment, park.
107
- - **Flat Story dispatch by design.** Host LLM fans out per-Story Agent
108
- calls directly with `subagent_type: general-purpose`. Keeping Story
109
- dispatch flat — the host owns the single fan-out level — is a
110
- **design choice**, not a harness constraint: the wave aggregator, idle
111
- watchdog, and merge-lock all assume one host-owned dispatch level. As of
112
- Claude Code 2.1.202 a level-1 sub-agent **does** carry the `Agent` tool
113
- and can nest further (verified depth 2, announced max depth 5; see
114
- [#2870](https://github.com/dsj1984/mandrel/issues/2870)), so a Story
115
- worker may itself fan out for its own sub-work within that depth budget —
116
- the Epic wave loop nonetheless stays flat by choice, not because nesting
117
- is unavailable.
118
- - **Operator-merges-PR exit.** Phase 7 opens the PR; the workflow
119
- never merges to `main` itself. Phase 8.5 may fire auto-merge when
120
- every signal is clean.
121
- - **Lifecycle bus is the runner model.** Phase transitions, ticket
122
- state flips, structured comments, and notifications are emitted as
123
- typed events on the in-session lifecycle bus; a fixed roster of
124
- listeners performs the side effects. Phase 7, 8.5, and 9 each fire
125
- exactly one lifecycle event via the generic
126
- [`lifecycle-emit.js`](../../scripts/lifecycle-emit.js) CLI
127
- (`--event epic.close.end` / `--event epic.automerge.start` /
128
- `--event epic.merge.armed`); the matching listener chain runs the
129
- bus-driven side effects (acceptance reconcile, automerge-armer,
130
- branch cleanup). The append-only NDJSON ledger at
131
- `temp/epic-<id>/lifecycle.ndjson` is the resume target. See
132
- [`docs/LIFECYCLE.md`](../../../docs/LIFECYCLE.md) for the bus
133
- contract, event taxonomy, ledger format, and listener model.
134
-
135
- > **Hierarchy.** `/deliver` operates over the 2-tier hierarchy
136
- > (Epic → Story). The fan-out is one `Agent` tool call per
137
- > Story per wave (§ 2b); Story branches merge into `epic/<id>` with
138
- > `--no-ff` via `story-close.js`; the close-validation chain
139
- > (Phase 3), epic-audit, code-review, retro, finalize, and auto-merge
140
- > gates all operate on Story-level units.
141
- > [`helpers/epic-deliver-story`](epic-deliver-story.md) runs a
142
- > single Story-implementation phase per Story against the Story's
143
- > inline `acceptance[]` / `verify[]` fields. See
144
- > [`.agents/instructions.md` § 5.D](../../instructions.md) and
145
- > [`.agents/docs/SDLC.md` § Ticket hierarchy](../../docs/SDLC.md) for the full
146
- > contract.
147
-
148
- ---
149
-
150
- ## Phase 1 — Prepare the Epic run
151
-
152
- ### Phase 1 prelude — Delivery preflight (Story #2899 / F13)
153
-
154
- Before `epic-deliver-prepare.js` seeds the checkpoint, run
155
- `epic-deliver-preflight.js` so the operator (and any reviewer reading the
156
- Epic ticket) sees the estimated Story count, install cost, dependency depth,
157
- GitHub API request volume, and Claude Max quota burn for the run that is
158
- about to fan out. **Preflight always runs before Story fan-out.**
159
-
160
- ```bash
161
- node .agents/scripts/epic-deliver-preflight.js --epic <epicId> --post
162
- ```
163
-
164
- The CLI upserts a `delivery-preflight` structured comment on the Epic
165
- (idempotent across re-runs) and prints a JSON envelope on stdout with
166
- the canonical metric keys `storyCount`, `installCostSeconds`,
167
- `dependencyDepth` (the longest dependency chain — the ready-set wall-clock
168
- floor, replacing the retired wave count), `githubApiRequests`,
169
- `claudeQuotaTokens`, plus a `breaches` array describing any
170
- `delivery.preflight.max*` thresholds the estimate exceeds.
171
-
172
- **Breach handling.** When `breaches` is non-empty, the workflow MUST
173
- flip the Epic to `agent::blocked`, surface the envelope in chat for the
174
- operator, and halt before Phase 1's `epic-deliver-prepare.js` call.
175
- Resume after the operator unblocks (raising the threshold in
176
- `.agentrc.json`, splitting the Epic, or accepting the cost) by re-running
177
- `/deliver <epicId>` — the preflight is idempotent and the second
178
- run upserts the same comment in place.
179
-
180
- Threshold defaults live in `delivery.preflight.*` in `.agentrc.json`
181
- (all keys default to "no cap" — the gate is opt-in until an operator
182
- configures `maxStories` etc.).
183
-
184
- **Remote evidence — land or block (issue #4483).** The envelope also
185
- carries `remoteVerified` + `remoteProbe` (deterministic probes:
186
- `git remote get-url origin`, bounded `git ls-remote origin HEAD`). When
187
- `remoteVerified` is `false`, flip the Epic to `agent::blocked`, post a
188
- friction comment quoting `remoteProbe.detail`, and halt — the same
189
- explicit-block shape as #4425/#4480. NEVER fall back to executing Stories
190
- inline in this session or committing the delivery to local `main`; the
191
- worktree/branch/PR path below is the only sanctioned mechanism. Phase 7's
192
- finalize additionally refuses with a `delivery-branch-missing-on-origin`
193
- blocker when `epic/<epicId>` never reached origin.
194
-
195
- ### Phase 1 main — Seed the wave plan
196
-
197
- ```bash
198
- node .agents/scripts/epic-deliver-prepare.js --epic <epicId> [--steal] [--as <handle>]
199
- ```
200
-
201
- Validates `type::epic`, enumerates `type::story` descendants, parses
202
- `blocked by #N` plus explicit `dependencies`, computes the dependency DAG
203
- (to enumerate the open Story set), and upserts the `epic-run-state`
204
- checkpoint in the per-Story-status shape (a flat `stories` map seeded at
205
- `pending`, plus the global `concurrencyCap`). Treat the printed JSON as
206
- `state`: `{ epicId, storyCount, concurrencyCap, stories, checkpointInitializedAt, docsDigestPath }`.
207
- `stories` is the flat dispatch hint (`{ storyId, worktree, title,
208
- checklistPath }` per open Story); the ready-set `tick` (Phase 2) decides
209
- which to dispatch on each beat. `checklistPath` is the repo-relative path to
210
- that Story's footprint-matched local-lens authoring checklist
211
- (`temp/epic-<epicId>/checklists/story-<storyId>.md`, Story #4410) — thread it
212
- into that child's prompt (§ 2b, item 7); it is `null` when the Story's
213
- predicted footprint matched no local lens. `docsDigestPath` is the
214
- repo-relative path to the per-Epic docs digest
215
- (`temp/epic-<epicId>/docs-digest.md`) that prepare writes from
216
- `project.docsContextFiles` — thread it into every child prompt (§ 2b, item 6).
217
- It is `null` when the project configured no `docsContextFiles` (no digest is
218
- written). Flip the Epic to `agent::executing` (idempotent) after the CLI
219
- returns.
220
-
221
- **No spec-ticket linkage to resolve (Story #4324).** The Tech Spec lives
222
- as managed sections of the Epic body itself — there is no separate
223
- Tech-Spec issue id in the envelope and no `--tech-spec` flag to thread
224
- into the per-Story `story-init.js` invocations. Story agents receive the
225
- Tech Spec via context hydration, which embeds the Epic body (with the
226
- `## Acceptance Table` section stripped) directly into each Story prompt.
227
-
228
- > **Preflight guards + acceptance-table start gate.** Before the snapshot
229
- > phase runs — and before any worktree is created — prepare runs two
230
- > **fail-closed** guards (checkout safety + Epic lease), then the snapshot
231
- > phase asserts the Epic carries an `acceptance::n-a` waiver or a
232
- > `## Acceptance Table` section. Both throw on failure. See
233
- > [`deliver-epic-reference.md` § Phase 1 — Preflight guards](deliver-epic-reference.md#phase-1--preflight-guards-story-3482--f-workflow-guards)
234
- > for the remediation detail (dirty-tree recovery, `--steal`, waiver
235
- > options).
236
-
237
- ---
238
-
239
- ## Phase 2 — Ready-set loop
240
-
241
- The scheduler lives in
242
- [`lib/wave-runner/tick.js`](../../scripts/lib/wave-runner/tick.js) — a thin
243
- **Epic adapter over the ready-set core**
244
- ([`lib/wave-runner/ready-set.js`](../../scripts/lib/wave-runner/ready-set.js)).
245
- One stateless `tick({ epic })` call re-derives readiness from the **live**
246
- Story bodies + labels on every beat and returns one `WaveTickResult`
247
- describing the next action. There is **no wave barrier** (Story #4155): a
248
- Story whose own dependencies are all done is dispatched the instant a slot is
249
- free under the GLOBAL in-flight cap, even while an unrelated sibling Story is
250
- still `agent::executing`. The loop is simply:
251
-
252
- ```text
253
- tick → dispatch the ready set → observe → re-tick → … → epic-complete
254
- ```
255
-
256
- The slash command's job each beat is to call `tick()` via its CLI shim,
257
- dispatch the Stories in `nextAction.stories` via the Agent tool, record each
258
- returned Story's terminal status, and re-tick until terminal. There is no
259
- `record-wave` / `currentWave` step — the checkpoint carries only a flat
260
- per-Story status map (for resume + the operator rollup) and the global cap.
261
-
262
- ### 2.0. Open the Epic PR as a draft at wave 1 (Story #4359)
263
-
264
- When `delivery.ci.earlyPr` is on (the default), open the Epic PR as a
265
- **draft** once, before the first `tick`, so every subsequent per-wave push
266
- to `epic/<epicId>` runs CI attributed to its own wave. (CI is keyed on the PR
267
- ref with `cancel-in-progress`, so each new wave push **supersedes** the prior
268
- wave's in-flight run rather than queuing behind it — the latest wave always
269
- gets the verdict, and CI-minute use stays bounded; intermediate wave runs are
270
- cancelled, not completed.) Resolve the flag through the
271
- [`getCiDelivery`](../../scripts/lib/config/ci.js) accessor (default `true`);
272
- do not read `delivery.ci.earlyPr` directly.
273
-
274
- > **This step is host-LLM-driven, with no runtime enforcement seam** — unlike
275
- > the Phase 7 ready-flip, which the `Finalizer` listener wires in
276
- > deterministically (`finalizer.js` resolves `earlyPr` and calls
277
- > `markPrReady`). The asymmetry is intentional and safe: if this wave-1
278
- > draft-open is skipped, the `earlyPr`-on Phase 7 `markPrReady` call degrades
279
- > to a no-op on the PR that finalize opens at close time (`gh pr ready` is a
280
- > no-op on an already-ready PR), so the merge gate is never stranded — the run
281
- > only loses the per-wave CI attribution this step buys.
282
-
283
- - **`earlyPr` on** — call
284
- [`openOrLocatePr`](../../scripts/lib/orchestration/finalize/open-or-locate-pr.js)
285
- with `{ epicId, headBranch: 'epic/<epicId>', baseBranch: 'main', draft: true }`.
286
- The helper probes for an existing open PR first, so this is idempotent — a
287
- resumed `/deliver` run re-locates the same draft and opens no duplicate.
288
- Phase 7 later flips this draft to ready-for-review (it does **not**
289
- re-create the PR).
290
- - **`earlyPr` off** — skip this step entirely. No draft is opened at wave 1;
291
- Phase 7 opens the PR at close time on the pre-Story timing.
292
-
293
- The draft carries the same title/body contract Phase 7 uses
294
- (`feat: Epic #<epicId>` / `Closes #<epicId>`), so no title/body reconciliation
295
- is needed when it is marked ready.
296
-
297
- ### 2a. Tick — plan the next action
298
-
299
- ```bash
300
- node .agents/scripts/wave-tick.js --epic <epicId>
301
- ```
302
-
303
- Stdout is one `WaveTickResult` envelope:
304
-
305
- ```json
306
- {
307
- "nextAction":
308
- { "kind": "dispatch", "stories": [{ "id": <n>, "title": "…" }, ...], "in-flight": [<storyId>, ...] }
309
- | { "kind": "observe", "waitingOn": [<storyId>, ...], "in-flight": [<storyId>, ...] }
310
- | { "kind": "halt", "reason": "dependency-cycle" | "unsatisfiable-dependency", "stuckStories": [<storyId>, ...], "cycle"?: [<storyId>, ...], "in-flight": [<storyId>, ...] }
311
- | { "kind": "epic-complete", "in-flight": [<storyId>, ...] },
312
- "blockedStories": [{ "storyId": <n>, "reason": "…", "detail"?: "…" }, ...],
313
- "gateFailures": [{ "storyId": <n>, "gate": "…", "detail"?: "…" }, ...],
314
- "readyCount": <n>,
315
- "inFlight": [<storyId>, ...]
316
- }
317
- ```
318
-
319
- `nextAction.stories` is the **ready set** for this beat — the
320
- dependency-satisfied, overlap-free subset of open Stories, capped at
321
- `globalCap − inFlight`. The CLI is a planner: it dispatches nothing and
322
- persists nothing. It emits only the two wave-window forensics signals that
323
- have a live consumer — `wave-start` (on the run's first dispatch) and
324
- `wave-complete` (when the run finishes), which the perf-aggregator brackets
325
- into the `waveParallelism` report (and `wave-start` anchors span-tree Story
326
- spans). The [`signals` helper](signals.md)
327
- (`node .agents/scripts/signals-view.js`) renders the forensics signals in the
328
- span-tree view.
329
-
330
- > **Old-shape checkpoint → fail-closed.** A pre-ready-set
331
- > (`plan` / `currentWave` / `totalWaves`) checkpoint makes the tick refuse
332
- > to run and throw; re-seed via `epic-deliver-prepare.js`. See
333
- > [`deliver-epic-reference.md` § Fail-closed on an old-shape checkpoint](deliver-epic-reference.md#fail-closed-on-an-old-shape-checkpoint).
334
-
335
- ### 2b. Dispatch — fan out per-Story Agent calls
336
-
337
- *You* (the LLM running this skill) are the dispatcher; you never invoke
338
- `helpers/epic-deliver-story` yourself. Emit **one `Agent` tool call per
339
- Story** in `nextAction.stories` (even when `length === 1` — the
340
- parent-child boundary keeps the return-parser uniform). The *children*
341
- run [`helpers/epic-deliver-story`](epic-deliver-story.md). Use
342
- `subagent_type: general-purpose`.
343
-
344
- Emit **one assistant turn** with **N parallel `Agent` calls** where
345
- `N === nextAction.stories.length` (the ready set is already capped at
346
- `globalCap − inFlight` by the tick, so it never exceeds available slots).
347
- Dispatch the ready set as background calls (`run_in_background: true`) and,
348
- as each child returns, record it (§ 2c) and **re-tick** (§ 2a) to pull the
349
- next ready set — never wait for the whole set before refilling.
350
-
351
- > **Throughput + capability tuning.** The default `concurrencyCap` of 3 is
352
- > a deliberate operator-tuning knob (raise
353
- > `delivery.deliverRunner.concurrencyCap`), and the optional per-call
354
- > `model:` escape hatch lets mechanical Stories run on a cheaper capability.
355
- > See [`deliver-epic-reference.md` § Throughput tradeoff](deliver-epic-reference.md#throughput-tradeoff)
356
- > and [§ Sub-agent dispatch capability](deliver-epic-reference.md#sub-agent-dispatch-capability).
357
-
358
- **Ledger the dispatch BEFORE the Agent call.** Immediately before each
359
- per-Story `Agent` tool call (one shell-out per Story, every attempt —
360
- including retries from a refill), invoke
361
- [`lifecycle-emit-story-dispatch.js`](../../scripts/lifecycle-emit-story-dispatch.js)
362
- so the lifecycle ledger durably records the dispatch attempt. The
363
- emit must happen **before** the Agent call fires — never after — so
364
- that a host-process crash mid-Agent leaves a `story.dispatch.start`
365
- record that `wave-tick.js` (see § 2a) excludes from the next beat's ready
366
- set and surfaces under `nextAction['in-flight']`:
367
-
368
- ```bash
369
- node .agents/scripts/lifecycle-emit-story-dispatch.js \
370
- --epic <epicId> --story <storyId> \
371
- --wave 0 --attempt <attempt>
372
- ```
373
-
374
- Pass `--wave 0` — the ready-set runtime has a single continuous front, so
375
- the ledger's `waveIndex` is a fixed `0` (it is metadata for the start/end
376
- pairing math, not a scheduling input). `<attempt>` starts at 1 for the
377
- Story's first dispatch and increments on each retry/refill. The CLI appends
378
- exactly one NDJSON line to `temp/epic-<epicId>/lifecycle.ndjson`; the
379
- matching `story.dispatch.end` record is appended later by
380
- `epic-execute-record-wave.js` (via `emit-story-dispatch-end.js`, Story #3900)
381
- after the Agent return is recorded in § 2c.
382
-
383
- Each Agent call's prompt must (1) name the Story + Epic ids, (2)
384
- instruct the child to invoke `helpers/epic-deliver-story <storyId>`
385
- (whose Step 4 defines the child's return shape), (3) remind the child
386
- of the **non-interactive contract** (no clarifying questions;
387
- transition to `agent::blocked` and exit if stuck), (4) tell the child to
388
- suppress per-Story chat relay and instead relay **one line per phase
389
- transition** (e.g. `Story #<id>: implementing → closing`) — the child's
390
- authoritative progress lands in the `story-run-progress` snapshot the
391
- `story-phase.js` CLI upserts, not in a verbatim body dump, (5) require the
392
- child to emit a `story.heartbeat` lifecycle event at least once per
393
- Story-level phase transition via `node .agents/scripts/story-phase.js` (or
394
- whenever it stalls on a long-running step), and if it cannot make progress
395
- to transition to `agent::blocked` rather than fall silent, and (6) pass the
396
- **docs digest path** — the `docsDigestPath` field from the
397
- `epic-deliver-prepare.js` envelope (§ Phase 1 main), which points at
398
- `temp/epic-<epicId>/docs-digest.md`. Instruct the child to read that
399
- digest instead of re-reading the full `project.docsContextFiles` set,
400
- and to pull individual docs files on demand (per
401
- [`.agents/instructions.md` § 3](../../instructions.md)). When
402
- `docsDigestPath` is null (the project configured no `docsContextFiles`),
403
- say so — the child then has no per-Story docs mandate. (7) pass the
404
- **checklist path** — the `checklistPath` field from that Story's entry in
405
- the `stories` dispatch hint (Story #4410), which points at
406
- `temp/epic-<epicId>/checklists/story-<storyId>.md`. Instruct the child to
407
- read that file (footprint-matched local-lens authoring checklists) and
408
- self-check its change against those concerns while writing. When
409
- `checklistPath` is null (the Story's predicted footprint matched no local
410
- lens), there is nothing to read. The pairing of
411
- `story.heartbeat` and `agent::blocked` is what lets the § 2d Idle
412
- Watchdog distinguish a working child from a dead one; a silent child
413
- with no recent heartbeat and no blocker label is the failure mode the
414
- watchdog is built to catch.
415
-
416
- There is **no per-child JSON return-parsing ceremony** for the parent
417
- to enforce. GitHub state is the contract: `epic-execute-record-wave.js`
418
- (§ 2c, mode B) treats each child's raw return text as a best-effort
419
- hint and reconciles any unparseable, empty, or missing return directly
420
- from the Story's live labels and comments.
421
-
422
- ### 2c. Record the Story outcomes
423
-
424
- As dispatched Stories return (record them as they land — you need not wait
425
- for the whole ready set), persist each Story's terminal status via
426
- `epic-execute-record-wave.js`. There is **no `--wave` flag and no
427
- `currentWave`** — the recorder splices each Story's status into the
428
- checkpoint's flat per-Story map and re-renders the rollup:
429
-
430
- ```bash
431
- # Mode A — host LLM already parsed each child return.
432
- node .agents/scripts/epic-execute-record-wave.js \
433
- --epic <epicId> --results @<file>|<inline-json>
434
-
435
- # Mode B — pipe the raw per-Story sub-agent return texts directly.
436
- node .agents/scripts/epic-execute-record-wave.js \
437
- --epic <epicId> --returns @<file>|<inline-json>
438
- # `<inline-json>` shape: [{ "storyId": <n>, "returnText": "<raw text>" }]
439
- ```
440
-
441
- **Mode B is the default path** — pipe the raw return texts through
442
- without inspecting them. The CLI reconciles parse failures from GitHub,
443
- records each Story's terminal status, emits one `story.dispatch.end` per
444
- recorded Story (closing the ledger pairing), re-renders
445
- `epic-run-progress`, and prints `{ status, nextAction, renderedBody, ... }`.
446
- Print `renderedBody` verbatim, then optionally append a short **Notable**
447
- section (0–5 bullets on newly blocked / failed / slow Stories, friction,
448
- elapsed-time surprises).
449
-
450
- > **Crash recovery.** A child that finished but was never recorded is
451
- > re-derived from its live label on the next `tick` and never
452
- > re-dispatched. See
453
- > [`deliver-epic-reference.md` § Crash recovery (record step)](deliver-epic-reference.md#crash-recovery-record-step)
454
- > for the manual re-record command.
455
-
456
- ### 2d. Loop on `nextAction`
457
-
458
- After `2c`, re-run `wave-tick.js`. Branch on the new envelope:
459
-
460
- - `dispatch` → repeat 2b/2c for the new ready set (the next beat's
461
- dependency-satisfied Stories), then re-tick.
462
- - `observe` → poll the Epic (children may still be in flight, or some
463
- are `agent::blocked`). If `blockedStories` is non-empty, post a
464
- friction comment, flip Epic to `agent::blocked`, park.
465
- - `halt` → the run is stuck: no Story is dispatchable, nothing is in
466
- flight, yet not every Story is done. `reason` distinguishes the two
467
- causes — `dependency-cycle` (the in-scope Stories form a `blocked by`
468
- cycle; `cycle` lists the offending Story ids) or
469
- `unsatisfiable-dependency` (a Story is gated on a dependency that can
470
- never satisfy). `stuckStories` names the Story id(s) that stranded the
471
- run. Post a friction comment quoting `reason` + `stuckStories`, flip the
472
- Epic to `agent::blocked`, and park for the operator. **Never** treat a
473
- `halt` as completion — proceeding to Phase 3 would silently drop the
474
- stuck Story.
475
- - `epic-complete` → **every** in-scope Story is done and nothing is in
476
- flight; proceed to Phase 3. (The tick returns `epic-complete` only when
477
- the done count equals the in-scope Story count — a stuck Story surfaces
478
- as `halt`, not a false `epic-complete`.)
479
-
480
- > **Idle Watchdog.** While any Story is in flight, re-tick every 30 minutes
481
- > with `wave-tick.js --epic <epicId> --check-idle 30` so a silent child
482
- > (crashed host, lost return) is surfaced as a `wave-stall` and
483
- > re-dispatched or blocked. The full cadence, staleness test (heartbeat +
484
- > deterministic branch-commit signal), stall envelope, and the "why 30 not
485
- > 10" rationale are in
486
- > [`deliver-epic-reference.md` § 2e. Idle Watchdog](deliver-epic-reference.md#2e-idle-watchdog).
487
- > Stop the cadence once the tick returns `epic-complete`.
488
-
489
- ---
490
-
491
- ## Phase 3 — Close-validation
492
-
493
- Run lint + test + ratchets against `epic/<epicId>` before opening the PR:
494
-
495
- ```bash
496
- node .agents/scripts/evidence-gate.js \
497
- --epic-id <epicId> --scope-id <epicId> --gate lint -- npm run lint
498
- node .agents/scripts/evidence-gate.js \
499
- --epic-id <epicId> --scope-id <epicId> --gate test -- npm test
500
- ```
501
-
502
- If either gate fails: STOP, fix on a hotfix branch, merge back to the
503
- Epic branch, restart this phase.
504
-
505
- ### 3.1 Refresh ratcheted baselines
506
-
507
- Inspect the scripts in `.husky/pre-push` (typecheck, lint, maintainability,
508
- design tokens, dependency audits, bundle-size budgets). Run each against
509
- the Epic branch; if any drifts, refresh and commit
510
- `chore(baselines): refresh <name> for Epic #<epicId>`.
511
-
512
- ---
513
-
514
- ## Phase 4 — Epic-close lens roster
515
-
516
- Skip when `--skip-epic-audit`. Otherwise auto-invoke
517
- [`helpers/epic-audit.md`](epic-audit.md) inline to **resolve** (not walk) the
518
- slim Epic-close lens roster. The helper runs
519
- [`epic-audit-prepare.js`](../../scripts/epic-audit-prepare.js) to ask the
520
- [`selectAudits`](../../scripts/lib/audit-suite/index.js) SDK which lenses fire
521
- at the `gate3` close gate, **unions in the model-judged risk-routed lenses**
522
- (Story #3889 — `epic-audit-prepare.js` reads the Epic's `planningRisk`
523
- envelope off the `epic-plan-state` checkpoint and maps each high-risk axis to
524
- its lens via `resolveAuditLenses`), then restricts that union to the tiers the
525
- Epic-close tier owns via
526
- [`selectEpicCloseLenses`](../../scripts/lib/orchestration/code-review.js): the
527
- envelope's **`epicCloseLenses`** field is the slim roster of **cumulative +
528
- global + risk-routed** lenses, with every **local-tier** change-set lens
529
- excluded (its concern is already verified shift-left at the write-time and
530
- Story-scope tiers). A high-risk Epic still auto-runs its risk-routed lenses
531
- even when the change set alone did not select them; a docs-only or
532
- already-shift-left-covered change set yields an empty roster.
533
-
534
- **The lens roster is not walked here.** Story #4412 folded the standalone
535
- Phase 4 lens walk into the Phase 5 code-review pass so the cumulative Epic diff
536
- is walked **once**. Phase 4 resolves `epicCloseLenses` (plus `depth`,
537
- `globalLenses`, `substitutionsPayload`) and hands it to Phase 5; there is no
538
- separate `audit-results` comment. Remediation of the lens findings happens in
539
- Phase 5 and is **tier-aware** (Story #4412): the Epic-close tier reads
540
- `delivery.epicAudit.autoFixSeverity` (default **`high`**) and routes only
541
- 🔴 Critical + 🟠 High lens findings into on-branch remediation while 🟡 Medium
542
- and 🟢 Suggestion findings graduate (🟡 Medium concerns are already remediated
543
- shift-left); setting `medium` opts back into routing 🔴/🟠/🟡.
544
-
545
- - **Selector reports `degraded: true`** — STOP. Propagate the
546
- `reason`/`detail`, post a friction comment, do not fall back to a
547
- full-roster audit.
548
- - **`epicCloseLenses` is empty** (docs-only change set, or every selected lens
549
- already covered shift-left, and no risk-routed lens) — there is no lens
550
- dimension for Phase 5 to walk; continue to Phase 5, which still runs its
551
- review pillars.
552
-
553
- ---
554
-
555
- ## Phase 5 — Code review (cumulative diff walked once)
556
-
557
- Skip when `--skip-code-review`. Otherwise resolve the **risk-derived review
558
- depth** for this Epic, then auto-invoke
559
- [`helpers/code-review.md`](code-review.md) inline (read-only audit)
560
- with the argument envelope `{ scope: 'epic', ticketId: <epicId>, baseRef:
561
- 'main', headRef: 'epic/<epicId>', depth: <reviewDepth> }`, threading the
562
- Phase 4 `epicCloseLenses` roster through. The pass walks the cumulative
563
- `main..epic/<epicId>` diff **once**: it executes the Epic-close lens roster as
564
- review dimensions (helper Step 1b) **and** the review pillars, folding both
565
- into a single aggregate. Findings persist as the unified `verification-results`
566
- structured comment on the Epic (the single findings surface — Story #4411
567
- unified the former `code-review` and `audit-results` contracts, and Story #4412
568
- folded the lens walk into this pass).
569
-
570
- The `depth` is the live epic-scope producer for Story #3876's review-depth
571
- lever (Story #3937). Resolve it from the Epic's judged risk envelope the same
572
- best-effort way Phase 4 routes audit lenses — via
573
- [`resolveReviewDepthForEpic`](../../scripts/lib/orchestration/code-review.js),
574
- which reads `planningRisk.overallLevel` off the Epic's `epic-plan-state`
575
- checkpoint and maps it: `high` → `deep`, `low` → `light`, everything else
576
- (including a missing/unparseable checkpoint, or an Epic that skipped
577
- `/plan`) → `standard`. The helper threads `depth` into `runCodeReview`,
578
- which forwards it to every provider's `runReview` input; the LLM-backed
579
- providers (codex, security-review, ultrareview) render it into the prompt they
580
- emit so a high-risk Epic gets a deeper adversarial pass and a low-risk one a
581
- lighter one. Depth is **input-only** — it never changes the findings envelope
582
- or the posted comment shape.
583
-
584
- Remediation in this pass is **tier-aware and split by finding class**
585
- (Story #4412). The **review-pillar** findings (Pillars 1–4) route off
586
- `delivery.codeReview.autoFixSeverity` (default **`medium`** — 🔴/🟠/🟡
587
- on-branch, Mediums batched per lens, 🟢 stays on the comment). The **Epic-close
588
- lens** findings (Step 1b) route off `delivery.epicAudit.autoFixSeverity`
589
- (default **`high`** — only 🔴/🟠 on-branch; 🟡 Medium + 🟢 graduate, because
590
- 🟡 Medium concerns were already remediated shift-left). Setting either key to
591
- its other value re-widens or narrows that class. Remediated findings are
592
- rendered under the single `verification-results` comment's `## Fixed on-branch`
593
- section so they never graduate to follow-up issues. The severity gate below is
594
- **unchanged** — it keys off the surviving (unfixed) findings.
595
-
596
- - **Any surviving 🔴 Critical Blocker** — STOP. Relay to the operator.
597
- - **Only 🟠/🟡/🟢 surviving** — log as non-blocking and continue.
598
-
599
- ---
600
-
601
- ## Phase 6 — Retro
602
-
603
- Skip when `--skip-retro`. Otherwise post the `epic-perf-report` via
604
- `node .agents/scripts/analyze-execution.js --epic <epicId>` (failure →
605
- warn and continue; the retro runner falls back). Then invoke the retro
606
- runner via its CLI wrapper:
607
-
608
- ```bash
609
- node .agents/scripts/retro-run.js --epic <epicId>
610
- ```
611
-
612
- [`retro-run.js`](../../scripts/retro-run.js) resolves the config/provider,
613
- constructs a lifecycle bus with a `LedgerWriter` (so the run's
614
- `retro.start` / `retro.end` boundaries land in
615
- `temp/epic-<epicId>/lifecycle.ndjson`), and calls `runRetro` — the
616
- canonical compose-and-post surface at
617
- [`.agents/scripts/lib/orchestration/retro-runner.js`](../../scripts/lib/orchestration/retro-runner.js).
618
- Propagate `--full-retro` to bypass the compact-path heuristic.
619
-
620
- Retro fires here (before the PR opens) so it stays in the operator's
621
- local session with full env access (env vars, credentials, MCP). After
622
- the GitHub upsert succeeds, the retro body is also **mirrored locally** to
623
- `temp/epic-<epicId>/retro.md` (path resolved via
624
- [`lib/config/temp-paths.js`](../../scripts/lib/config/temp-paths.js)'s
625
- `epicRetroMirrorPath`). GitHub remains the source of truth — a
626
- mirror-write failure only logs a warn and never fails the phase.
627
-
628
- **Auto-file routed proposals (Story #4418).** Between gathering the retro
629
- signals and composing the body, the runner files the retro's **actionable
630
- routed proposals** (the `framework` / `consumer` friction categories that
631
- recurred ≥ 2× or were force-flagged by an unresolved `agent::blocked`) as
632
- GitHub follow-up issues via the graduator pre-parsed-findings seam
633
- ([`retro-proposals-graduator.js`](../../scripts/lib/feedback-loop/retro-proposals-graduator.js)).
634
- Each filed issue carries `meta::<framework-gap|consumer-improvement>` +
635
- `friction::<category>` labels — the join key `/plan` Phase 0's
636
- prior-feedback fetcher reads back — and the rendered retro sections then
637
- list the **real filed issue numbers** instead of paste-ready `gh issue
638
- create` command stanzas. Filing is idempotent (a content-hash marker probe
639
- skips already-filed categories) and respects the graduator per-run filing
640
- cap. The beat runs behind `delivery.feedbackLoop.retroProposals` (default
641
- **ON**); set it to `false` to suppress auto-filing and fall back to the
642
- command stanzas. Filing never fails the phase — a filing error degrades to
643
- the command stanzas.
644
-
645
- ---
646
-
647
- ## Phase 6.5 — Post-wave integration gate (Epic #4131, F1/F4)
648
-
649
- This phase runs **after** the Phase 2 wave loop reports `epic-complete` and
650
- **before** the Phase 7 finalize emit opens the PR to `main`. It is the one
651
- **deliberately-global** gate — its evidence spans the whole product, not just
652
- the Epic's change set — so it catches the surface each Story shipped correctly
653
- in isolation yet the assembled product cannot reach (an unnavigable route, a
654
- broken persona journey).
655
-
656
- Skip when `--skip-integration-gate` (log the override; record a manual
657
- intervention per
658
- [`deliver-epic-reference.md` § Recording manual interventions](deliver-epic-reference.md#recording-manual-interventions)).
659
- The gate is otherwise **always evaluated** but a **silent no-op when
660
- unconfigured** (no `routeGlobs` / `navRegistry` / `journeySuite` in
661
- `.agentrc.json`).
662
-
663
- Sub-steps and hard-failure semantics:
664
-
665
- - **6.5a — Whole-product navigability**: run the `navigability` lens in
666
- whole-route mode over the `epic/<epicId>` tip. An **orphaned** route (no
667
- nav door for any entitled persona) or a dead nav href is a hard failure
668
- that **blocks finalize** and names the surface.
669
- - **6.5b — Consumer journey suite**: run
670
- `delivery.quality.navigability.journeySuite` over the tip. A failing
671
- persona journey is a hard failure that **blocks finalize** and names the
672
- broken journey.
673
- - **6.5c — `@pending` ≠ green for surface-adding Epics (F4)**: for a
674
- **surface-adding** Epic, an AC covered **only** by `@pending` scenarios is
675
- treated as unsatisfied and **fails the close gate** instead of passing
676
- green. This is **purely additive** and scoped to surface-adding Epics —
677
- refactor-only and docs-only Epics are **unaffected** and the existing
678
- `satisfied` / `missing` reconciliation is **not de-scoped** for any Epic.
679
-
680
- On any hard failure, post a friction structured comment naming the surface
681
- (route / nav-door identifier only — never route bodies or persona PII per
682
- `security-baseline.md`), flip the Epic to `agent::blocked`, and **do not**
683
- open the PR — the gate fails safe and loud. See
684
- [`deliver-epic-reference.md` § Phase 6.5](deliver-epic-reference.md#phase-65--post-wave-integration-gate-epic-4131-f1f4)
685
- for the full lens config, the surface-adding-signal derivation, the no-op
686
- degradation contract, and the fail-safe-and-loud security note.
687
-
688
- ---
689
-
690
- ## Phase 7 — Finalize (ready the PR / open PR to main)
691
-
692
- Before the close-tail emit, sync the Epic branch with `origin/main` so the
693
- PR opens with the latest base commits already integrated (a stale base
694
- stalls at branch-protection's `up-to-date branch` rule):
695
-
696
- ```bash
697
- git checkout epic/<epicId>
698
- node .agents/scripts/sync-branch-from-base.js \
699
- --branch epic/<epicId> --base main
700
- git push origin epic/<epicId>
701
- ```
702
-
703
- Then fire the close-tail emit:
704
-
705
- ```bash
706
- node .agents/scripts/lifecycle-emit.js --epic <epicId> --event epic.close.end
707
- ```
708
-
709
- `epic.close.end` drives the bus-owned `Finalizer` chain: acceptance-table
710
- reconciliation (throws and aborts finalize on a coverage gap, `waived` under
711
- `acceptance::n-a`), the PR-open/ready step (below), and the
712
- `epic-handoff` comment naming the PR URL. The chain emits `pr.created` →
713
- `epic.finalize.end` and **stops** — it never emits `epic.merge.ready` (the
714
- auto-merge arm is driven later from the Phase 8.5 gated watch path). The
715
- operator shells nothing beyond the sync and the single emit.
716
-
717
- **PR-open/ready is gated by `delivery.ci.earlyPr` (Story #4359).** Resolve
718
- the flag through the [`getCiDelivery`](../../scripts/lib/config/ci.js)
719
- accessor (default `true`); do not read `delivery.ci.earlyPr` directly.
720
-
721
- - **`earlyPr` on (default)** — the Epic PR already exists as a draft (Phase
722
- 2 opened it at wave 1). Finalize **locates** the existing PR and flips it
723
- ready-for-review via
724
- [`markPrReady`](../../scripts/lib/orchestration/finalize/open-or-locate-pr.js)
725
- rather than creating a PR. `gh pr ready` on an already-ready PR is a
726
- no-op, so a re-run is idempotent.
727
- - **`earlyPr` off** — no draft was opened at wave 1; finalize opens the PR
728
- now via `openOrLocatePr` (no `draft`), exactly as the pre-Story timing.
729
-
730
- In both modes the PR title/body contract (`feat: Epic #<epicId>` /
731
- `Closes #<epicId>`) is identical.
732
-
733
- See
734
- [`deliver-epic-reference.md` § Phase 7 — Finalize](deliver-epic-reference.md#phase-7--finalize-close-tail-listener-chain)
735
- for the branch-sync outcome table (conflict / fetch-failed recovery) and the
736
- full three-step listener contract (why finalize must not emit
737
- `epic.merge.ready`, the merge-lockout lint rule, the no planning-ticket close
738
- sweep).
739
-
740
- ---
741
-
742
- ## Phase 8 — Watch-and-iterate until CI is green
743
-
744
- The host LLM owns the green-bar loop until the operator merges. Use
745
- `pr-watch-with-update.js` — the **single CI-watch mechanism** shared with
746
- the standalone single-Story Step 4 path (Story #4358). It polls the PR's
747
- required checks to a terminal state and additionally auto-recovers from
748
- `mergeStateStatus: BEHIND` by calling `gh pr update-branch` once every
749
- required check is green (branch-protection rules requiring "up to date
750
- before merging" otherwise park the PR until the operator clicks **Update
751
- branch** manually):
752
-
753
- ```bash
754
- node <agentRoot>/scripts/pr-watch-with-update.js --pr <prNumber> --epic <epicId>
755
- ```
756
-
757
- `<agentRoot>` resolves from `project.paths.agentRoot` (default `.agents`).
758
- Poll cadence and caps come from `delivery.ci.watch.*`
759
- (`pollIntervalMs`, `maxPolls`, `maxResumes`); pass `--poll-interval-ms`,
760
- `--max-polls`, `--max-resumes`, or `--max-updates` to override for one
761
- run. Passing `--epic <epicId>` scopes the red-path failure digest to
762
- `temp/epic-<epicId>-ci-digest.{json,md}`.
763
-
764
- **Three-way exit (slow-vs-failed semantics):**
765
-
766
- - **Exit 0** — every required check is green → proceed to Phase 8.5.
767
- - **Exit 1** — a required check genuinely failed (red). The CLI writes
768
- `temp/epic-<epicId>-ci-digest.{json,md}` (failing check, run id,
769
- `gh run view --log-failed` tail, coarse classification) and surfaces
770
- the fix-loop handoff. Remediate on `epic/<epicId>` and re-run the
771
- helper (auto-merge stays armed across retries). If the same failure
772
- class recurs, hand the convergence off to a self-paced host loop
773
- (`/loop`) that re-runs the failing check and applies the smallest fix
774
- until it exits green.
775
- - **Exit 2** — **still-running** (slow CI, not red): the poll cap fired
776
- with checks still pending and the watcher exhausted its
777
- `delivery.ci.watch.maxResumes` re-arm budget with nothing red. This is
778
- **never** a failure and **never** `timed_out`. Hand the wait off to the
779
- host's interval loop rather than blocking the delivery turn: `/loop 5m`
780
- polling `gh pr checks` until the checks settle.
781
-
782
- > **Triage authority.** How to classify and remediate a red (or repeatedly
783
- > slow) check — the root-cause-only decision tree for infra/transient and
784
- > flaky failures (reproduce → check `main` → bisect env vs code → fix in-scope
785
- > or file a `meta::framework-gap` issue), the never-rerun / never-quarantine
786
- > prohibitions, and the escalation criteria (three-strikes, the 30-minute
787
- > wall-clock timebox, and the clearly-environmental fast path) — is defined
788
- > once in [`.agents/rules/ci-remediation.md`](../../rules/ci-remediation.md).
789
- > Read it before remediating.
790
- >
791
- > **Remediation + hard prohibitions.** For the per-check fix table (lint,
792
- > baseline drift, test, coverage), the three-strikes halt rule, and the
793
- > never-merge / never-force-push / never-dodge prohibitions, see
794
- > [`deliver-epic-reference.md` § Phase 8 — Watch-and-iterate remediation](deliver-epic-reference.md#phase-8--watch-and-iterate-remediation).
795
-
796
- ---
797
-
798
- ## Phase 8.5 — Auto-merge gate
799
-
800
- After Phase 8 exits 0, evaluate the auto-merge predicate by emitting
801
- `epic.automerge.start`. When this `/deliver` run was invoked with `--yes`,
802
- add `--headless true` so the downstream `MergeWatcher` engages the
803
- must-land terminal step (Story #4427, § Arguments above); omit the flag
804
- (or pass `--headless false`) for an attended run:
805
-
806
- ```bash
807
- node .agents/scripts/lifecycle-emit.js --epic <epicId> \
808
- --event epic.automerge.start --pr-url <prUrl> [--headless true]
809
- ```
810
-
811
- **Must-land terminal step (headless only).** `MergeWatcher` polls
812
- `epic.merge.armed` to confirmation as usual. If its poll budget is
813
- exhausted, a headless (`--headless true`) run does not exit silently —
814
- it classifies the block (`classifyMergeBlock`, the shared classifier
815
- from Story #4426) and applies one bounded retry before giving up:
816
-
817
- - `checks-pending-timeout` (required checks still progressing) — extend
818
- the watch budget once and keep polling.
819
- - `api-race-other` (no definitive block signal) — re-arm once by
820
- re-emitting `epic.merge.ready` on the bus (never a direct `gh pr merge`
821
- call — `AutomergeArmer` remains the sole authorized call site).
822
- - `branch-protection-human-required`, or both bounded retries already
823
- spent — terminal: emit `merge.unlanded` (`scope: "epic"`, carrying the
824
- block class) and fall through to the existing single `epic.blocked`
825
- emit — one blocked path, never a duplicate `agent::blocked` transition.
826
-
827
- Attended runs (no `--headless` flag) keep today's exact behavior: budget
828
- exhaustion emits `epic.blocked` immediately, with no classification, no
829
- retry, and no `merge.unlanded`.
830
-
831
- `AutomergePredicate` first runs a **live `gh pr checks --required` probe**
832
- (Story #4361): green required CI is the arming signal, so if any required
833
- check is red, pending, or the probe is unreadable it emits
834
- `epic.merge.blocked` immediately — even if the Phase 8 watch was interrupted
835
- before it observed green (closing the Story #3901 interrupted-watch hole).
836
- When the probe is green it evaluates the structured-signal verdict under the
837
- `delivery.ci.autoMerge` policy (default `"trust-ci"`; see
838
- [`configuration.md`](../../docs/configuration.md)):
839
-
840
- - **`trust-ci`** (default) — the ONLY structured conditions that block
841
- arming are an unresolved 🔴 critical (red) code-review finding or an
842
- `agent::blocked` state (a story-level blocker recorded in run-state, a
843
- non-done story, or a missing run-state checkpoint). Manual interventions,
844
- 🟠 warning-level findings, and a non-clean retro are **recorded for audit**
845
- (surfaced on the classification log and the arm-reason) but no longer block.
846
- - **`strict`** — restores the prior clean-sprint predicate exactly: empty
847
- manual-interventions, every story done, no story blocked, `0` 🔴 + `0` 🟠
848
- review findings, and the retro's `automerge-verdict` trailer reporting
849
- `cleanSprint: true`. Any dirty signal blocks.
850
-
851
- On an arming decision the predicate emits `epic.merge.ready`; the downstream
852
- `AutomergeArmer` (the sole authorized `gh pr merge` call site) fires
853
- `gh pr merge --auto --squash --delete-branch`. Otherwise the predicate emits
854
- `epic.merge.blocked` with the disqualifying reasons and exits without merging
855
- — the operator merges manually.
856
-
857
- **Blocked-path output (operator merges the button).** When arming is
858
- declined, `epic.merge.armed` never fires inside this run, so Phase 9 does not
859
- reap automatically. Surface the exact one-liner the operator runs **after**
860
- they merge the PR by hand so local refs are reaped and `main` is
861
- fast-forwarded (the idempotent-resume path below runs this automatically on
862
- the next `/deliver <epicId>`):
863
-
864
- ```bash
865
- node .agents/scripts/lifecycle-emit.js --epic <epicId> \
866
- --event epic.merge.armed --pr-url <prUrl>
867
- ```
868
-
869
- Close the phase wrapper by emitting `epic.automerge.end` (records the arm
870
- outcome on the ledger; `merged: true` once GitHub completes the squash,
871
- `merged: false` with a reason otherwise):
872
-
873
- ```bash
874
- node .agents/scripts/lifecycle-emit.js --epic <epicId> \
875
- --event epic.automerge.end --pr-url <prUrl> --merged <true|false>
876
- ```
877
-
878
- > **Predicate wiring + manual-intervention recording.** For the full
879
- > predicate contract (the trailer read, the `delivery.ci.autoMerge` policy
880
- > split, and the Story #4361 live `gh pr checks --required` probe that
881
- > replaced the former CI-freshness skip) and the
882
- > `epic-deliver-note-intervention.js` command + its trigger list, see
883
- > [`deliver-epic-reference.md` § Phase 8.5 — Auto-merge predicate detail](deliver-epic-reference.md#phase-85--auto-merge-predicate-detail).
884
-
885
- ---
886
-
887
- ## Phase 9 — Local branch cleanup
888
-
889
- Phase 9 runs **automatically** inside the lifecycle bus once auto-merge
890
- arms: the `BranchCleaner` listener subscribes to `epic.cleanup.start`
891
- and reaps local refs (the `epic/<id>` branch, every `story-<id>` in the
892
- checkpoint, attached worktrees, and stale tracking refs) before `Cleaner`
893
- archives the `temp/epic-<id>/` tree. No operator step is required on the
894
- auto-merge path.
895
-
896
- For out-of-band cleanup re-entry (resume after a crash, or operator
897
- override), fire `epic.merge.armed`:
898
-
899
- ```bash
900
- node .agents/scripts/lifecycle-emit.js --epic <epicId> \
901
- --event epic.merge.armed --pr-url <prUrl>
902
- ```
903
-
904
- > **Reap order + operator-merges fallback.** For the full in-process reap
905
- > order, the per-branch classification log, and the manual reap sequence
906
- > when Phase 8.5 fell back to the operator-merges-button path (auto-merge
907
- > declined, `epic.merge.armed` never fired), see
908
- > [`deliver-epic-reference.md` § Phase 9 — Local branch cleanup detail](deliver-epic-reference.md#phase-9--local-branch-cleanup-detail).
909
-
910
- ---
911
-
912
- ## Idempotence and resume
913
-
914
- Re-runs pick up at the next undispatched wave (in-flight Stories finish
915
- via `helpers/epic-deliver-story`'s own checkpointing). The PR from Phase 7 is
916
- updated in place on subsequent runs. The authoritative live view is
917
- the `epic-run-progress` structured comment.
918
-
919
- **Resume auto-arm for a merged-but-uncleaned Epic.** When `/deliver` resumes
920
- against an Epic whose PR already merged (operator merged the button in a prior
921
- session) but whose local `epic/<id>` / `story-<id>` refs still linger, the
922
- resume path detects the merged-but-uncleaned state
923
- (`detectMergedUncleanedEpic` in
924
- [`epic-cleanup.js`](../../scripts/lib/orchestration/epic-cleanup.js)) and fires
925
- `epic.merge.armed` automatically so Phase 9 reaps — no manual command. The
926
- detection is idempotent: an already-reaped Epic (no local refs) is a clean
927
- no-op, and an unmerged Epic never arms. It resolves the merged PR's URL for the
928
- required `epic.merge.armed` payload and fails closed (does **not** arm) on any
929
- indeterminate `gh` probe. The one-liner under Phase 8.5 / Phase 9 is the manual
930
- equivalent for the case where the operator does not re-run `/deliver`.
931
-
932
- ---
933
-
934
- ## Constraints
935
-
936
- - **Never** merge `epic/<epicId>` to `main` outside Phase 8.5.
937
- - **Never** dispatch more than the global `concurrencyCap` allows;
938
- concurrency lives inside the ready-set fan-out.
939
- - **Never** flip Story-level labels from this skill; **never** invoke
940
- `helpers/epic-deliver-story` yourself (children run it via Agent fan-out,
941
- even for single-Story waves); **never** spawn a subprocess for dispatch.
942
- - **Always** checkpoint via `epic-deliver-prepare.js` /
943
- `epic-execute-record-wave.js`; never write run state elsewhere.
944
- - **Always** post a friction structured comment before a non-`complete`
945
- outcome.
946
- - **Always** auto-invoke the epic-audit, code-review, and retro helpers
947
- (Phases 4–6) when their artefacts aren't already present.
948
- - **Always** run the Phase 6.5 integration gate after the wave loop
949
- reports `epic-complete` and before Phase 7 finalize (unless
950
- `--skip-integration-gate`); **never** open the PR while the gate
951
- reports a hard failure (orphaned surface, dead nav href, broken
952
- journey, or a surface-adding Epic with only `@pending` AC coverage).
953
- - **Always** drive Phase 8 to green CI before returning control — the
954
- host LLM owns the loop until the PR is mergeable or the Epic is
955
- parked at `agent::blocked`.