mandrel 2.0.0 → 2.2.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 (323) hide show
  1. package/.agents/README.md +59 -28
  2. package/.agents/agents/acceptance-critic.md +20 -9
  3. package/.agents/agents/story-worker.md +45 -48
  4. package/.agents/audit-checklists/performance.md +1 -1
  5. package/.agents/docs/SDLC.md +60 -46
  6. package/.agents/docs/agentrc-reference.json +8 -13
  7. package/.agents/docs/configuration.md +33 -57
  8. package/.agents/docs/execution-reference.md +39 -10
  9. package/.agents/docs/quality-gates.md +17 -19
  10. package/.agents/docs/workflows.md +6 -6
  11. package/.agents/instructions.md +64 -79
  12. package/.agents/rules/ci-remediation.md +3 -3
  13. package/.agents/rules/gherkin-standards.md +10 -0
  14. package/.agents/rules/git-conventions-reference.md +42 -51
  15. package/.agents/schemas/acceptance-eval-verdict.schema.json +2 -2
  16. package/.agents/schemas/agentrc.schema.json +35 -46
  17. package/.agents/schemas/audit-rules.json +59 -1
  18. package/.agents/schemas/audit-rules.schema.json +33 -1
  19. package/.agents/schemas/lifecycle/README.md +1 -2
  20. package/.agents/schemas/lifecycle/ledger-record.schema.json +1 -1
  21. package/.agents/schemas/lifecycle/merge.flip-failed.schema.json +33 -0
  22. package/.agents/schemas/lifecycle/merge.unlanded.schema.json +1 -0
  23. package/.agents/schemas/lifecycle/story.merged.schema.json +1 -1
  24. package/.agents/schemas/signal-event.schema.json +3 -3
  25. package/.agents/schemas/story-deliver-terminal.schema.json +152 -0
  26. package/.agents/schemas/validation-evidence.schema.json +1 -1
  27. package/.agents/scripts/acceptance-eval.js +24 -68
  28. package/.agents/scripts/agents-bootstrap-github.js +1 -1
  29. package/.agents/scripts/bootstrap.js +3 -3
  30. package/.agents/scripts/check-dead-exports.js +43 -104
  31. package/.agents/scripts/check-doc-links.js +2 -2
  32. package/.agents/scripts/check-lifecycle-lint.js +1 -1
  33. package/.agents/scripts/check-workflow-cli-lint.js +91 -0
  34. package/.agents/scripts/deliver-recover.js +122 -0
  35. package/.agents/scripts/drain-pending-cleanup.js +1 -1
  36. package/.agents/scripts/evidence-gate.js +20 -50
  37. package/.agents/scripts/generate-skills-index.js +17 -1
  38. package/.agents/scripts/generate-workflows-doc.js +4 -4
  39. package/.agents/scripts/lib/ITicketingProvider.js +1 -19
  40. package/.agents/scripts/lib/audit-suite/selector.js +323 -23
  41. package/.agents/scripts/lib/baselines/kinds/maintainability.js +0 -11
  42. package/.agents/scripts/lib/bootstrap/ci-workflow-template.js +28 -33
  43. package/.agents/scripts/lib/bootstrap/manifest.js +8 -11
  44. package/.agents/scripts/lib/bootstrap/project-bootstrap.js +30 -53
  45. package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +0 -2
  46. package/.agents/scripts/lib/checks/core-bare-clean.js +4 -1
  47. package/.agents/scripts/lib/checks/index.js +1 -1
  48. package/.agents/scripts/lib/checks/loop-health.js +12 -11
  49. package/.agents/scripts/lib/checks/state.js +17 -248
  50. package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +3 -3
  51. package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +3 -4
  52. package/.agents/scripts/lib/checks/worktree-bootstrap-env.js +2 -2
  53. package/.agents/scripts/lib/checks/worktree-residue-biome.js +3 -3
  54. package/.agents/scripts/lib/cli-args.js +23 -2
  55. package/.agents/scripts/lib/close-validation/gates.js +13 -13
  56. package/.agents/scripts/lib/close-validation/projections/inputs.js +7 -7
  57. package/.agents/scripts/lib/close-validation/projections/maintainability.js +12 -12
  58. package/.agents/scripts/lib/close-validation/runner.js +13 -21
  59. package/.agents/scripts/lib/close-validation/telemetry.js +17 -8
  60. package/.agents/scripts/lib/config/acceptance-eval.js +2 -2
  61. package/.agents/scripts/lib/config/delivery-routing.js +7 -6
  62. package/.agents/scripts/lib/config/explain.js +10 -16
  63. package/.agents/scripts/lib/config/github.js +7 -5
  64. package/.agents/scripts/lib/config/limits.js +15 -25
  65. package/.agents/scripts/lib/config/quality.js +11 -14
  66. package/.agents/scripts/lib/config/runners.js +8 -21
  67. package/.agents/scripts/lib/config/temp-paths.js +18 -56
  68. package/.agents/scripts/lib/config-settings-schema-delivery.js +34 -16
  69. package/.agents/scripts/lib/config-settings-schema-quality.js +9 -2
  70. package/.agents/scripts/lib/config-settings-schema.js +48 -22
  71. package/.agents/scripts/lib/dead-exports-knip.js +105 -0
  72. package/.agents/scripts/lib/dead-exports-mode.js +51 -0
  73. package/.agents/scripts/lib/duplicate-search.js +38 -7
  74. package/.agents/scripts/lib/findings/promote-finding.js +23 -14
  75. package/.agents/scripts/lib/format-generated-json.js +97 -0
  76. package/.agents/scripts/lib/framework-version.js +19 -189
  77. package/.agents/scripts/lib/gh-exec.js +8 -0
  78. package/.agents/scripts/lib/git-branch-lifecycle.js +0 -158
  79. package/.agents/scripts/lib/git-utils.js +0 -14
  80. package/.agents/scripts/lib/json-utils.js +1 -2
  81. package/.agents/scripts/lib/label-constants.js +0 -15
  82. package/.agents/scripts/lib/label-taxonomy.js +1 -12
  83. package/.agents/scripts/lib/observability/active-story-env.js +42 -163
  84. package/.agents/scripts/lib/observability/runtime-friction.js +243 -0
  85. package/.agents/scripts/lib/observability/signal-validator.js +4 -4
  86. package/.agents/scripts/lib/observability/signals-writer.js +6 -82
  87. package/.agents/scripts/lib/observability/source-classifier.js +2 -2
  88. package/.agents/scripts/lib/observability/tool-trace-hook.js +2 -12
  89. package/.agents/scripts/lib/orchestration/acceptance-clusters.js +1 -1
  90. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +2 -2
  91. package/.agents/scripts/lib/orchestration/ceremony-routing.js +43 -45
  92. package/.agents/scripts/lib/orchestration/change-set.js +103 -0
  93. package/.agents/scripts/lib/orchestration/code-review.js +70 -191
  94. package/.agents/scripts/lib/orchestration/consolidation-precondition.js +3 -3
  95. package/.agents/scripts/lib/orchestration/deliver-recover.js +328 -0
  96. package/.agents/scripts/lib/orchestration/detectors-phase.js +12 -6
  97. package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +34 -0
  98. package/.agents/scripts/lib/orchestration/lease-guard-shared.js +3 -2
  99. package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +142 -0
  100. package/.agents/scripts/lib/orchestration/lifecycle/emit-loop-tick.js +9 -11
  101. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +86 -0
  102. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +37 -103
  103. package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +7 -3
  104. package/.agents/scripts/lib/orchestration/lifecycle/listeners/watcher.js +50 -85
  105. package/.agents/scripts/lib/orchestration/lifecycle/trace-logger.js +3 -14
  106. package/.agents/scripts/lib/orchestration/merge-block-class.js +76 -20
  107. package/.agents/scripts/lib/orchestration/merge-poll.js +104 -0
  108. package/.agents/scripts/lib/orchestration/plan-context.js +116 -33
  109. package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +26 -36
  110. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +31 -22
  111. package/.agents/scripts/lib/orchestration/plan-metrics.js +38 -6
  112. package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +16 -6
  113. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +173 -25
  114. package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +116 -0
  115. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +280 -100
  116. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +472 -55
  117. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +21 -16
  118. package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +509 -0
  119. package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +230 -0
  120. package/.agents/scripts/lib/orchestration/planning/authoring-context.js +41 -40
  121. package/.agents/scripts/lib/orchestration/planning/decomposer-context.js +1 -2
  122. package/.agents/scripts/lib/orchestration/planning/spec-authoring-grounding.js +1 -1
  123. package/.agents/scripts/lib/orchestration/resolve-stories.js +344 -0
  124. package/.agents/scripts/lib/orchestration/retro-proposals.js +7 -7
  125. package/.agents/scripts/lib/orchestration/review-depth.js +105 -40
  126. package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +3 -13
  127. package/.agents/scripts/lib/orchestration/review-providers/native.js +1 -154
  128. package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +3 -2
  129. package/.agents/scripts/lib/orchestration/review-providers/security-review.js +1 -1
  130. package/.agents/scripts/lib/orchestration/review-providers/types.js +5 -4
  131. package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +1 -1
  132. package/.agents/scripts/lib/orchestration/run-epilogue.js +374 -16
  133. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +24 -0
  134. package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +11 -9
  135. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +4 -4
  136. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +4 -13
  137. package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +608 -152
  138. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +72 -30
  139. package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +305 -0
  140. package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +1 -1
  141. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +12 -8
  142. package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +37 -4
  143. package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +2 -2
  144. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +264 -43
  145. package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +1 -1
  146. package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +10 -10
  147. package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +104 -279
  148. package/.agents/scripts/lib/orchestration/story-close/phases/local-lens-review.js +191 -0
  149. package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +120 -0
  150. package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +360 -0
  151. package/.agents/scripts/lib/orchestration/story-follow-ups.js +75 -14
  152. package/.agents/scripts/lib/orchestration/story-init-remote.js +12 -8
  153. package/.agents/scripts/lib/orchestration/story-plan-state.js +14 -29
  154. package/.agents/scripts/lib/orchestration/task-body-validator.js +52 -7
  155. package/.agents/scripts/lib/orchestration/ticket-lease.js +27 -74
  156. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +119 -14
  157. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +3 -4
  158. package/.agents/scripts/lib/orchestration/ticket-validator.js +121 -18
  159. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +14 -47
  160. package/.agents/scripts/lib/orchestration/ticketing/reads.js +19 -32
  161. package/.agents/scripts/lib/orchestration/ticketing/transition.js +61 -1
  162. package/.agents/scripts/lib/orchestration/ticketing.js +0 -1
  163. package/.agents/scripts/lib/plan-phase-cleanup.js +12 -14
  164. package/.agents/scripts/lib/planning-corpus.js +12 -286
  165. package/.agents/scripts/lib/preflight-runner.js +2 -2
  166. package/.agents/scripts/lib/qa/qa-context-hydrator.js +5 -5
  167. package/.agents/scripts/lib/signals/index.js +4 -17
  168. package/.agents/scripts/lib/signals/read.js +35 -35
  169. package/.agents/scripts/lib/signals/schema.js +8 -11
  170. package/.agents/scripts/lib/signals/span-tree.js +7 -7
  171. package/.agents/scripts/lib/signals/write.js +0 -1
  172. package/.agents/scripts/lib/single-story/story-merged-notify.js +13 -2
  173. package/.agents/scripts/lib/skills/parse-skill.js +16 -3
  174. package/.agents/scripts/lib/story-adjacency.js +8 -7
  175. package/.agents/scripts/lib/story-body/story-body.js +81 -13
  176. package/.agents/scripts/lib/templates/decomposer-prompts.js +15 -16
  177. package/.agents/scripts/lib/test-env.js +14 -1
  178. package/.agents/scripts/lib/test-tiers.js +0 -3
  179. package/.agents/scripts/lib/ticket-body-sections.js +0 -14
  180. package/.agents/scripts/lib/validation-evidence.js +31 -59
  181. package/.agents/scripts/lib/wave-runner/live-probe.js +315 -0
  182. package/.agents/scripts/lib/wave-runner/ready-set.js +32 -6
  183. package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +1 -1
  184. package/.agents/scripts/lib/worktree/lifecycle/reap.js +68 -19
  185. package/.agents/scripts/lib/worktree/lifecycle-manager.js +1 -2
  186. package/.agents/scripts/plan-context.js +38 -7
  187. package/.agents/scripts/plan-critics.js +203 -0
  188. package/.agents/scripts/plan-persist.js +145 -35
  189. package/.agents/scripts/plan-run-epilogue.js +83 -38
  190. package/.agents/scripts/post-structured-comment.js +0 -38
  191. package/.agents/scripts/pr-watch-with-update.js +43 -22
  192. package/.agents/scripts/providers/github/compose.js +0 -1
  193. package/.agents/scripts/providers/github/errors.js +0 -19
  194. package/.agents/scripts/providers/github/issues.js +1 -11
  195. package/.agents/scripts/providers/github/mappers.js +5 -0
  196. package/.agents/scripts/providers/github/sub-issues.js +0 -47
  197. package/.agents/scripts/providers/github/tickets.js +33 -153
  198. package/.agents/scripts/providers/github.js +17 -6
  199. package/.agents/scripts/quality-preview.js +13 -6
  200. package/.agents/scripts/resolve-stories.js +236 -0
  201. package/.agents/scripts/run-coverage.js +4 -1
  202. package/.agents/scripts/run-lint.js +2 -2
  203. package/.agents/scripts/run-verify.js +31 -2
  204. package/.agents/scripts/signals-view.js +9 -10
  205. package/.agents/scripts/single-story-close.js +173 -18
  206. package/.agents/scripts/single-story-confirm-merge.js +288 -15
  207. package/.agents/scripts/single-story-init.js +6 -10
  208. package/.agents/scripts/stories-wave-tick.js +380 -53
  209. package/.agents/scripts/story-plan.js +3 -3
  210. package/.agents/scripts/update-ticket-state.js +8 -50
  211. package/.agents/skills/core/code-review-and-quality/SKILL.md +28 -450
  212. package/.agents/skills/core/code-review-and-quality/reference.md +458 -0
  213. package/.agents/skills/core/debugging-and-error-recovery/SKILL.md +22 -315
  214. package/.agents/skills/core/debugging-and-error-recovery/reference.md +323 -0
  215. package/.agents/skills/core/diagnose-friction/SKILL.md +14 -18
  216. package/.agents/skills/core/documentation-and-adrs/SKILL.md +25 -397
  217. package/.agents/skills/core/documentation-and-adrs/reference.md +403 -0
  218. package/.agents/skills/core/gates-and-baselines/SKILL.md +12 -12
  219. package/.agents/skills/core/idea-refinement/SKILL.md +3 -3
  220. package/.agents/skills/core/scope-triage/SKILL.md +3 -0
  221. package/.agents/skills/core/security-and-hardening/SKILL.md +22 -367
  222. package/.agents/skills/core/security-and-hardening/reference.md +375 -0
  223. package/.agents/skills/skills.index.json +2 -12
  224. package/.agents/skills/stack/qa/playwright-bdd/SKILL.md +2 -4
  225. package/.agents/skills/stack/qa/qa-explore-driving/SKILL.md +1 -1
  226. package/.agents/skills/stack/qa/qa-harness/SKILL.md +1 -3
  227. package/.agents/workflows/audit-architecture.md +3 -4
  228. package/.agents/workflows/audit-clean-code.md +4 -4
  229. package/.agents/workflows/audit-documentation.md +4 -5
  230. package/.agents/workflows/audit-lighthouse.md +8 -0
  231. package/.agents/workflows/audit-navigability.md +10 -0
  232. package/.agents/workflows/audit-performance.md +2 -3
  233. package/.agents/workflows/audit-quality.md +8 -9
  234. package/.agents/workflows/audit-security.md +1 -2
  235. package/.agents/workflows/audit-seo.md +10 -0
  236. package/.agents/workflows/audit-ux-ui.md +7 -0
  237. package/.agents/workflows/deliver.md +133 -45
  238. package/.agents/workflows/git-cleanup.md +2 -2
  239. package/.agents/workflows/git-deliver.md +1 -1
  240. package/.agents/workflows/helpers/acceptance-self-eval.md +34 -17
  241. package/.agents/workflows/helpers/code-quality-guardrails.md +15 -12
  242. package/.agents/workflows/helpers/code-review.md +14 -12
  243. package/.agents/workflows/helpers/deliver-story-reference.md +73 -32
  244. package/.agents/workflows/helpers/deliver-story.md +209 -118
  245. package/.agents/workflows/helpers/parallel-tooling.md +2 -2
  246. package/.agents/workflows/helpers/worktree-lifecycle.md +28 -32
  247. package/.agents/workflows/plan.md +239 -19
  248. package/.agents/workflows/qa-assist.md +6 -6
  249. package/.agents/workflows/qa-explore.md +3 -3
  250. package/.agents/workflows/qa-run.md +1 -5
  251. package/bin/mandrel.js +12 -1
  252. package/docs/CHANGELOG.md +62 -0
  253. package/lib/cli/registry.js +262 -19
  254. package/lib/cli/sync-agents.js +157 -0
  255. package/lib/cli/sync-commands.js +115 -6
  256. package/lib/cli/sync.js +168 -6
  257. package/lib/cli/update.js +105 -8
  258. package/lib/cli/version-helpers.js +131 -0
  259. package/lib/migrations/README.md +7 -5
  260. package/lib/migrations/index.js +17 -9
  261. package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +100 -0
  262. package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +101 -0
  263. package/lib/migrations/steps/2.2.0-retire-epic-ac-tags.js +154 -0
  264. package/package.json +2 -2
  265. package/.agents/schemas/epic-perf-report.schema.json +0 -89
  266. package/.agents/schemas/lifecycle/acceptance.reconcile.failed.schema.json +0 -13
  267. package/.agents/schemas/lifecycle/acceptance.reconcile.ok.schema.json +0 -13
  268. package/.agents/schemas/lifecycle/acceptance.reconcile.skipped.schema.json +0 -13
  269. package/.agents/schemas/lifecycle/acceptance.reconcile.start.schema.json +0 -12
  270. package/.agents/schemas/lifecycle/acceptance.reconcile.waived.schema.json +0 -13
  271. package/.agents/schemas/lifecycle/epic.automerge.end.schema.json +0 -15
  272. package/.agents/schemas/lifecycle/epic.automerge.start.schema.json +0 -13
  273. package/.agents/schemas/lifecycle/epic.blocked.schema.json +0 -13
  274. package/.agents/schemas/lifecycle/epic.cleanup.end.schema.json +0 -12
  275. package/.agents/schemas/lifecycle/epic.cleanup.start.schema.json +0 -12
  276. package/.agents/schemas/lifecycle/epic.close.end.schema.json +0 -12
  277. package/.agents/schemas/lifecycle/epic.complete.schema.json +0 -13
  278. package/.agents/schemas/lifecycle/epic.finalize.end.schema.json +0 -13
  279. package/.agents/schemas/lifecycle/epic.finalize.start.schema.json +0 -12
  280. package/.agents/schemas/lifecycle/epic.merge.armed.schema.json +0 -13
  281. package/.agents/schemas/lifecycle/epic.merge.blocked.schema.json +0 -14
  282. package/.agents/schemas/lifecycle/epic.merge.confirmed.schema.json +0 -17
  283. package/.agents/schemas/lifecycle/epic.merge.ready.schema.json +0 -15
  284. package/.agents/schemas/lifecycle/epic.plan.end.schema.json +0 -18
  285. package/.agents/schemas/lifecycle/epic.plan.start.schema.json +0 -12
  286. package/.agents/schemas/lifecycle/epic.snapshot.end.schema.json +0 -16
  287. package/.agents/schemas/lifecycle/epic.snapshot.start.schema.json +0 -12
  288. package/.agents/schemas/lifecycle/epic.watch.end.schema.json +0 -29
  289. package/.agents/schemas/lifecycle/epic.watch.start.schema.json +0 -16
  290. package/.agents/schemas/lifecycle/story.heartbeat.schema.json +0 -20
  291. package/.agents/schemas/risk-verdict.schema.json +0 -53
  292. package/.agents/schemas/story-perf-summary.schema.json +0 -73
  293. package/.agents/scripts/analyze-execution.js +0 -444
  294. package/.agents/scripts/check-prepush-recovery.js +0 -90
  295. package/.agents/scripts/lib/git-merge-orchestrator.js +0 -261
  296. package/.agents/scripts/lib/observability/baseline-refresh-rate.js +0 -221
  297. package/.agents/scripts/lib/observability/hook-heartbeat.js +0 -187
  298. package/.agents/scripts/lib/observability/perf-aggregator.js +0 -813
  299. package/.agents/scripts/lib/observability/perf-report-readers.js +0 -328
  300. package/.agents/scripts/lib/observability/perf-report-render.js +0 -182
  301. package/.agents/scripts/lib/orchestration/audit-lens-routing.js +0 -128
  302. package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +0 -273
  303. package/.agents/scripts/lib/orchestration/error-journal.js +0 -139
  304. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +0 -155
  305. package/.agents/scripts/lib/orchestration/lifecycle/ledger-diff.js +0 -140
  306. package/.agents/scripts/lib/orchestration/lifecycle/listeners/merge-watcher.js +0 -665
  307. package/.agents/scripts/lib/orchestration/plan-review-routing.js +0 -63
  308. package/.agents/scripts/lib/orchestration/planning/risk-verdict.js +0 -104
  309. package/.agents/scripts/lib/orchestration/planning-context-budget.js +0 -213
  310. package/.agents/scripts/lib/orchestration/planning-risk.js +0 -194
  311. package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +0 -56
  312. package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +0 -21
  313. package/.agents/scripts/lib/orchestration/post-merge/phases/notification.js +0 -78
  314. package/.agents/scripts/lib/orchestration/post-merge/phases/temp-cleanup.js +0 -68
  315. package/.agents/scripts/lib/orchestration/post-merge/phases/ticket-closure.js +0 -118
  316. package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +0 -397
  317. package/.agents/scripts/lib/orchestration/preflight-cache.js +0 -187
  318. package/.agents/scripts/lib/orchestration/resolve-plan-run.js +0 -155
  319. package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +0 -275
  320. package/.agents/scripts/lib/orchestration/story-progress/story-run-progress-writer.js +0 -400
  321. package/.agents/scripts/lib/single-story/confirm-merge-follow-ups.js +0 -36
  322. package/.agents/scripts/resolve-plan-run.js +0 -117
  323. package/.agents/skills/core/analyze-execution/SKILL.md +0 -101
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  description:
3
3
  Execute one Story end-to-end. Creates story-<id> from main, implements in a
4
- worktree (optional ## Slicing checkpoints), runs risk-routed ceremony, opens
5
- a PR against main, and lands.
4
+ worktree (optional ## Slicing checkpoints), runs derived-level ceremony,
5
+ opens a PR against main, and lands.
6
6
  ---
7
7
 
8
8
  # /deliver-story #[Story ID]
@@ -18,10 +18,10 @@ description:
18
18
  large — uses the same machinery:
19
19
 
20
20
  ```text
21
- /deliver <storyId> (or /deliver --run <planRunId> one Story at a time)
21
+ /deliver <storyId> [<storyId> ...] (each Story runs through this engine)
22
22
  → single-story-init.js (branch from main, worktree, agent::executing)
23
23
  → agent implements + commits (optional ## Slicing intra-session checkpoints)
24
- risk-routed ceremony (acceptance critics · review · audit lenses)
24
+ derived-level ceremony (acceptance critics · review depth)
25
25
  → single-story-close.js (gates, push, gh pr create → main, agent::closing)
26
26
  → CI watch + fix loop (until required checks pass + PR merged)
27
27
  → single-story-confirm-merge.js (PR merged → agent::done + follow-ups)
@@ -34,7 +34,7 @@ large — uses the same machinery:
34
34
  | Merge target | `main` via PR (squash + required checks) |
35
35
  | Epic integration branch | **None** — no `epic/<id>`, no `--no-ff` wave merge |
36
36
  | Spec / slices | Folded `## Spec` + optional `## Slicing` checkpoints in-session |
37
- | Ceremony | Per-Story risk-routed via `ceremony-routing.js` |
37
+ | Ceremony | Per-Story, routed off the derived change level via `ceremony-routing.js` |
38
38
 
39
39
  If the Story still carries an `Epic: #N` reference, **stop** — that is a v1
40
40
  Epic-attached ticket; re-plan as a v2 Story or finish it on a pre-v2 checkout.
@@ -200,27 +200,48 @@ Story-path specifics:
200
200
 
201
201
  ---
202
202
 
203
- ## Step 2 — Ceremony (profile + risk)
203
+ ## Step 2 — Ceremony (profile + derived level)
204
204
 
205
205
  Per-Story ceremony is selected by `delivery.routing.ceremonyProfile`
206
206
  (`minimal` | `standard` | `strict`, default `standard`) and the Story's
207
- own risk envelope (folded plan `planningRisk` / `risk-verdict` on the
208
- Story or its plan-run context — never an Epic parent). Resolve
209
- fresh-vs-inline acceptance critics per AC-cluster with
207
+ **derived change level** not a planner-authored verdict (Story #4542 retired
208
+ that).
209
+
210
+ **Compute the change set once** (Story #4593) with the shared enumerator
211
+ [`computeChangeSet`](../../scripts/lib/orchestration/change-set.js) — the same
212
+ module close uses — and reuse that one list for everything downstream:
213
+
214
+ ```bash
215
+ node --input-type=module -e '
216
+ import { computeChangeSet } from "<main-repo>/.agents/scripts/lib/orchestration/change-set.js";
217
+ const { files } = computeChangeSet({ baseRef: "main", headRef: "story-<storyId>" });
218
+ console.log(JSON.stringify(files));
219
+ '
220
+ ```
221
+
222
+ Then derive the level with
223
+ [`deriveChangeLevel`](../../scripts/lib/orchestration/review-depth.js) over that
224
+ list: a diff touching a sensitive path registered in
225
+ `.agents/schemas/audit-rules.json` derives `high`, one touching none derives
226
+ `low`, and an unenumerable diff (`files === null`) derives `null`. Hand the
227
+ **same** list to every acceptance critic you spawn (Step 1a) — a critic that
228
+ re-ran its own `git diff` could score against a different set than the one that
229
+ routed it.
230
+
231
+ Resolve fresh-vs-inline acceptance critics per AC-cluster with
210
232
  [`resolveCeremonyForRisk`](../../scripts/lib/orchestration/ceremony-routing.js)
211
233
  (`minimal` → always inline; `strict` → always fresh; `standard` →
212
- `high`/`medium`/`missing` → `fresh`, `low` → `inline` unless the
213
- `freshCriticSampleRate` floor forces `fresh`). Review depth and audit lenses
214
- follow the same envelope via `review-depth.js` /
215
- `audit-lens-routing.js#resolveAuditLenses` inside close.
234
+ `high`/`null` → `fresh`, `low` → `inline` unless the `freshCriticSampleRate`
235
+ floor forces `fresh`). Review depth reads the same derived level via
236
+ `review-depth.js` inside close, so the two decisions cannot disagree.
216
237
 
217
238
  Hard gates (lint / test / format / coverage / CRAP / maintainability) always
218
- run in Step 3 — risk never disables them. Do **not** pre-run the full
219
- close-validation chain here unless interactively iterating on a fix.
239
+ run in Step 3 — the derived level never disables them. Do **not** pre-run the
240
+ full close-validation chain here unless interactively iterating on a fix.
220
241
 
221
242
  ---
222
243
 
223
- ## Step 3 — Close (`single-story-close.js`)
244
+ ## Step 3 — Close and land (`single-story-close.js`)
224
245
 
225
246
  Invoke from the main checkout (or pass `--cwd <main-repo>` from inside
226
247
  the worktree):
@@ -229,14 +250,56 @@ the worktree):
229
250
  node <main-repo>/.agents/scripts/single-story-close.js --story <storyId> --cwd <main-repo>
230
251
  ```
231
252
 
253
+ **This step is the whole delivery tail.** Close owns the gates, the PR, the
254
+ merge wait, the `agent::done` flip, and the post-land tail (follow-up
255
+ capture, status-column resync, local ref cleanup, base fast-forward) in one
256
+ process. Your job is to run it and **branch on the terminal envelope's
257
+ `status`** — nothing more (Story #4543).
258
+
259
+ ### Branch on the terminal envelope
260
+
261
+ Every invocation emits exactly one schema-validated envelope
262
+ ([`story-deliver-terminal.schema.json`](../../schemas/story-deliver-terminal.schema.json))
263
+ between `--- STORY DELIVER TERMINAL ---` markers, and the exit code mirrors
264
+ its `status`:
265
+
266
+ | `status` | Exit | What it means | What you do |
267
+ | --- | --- | --- | --- |
268
+ | `landed` | 0 | PR merged, Story `agent::done`, tail ran. `tail.*` booleans expose any partial degradation — a `false` there does **not** demote the land. | Go to Step 7 and relay the envelope. Nothing else. |
269
+ | `pending` | 3 | **Resumable, not a failure.** The per-invocation merge wait expired with the PR healthy and in flight, or the operator owns the merge. No label was mutated; no `merge.unlanded` was emitted. | Run the envelope's `nextCommand`. Repeat until it resolves. Relay `pending` only once you have exhausted your own budget. |
270
+ | `blocked` | 1 | A classified hard block. Story carries `agent::blocked`; `blocked.blockClass` names the class and `blocked.frictionCommentId` points at the remediation. | `checks-failed` → fix the red check and push (Step 4). Otherwise go to Step 7 and relay the envelope. |
271
+ | `failed` | 1 | A phase crashed; `phase` names which. | Diagnose, fix, re-run close. |
272
+
273
+ Do **not** re-sequence the post-close steps by hand. Steps 4–6 below are
274
+ **recovery-only** — reached from a `blocked`/`pending` envelope, never as
275
+ routine choreography.
276
+
277
+ ### What close does internally
278
+
232
279
  The script runs the close-validation gates against `baseBranch`, syncs the
233
280
  Story branch from `origin/<baseBranch>` (Story #2580 — the parallel-race
234
281
  defence), pushes `story-<id>`, opens (or reuses) a PR against `baseBranch`
235
282
  with a `Closes #<storyId>` footer, enables GitHub native auto-merge
236
283
  (`--auto --squash --delete-branch`) **when `delivery.ci.autoMerge` is
237
- `"trust-ci"` (the default)**, flips the Story to **`agent::closing`**
238
- (NOT `agent::done` the issue stays OPEN until Step 5 confirms the merge,
239
- Story #3385), reaps the worktree, and releases the Story lease.
284
+ `"trust-ci"` (the default)**, flips the Story to `agent::closing`, reaps the
285
+ worktree, releases the lease, then **waits for the merge** and on a
286
+ confirmed merge flips `agent::done` and runs the post-land tail.
287
+
288
+ ### The merge wait is bounded and resumable
289
+
290
+ Two budgets, deliberately separate (`delivery.mergeWatch.*`):
291
+
292
+ - **`maxWaitSeconds`** (default 300) bounds **one invocation**, sized to fit
293
+ inside a single host tool invocation (~10 min ceiling) alongside the gates
294
+ that precede it. Expiry → `pending`. Pass `--max-wait-seconds <n>` to raise
295
+ it when your host has no such ceiling and you want to land in one block.
296
+ - **`maxBudgetSeconds`** (default 3600) bounds the **cumulative** wait across
297
+ resumes, anchored at the PR's `createdAt` so resuming does not restart the
298
+ clock. Exhausting *this* is the genuine give-up → `blocked`.
299
+
300
+ The wait probes the checks every poll: a red required check fails fast as
301
+ `checks-failed` instead of burning the budget, and a PR that falls behind its
302
+ base is brought up to date within `updateAttempts` tries.
240
303
 
241
304
  > **`delivery.ci.autoMerge` policy.** Under the default `"trust-ci"`, GitHub
242
305
  > native auto-merge is armed and the PR squash-merges once its **required**
@@ -254,20 +317,19 @@ Flags:
254
317
  behaviour and warrants a pre-merge eyeball; the operator then merges via
255
318
  the GitHub UI.
256
319
  - `--wait-merge` — **close-and-land** (Story #4428). Forces close to poll
257
- the armed PR to merge confirmation on the `delivery.mergeWatch.*`
258
- cadence (reusing the same `confirmStoryMerged` flip logic) and flip
259
- `agent::done` itself. If the arm fails, the PR closes without merging,
260
- or the poll budget is exhausted first, close classifies the block
261
- (`checks-pending-timeout` \| `branch-protection-human-required` \|
262
- `arm-failure` \| `api-race-other`), emits a `merge.unlanded` lifecycle
263
- event, posts a `friction` comment, transitions the Story to
264
- `agent::blocked`, and exits non-zero — never a silent `agent::closing`
265
- rest. When neither land flag is passed, close defaults from
266
- `delivery.routing.closeAndLand` (**true**): attended and headless
267
- delivers share the land-in-one-close happy path.
320
+ the armed PR to merge confirmation and flip `agent::done` itself. When
321
+ neither land flag is passed, close defaults from
322
+ `delivery.routing.closeAndLand` (**true**): attended and headless delivers
323
+ share the land-in-one-close happy path.
268
324
  - `--no-wait-merge` — explicit opt-out that always wins. Use when the
269
325
  operator wants the PR left at `agent::closing` for a human land (or a
270
- wrapper that will invoke `single-story-confirm-merge.js` itself).
326
+ wrapper that will invoke `single-story-confirm-merge.js` itself). Reports
327
+ `pending` — the work is not done, nothing is broken, and one named command
328
+ finishes it.
329
+ - `--max-wait-seconds <n>` — raise the merge wait's per-invocation bound for
330
+ this run (Story #4543). Use from a headless caller with no host
331
+ tool-invocation ceiling to keep single-block semantics without editing the
332
+ consumer's config.
271
333
 
272
334
  > **Full close pipeline (base-sync outcomes, `agent::closing` rationale,
273
335
  > lease release).** For the numbered close pipeline, the base-sync outcome
@@ -277,43 +339,48 @@ Flags:
277
339
 
278
340
  ---
279
341
 
280
- ## Step 4 — CI watch + fix loop (**required, not optional**)
281
-
282
- > **Close-and-land runs skip Steps 4 and 5.** When Step 3 lands through
283
- > merge (`--wait-merge` or the `closeAndLand` default),
284
- > `single-story-close.js` already polled the PR to a confirmed merge
285
- > (flipping `agent::done` itself) or exited non-zero after transitioning
286
- > the Story to `agent::blocked` with a `merge.unlanded` event there is
287
- > no separate CI-watch turn or manual confirm step to run. Proceed
288
- > straight to Step 5.5. Only `--no-wait-merge` runs still own Steps 4
289
- > and 5 as documented below.
290
-
291
- The Story is **not done** when `single-story-close.js` returns. Auto-merge
292
- only fires when every required CI check turns green. Local close-validation
293
- gates pass on the dev host's environment; CI runs on a different OS and
294
- concurrency, and coverage rounding, platform-conditional branches, and
295
- timing-sensitive tests routinely drift between the two. The agent owns the
296
- green-CI outcome, not just the push.
297
-
298
- > **The auto-merge wait is an internally-blocking step, not a reason to end
299
- > your turn.** `pr-watch-with-update.js` blocks the current turn until CI
300
- > resolves — that IS how you wait. Keep the turn alive: watch → (fix +
301
- > push + re-watch on red) → confirm the merge (Step 5) → flip
302
- > `agent::done` post-merge steps return the terminal JSON contract.
303
- > Ending the turn with prose and an unconfirmed merge is a contract
304
- > violation (the Story #1553 / PR #1554 failure mode). See
342
+ ## Step 4 — CI fix loop (**recovery-only**)
343
+
344
+ > **Steps 4, 5, 5.5, and 6 are recovery paths, not routine choreography
345
+ > (Story #4543).** On the default path Step 3 already polled the PR to a
346
+ > confirmed merge, flipped `agent::done`, and ran the whole post-land tail
347
+ > follow-up capture, status resync, ref cleanup, base fast-forward in one
348
+ > process. A `landed` envelope means all of it ran; go straight to Step 7.
349
+ >
350
+ > Enter this step **only** when Step 3 returned `blocked` with
351
+ > `blockClass: "checks-failed"` (a required check went red), or when a
352
+ > `--no-wait-merge` run left the PR for you to shepherd.
353
+
354
+ When a required check is red, the agent owns the green-CI outcome, not just
355
+ the push. Local close-validation gates pass on the dev host's environment;
356
+ CI runs on a different OS and concurrency, and coverage rounding,
357
+ platform-conditional branches, and timing-sensitive tests routinely drift
358
+ between the two.
359
+
360
+ Fix the failure and push a new commit on `story-<storyId>` auto-merge stays
361
+ armed across retries, so you do not re-arm then resume the land with the
362
+ envelope's `nextCommand`.
363
+
364
+ > **A watch is an internally-blocking step, not a reason to end your turn.**
365
+ > `pr-watch-with-update.js` blocks the current turn until CI resolves that
366
+ > IS how you wait. Ending the turn with prose and an unconfirmed merge is a
367
+ > contract violation (the Story #1553 / PR #1554 failure mode). See
305
368
  > [`deliver-story-reference.md` § The auto-merge wait is an internally-blocking step](deliver-story-reference.md#the-auto-merge-wait-is-an-internally-blocking-step).
306
369
 
307
- After `single-story-close.js` succeeds, enter the watch + fix loop. Drive
308
- `pr-watch-with-update.js` — the **single CI-watch mechanism** shared with
309
- the Epic Phase 8 path (Story #4358). It polls the required checks to a
370
+ To watch the checks on the red path, drive
371
+ `pr-watch-with-update.js` — the **single CI-watch mechanism**
372
+ (Story #4358). It polls the required checks to a
310
373
  terminal state and auto-recovers from `mergeStateStatus: BEHIND`; do
311
374
  **not** fall back to a bare `gh pr checks` watch invocation:
312
375
 
313
376
  ```bash
314
- node <agentRoot>/scripts/pr-watch-with-update.js --pr <prNumber>
377
+ node <agentRoot>/scripts/pr-watch-with-update.js --pr <prNumber> --story <storyId>
315
378
  ```
316
379
 
380
+ `--story` is what keys the red-path CI digest
381
+ (`temp/story-<id>-ci-digest.{json,md}` — failing check name, run id, and a
382
+ `gh run view --log-failed` tail). Omit it and a red check writes no digest.
383
+
317
384
  Poll cadence and caps come from `delivery.ci.watch.*`
318
385
  (`pollIntervalMs`, `maxPolls`, `maxResumes`); pass `--poll-interval-ms`,
319
386
  `--max-polls`, or `--max-resumes` to override for one run.
@@ -354,30 +421,22 @@ When the watch exits, branch on the exit code:
354
421
 
355
422
  ---
356
423
 
357
- ## Step 5 — Merge confirmation + `agent::done` flip (**required, not optional**)
358
-
359
- With auto-merge enabled (default), GitHub squash-merges the PR when
360
- every required check turns green and the `Closes #<id>` footer
361
- auto-closes the Story issue.
424
+ ## Step 5 — Merge confirmation + land tail (**recovery-only**)
362
425
 
363
- Confirm the merge landed:
364
-
365
- ```bash
366
- gh pr view <prNumber> --json state,mergedAt,mergeCommit
367
- ```
368
-
369
- Expect `state: "MERGED"`. With `--no-auto-merge`, the PR is the merge
370
- gate — the operator reviews and merges via the GitHub UI; the same
371
- `Closes #<id>` auto-close fires when the merge lands on `main`.
372
-
373
- **Then flip the Story to `agent::done`.** Step 3 deferred this flip
374
- (Story #3385); now that the merge is confirmed, drive the
375
- `agent::closing → agent::done` transition (which closes the issue) via:
426
+ > On the default path Step 3 already did this. Run it only to resume a
427
+ > `pending` envelope, to finish a `--no-wait-merge` run, or to rescue a
428
+ > merged-but-mislabelled Story.
376
429
 
377
430
  ```bash
378
431
  node .agents/scripts/single-story-confirm-merge.js --story <storyId> --cwd <main-repo>
379
432
  ```
380
433
 
434
+ This is the **same** shared land path Step 3 reaches: it flips
435
+ `agent::closing → agent::done` on a confirmed merge (closing the issue) and
436
+ runs the **same** post-land tail — so the two surfaces cannot diverge. It is
437
+ idempotent, emits the same terminal envelope, and is safe to re-run while
438
+ the PR is still open (returns `pending`).
439
+
381
440
  > **Confirmation outcomes.** `single-story-confirm-merge.js` re-reads the
382
441
  > live PR state and flips to `agent::done` only on a confirmed `MERGED` PR;
383
442
  > it is idempotent and safe to re-run while the PR is still open (returns
@@ -386,12 +445,16 @@ node .agents/scripts/single-story-confirm-merge.js --story <storyId> --cwd <main
386
445
 
387
446
  ---
388
447
 
389
- ## Step 5.5 — Re-assert Status column (**required, not optional**)
448
+ ## Step 5.5 — Re-assert Status column (**recovery-only**)
449
+
450
+ > **The land tail already ran this** (Story #4543) — it is `tail.statusResync`
451
+ > in the terminal envelope. Run it by hand only when that step reported
452
+ > `false`, or after a manual merge on a `--no-wait-merge` run.
390
453
 
391
454
  GitHub Projects v2 built-in workflows fire minutes *after* auto-merge lands
392
455
  and clobber the `Done` Status the confirm step set, stranding closed
393
456
  Stories at `In Progress` on the board (reproduced on Story #2813).
394
- Re-assert authority once the merge confirms:
457
+ Re-assert authority:
395
458
 
396
459
  ```bash
397
460
  node .agents/scripts/resync-status-column.js --story <storyId>
@@ -399,9 +462,7 @@ node .agents/scripts/resync-status-column.js --story <storyId>
399
462
 
400
463
  The helper re-fires the `ColumnSync` mutation and **polls for ~15 s** to win
401
464
  the race against the bot's late write (Story #2876). It is idempotent and
402
- no-op-safe (`no-project` / `not-on-project` exit 0). Skip Step 5.5 only when
403
- the operator opted out of auto-merge AND has not yet merged the PR — run it
404
- after the manual merge instead.
465
+ no-op-safe (`no-project` / `not-on-project` exit 0).
405
466
 
406
467
  > **Status-column detail + tuning flags + operator fix.** For the poll-loop
407
468
  > flags (`--poll-attempts`, `--poll-delay-ms`), the `attempts` / `drifted`
@@ -411,12 +472,18 @@ after the manual merge instead.
411
472
 
412
473
  ---
413
474
 
414
- ## Step 6 — Local branch cleanup (**required, not optional**)
475
+ ## Step 6 — Local branch cleanup (**recovery-only**)
476
+
477
+ > **The land tail already ran this** (Story #4543) — it is `tail.refCleanup`
478
+ > and `tail.baseFastForward` in the terminal envelope, done in-process
479
+ > against the same planners this command drives. Run it by hand only when
480
+ > either step reported `false` (a dirty shared checkout is the common,
481
+ > benign cause), or after a manual merge on a `--no-wait-merge` run.
415
482
 
416
483
  GitHub deletes the **remote** branch on auto-merge, but the **local**
417
484
  `story-<storyId>` ref lingers in the main checkout until something prunes
418
- it. After Step 5 confirms `state: "MERGED"`, prune the story ref **and**
419
- fast-forward local `main` (or `project.baseBranch`):
485
+ it. To prune the story ref **and** fast-forward local `main` (or
486
+ `project.baseBranch`):
420
487
 
421
488
  ```bash
422
489
  node .agents/scripts/git-cleanup.js \
@@ -444,37 +511,62 @@ run the cleanup after the manual merge lands.
444
511
 
445
512
  ## Step 7 — Return contract (**required when dispatched as a sub-agent**) {#return-contract}
446
513
 
514
+ The return contract is the shipped schema
515
+ [`story-deliver-terminal.schema.json`](../../schemas/story-deliver-terminal.schema.json)
516
+ — **the single source of truth for every field, and the only place they are
517
+ defined** (Story #4543). Do not restate its fields here or anywhere else:
518
+ this section and
519
+ [`agents/story-worker.md`](../../agents/story-worker.md) each used to define
520
+ their own divergent shape, neither validated by anything, which is exactly
521
+ how they drifted apart.
522
+
447
523
  When this workflow runs as a per-Story sub-agent (dispatched by
448
- [`/deliver`](../deliver.md)), the **only** acceptable way to end your turn
449
- is to **return a single terminal JSON status object** — never free-form
450
- prose:
451
-
452
- ```json
453
- {
454
- "storyId": <number>,
455
- "status": "done" | "blocked" | "failed",
456
- "phase": "init|implementing|closing|blocked|done",
457
- "branchDeleted": <boolean>,
458
- "blockerCommentId": <string|null>,
459
- "detail": "<one-liner: what changed + what was verified, e.g. PR #N merged>",
460
- "renderedBody": "<terminal Story body>"
461
- }
462
- ```
524
+ [`/deliver`](../deliver.md)), the **only** acceptable way to end your turn is
525
+ to return a single terminal JSON object conforming to that schema — never
526
+ free-form prose. `single-story-close.js` already emits a validated one
527
+ between its `--- STORY DELIVER TERMINAL ---` markers; **relay that envelope**
528
+ rather than composing a new object by hand.
529
+
530
+ Its `status` is one of exactly four values, and the no-park rule follows
531
+ directly from them:
532
+
533
+ - `landed` — the PR merged, the Story is `agent::done`, and the tail was
534
+ attempted. Terminal; you are done.
535
+ - `pending` **resumable**, and the only sanctioned way to end a turn
536
+ without a merge. It carries the `nextCommand` that resumes it. Return this
537
+ only when you have exhausted your own budget, not as a way to avoid
538
+ waiting: the wait is internally blocking (Step 4).
539
+ - `blocked` — the Story carries `agent::blocked` and `blocked.blockClass`
540
+ names the class.
541
+ - `failed` — a phase crashed; `phase` names it.
542
+
543
+ Ending the turn with prose and an unconfirmed merge is a contract violation
544
+ (the Story #1553 / PR #1554 failure mode).
545
+
546
+ > **No-park rule + handoff discipline.** For why a prose hand-off with an
547
+ > unconfirmed merge is the very bug this workflow prevents, and the
548
+ > report-state-not-process handoff discipline, see
549
+ > [`deliver-story-reference.md` § Step 7 — Return-contract detail](deliver-story-reference.md#step-7--return-contract-detail).
463
550
 
464
- This section is the single-homed return contract for the Story worker so it
465
- is self-contained when this workflow is the entry point.
551
+ ---
466
552
 
467
- There is **no fourth "pending" status** — the CI/auto-merge wait is handled
468
- internally by blocking on `pr-watch-with-update.js` (Step 4) and confirming
469
- the merge (Step 5). Return **only** on a confirmed `MERGED` PR (`status: "done"`),
470
- an `agent::blocked` transition (`status: "blocked"`), or an unrecoverable
471
- failure (`status: "failed"`).
553
+ ## Recovering a stranded Story {#recover}
472
554
 
473
- > **No-park rule + per-status contract + handoff discipline.** For the full
474
- > terminal-status contract (what each status requires), why a prose hand-off
475
- > with an unconfirmed merge is the very bug this workflow prevents, and the
476
- > report-state-not-process handoff discipline, see
477
- > [`deliver-story-reference.md` § Step 7 — Return-contract detail](deliver-story-reference.md#step-7--return-contract-detail).
555
+ When a Story is in an unclear state a killed run, a `pending` envelope you
556
+ no longer have, a Story a `/deliver` re-run refuses do not guess and do not
557
+ re-run the pipeline hoping it converges. Probe it:
558
+
559
+ ```bash
560
+ node .agents/scripts/deliver-recover.js --story <storyId>
561
+ ```
562
+
563
+ It is **read-only**: it probes the labels, lease, branch, worktree, and PR
564
+ (state + checks), then prints the **one** next command with the evidence it
565
+ was derived from — never a menu.
566
+
567
+ It is the only automated way out of the **merged-but-label-stale** strand: a
568
+ `/deliver` re-run refuses that Story outright, because `single-story-init.js`
569
+ hard-errors on an already-closed one.
478
570
 
479
571
  ---
480
572
 
@@ -510,9 +602,8 @@ safe.
510
602
  your caller (the `/deliver` aggregator or the interactive operator),
511
603
  report essential terminal state only: the Story branch, the closing commit
512
604
  SHA, what changed, and what was verified. Mirror the fields the close
513
- pipeline already emits (`single-story-close.js` / `story-phase.js`
514
- envelopes, the `story-run-progress` snapshot) rather than inventing a new
515
- contract. Do not narrate the steps you took, and do not prescribe how the
605
+ pipeline already emits (the `single-story-close.js` terminal envelope)
606
+ rather than inventing a new contract. Do not narrate the steps you took, and do not prescribe how the
516
607
  next stage should do its work. Prose process commentary only bloats the
517
608
  hydrated prompt.
518
609
  - **Label transitions**: drive every `agent::*` state change through
@@ -525,7 +616,7 @@ safe.
525
616
 
526
617
  ## See also
527
618
 
528
- - [`/deliver`](../deliver.md) — unified entry point (`<storyId...>` or
529
- `--run <planRunId>`; sequences via `depends_on`).
619
+ - [`/deliver`](../deliver.md) — unified entry point (`<storyId...>`;
620
+ sequences via `depends_on`, resolved from live state).
530
621
  - [`deliver-story-reference.md`](deliver-story-reference.md) —
531
622
  lease, sweep, CI-recovery, and Status-column reference detail.
@@ -20,8 +20,8 @@ them in one assistant turn rather than serially. The host runtime executes
20
20
  the batch in parallel; serial calls cost N round-trips for no gain.
21
21
 
22
22
  - **Tool primitives:** `Read`, `Grep`, `Glob`, MCP `list_*` / `get_*` calls.
23
- - **When:** reading the Epic body (with its folded Tech Spec sections)
24
- and Story body up front; grepping
23
+ - **When:** reading the Story body (with its inline `## Spec`)
24
+ up front; grepping
25
25
  for multiple unrelated patterns; globbing several directory trees;
26
26
  fetching independent GitHub tickets.
27
27
  - **Anti-pattern:** sequential `Read` → wait → `Read` → wait → `Grep` chains
@@ -19,32 +19,29 @@ for the broader execution flow.
19
19
 
20
20
  ## Configuration
21
21
 
22
- All knobs live under `delivery.worktreeIsolation` in `.agentrc.json`:
23
-
24
- ```jsonc
25
- {
26
- "delivery": {
27
- "worktreeIsolation": {
28
- "enabled": true, // master switch; false = single-tree (v5.5.1)
29
- "root": ".worktrees", // relative to repo root; must stay inside it
30
- "nodeModulesStrategy": "clone", // clone | per-worktree | symlink | pnpm-store
31
- "primeFromPath": null, // required when strategy = "symlink"
32
- "allowSymlinkOnWindows": false, // explicit opt-in for symlink on win32
33
- "reapOnSuccess": true, // remove worktree after successful story merge
34
- "bootstrapFiles": [
35
- ".env",
36
- ".mcp.json",
37
- ".agentrc.local.json",
38
- ".agents/instructions.local.md"
39
- ]
40
- }
41
- }
42
- }
43
- ```
44
-
45
- The schema is validated by `config-resolver.js`. Unknown strategies, `root`
46
- values that escape the repo root, and shell-metacharacter injection in `root`
47
- are all rejected at config-load time.
22
+ All knobs live under `delivery.worktreeIsolation` in `.agentrc.json`. The
23
+ **key list, types, and accepted enum values are not restated here** — the
24
+ runtime schema in `config-resolver.js` validates them and
25
+ [`.agents/docs/configuration.md`](../../docs/configuration.md) is generated
26
+ from it, so a copy in this file could only drift out of agreement with the
27
+ thing that actually enforces it. Read the generated table for the shape.
28
+
29
+ What that table cannot tell you is which knob to reach for, so this document
30
+ covers the judgement instead, each in its own section below:
31
+
32
+ - `enabled` the master switch; see [Fallback: single-tree mode](#fallback-single-tree-mode).
33
+ - `nodeModulesStrategy`, `primeFromPath`, `allowSymlinkOnWindows` see
34
+ [node_modules strategies](#node_modules-strategies).
35
+ - `root` — where worktrees materialize; see [Windows notes](#windows-notes)
36
+ for the long-path constraint on it.
37
+ - `reapOnSuccess` — drives the **Reap** phase in the lifecycle table below.
38
+ - `bootstrapFiles` — untracked, per-developer files (local env, MCP, and
39
+ `.agentrc.local.json` / `instructions.local.md` overrides) copied into each
40
+ new worktree, because a worktree checkout carries only tracked content and
41
+ would otherwise boot without the operator's local configuration.
42
+
43
+ Config-load rejects unknown strategies, `root` values that escape the repo
44
+ root, and shell-metacharacter injection in `root`.
48
45
 
49
46
  ## Lifecycle
50
47
 
@@ -119,7 +116,7 @@ PowerShell `Get-CimInstance Win32_Process`, terminating them with
119
116
 
120
117
  ### When to run it manually
121
118
 
122
- - The end-of-epic banner reports `pending-cleanup persistent-lock: story-N, ...`.
119
+ - The close output reports `pending-cleanup persistent-lock: story-N, ...`.
123
120
  - `git worktree list` shows `.worktrees/story-N/` for a closed Story.
124
121
  - `npm run lint` fails because of a nested `biome.json` in a half-reaped
125
122
  worktree. The `worktree-residue-biome` self-healing check detects this
@@ -237,7 +234,7 @@ Symlink strategy:
237
234
  the pre-flight warning below catches those cases before a build breaks.
238
235
  - **Long-path warning**: when `worktreePath.length + 80` exceeds
239
236
  `windowsPathLengthWarnThreshold` (default 240), `WorktreeManager` emits a
240
- warning locally and the dispatcher posts an `⚠️` comment on the Epic issue.
237
+ warning locally.
241
238
  Relocate `delivery.worktreeIsolation.root` to a shorter prefix (e.g.
242
239
  `C:\w`) if you see this.
243
240
  - **`packed-refs` contention**: two worktrees fetching concurrently can collide
@@ -335,12 +332,11 @@ Pick single-tree mode when:
335
332
 
336
333
  Human reviewers should **keep using the main checkout** — not a worktree:
337
334
 
338
- - The Epic branch accumulates the cumulative diff for code review; that lives on
339
- the main checkout, not in any per-story worktree.
335
+ - Each Story's diff is reviewed on its PR on GitHub (`story-<id>` `main`);
336
+ no local branch accumulates a cumulative diff for review.
340
337
  - Opening a worktree in an IDE can mislead: the working directory looks like the
341
338
  main repo but carries a different HEAD. The main checkout is the canonical
342
- place to read Epic planning bodies and run the `helpers/code-review.md`
343
- procedure.
339
+ place to run the `helpers/code-review.md` procedure.
344
340
  - `git worktree list --porcelain` on the main checkout enumerates any still
345
341
  in-flight story worktrees if you need to inspect one — prefer read-only
346
342
  operations (`git log`, `git show`) when you do.