mandrel 1.94.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 (393) hide show
  1. package/.agents/README.md +59 -73
  2. package/.agents/agents/story-worker.md +12 -13
  3. package/.agents/docs/SDLC.md +489 -1285
  4. package/.agents/docs/agentrc-reference.json +177 -67
  5. package/.agents/docs/configuration.md +104 -138
  6. package/.agents/docs/execution-reference.md +17 -20
  7. package/.agents/docs/quality-gates.md +13 -19
  8. package/.agents/docs/workflows.md +3 -3
  9. package/.agents/instructions.md +70 -81
  10. package/.agents/rules/ci-remediation.md +8 -12
  11. package/.agents/rules/git-conventions-reference.md +6 -7
  12. package/.agents/rules/git-conventions.md +16 -22
  13. package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
  14. package/.agents/schemas/agentrc.schema.json +54 -214
  15. package/.agents/schemas/lifecycle/ledger-record.schema.json +1 -1
  16. package/.agents/schemas/lifecycle/retro.end.schema.json +1 -1
  17. package/.agents/schemas/risk-verdict.schema.json +0 -13
  18. package/.agents/scripts/analyze-execution.js +1 -1
  19. package/.agents/scripts/audit-to-stories.js +7 -7
  20. package/.agents/scripts/boot-sweep.js +1 -1
  21. package/.agents/scripts/check-lifecycle-lint.js +6 -9
  22. package/.agents/scripts/check-prepush-recovery.js +1 -1
  23. package/.agents/scripts/cleanup-repo-test-temp.js +6 -1
  24. package/.agents/scripts/lib/Logger.js +6 -10
  25. package/.agents/scripts/lib/audit-suite/runner.js +2 -2
  26. package/.agents/scripts/lib/audit-suite/selector.js +5 -5
  27. package/.agents/scripts/lib/audit-to-stories/{seed-epic-from-findings.js → seed-from-findings.js} +9 -9
  28. package/.agents/scripts/lib/baselines/kernel.js +206 -18
  29. package/.agents/scripts/lib/baselines/kinds/maintainability.js +0 -4
  30. package/.agents/scripts/lib/baselines/reader.js +1 -6
  31. package/.agents/scripts/lib/bdd-runner-detect.js +5 -9
  32. package/.agents/scripts/lib/bootstrap/issue-forms-template.js +32 -33
  33. package/.agents/scripts/lib/checks/core-bare-clean.js +2 -2
  34. package/.agents/scripts/lib/checks/index.js +2 -1
  35. package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +23 -21
  36. package/.agents/scripts/lib/cli/standard-args.js +13 -22
  37. package/.agents/scripts/lib/cli-args.js +16 -7
  38. package/.agents/scripts/lib/close-validation/gates.js +2 -2
  39. package/.agents/scripts/lib/config/ci.js +6 -31
  40. package/.agents/scripts/lib/config/delivery-routing.js +45 -29
  41. package/.agents/scripts/lib/config/explain.js +55 -36
  42. package/.agents/scripts/lib/config/limits.js +17 -58
  43. package/.agents/scripts/lib/config/paths.js +0 -2
  44. package/.agents/scripts/lib/config/quality.js +1 -1
  45. package/.agents/scripts/lib/config/runners.js +17 -50
  46. package/.agents/scripts/lib/config/temp-paths.js +19 -14
  47. package/.agents/scripts/lib/config/worktree-isolation.js +0 -5
  48. package/.agents/scripts/lib/config-resolver.js +2 -7
  49. package/.agents/scripts/lib/config-settings-schema-delivery.js +24 -148
  50. package/.agents/scripts/lib/config-settings-schema-quality.js +8 -14
  51. package/.agents/scripts/lib/config-settings-schema.js +52 -38
  52. package/.agents/scripts/lib/dependency-parser.js +3 -2
  53. package/.agents/scripts/lib/doc-tiers.js +2 -2
  54. package/.agents/scripts/lib/duplicate-search.js +211 -41
  55. package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +1 -1
  56. package/.agents/scripts/lib/findings/promote-finding.js +5 -5
  57. package/.agents/scripts/lib/framework-version.js +2 -3
  58. package/.agents/scripts/lib/git-branch-cleanup.js +1 -10
  59. package/.agents/scripts/lib/git-branch-lifecycle.js +17 -22
  60. package/.agents/scripts/lib/git-utils.js +32 -6
  61. package/.agents/scripts/lib/github/framework-repo.js +6 -0
  62. package/.agents/scripts/lib/label-constants.js +10 -23
  63. package/.agents/scripts/lib/label-taxonomy.js +9 -43
  64. package/.agents/scripts/lib/observability/active-story-env.js +1 -1
  65. package/.agents/scripts/lib/observability/hook-heartbeat.js +20 -52
  66. package/.agents/scripts/lib/observability/source-classifier.js +3 -3
  67. package/.agents/scripts/lib/onboard/init-tail.js +1 -3
  68. package/.agents/scripts/lib/orchestration/audit-lens-routing.js +128 -0
  69. package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +8 -5
  70. package/.agents/scripts/lib/orchestration/ceremony-routing.js +83 -20
  71. package/.agents/scripts/lib/orchestration/code-review.js +20 -268
  72. package/.agents/scripts/lib/orchestration/column-sync.js +1 -1
  73. package/.agents/scripts/lib/orchestration/consolidation-precondition.js +1 -1
  74. package/.agents/scripts/lib/orchestration/context-envelope.js +2 -5
  75. package/.agents/scripts/lib/orchestration/docs-digest.js +8 -8
  76. package/.agents/scripts/lib/orchestration/file-assumptions.js +7 -13
  77. package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +1 -1
  78. package/.agents/scripts/lib/orchestration/lifecycle/emit-loop-tick.js +8 -8
  79. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +2 -2
  80. package/.agents/scripts/lib/orchestration/lifecycle/ledger-writer.js +6 -3
  81. package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +17 -43
  82. package/.agents/scripts/lib/orchestration/lint-baseline-service.js +4 -4
  83. package/.agents/scripts/lib/orchestration/merge-block-class.js +1 -1
  84. package/.agents/scripts/lib/orchestration/phase-runner.js +3 -2
  85. package/.agents/scripts/lib/orchestration/plan-context.js +248 -266
  86. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +1 -1
  87. package/.agents/scripts/lib/orchestration/plan-navigation.js +92 -0
  88. package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +61 -0
  89. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +97 -0
  90. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +223 -854
  91. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +361 -0
  92. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +35 -108
  93. package/.agents/scripts/lib/orchestration/plan-reachability.js +9 -14
  94. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +1 -1
  95. package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/authoring-context.js +13 -13
  96. package/.agents/scripts/lib/orchestration/planning/decomposer-context.js +27 -0
  97. package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/risk-verdict.js +3 -4
  98. package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +2 -2
  99. package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +8 -20
  100. package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +3 -2
  101. package/.agents/scripts/lib/orchestration/pr-base-guard.js +18 -28
  102. package/.agents/scripts/lib/orchestration/preflight-cache.js +5 -5
  103. package/.agents/scripts/lib/orchestration/remote-verifier.js +1 -1
  104. package/.agents/scripts/lib/orchestration/resolve-plan-run.js +155 -0
  105. package/.agents/scripts/lib/orchestration/resolves-token.js +1 -1
  106. package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +8 -8
  107. package/.agents/scripts/lib/orchestration/retro-proposals.js +140 -79
  108. package/.agents/scripts/lib/orchestration/review-depth.js +26 -12
  109. package/.agents/scripts/lib/orchestration/review-providers/codex.js +2 -2
  110. package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +21 -56
  111. package/.agents/scripts/lib/orchestration/run-epilogue.js +426 -0
  112. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +1 -1
  113. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +95 -41
  114. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +16 -13
  115. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +40 -0
  116. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +11 -3
  117. package/.agents/scripts/lib/orchestration/spec-freshness.js +14 -205
  118. package/.agents/scripts/lib/orchestration/spec-section-validator.js +4 -5
  119. package/.agents/scripts/lib/orchestration/spec-spill.js +60 -0
  120. package/.agents/scripts/lib/orchestration/split-policy-validator.js +188 -0
  121. package/.agents/scripts/lib/orchestration/story-close/emit-blocked.js +49 -0
  122. package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +15 -12
  123. package/.agents/scripts/lib/orchestration/story-follow-ups.js +237 -0
  124. package/.agents/scripts/lib/orchestration/story-init-remote.js +47 -0
  125. package/.agents/scripts/lib/orchestration/story-plan-state.js +48 -0
  126. package/.agents/scripts/lib/orchestration/{epic-runner → story-progress}/story-run-progress-writer.js +3 -3
  127. package/.agents/scripts/lib/orchestration/structured-comment-parser.js +1 -1
  128. package/.agents/scripts/lib/orchestration/task-body-validator.js +8 -18
  129. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +11 -61
  130. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +189 -373
  131. package/.agents/scripts/lib/orchestration/ticket-validator.js +2 -7
  132. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +0 -25
  133. package/.agents/scripts/lib/orchestration/ticketing/reads.js +29 -26
  134. package/.agents/scripts/lib/orchestration/ticketing/transition.js +5 -5
  135. package/.agents/scripts/lib/planning-corpus.js +16 -11
  136. package/.agents/scripts/lib/preflight-runner.js +2 -2
  137. package/.agents/scripts/lib/qa/coverage-verdict.js +5 -5
  138. package/.agents/scripts/lib/single-story/confirm-merge-follow-ups.js +36 -0
  139. package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +1 -1
  140. package/.agents/scripts/lib/story-adjacency.js +11 -14
  141. package/.agents/scripts/lib/story-body/story-body.js +124 -70
  142. package/.agents/scripts/lib/story-plan.js +2 -4
  143. package/.agents/scripts/lib/templates/decomposer-prompts.js +46 -45
  144. package/.agents/scripts/lib/templates/spec-author-prompts.js +47 -45
  145. package/.agents/scripts/lib/{epic-body-sections.js → ticket-body-sections.js} +26 -26
  146. package/.agents/scripts/lib/validation-evidence.js +1 -1
  147. package/.agents/scripts/lib/wave-runner/ready-set.js +6 -6
  148. package/.agents/scripts/lib/workspace-provisioner.js +1 -1
  149. package/.agents/scripts/lib/worktree/lifecycle/reap.js +5 -7
  150. package/.agents/scripts/lint-issue-body.js +71 -40
  151. package/.agents/scripts/mandrel-update-preflight.js +1 -1
  152. package/.agents/scripts/notify.js +4 -3
  153. package/.agents/scripts/plan-context.js +64 -74
  154. package/.agents/scripts/plan-persist.js +121 -280
  155. package/.agents/scripts/plan-run-epilogue.js +97 -0
  156. package/.agents/scripts/providers/github/issues.js +17 -33
  157. package/.agents/scripts/providers/github/mappers.js +0 -12
  158. package/.agents/scripts/providers/github/tickets.js +2 -5
  159. package/.agents/scripts/resolve-plan-run.js +117 -0
  160. package/.agents/scripts/signals-view.js +24 -19
  161. package/.agents/scripts/single-story-close.js +11 -14
  162. package/.agents/scripts/single-story-confirm-merge.js +39 -23
  163. package/.agents/scripts/single-story-init.js +29 -20
  164. package/.agents/scripts/stories-wave-tick.js +6 -6
  165. package/.agents/scripts/story-plan.js +26 -47
  166. package/.agents/scripts/update-ticket-state.js +6 -15
  167. package/.agents/skills/core/analyze-execution/SKILL.md +21 -18
  168. package/.agents/skills/core/idea-refinement/SKILL.md +6 -6
  169. package/.agents/skills/core/scope-triage/SKILL.md +28 -172
  170. package/.agents/skills/skills.index.json +3 -43
  171. package/.agents/starter-agentrc.json +0 -5
  172. package/.agents/templates/agent-protocol.md +9 -10
  173. package/.agents/workflows/audit-architecture.md +3 -3
  174. package/.agents/workflows/audit-clean-code.md +3 -3
  175. package/.agents/workflows/audit-dependencies.md +3 -3
  176. package/.agents/workflows/audit-devops.md +3 -3
  177. package/.agents/workflows/audit-documentation.md +5 -5
  178. package/.agents/workflows/audit-lighthouse.md +3 -3
  179. package/.agents/workflows/audit-navigability.md +3 -2
  180. package/.agents/workflows/audit-performance.md +3 -3
  181. package/.agents/workflows/audit-privacy.md +3 -3
  182. package/.agents/workflows/audit-quality.md +3 -3
  183. package/.agents/workflows/audit-security.md +3 -3
  184. package/.agents/workflows/audit-seo.md +3 -3
  185. package/.agents/workflows/audit-sre.md +3 -3
  186. package/.agents/workflows/audit-to-stories.md +20 -20
  187. package/.agents/workflows/audit-ux-ui.md +3 -3
  188. package/.agents/workflows/deliver.md +122 -174
  189. package/.agents/workflows/git-cleanup.md +3 -4
  190. package/.agents/workflows/helpers/_merge-conflict-template.md +1 -1
  191. package/.agents/workflows/helpers/acceptance-self-eval.md +16 -29
  192. package/.agents/workflows/helpers/code-review.md +70 -193
  193. package/.agents/workflows/helpers/{single-story-deliver-reference.md → deliver-story-reference.md} +12 -14
  194. package/.agents/workflows/helpers/{single-story-deliver.md → deliver-story.md} +113 -139
  195. package/.agents/workflows/helpers/diagnose.md +10 -10
  196. package/.agents/workflows/helpers/parallel-tooling.md +1 -1
  197. package/.agents/workflows/helpers/signals.md +16 -16
  198. package/.agents/workflows/helpers/worktree-lifecycle.md +48 -64
  199. package/.agents/workflows/mandrel-update.md +2 -1
  200. package/.agents/workflows/plan.md +112 -145
  201. package/.agents/workflows/qa-assist.md +24 -30
  202. package/.agents/workflows/qa-explore.md +29 -38
  203. package/.agents/workflows/qa-run.md +2 -2
  204. package/README.md +9 -8
  205. package/docs/CHANGELOG.md +30 -0
  206. package/lib/migrations/index.js +6 -5
  207. package/package.json +2 -2
  208. package/.agents/agents/retro.md +0 -42
  209. package/.agents/personas/architect.md +0 -113
  210. package/.agents/personas/devops-engineer.md +0 -38
  211. package/.agents/personas/engineer.md +0 -33
  212. package/.agents/personas/project-manager.md +0 -114
  213. package/.agents/personas/qa-engineer.md +0 -95
  214. package/.agents/personas/security-engineer.md +0 -111
  215. package/.agents/personas/technical-writer.md +0 -101
  216. package/.agents/schemas/dispatch-manifest.json +0 -232
  217. package/.agents/schemas/epic-spec.schema.json +0 -153
  218. package/.agents/schemas/lifecycle/slice.end.schema.json +0 -21
  219. package/.agents/schemas/lifecycle/slice.heartbeat.schema.json +0 -20
  220. package/.agents/schemas/lifecycle/slice.start.schema.json +0 -17
  221. package/.agents/scripts/acceptance-spec-reconciler.js +0 -642
  222. package/.agents/scripts/bookkeeping-reconcile.js +0 -117
  223. package/.agents/scripts/dispatcher.js +0 -295
  224. package/.agents/scripts/epic-audit-prepare.js +0 -497
  225. package/.agents/scripts/epic-audit-recheck.js +0 -274
  226. package/.agents/scripts/epic-deliver-note-intervention.js +0 -192
  227. package/.agents/scripts/epic-deliver-preflight.js +0 -462
  228. package/.agents/scripts/epic-deliver-prepare.js +0 -852
  229. package/.agents/scripts/epic-execute-record-wave.js +0 -449
  230. package/.agents/scripts/epic-plan-clarity.js +0 -211
  231. package/.agents/scripts/epic-plan-healthcheck.js +0 -581
  232. package/.agents/scripts/epic-reconcile.js +0 -625
  233. package/.agents/scripts/lib/baseline-snapshot.js +0 -979
  234. package/.agents/scripts/lib/checks/epic-merge-lock-stale.js +0 -54
  235. package/.agents/scripts/lib/checks/stale-origin-epic.js +0 -49
  236. package/.agents/scripts/lib/config/lifecycle.js +0 -40
  237. package/.agents/scripts/lib/config/preflight.js +0 -58
  238. package/.agents/scripts/lib/config/retro.js +0 -77
  239. package/.agents/scripts/lib/epic-merge-lock.js +0 -322
  240. package/.agents/scripts/lib/epic-plan-clarity.js +0 -181
  241. package/.agents/scripts/lib/epic-plan-ideation.js +0 -261
  242. package/.agents/scripts/lib/orchestration/context-hydration-engine.js +0 -539
  243. package/.agents/scripts/lib/orchestration/deliver-route.js +0 -173
  244. package/.agents/scripts/lib/orchestration/dispatch-engine.js +0 -134
  245. package/.agents/scripts/lib/orchestration/dispatch-pipeline.js +0 -183
  246. package/.agents/scripts/lib/orchestration/epic-cleanup.js +0 -801
  247. package/.agents/scripts/lib/orchestration/epic-deliver-lease-guard.js +0 -310
  248. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/context.js +0 -163
  249. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/creation.js +0 -140
  250. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/dag.js +0 -64
  251. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/diagnostics.js +0 -72
  252. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +0 -156
  253. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist.js +0 -345
  254. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +0 -41
  255. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/reconcile-spawn.js +0 -86
  256. package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +0 -391
  257. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/drain.js +0 -94
  258. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +0 -236
  259. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +0 -307
  260. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-freshness.js +0 -117
  261. package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +0 -117
  262. package/.agents/scripts/lib/orchestration/epic-run-state-store.js +0 -621
  263. package/.agents/scripts/lib/orchestration/epic-runner/concurrency-gate.js +0 -186
  264. package/.agents/scripts/lib/orchestration/epic-runner/deliver-phases.js +0 -50
  265. package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +0 -129
  266. package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +0 -103
  267. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/composition.js +0 -267
  268. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/signals.js +0 -210
  269. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/transport.js +0 -238
  270. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/_bullet-format.js +0 -32
  271. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/component-drift.js +0 -203
  272. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/crap-drift.js +0 -227
  273. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/maintainability-drift.js +0 -117
  274. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/stalled-worktree.js +0 -37
  275. package/.agents/scripts/lib/orchestration/epic-runner/story-launcher.js +0 -127
  276. package/.agents/scripts/lib/orchestration/epic-runner/sub-agent-return.js +0 -276
  277. package/.agents/scripts/lib/orchestration/epic-runner/wave-scheduler.js +0 -66
  278. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-apply.js +0 -789
  279. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +0 -676
  280. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-discriminator.js +0 -389
  281. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-format.js +0 -230
  282. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-ops.js +0 -361
  283. package/.agents/scripts/lib/orchestration/finalize/open-or-locate-pr.js +0 -306
  284. package/.agents/scripts/lib/orchestration/finalize/post-handoff-comment.js +0 -489
  285. package/.agents/scripts/lib/orchestration/finalize/sanitize-skip-ci.js +0 -88
  286. package/.agents/scripts/lib/orchestration/lifecycle/emit-slice-lifecycle.js +0 -270
  287. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-dispatch-end.js +0 -147
  288. package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +0 -465
  289. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +0 -501
  290. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +0 -984
  291. package/.agents/scripts/lib/orchestration/lifecycle/listeners/branch-cleaner.js +0 -264
  292. package/.agents/scripts/lib/orchestration/lifecycle/listeners/checkpoint-pointer-writer.js +0 -284
  293. package/.agents/scripts/lib/orchestration/lifecycle/listeners/cleaner.js +0 -355
  294. package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +0 -673
  295. package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +0 -378
  296. package/.agents/scripts/lib/orchestration/lifecycle/listeners/intervention-recorder.js +0 -140
  297. package/.agents/scripts/lib/orchestration/lifecycle/listeners/label-transitioner.js +0 -144
  298. package/.agents/scripts/lib/orchestration/lifecycle/listeners/notify-dispatcher.js +0 -174
  299. package/.agents/scripts/lib/orchestration/manifest-builder.js +0 -222
  300. package/.agents/scripts/lib/orchestration/plan-persist/amend.js +0 -359
  301. package/.agents/scripts/lib/orchestration/plan-persist/delivery-mode.js +0 -127
  302. package/.agents/scripts/lib/orchestration/post-merge-pipeline.js +0 -205
  303. package/.agents/scripts/lib/orchestration/recurring-failure-detector.js +0 -152
  304. package/.agents/scripts/lib/orchestration/retro/phases/checks.js +0 -94
  305. package/.agents/scripts/lib/orchestration/retro/phases/compose-body.js +0 -571
  306. package/.agents/scripts/lib/orchestration/retro/phases/gather-signals.js +0 -450
  307. package/.agents/scripts/lib/orchestration/retro/phases/post-and-mirror.js +0 -191
  308. package/.agents/scripts/lib/orchestration/retro-heuristics.js +0 -57
  309. package/.agents/scripts/lib/orchestration/retro-runner.js +0 -197
  310. package/.agents/scripts/lib/orchestration/spec-renderer.js +0 -447
  311. package/.agents/scripts/lib/orchestration/story-close/auto-refresh-runner.js +0 -747
  312. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/gate-failure.js +0 -211
  313. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/pre-merge-attribution.js +0 -158
  314. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +0 -446
  315. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/regression-projection.js +0 -297
  316. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/scope-discovery.js +0 -48
  317. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution-wiring.js +0 -67
  318. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution.js +0 -161
  319. package/.agents/scripts/lib/orchestration/story-close/baseline-friction-body.js +0 -117
  320. package/.agents/scripts/lib/orchestration/story-close/cd-out-guard.js +0 -86
  321. package/.agents/scripts/lib/orchestration/story-close/cleanup-reconciler.js +0 -147
  322. package/.agents/scripts/lib/orchestration/story-close/close-inputs.js +0 -142
  323. package/.agents/scripts/lib/orchestration/story-close/comment-bodies.js +0 -62
  324. package/.agents/scripts/lib/orchestration/story-close/merge-runner.js +0 -658
  325. package/.agents/scripts/lib/orchestration/story-close/merge-subject.js +0 -198
  326. package/.agents/scripts/lib/orchestration/story-close/phases/branch-restore.js +0 -105
  327. package/.agents/scripts/lib/orchestration/story-close/phases/close.js +0 -222
  328. package/.agents/scripts/lib/orchestration/story-close/phases/gates.js +0 -292
  329. package/.agents/scripts/lib/orchestration/story-close/phases/locked-pipeline.js +0 -270
  330. package/.agents/scripts/lib/orchestration/story-close/phases/preflight.js +0 -110
  331. package/.agents/scripts/lib/orchestration/story-close/phases/refresh.js +0 -86
  332. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked-emitter.js +0 -112
  333. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked.js +0 -157
  334. package/.agents/scripts/lib/orchestration/story-close/post-merge-close.js +0 -421
  335. package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +0 -302
  336. package/.agents/scripts/lib/orchestration/story-close/shared-checkout-guard.js +0 -163
  337. package/.agents/scripts/lib/orchestration/story-close-recovery.js +0 -690
  338. package/.agents/scripts/lib/orchestration/wave-marker.js +0 -28
  339. package/.agents/scripts/lib/orchestration/wave-record-io.js +0 -218
  340. package/.agents/scripts/lib/orchestration/wave-record-notifications.js +0 -145
  341. package/.agents/scripts/lib/orchestration/wave-record-projection.js +0 -212
  342. package/.agents/scripts/lib/presentation/dispatch-manifest-render.js +0 -111
  343. package/.agents/scripts/lib/presentation/manifest-builder.js +0 -239
  344. package/.agents/scripts/lib/presentation/manifest-formatter.js +0 -242
  345. package/.agents/scripts/lib/presentation/manifest-helpers.js +0 -213
  346. package/.agents/scripts/lib/presentation/manifest-persistence.js +0 -261
  347. package/.agents/scripts/lib/presentation/manifest-procedures.js +0 -55
  348. package/.agents/scripts/lib/presentation/manifest-render-waves.js +0 -306
  349. package/.agents/scripts/lib/presentation/manifest-renderer.js +0 -188
  350. package/.agents/scripts/lib/presentation/manifest-story-views.js +0 -110
  351. package/.agents/scripts/lib/push-epic-retry.js +0 -209
  352. package/.agents/scripts/lib/spec/index.js +0 -36
  353. package/.agents/scripts/lib/spec/loader.js +0 -425
  354. package/.agents/scripts/lib/spec/state.js +0 -208
  355. package/.agents/scripts/lib/story-init/blocker-validator.js +0 -68
  356. package/.agents/scripts/lib/story-init/branch-initializer.js +0 -408
  357. package/.agents/scripts/lib/story-init/context-resolver.js +0 -92
  358. package/.agents/scripts/lib/story-init/donor-precheck.js +0 -207
  359. package/.agents/scripts/lib/story-init/state-transitioner.js +0 -80
  360. package/.agents/scripts/lib/story-init/task-graph-builder.js +0 -124
  361. package/.agents/scripts/lib/story-init/transition-summary.js +0 -34
  362. package/.agents/scripts/lib/test-reserved-epic-temp-ids.js +0 -35
  363. package/.agents/scripts/lib/wave-runner/tick.js +0 -754
  364. package/.agents/scripts/lib/wave-runner/wave-runner-error.js +0 -20
  365. package/.agents/scripts/lifecycle-emit-story-dispatch.js +0 -194
  366. package/.agents/scripts/lifecycle-emit.js +0 -510
  367. package/.agents/scripts/retro-run.js +0 -218
  368. package/.agents/scripts/slice-phase.js +0 -361
  369. package/.agents/scripts/standalone-feedback-rollup.js +0 -188
  370. package/.agents/scripts/story-close.js +0 -294
  371. package/.agents/scripts/story-init.js +0 -599
  372. package/.agents/scripts/story-phase.js +0 -369
  373. package/.agents/scripts/wave-tick.js +0 -464
  374. package/.agents/skills/core/epic-plan-consolidate/SKILL.md +0 -172
  375. package/.agents/skills/core/epic-plan-consolidate/examples.md +0 -51
  376. package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +0 -441
  377. package/.agents/skills/core/epic-plan-decompose-author/examples.md +0 -47
  378. package/.agents/skills/core/epic-plan-premortem/SKILL.md +0 -146
  379. package/.agents/skills/core/epic-plan-premortem/examples.md +0 -53
  380. package/.agents/skills/core/epic-plan-spec-author/SKILL.md +0 -383
  381. package/.agents/skills/core/epic-plan-spec-author/examples.md +0 -91
  382. package/.agents/workflows/helpers/deliver-epic-reference.md +0 -547
  383. package/.agents/workflows/helpers/deliver-epic-single.md +0 -331
  384. package/.agents/workflows/helpers/deliver-epic.md +0 -998
  385. package/.agents/workflows/helpers/deliver-stories.md +0 -450
  386. package/.agents/workflows/helpers/epic-audit.md +0 -189
  387. package/.agents/workflows/helpers/epic-deliver-story.md +0 -436
  388. package/.agents/workflows/helpers/epic-testing.md +0 -125
  389. package/.agents/workflows/helpers/plan-epic-reference.md +0 -160
  390. package/.agents/workflows/helpers/plan-epic.md +0 -353
  391. package/.agents/workflows/helpers/plan-story.md +0 -251
  392. package/.agents/workflows/helpers/scope-triage-gate.md +0 -108
  393. /package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/spec-authoring-grounding.js +0 -0
@@ -1,91 +0,0 @@
1
- # epic-plan-spec-author — examples & extended rationale
2
-
3
- Read this file on demand while authoring the Tech Spec. The SKILL.md carries
4
- the operating contract (Policy Capsule, Inputs / Outputs, Procedure, the two
5
- authoritative system prompts, and Constraints); this file carries the worked
6
- Delivery Slicing example and the extended rationale behind the slicing rules.
7
-
8
- ## Delivery Slicing — extended rationale
9
-
10
- The Tech Spec MUST carry a `## Delivery Slicing` section in which the Architect
11
- — who holds the full design — proposes how the Epic's enumerated capabilities
12
- **cluster into N shippable Stories**. This section is the intentional grouping
13
- the Phase 8 consolidation pass
14
- ([`epic-plan-consolidate`](../epic-plan-consolidate/SKILL.md)) reconciles the
15
- decomposer's draft against before any GitHub write. Without it, the decompose
16
- phase maps Epic capabilities to Stories ~1:1 and cannot produce a coarser,
17
- holistic plan; with it, the consolidation critic has a well-defined reference
18
- instead of a guess.
19
-
20
- **The proposed count is a ceiling, not a target.** Consolidation reconciles
21
- the draft *toward* your grouping, but it treats the count as an upper bound: it
22
- may **merge below** your proposed count when slices form dependent
23
- single-consumer chains, and it **never splits above** it. Over-slicing here
24
- therefore locks in fragmentation only when the extra slices are genuinely
25
- independent — so keep a slice separate only when it earns its own delivery
26
- session.
27
-
28
- **Write the Delivery Slicing section before any other section — it is the
29
- primary input to Phase 8 consolidation.** Author it first so the rest of the
30
- spec (Core Components, API Changes, Data Models) hangs off a deliberate
31
- slicing decision rather than being reverse-engineered into one at the end.
32
- Drafting it last is exactly how the model omits it under the weight of the
33
- other sections.
34
-
35
- Author the section as a table — one row per proposed slice — naming the
36
- capability cluster each slice would deliver, what ships in it, and whether it
37
- can ship independently. Use **noun phrases** for slice names ("Foundation",
38
- "Transport seam", "Send helper") so they map cleanly onto Feature titles in the
39
- resulting decomposition — never verb phrases ("Add transport") or file names
40
- ("`sender.ts`"). Do **not** coarsen the Epic's capability enumeration to produce
41
- the slicing: the granularity lever is *this* grouping recommendation, not a
42
- dumbed-down Epic enumeration.
43
-
44
- **What "Independent?" means:** can this slice ship to production and provide
45
- value *without the next slice landing*? A `Yes` slice is releasable on its own;
46
- a `No` slice only becomes valuable once a later slice lands on top of it.
47
-
48
- **"Independent? No" is a smell that must be justified.** A dependent,
49
- single-consumer slice (one that only feeds the next slice) folds into its
50
- consumer by default — it is not worth its own delivery session's hydration,
51
- branch, PR, and CI ceremony. Mark a slice `No` only when you can name a
52
- one-line reason to keep it separate anyway: **parallelism** (two `No` slices
53
- that can be delivered concurrently by different sessions), **risk isolation**
54
- (a blast-radius or reviewability reason to land it as its own reviewable PR),
55
- or **delivery-envelope pressure** (folding it in would push the consumer past a
56
- single-session sizing envelope). Absent such a justification, do not author the
57
- slice as its own row — fold it into its consumer and let the merged slice carry
58
- the combined capability.
59
-
60
- ### Worked example
61
-
62
- ```text
63
- ## Delivery Slicing
64
-
65
- Proposed shippable slices (consolidation ceiling for Phase 8):
66
-
67
- | Slice | What ships | Independent? |
68
- | -------------- | ------------------------------------------------------ | ------------ |
69
- | Foundation | Config schema, types, and the no-op default path | Yes |
70
- | Transport seam | The pluggable transport interface + in-memory adapter | Yes |
71
- | Send helper | The send() helper + retries, built on the transport | No (justified: risk isolation) |
72
-
73
- - **Foundation** folds Epic capabilities "config surface" + "type model" — they
74
- share a reason to exist and ship as one reviewable PR.
75
- - **Transport seam** is the pluggable boundary; it provides value on its own
76
- (in-memory adapter is usable for tests) so it is independently shippable.
77
- - **Send helper** depends on the transport seam landing first, so it is *not*
78
- independent. It stays its own slice only because the retry/backoff logic is a
79
- large, high-blast-radius surface worth isolating in its own reviewable PR
80
- (risk isolation). Absent that justification it would fold into Transport
81
- seam — a bare "depends on the previous slice" is not a reason to keep it
82
- separate.
83
- ```
84
-
85
- The consolidation pass degrades gracefully when this section is absent (it
86
- falls back to cohesion + single-Story-Feature rules only), so authoring it is
87
- how the Architect steers the decomposition toward fewer, right-sized Stories.
88
- Because the count is a **ceiling**, an over-sliced table is coarsened back
89
- during consolidation — but only where the extra slices are dependent
90
- single-consumer chains, so an unjustified `No` slice is the one you should fold
91
- in yourself rather than leaning on the consolidator to catch.
@@ -1,547 +0,0 @@
1
- ---
2
- description: >-
3
- Reference companion to `helpers/deliver-epic.md` — the recovery
4
- procedures, historical rationale, and troubleshooting detail lifted out
5
- of the runtime core so the always-ingested Epic-delivery prose stays lean.
6
- Not a slash command; consulted on demand when the core file points here.
7
- caller: helpers/deliver-epic.md
8
- ---
9
-
10
- # helpers/deliver-epic — reference (recovery, rationale, troubleshooting)
11
-
12
- > **Not a slash command, not the runtime path.** This file is the
13
- > reference companion to [`deliver-epic.md`](deliver-epic.md). The core
14
- > file carries the phase flow, commands, gate contracts, and return shapes
15
- > a `/deliver` run needs on every beat; this file holds the recovery
16
- > procedures, the "why it works this way" rationale, and the
17
- > troubleshooting detail the core points at with one-line pointers. Read a
18
- > section here only when the matching pointer in the core sends you.
19
-
20
- ---
21
-
22
- ## Phase 1 — Preflight guards (Story #3482 / F-workflow-guards)
23
-
24
- Before the snapshot phase runs — and before any worktree is created —
25
- `epic-deliver-prepare.js` runs two **fail-closed** guards
26
- ([`lib/orchestration/epic-deliver-lease-guard.js`](../../scripts/lib/orchestration/epic-deliver-lease-guard.js)):
27
-
28
- 1. **Checkout safety.** Prepare refuses to start when the working tree is
29
- dirty or HEAD is on a branch other than the expected one (`epic/<id>`
30
- on a resume, or the project base branch on a fresh run). It will
31
- **not** check `epic/<id>` out over your work — the historic
32
- HEAD-yank footgun. Remediation: commit/stash/clean the tree, or
33
- switch to the expected branch, then re-run.
34
- 2. **Epic lease.** Prepare acquires the assignee-as-lease on the Epic
35
- ticket (`ticket-lease.acquireLease`). On a **live foreign claim**
36
- (a teammate's run with a fresh `story.heartbeat` within
37
- `delivery.lease.ttlMs`) it exits non-zero and names the current owner;
38
- a **stale** claim is silently reclaimed. The operator identity is
39
- resolved from `--as <handle>` → `github.operatorHandle` →
40
- `git config user.email`. Pass `--steal` to forcibly transfer a live
41
- foreign claim (the takeover is logged for auditability). The committed
42
- `github.operatorHandle` is the non-personal `@[USERNAME]` placeholder,
43
- which resolves to null — so when none of the three sources yields a real
44
- identity the guard **fails closed** (throws after the checkout guard
45
- runs) rather than driving an ownerless, unguarded delivery. Set your own
46
- handle in `.agentrc.local.json`, pass `--as <handle>`, or configure
47
- `git user.email`. The lease is the cross-clone coordination layer, while
48
- `epic-merge-lock.js` continues to serialize same-machine sessions.
49
-
50
- Both guards throw on failure, which `runAsCli` maps to `process.exit(1)`
51
- per [`orchestration-error-handling.md`](../../rules/orchestration-error-handling.md).
52
-
53
- ### Acceptance-table start gate
54
-
55
- Once the preflight guards pass, the snapshot phase applies one more gate.
56
- Before the wave loop fans out, the snapshot phase
57
- ([`lib/orchestration/epic-runner/phases/snapshot.js`](../../scripts/lib/orchestration/epic-runner/phases/snapshot.js))
58
- asserts that the Epic either carries the `acceptance::n-a` waiver label
59
- **or** has a `## Acceptance Table` managed section in its body — section
60
- presence is sufficient. The reviewer's OK during `/plan` Phase 7 is the
61
- approval signal. Neither condition met → the snapshot throws a clear error
62
- (`[epic-deliver] Epic #<id> cannot launch: …` — naming the missing
63
- `## Acceptance Table` section and the absent waiver) and `runAsCli` maps it
64
- to `process.exit(1)`. Operator remediation: either run `/plan` Phase 7 to
65
- author the acceptance table, or apply the `acceptance::n-a` label to opt
66
- out.
67
-
68
- ---
69
-
70
- ## Phase 2 — Dispatch rationale and recovery
71
-
72
- ### Throughput tradeoff
73
-
74
- The default `concurrencyCap` of 3 is the GLOBAL in-flight cap,
75
- intentionally conservative — it keeps host-quota consumption low and avoids
76
- flooding the GitHub API. For Epics with wide dependency-free fronts where
77
- the host has adequate parallel-agent quota, raising
78
- `delivery.deliverRunner.concurrencyCap` in `.agentrc.json` reduces
79
- wall-clock time proportionally to the extra concurrency. The safe default
80
- is left in place; this is a deliberate operator-tuning knob, not a hidden
81
- performance ceiling. See `agentrc-reference.json`
82
- `delivery.deliverRunner.concurrencyCap` for the configuration surface.
83
-
84
- ### Sub-agent dispatch capability
85
-
86
- `Agent` calls emit no `model:` argument by default — children inherit from
87
- their sub-agent definition and the parent's worktree context. With
88
- `delivery.routing.roleScopedAgents` on (the default, Epic #4478), a Story child
89
- boots on the role-scoped [`story-worker`](../../agents/story-worker.md)
90
- definition — its own system prompt, no `CLAUDE.md` @-closure — instead of the
91
- full-closure `general-purpose` definition the kill-switch (`roleScopedAgents:
92
- false`) falls back to. No `--dangerously-skip-permissions` (no subprocess is
93
- spawned).
94
- Per [`.agents/instructions.md` § 4](../../instructions.md)'s cost-aware
95
- spawning heuristic, this optional per-call `model:` is the escape hatch: if
96
- a specific call would run better on a cheaper or faster capability the host
97
- exposes (a mechanical or read-only Story), pass `model:` as a per-call
98
- literal at the `Agent(...)` site. This is **guidance only** — it adds no
99
- config key, requires no model argument, and names no specific model; the
100
- host and operator own the concrete choice.
101
-
102
- ### Fail-closed on an old-shape checkpoint
103
-
104
- If the Epic still carries a pre-ready-set (`plan` / `currentWave` /
105
- `totalWaves`) `epic-run-state` checkpoint, the tick **refuses to run** and
106
- throws an explicit operator message — re-run
107
- `epic-deliver-prepare.js --epic <id>` to re-seed the checkpoint in the
108
- per-Story-status shape, then re-run `/deliver`.
109
-
110
- ### Crash recovery (record step)
111
-
112
- If the host crashed *after* a child finished but *before* its return was
113
- recorded, the next `tick` re-derives that Story's state directly from its
114
- live label (the tick reads labels every beat), so a done-but-unrecorded
115
- Story is recognised as done and never re-dispatched — there is no
116
- falsely-`complete` empty wave to recover from. If you want to reconcile a
117
- known-completed Story whose return text was lost, re-record it from its
118
- live state by passing `--results '[{"storyId":<n>,"status":"done"}]'`
119
- (verification re-checks the live label before recording `done`).
120
-
121
- ### 2e. Idle Watchdog
122
-
123
- A Story's implementation loop can run for many minutes between
124
- `story.dispatch.start` and the post-merge `story.merged` record. While
125
- `observe` keeps the host LLM polling the Epic, it does **not** flag a
126
- sub-agent that has gone silent (host crash, mid-Story stall, lost
127
- return). The Idle Watchdog closes that gap.
128
-
129
- **Cadence.** While any Story is in flight (i.e. `nextAction.kind` is
130
- `observe` or the most recent dispatch's `in-flight` list is non-empty),
131
- re-tick every **30 minutes** with the watchdog flag:
132
-
133
- ```bash
134
- node .agents/scripts/wave-tick.js --epic <epicId> --check-idle 30
135
- ```
136
-
137
- > **Why 30, not 10 (Story #3900).** Heartbeats fire only at Story-level
138
- > phase transitions, and `implementing → closing` routinely exceeds 10
139
- > minutes for a healthy Story. A 10-minute threshold therefore tripped the
140
- > watchdog on every long-running Story, whose prescribed remediation —
141
- > re-dispatch — put two agents on one `story-<id>` branch (the worst
142
- > failure mode in the system). The threshold is widened to 30 minutes and
143
- > the staleness test now also consults a deterministic branch-commit
144
- > signal (below), so a Story still gaining commits is never flagged.
145
-
146
- The `--check-idle <minutes>` mode scans the per-Epic lifecycle ledger
147
- (`temp/epic-<epicId>/lifecycle.ndjson`) for Stories that carry a
148
- `story.dispatch.start` without a matching `story.dispatch.end` (the
149
- canonical in-flight list — see § 2a's `nextAction['in-flight']`), and
150
- compares each in-flight Story's most recent ledger event (any
151
- `story.*` event, notably the `story.heartbeat` records) against the
152
- threshold. **As of Epic #4476 (M5) those `story.heartbeat` records are
153
- emitted OFF the token stream by the PostToolUse hook** (a throttled
154
- heartbeat per tool call, keyed off the active-Story env) rather than by a
155
- per-transition `story-phase.js` LLM turn — the signal the watchdog reads is
156
- unchanged; only its emission mechanism moved. Single-delivery runs have no
157
- Story fan-out; their liveness signal is `slice.heartbeat` (same hook, keyed
158
- off the active-slice env), and the watchdog reads it via the additive
159
- `inFlightSlices` / `stalledSlices` envelope fields — a slice that has gone
160
- silent past the threshold with no recent commit on `epic-<id>` is flagged
161
- exactly as a stalled Story is. **Before flagging a stall, it also checks the last commit on
162
- `story-<id>` via `git log` (Story #3900): a Story whose branch carries a
163
- commit newer than the threshold is making forward progress and is left
164
- in-flight, never stalled — deterministic protection against the
165
- false-positive re-dispatch hazard even when no heartbeat has landed.**
166
- The CLI emits one envelope on stdout and exits non-zero when at least
167
- one in-flight Story has been silent for ≥ the threshold:
168
-
169
- ```json
170
- {
171
- "kind": "wave-stall",
172
- "epicId": <n>,
173
- "thresholdMinutes": <n>,
174
- "checkedAt": "<ISO-8601>",
175
- "stalled": [{ "storyId": <n>, "lastEventAt": "<ISO-8601>", "idleMinutes": <n> }],
176
- "inFlight": [<storyId>, ...]
177
- }
178
- ```
179
-
180
- **On a stall.** When the watchdog exits non-zero, post the envelope
181
- verbatim as a `wave-stall` structured comment on the Epic (use
182
- [`post-structured-comment.js`](../../scripts/post-structured-comment.js)
183
- with `--kind wave-stall`), then re-evaluate the affected Stories: if a
184
- child sub-agent has crashed (no `story.dispatch.end`, no recent
185
- heartbeat, no commit on `story-<id>`), re-dispatch the Story per § 2b of
186
- the core incrementing the `--attempt` counter; if the child is alive but
187
- genuinely blocked, flip the Story to `agent::blocked` and proceed per
188
- § 2d's `observe` branch.
189
-
190
- Stop the watchdog cadence once `wave-tick.js` returns `epic-complete` —
191
- there are no in-flight Stories left to monitor.
192
-
193
- ---
194
-
195
- ## Phase 6.5 — Post-wave integration gate (Epic #4131, F1/F4)
196
-
197
- This phase runs **after** the Phase 2 wave loop reports `epic-complete` and
198
- **before** the Phase 7 finalize emit opens the PR to `main`. Where every gate
199
- before it (`selectAudits`, the cross-epic-leak guard `#3362`, diff-against-base,
200
- the file-assumption gate) is **change-set-scoped** — it narrows its evidence to
201
- the Epic's `changedFiles` — this is the one **deliberately-global** gate: its
202
- evidence spans the **whole product**, not just the change set. The disease it
203
- catches is the surface that each Story shipped correctly in isolation yet that
204
- the assembled product cannot reach: a route nobody can navigate to, or a
205
- persona journey that the integrated waves silently broke. A change-set lens
206
- never sees that, because no single Story's diff contains the orphan.
207
-
208
- Skip when `--skip-integration-gate` (log the override; record a manual
209
- intervention per [§ Recording manual interventions](#recording-manual-interventions)).
210
- The gate is otherwise **always evaluated**, but it is a **silent no-op when
211
- unconfigured** (see *No-op when unconfigured* below) so consumers who ship no
212
- nav config and no journey suite are unaffected.
213
-
214
- ### 6.5a — Whole-product navigability (reuses the Phase 4 lens)
215
-
216
- Run the `navigability` lens
217
- ([`audit-navigability.md`](../audit-navigability.md), the deliberately-global
218
- lens delivered in this Epic's wave 0) in **whole-route mode** against the
219
- integrated `epic/<epicId>` tip. Unlike its Phase 4 change-set-routed invocation,
220
- here it is driven explicitly over the consumer's **entire** route tree + nav
221
- registry — it is on the global-lens allowlist (`GLOBAL_LENS_ALLOWLIST` in
222
- [`lib/audit-suite/selector.js`](../../scripts/lib/audit-suite/selector.js)) and
223
- exempt from the cross-epic-leak guard `#3362`, so a route orphaned anywhere in
224
- the product is in scope even when no Story in this Epic touched it.
225
-
226
- The lens reads the consumer's navigability config (resolved from `.agentrc.json`):
227
-
228
- - `delivery.quality.navigability.routeGlobs` — the route-tree SSOT the lens
229
- enumerates.
230
- - `delivery.quality.navigability.navRegistry` — the nav-registry SSOT the lens
231
- cross-checks every route against.
232
-
233
- A whole-product finding is a **hard failure**: an **orphaned route** (a route
234
- with no nav door for any entitled persona) or a **dead nav href** (a nav door
235
- pointing at a route that no longer exists). On a hard failure the gate **blocks
236
- finalize** and names the orphaned surface (route identifier / nav-door
237
- identifier only — never the route body or persona PII, per
238
- `security-baseline.md`). Do **not** proceed to Phase 7.
239
-
240
- ### 6.5b — Consumer journey suite
241
-
242
- Run the consumer's per-persona journey suite — the integrated, cross-Epic
243
- persona-journey verification — over the `epic/<epicId>` tip:
244
-
245
- - `delivery.quality.navigability.journeySuite` — path/command for the journey
246
- suite. Absent ⇒ this sub-step is skipped (no-op).
247
-
248
- A failing journey (a persona cannot complete an end-to-end journey through the
249
- assembled product) is a **hard failure**: block finalize and name the broken
250
- journey. This is the runtime complement to 6.5a's static reachability check —
251
- 6.5a proves a door exists; the journey suite proves the door, and everything
252
- behind it, actually works when the waves are integrated.
253
-
254
- ### 6.5c — `@pending` ≠ green for surface-adding Epics (F4)
255
-
256
- The Phase 7 finalize chain runs the acceptance-spec reconciler
257
- ([`acceptance-spec-reconciler.js`](../../scripts/acceptance-spec-reconciler.js)),
258
- which classifies every AC ID into `satisfied` (covered by a non-pending
259
- scenario), `pending` (covered **only** by scenarios tagged `@pending`), or
260
- `missing`. For a **surface-adding Epic** — one whose risk verdict carries a
261
- surface-adding signal (a route-adding change set, the `navigability` lens routed
262
- in Phase 4, or a configured `routeGlobs` match) — this phase tightens that
263
- contract: an AC whose coverage is **only `@pending`** is treated as
264
- **unsatisfied**, not green. A surface-adding Epic whose acceptance coverage is
265
- **only `@pending`** therefore **fails the close gate** instead of passing —
266
- shipping a new surface behind a deferred-forever `@pending` scenario is exactly
267
- the late-gate gap this Epic exists to close.
268
-
269
- This is **purely additive** and **scoped to surface-adding Epics**:
270
- refactor-only and docs-only Epics (no surface-adding signal) are **unaffected** —
271
- their `@pending` handling is exactly as before, and the existing
272
- `satisfied` / `missing` reconciliation is **not** de-scoped for any Epic.
273
-
274
- ### No-op when unconfigured
275
-
276
- With **no** navigability config (`routeGlobs` / `navRegistry`) and **no**
277
- `journeySuite` present in `.agentrc.json`, this entire phase degrades to a
278
- **silent no-op**: 6.5a and 6.5b skip (nothing to enumerate or run) and 6.5c's
279
- surface-adding signal cannot fire without route globs, so the `@pending`
280
- tightening never engages. The gate adds **zero** behaviour to an unconfigured
281
- consumer — it neither blocks finalize nor changes the existing change-set-scoped
282
- gates. The override flag `--skip-integration-gate` is the explicit operator
283
- escape hatch (consistent with `--skip-epic-audit`) for a configured consumer who
284
- wants to bypass the gate for a specific run.
285
-
286
- ### Fail safe and loud
287
-
288
- Per the Tech Spec's security note, this gate sits on the **critical path** to
289
- finalize. It MUST fail **safe and loud**: a hard failure **blocks** finalize and
290
- **names the cause** (the orphaned route, dead href, broken journey, or
291
- `@pending`-only AC), never silently passes. A genuinely unconfigured consumer is
292
- the **only** silent path, and that path **passes** (it is a no-op, not a block).
293
- On a hard failure, post a friction structured comment naming the surface, flip
294
- the Epic to `agent::blocked`, and park for the operator — do **not** open the PR.
295
-
296
- ---
297
-
298
- ## Phase 7 — Finalize (close-tail listener chain)
299
-
300
- ### 7.0 — Sync Epic branch from `main` (Story #2580)
301
-
302
- Before firing the close-tail emit, sync the Epic branch with
303
- `origin/main` so the PR opens with the latest base commits already
304
- integrated. The Epic branch may be behind `main` if other PRs merged
305
- during the wave loop; without this step, the Epic→`main` PR opens
306
- "behind base" and (with branch-protection's `up-to-date branch` rule)
307
- stalls at the merge gate.
308
-
309
- ```bash
310
- git checkout epic/<epicId>
311
- node .agents/scripts/sync-branch-from-base.js \
312
- --branch epic/<epicId> --base main
313
- ```
314
-
315
- Outcomes:
316
-
317
- - **`fast-forward` / `merge-commit` / `noop-already-current`** → push
318
- the resulting tip and continue to Phase 7.1: `git push origin epic/<epicId>`.
319
- - **`conflict`** → resolve in the Epic checkout (`git merge --no-edit
320
- origin/main`, fix conflicts, `git commit --no-edit`), then re-run the
321
- sync command. Once it exits 0, continue. Operator-recoverable; not an
322
- agent loop.
323
- - **`fetch-failed`** → re-check network / `origin` access and re-run.
324
-
325
- This is a workflow-level step (operator-driven), not part of the
326
- close-tail listener chain. The sync runs from the main checkout so
327
- the resulting tip lands on `epic/<epicId>` before Phase 7.1 fires
328
- the bus-driven close-tail.
329
-
330
- ### 7.1 — Close-tail listener chain
331
-
332
- `node .agents/scripts/lifecycle-emit.js --epic <epicId> --event epic.close.end`
333
- emits `epic.close.end` onto the lifecycle bus. **Every close-time
334
- responsibility below runs inside the listener chain — the operator
335
- shells nothing manually. The `Finalizer` listener (Story #2894 —
336
- bus-owned finalize) composes three helpers under
337
- `.agents/scripts/lib/orchestration/finalize/` and emits the canonical
338
- chain.** Treat this section as a runtime contract — `/deliver`
339
- just fires the emit and reads the resulting ledger.
340
-
341
- 1. **Acceptance-table reconciliation — bus-driven.** The
342
- `AcceptanceReconciler` listener invokes
343
- [`acceptance-spec-reconciler.js`](../../scripts/acceptance-spec-reconciler.js)
344
- to diff the AC IDs declared in the Epic body's `## Acceptance Table`
345
- section against `@ac-*` / `@pending` tags in `tests/features/**`,
346
- recording each row's verification outcome
347
- (`satisfied` / `pending` / `missing`) into the table's Disposition
348
- column via a section-scoped upsert of the Epic body. A
349
- non-OK reconciliation throws (per
350
- [`rules/orchestration-error-handling.md`](../../rules/orchestration-error-handling.md)),
351
- aborting finalize **before** any PR is opened — so the Epic stays
352
- unfinalized until the AC coverage gap is fixed. The reconciler returns
353
- `status: 'waived'` without scanning features when the Epic carries
354
- `acceptance::n-a`, and defends against direct CLI invocation by
355
- refusing to run when the body has no `## Acceptance Table` section
356
- and no waiver is set (the
357
- start gate in Phase 1 would normally catch that first).
358
- 2. **PR open / ready — bus-driven (Story #2894; earlyPr split Story
359
- #4359).** On `acceptance.reconcile.ok` the `Finalizer` listener
360
- resolves `delivery.ci.earlyPr` via
361
- [`getCiDelivery`](../../scripts/lib/config/ci.js) (default `true`) and
362
- branches:
363
- - **`earlyPr` on (default)** — the Epic PR already exists as a draft
364
- (Phase 2 opened it at wave 1 with
365
- [`openOrLocatePr`](../../scripts/lib/orchestration/finalize/open-or-locate-pr.js)
366
- `{ draft: true }`). Finalize locates it and flips it ready-for-review
367
- via
368
- [`markPrReady`](../../scripts/lib/orchestration/finalize/open-or-locate-pr.js)
369
- rather than creating a PR. `gh pr ready` on an already-ready PR is a
370
- no-op, so replay is idempotent.
371
- - **`earlyPr` off** — finalize invokes `openOrLocatePr` with
372
- `{ epicId, headBranch: 'epic/<id>', baseBranch: 'main' }` (no
373
- `draft`). The helper probes for an existing open PR on the head branch
374
- first (idempotent locate path — a re-run of `/deliver` on the same
375
- branch short-circuits without opening a duplicate) and only opens a
376
- new PR when none exists.
377
-
378
- In both modes the PR title/body contract (`feat: Epic #<id>` /
379
- `Closes #<id>`) is identical. The listener then
380
- emits `pr.created` → `epic.finalize.end` and **stops** (Story
381
- #3367). It does **not** emit `epic.merge.ready`: that event is
382
- the sole `AutomergeArmer` trigger, and emitting it from finalize
383
- would cascade `epic.close.end` synchronously through the arm →
384
- `MergeWatcher` → `Cleaner` → `BranchCleaner` reap, deleting the
385
- `epic/<id>` branch before the PR merged and bypassing the
386
- `AutomergePredicate` disqualification gate. The auto-merge arm is
387
- driven later from the gated watch path (`pr.created` → `Watcher`
388
- → `epic.watch.end` → `AutomergePredicate` → `epic.merge.ready` →
389
- `AutomergeArmer`) re-entered in Phase 8.5. The merge-lockout rule
390
- in [`check-lifecycle-lint.js`](../../scripts/check-lifecycle-lint.js)
391
- keeps `gh pr merge --auto --squash --delete-branch` confined to
392
- `AutomergeArmer` — Phase 7 never shells the merge command.
393
- 3. **Hand-off — bus-driven (Story #2894).** After `openOrLocatePr`
394
- returns, the `Finalizer` chains
395
- [`postHandoffComment`](../../scripts/lib/orchestration/finalize/post-handoff-comment.js)
396
- to upsert the canonical `epic-handoff` structured comment naming
397
- the PR URL. The helper is idempotent — the handoff comment is
398
- edited in place via `upsertStructuredComment` rather than
399
- appending a duplicate. There is **no planning-ticket close sweep**
400
- (Story #4324): the planning artifacts live as sections of the Epic
401
- body itself, so there are no context tickets to close and nothing
402
- blocks the Epic's `Closes #<id>` auto-close path.
403
-
404
- Branch cleanup is out-of-band (Phase 9 reaps local refs after merge; the
405
- rare "scrap and reset" case for an unmerged Epic is handled manually).
406
-
407
- ---
408
-
409
- ## Phase 8 — Watch-and-iterate remediation
410
-
411
- ### 8.1 Remediation
412
-
413
- For each failed required check: fetch the log
414
- (`gh run view <runId> --log-failed`), classify and fix:
415
-
416
- - **lint / format** → `npm run lint` + `npx biome check --apply` (or
417
- `format --write`); commit, push.
418
- - **maintainability / crap baseline drift** → re-run the ratcheted
419
- script. Refresh the baseline only when drift is justified by the
420
- diff; otherwise fix at source.
421
- - **test failure** → reproduce with `npm test`, fix source or test.
422
- - **coverage threshold** → add tests (preferred); refresh baseline only
423
- when the diff demonstrably can't be covered.
424
- - **anything else** → read the log, fix at source.
425
-
426
- Push to `epic/<epicId>` and re-run
427
- `node <agentRoot>/scripts/pr-watch-with-update.js --pr <prNumber>`.
428
-
429
- ### 8.2 When to halt
430
-
431
- Three consecutive iterations on the same failure class without
432
- convergence → friction comment, flip to `agent::blocked`, park. Unknown
433
- failure class on first encounter → attempt source-level fix; log
434
- friction if diagnosis takes more than one round.
435
-
436
- ### 8.3 Hard prohibitions
437
-
438
- **Never** `gh pr merge` from Phase 8 (Phase 8.5 is the only merge
439
- site). **Never** force-push to `main`. **Never** push empty commits or
440
- refresh baselines to dodge a red check.
441
-
442
- ---
443
-
444
- ## Phase 8.5 — Auto-merge predicate detail
445
-
446
- `AutomergePredicate` subscribes to `epic.automerge.start` (Story #3901 —
447
- before that this event had **zero** subscribers and the entire Phase 8.5
448
- gate was a dead wire). It evaluates the structured-signal verdict and
449
- emits `epic.merge.ready` on a clean verdict or `epic.merge.blocked`
450
- otherwise. The CI-freshness gate is skipped on this event because Phase 8
451
- already polled every required check to green — `epic.automerge.start`
452
- carries `prUrl` but no `checkOutcomes`.
453
-
454
- The `AutomergeArmer` listener subscribes to the downstream
455
- `epic.merge.ready` outcome and fires `gh pr merge --auto --squash
456
- --delete-branch` only when `clean: true`. `clean: true` requires
457
- **all** of:
458
-
459
- - `state.manualInterventions[]` is empty;
460
- - every wave's `status === "complete"`;
461
- - no story envelope carries a `blockerCommentId` or non-`done` status;
462
- - code-review reports `0` 🔴 + `0` 🟠 findings;
463
- - the retro's machine-readable `automerge-verdict` trailer reports
464
- `cleanSprint: true` (Story #3901 — the predicate reads the parsed JSON
465
- trailer `retro-run.js` writes into the retro body, **not** an emoji
466
- string-match on the human-facing "🟢 Clean sprint" prose).
467
-
468
- When clean, the listener fires `gh pr merge --squash --delete-branch`.
469
- Otherwise the listener records disqualifying reasons via
470
- `epic.merge.blocked` and exits without merging — operator merges
471
- manually.
472
-
473
- ### Recording manual interventions
474
-
475
- Whenever you step outside the happy path during a delivery, record it
476
- (each entry disqualifies auto-merge):
477
-
478
- ```bash
479
- node .agents/scripts/epic-deliver-note-intervention.js \
480
- --epic <epicId> --reason "<one-line description>"
481
- ```
482
-
483
- Triggers: `AskUserQuestion` mid-run; `git restore`/`reset` against the
484
- tree; child-reported `--no-ff` recovery, stash dance, or out-of-band
485
- merge surgery; child closes via `--skipValidation`; force-pushing or
486
- empty-committing to dodge CI diagnosis.
487
-
488
- ---
489
-
490
- ## Phase 9 — Local branch cleanup detail
491
-
492
- Phase 9 runs **automatically** inside the lifecycle bus once auto-merge
493
- arms: the `BranchCleaner` listener subscribes to `epic.cleanup.start`
494
- and reaps local refs before `Cleaner` archives the `temp/epic-<id>/`
495
- tree. No operator step is required on the auto-merge path.
496
-
497
- What gets reaped (in order, all in-process):
498
-
499
- 1. The main checkout is switched off `epic/<id>` to `baseBranch` when
500
- needed (otherwise `git branch -D epic/<id>` is refused).
501
- 2. Every `story-<id>` listed in the `epic-run-state` checkpoint, plus
502
- `epic/<id>`. Attached worktrees are removed with the standard
503
- `git worktree remove` → `--force` → filesystem-rm fallback (the
504
- last step covers Windows file-locks).
505
- 3. `git remote prune <remote>` drops stale `<remote>/...` tracking
506
- refs left behind by `gh pr merge --delete-branch`.
507
- 4. The `wt-branch` scratch ref left by `story-close.js`'s internal
508
- merge worktree is deleted when no worktree still points at it.
509
-
510
- Per-branch failures aggregate into the listener's classification log
511
- (`reaped` / `failed` / `no-state` / `skipped-duplicate`) and are
512
- visible in `temp/epic-<id>/lifecycle.ndjson`. They do not block the
513
- rest of cleanup.
514
-
515
- For out-of-band cleanup re-entry (resume after a crash, or operator
516
- override), fire `epic.merge.armed` via the lifecycle-emit helper:
517
-
518
- ```bash
519
- node .agents/scripts/lifecycle-emit.js --epic <epicId> \
520
- --event epic.merge.armed --pr-url <prUrl>
521
- ```
522
-
523
- If Phase 8.5 fell back to the operator-merges-button path (`gh pr
524
- merge --auto` was declined), the `epic.merge.armed` event never fires
525
- inside this run and Phase 9 will not run automatically. **Do not** hand-reap
526
- the refs with a raw `git branch -D` sequence — drive the same
527
- `BranchCleaner`-backed reap the auto-merge path uses by firing
528
- `epic.merge.armed` after the operator merges the PR:
529
-
530
- ```bash
531
- node .agents/scripts/lifecycle-emit.js --epic <epicId> \
532
- --event epic.merge.armed --pr-url <prUrl>
533
- ```
534
-
535
- That single emit reaps `epic/<epicId>` and every `story-<id>` ref from the
536
- checkpoint, prunes stale tracking refs, and fast-forwards local `main` to
537
- `origin/main` — the whole Phase 9 reap, not a partial hand-roll. A plain
538
- `git-cleanup.js` sweep alone will **not** catch the `story-<id>` refs here,
539
- because the epic PR squash-merge breaks the `git branch --merged main` signal
540
- and the stories never had their own PRs; the lifecycle-emit surface above is
541
- the correct driver.
542
-
543
- Re-running `/deliver <epicId>` reaches the same outcome without the manual
544
- emit: the idempotent-resume auto-arm
545
- (`detectMergedUncleanedEpic` → `armCleanupIfMerged` in
546
- [`epic-cleanup.js`](../../scripts/lib/orchestration/epic-cleanup.js)) detects
547
- the merged-but-uncleaned Epic and fires `epic.merge.armed` for you.