mandrel 2.59.0 → 2.61.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 (678) hide show
  1. package/.agents/README.md +21 -19
  2. package/.agents/agents/acceptance-critic.md +24 -43
  3. package/.agents/agents/story-worker.md +20 -21
  4. package/.agents/docs/agentrc-reference.json +5 -84
  5. package/.agents/docs/configuration.md +48 -132
  6. package/.agents/docs/workflows.md +2 -2
  7. package/.agents/instructions.md +5 -8
  8. package/.agents/rules/ci-remediation.md +41 -8
  9. package/.agents/rules/gherkin-standards.md +4 -0
  10. package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
  11. package/.agents/schemas/agentrc.schema.json +16 -496
  12. package/.agents/schemas/story-deliver-terminal.schema.json +13 -3
  13. package/.agents/schemas/validation-evidence.schema.json +2 -1
  14. package/.agents/scripts/README.md +23 -13
  15. package/.agents/scripts/acceptance-eval.js +35 -169
  16. package/.agents/scripts/agents-bootstrap-github.js +27 -129
  17. package/.agents/scripts/apply-quality-bootstrap.js +4 -40
  18. package/.agents/scripts/audit-baselines.js +6 -27
  19. package/.agents/scripts/audit-labels-bootstrap.js +5 -29
  20. package/.agents/scripts/audit-to-stories.js +91 -361
  21. package/.agents/scripts/boot-sweep.js +19 -72
  22. package/.agents/scripts/bootstrap.js +74 -395
  23. package/.agents/scripts/ceremony-derive.js +10 -41
  24. package/.agents/scripts/check-arch-cycles.js +14 -64
  25. package/.agents/scripts/check-baselines.js +8 -48
  26. package/.agents/scripts/check-context-budget.js +105 -311
  27. package/.agents/scripts/check-cyclomatic.js +12 -44
  28. package/.agents/scripts/check-dead-exports.js +13 -64
  29. package/.agents/scripts/check-doc-links.js +38 -186
  30. package/.agents/scripts/check-gherkin-corpus.js +24 -127
  31. package/.agents/scripts/check-test-temp-hygiene.js +28 -169
  32. package/.agents/scripts/coverage-capture.js +34 -98
  33. package/.agents/scripts/deliver-light.js +25 -171
  34. package/.agents/scripts/deliver-recover.js +6 -42
  35. package/.agents/scripts/deliver-run.js +534 -0
  36. package/.agents/scripts/diagnose-friction.js +24 -116
  37. package/.agents/scripts/drain-pending-cleanup.js +1 -1
  38. package/.agents/scripts/evidence-gate.js +23 -85
  39. package/.agents/scripts/file-ci-gap.js +57 -49
  40. package/.agents/scripts/generate-config-docs.js +30 -170
  41. package/.agents/scripts/generate-lens-checklists.js +8 -52
  42. package/.agents/scripts/generate-skills-index.js +14 -112
  43. package/.agents/scripts/generate-workflows-doc.js +10 -70
  44. package/.agents/scripts/git-cleanup.js +2 -34
  45. package/.agents/scripts/lib/Graph.js +24 -81
  46. package/.agents/scripts/lib/ITicketingProvider.js +47 -143
  47. package/.agents/scripts/lib/Logger.js +14 -76
  48. package/.agents/scripts/lib/audit-baselines/engine.js +11 -31
  49. package/.agents/scripts/lib/audit-baselines/gate-surface.js +3 -17
  50. package/.agents/scripts/lib/audit-baselines/headroom.js +4 -20
  51. package/.agents/scripts/lib/audit-baselines/hotspots.js +3 -15
  52. package/.agents/scripts/lib/audit-baselines/kinds.js +23 -89
  53. package/.agents/scripts/lib/audit-baselines/outliers.js +6 -23
  54. package/.agents/scripts/lib/audit-baselines/read.js +3 -16
  55. package/.agents/scripts/lib/audit-baselines/staleness.js +7 -26
  56. package/.agents/scripts/lib/audit-baselines/surface-entry.js +7 -28
  57. package/.agents/scripts/lib/audit-baselines/trend.js +7 -20
  58. package/.agents/scripts/lib/audit-baselines/weights.js +9 -37
  59. package/.agents/scripts/lib/audit-suite/audit-rules-reader.js +3 -18
  60. package/.agents/scripts/lib/audit-suite/checklist-threading.js +26 -124
  61. package/.agents/scripts/lib/audit-suite/dispatch-checklist.js +14 -45
  62. package/.agents/scripts/lib/audit-suite/findings.js +12 -52
  63. package/.agents/scripts/lib/audit-suite/frontmatter.js +5 -29
  64. package/.agents/scripts/lib/audit-suite/index.js +1 -15
  65. package/.agents/scripts/lib/audit-suite/lens-checklist.js +10 -45
  66. package/.agents/scripts/lib/audit-suite/lens-diff-floor.js +11 -76
  67. package/.agents/scripts/lib/audit-suite/runner.js +13 -43
  68. package/.agents/scripts/lib/audit-suite/selector.js +49 -349
  69. package/.agents/scripts/lib/audit-suite/substitutions.js +12 -40
  70. package/.agents/scripts/lib/audit-suite/workflow-loader.js +3 -15
  71. package/.agents/scripts/lib/audit-to-stories/audit-label-taxonomy.js +11 -73
  72. package/.agents/scripts/lib/audit-to-stories/audit-lenses.js +8 -37
  73. package/.agents/scripts/lib/audit-to-stories/build-story-body.js +25 -143
  74. package/.agents/scripts/lib/audit-to-stories/dedupe-against-github.js +14 -80
  75. package/.agents/scripts/lib/audit-to-stories/epic-grouping-directive.js +4 -18
  76. package/.agents/scripts/lib/audit-to-stories/finding-adapter.js +7 -40
  77. package/.agents/scripts/lib/audit-to-stories/group-findings.js +9 -39
  78. package/.agents/scripts/lib/audit-to-stories/issue-corpus.js +10 -66
  79. package/.agents/scripts/lib/audit-to-stories/issue-index.js +6 -30
  80. package/.agents/scripts/lib/audit-to-stories/issues-file.js +6 -36
  81. package/.agents/scripts/lib/audit-to-stories/ledger-commit.js +17 -69
  82. package/.agents/scripts/lib/audit-to-stories/ledger-pr.js +17 -85
  83. package/.agents/scripts/lib/audit-to-stories/ledger-record.js +10 -48
  84. package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +38 -146
  85. package/.agents/scripts/lib/audit-to-stories/seed-from-findings.js +7 -42
  86. package/.agents/scripts/lib/audit-to-stories/wire-dependencies.js +10 -57
  87. package/.agents/scripts/lib/baseline-loader.js +12 -51
  88. package/.agents/scripts/lib/baseline-schema-registry.js +5 -22
  89. package/.agents/scripts/lib/baselines/component-matcher.js +3 -12
  90. package/.agents/scripts/lib/baselines/components.js +10 -61
  91. package/.agents/scripts/lib/baselines/coverage-updater-cli.js +7 -36
  92. package/.agents/scripts/lib/baselines/crap-preview-incremental.js +7 -19
  93. package/.agents/scripts/lib/baselines/crap-preview-scan.js +19 -45
  94. package/.agents/scripts/lib/baselines/crap-updater-cli.js +16 -65
  95. package/.agents/scripts/lib/baselines/diff-scope-cli.js +5 -33
  96. package/.agents/scripts/lib/baselines/duplication-scanner.js +11 -60
  97. package/.agents/scripts/lib/baselines/env-overrides.js +12 -67
  98. package/.agents/scripts/lib/baselines/envelope.js +13 -129
  99. package/.agents/scripts/lib/baselines/exit-codes.js +6 -49
  100. package/.agents/scripts/lib/baselines/git-base.js +23 -142
  101. package/.agents/scripts/lib/baselines/kernel.js +11 -111
  102. package/.agents/scripts/lib/baselines/kinds/_crap-new-method-gate.js +9 -47
  103. package/.agents/scripts/lib/baselines/kinds/_crap-read.js +8 -51
  104. package/.agents/scripts/lib/baselines/kinds/_shared-metric.js +7 -62
  105. package/.agents/scripts/lib/baselines/kinds/bundle-size.js +8 -29
  106. package/.agents/scripts/lib/baselines/kinds/coverage.js +3 -15
  107. package/.agents/scripts/lib/baselines/kinds/crap.js +94 -415
  108. package/.agents/scripts/lib/baselines/kinds/duplication.js +4 -30
  109. package/.agents/scripts/lib/baselines/kinds/kind-factory.js +7 -53
  110. package/.agents/scripts/lib/baselines/kinds/maintainability.js +15 -80
  111. package/.agents/scripts/lib/baselines/kinds/mutation.js +12 -72
  112. package/.agents/scripts/lib/baselines/maintainability-baseline-io.js +4 -11
  113. package/.agents/scripts/lib/baselines/merge-envelopes.js +30 -146
  114. package/.agents/scripts/lib/baselines/path-canon.js +19 -128
  115. package/.agents/scripts/lib/baselines/preview-gates.js +8 -37
  116. package/.agents/scripts/lib/baselines/reader.js +14 -107
  117. package/.agents/scripts/lib/baselines/refresh-service.js +35 -252
  118. package/.agents/scripts/lib/baselines/scope.js +11 -135
  119. package/.agents/scripts/lib/baselines/writer.js +16 -149
  120. package/.agents/scripts/lib/bdd-runner-detect.js +18 -113
  121. package/.agents/scripts/lib/bdd-scenario-budget.js +9 -36
  122. package/.agents/scripts/lib/bdd-scenario-scanner.js +11 -73
  123. package/.agents/scripts/lib/bdd-step-index.js +26 -100
  124. package/.agents/scripts/lib/bootstrap/baseline-merge-driver.js +23 -103
  125. package/.agents/scripts/lib/bootstrap/branch-protection.js +2 -5
  126. package/.agents/scripts/lib/bootstrap/commit-push.js +12 -50
  127. package/.agents/scripts/lib/bootstrap/gh-preflight.js +14 -101
  128. package/.agents/scripts/lib/bootstrap/hitl-confirm.js +5 -30
  129. package/.agents/scripts/lib/bootstrap/install-ledger.js +17 -73
  130. package/.agents/scripts/lib/bootstrap/issue-forms-template.js +17 -121
  131. package/.agents/scripts/lib/bootstrap/manifest.js +15 -86
  132. package/.agents/scripts/lib/bootstrap/merge-methods.js +4 -33
  133. package/.agents/scripts/lib/bootstrap/preflight.js +12 -61
  134. package/.agents/scripts/lib/bootstrap/project-bootstrap.js +34 -235
  135. package/.agents/scripts/lib/bootstrap/prompt.js +21 -129
  136. package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +27 -141
  137. package/.agents/scripts/lib/bootstrap/summary.js +1 -8
  138. package/.agents/scripts/lib/bootstrap/workflow-audit.js +11 -84
  139. package/.agents/scripts/lib/branch-name-guard.js +4 -23
  140. package/.agents/scripts/lib/changed-files.js +39 -121
  141. package/.agents/scripts/lib/checks/core-bare-clean.js +4 -24
  142. package/.agents/scripts/lib/checks/index.js +18 -101
  143. package/.agents/scripts/lib/checks/loop-health.js +11 -53
  144. package/.agents/scripts/lib/checks/state.js +16 -91
  145. package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +10 -61
  146. package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +14 -83
  147. package/.agents/scripts/lib/child-exec.js +39 -108
  148. package/.agents/scripts/lib/cli/standard-args.js +9 -116
  149. package/.agents/scripts/lib/cli-args.js +31 -146
  150. package/.agents/scripts/lib/cli-usage.js +5 -27
  151. package/.agents/scripts/lib/cli-utils.js +2 -12
  152. package/.agents/scripts/lib/close-validation/commands.js +13 -76
  153. package/.agents/scripts/lib/close-validation/gates.js +92 -331
  154. package/.agents/scripts/lib/close-validation/process.js +121 -151
  155. package/.agents/scripts/lib/close-validation/projections/advisories.js +5 -31
  156. package/.agents/scripts/lib/close-validation/projections/crap.js +19 -67
  157. package/.agents/scripts/lib/close-validation/projections/head-sha.js +1 -17
  158. package/.agents/scripts/lib/close-validation/projections/inputs.js +4 -34
  159. package/.agents/scripts/lib/close-validation/projections/maintainability.js +11 -58
  160. package/.agents/scripts/lib/close-validation/runner.js +53 -110
  161. package/.agents/scripts/lib/command-header.js +6 -28
  162. package/.agents/scripts/lib/config/acceptance-eval.js +4 -30
  163. package/.agents/scripts/lib/config/baselines.js +3 -14
  164. package/.agents/scripts/lib/config/ci.js +8 -38
  165. package/.agents/scripts/lib/config/commands.js +1 -15
  166. package/.agents/scripts/lib/config/defaults.js +4 -33
  167. package/.agents/scripts/lib/config/delivery-routing.js +6 -34
  168. package/.agents/scripts/lib/config/explain.js +10 -83
  169. package/.agents/scripts/lib/config/gates/coverage.schema.js +0 -12
  170. package/.agents/scripts/lib/config/gates/crap-incremental-coverage.schema.js +3 -31
  171. package/.agents/scripts/lib/config/gates/crap.schema.js +1 -34
  172. package/.agents/scripts/lib/config/gates/duplication.schema.js +1 -8
  173. package/.agents/scripts/lib/config/gates/index.js +2 -17
  174. package/.agents/scripts/lib/config/gates/maintainability.schema.js +1 -20
  175. package/.agents/scripts/lib/config/gates/mutation.schema.js +1 -7
  176. package/.agents/scripts/lib/config/gates/shared.js +4 -64
  177. package/.agents/scripts/lib/config/github.js +4 -22
  178. package/.agents/scripts/lib/config/limits.js +4 -57
  179. package/.agents/scripts/lib/config/paths.js +2 -21
  180. package/.agents/scripts/lib/config/qa.js +4 -38
  181. package/.agents/scripts/lib/config/quality.js +76 -432
  182. package/.agents/scripts/lib/config/runners.js +12 -56
  183. package/.agents/scripts/lib/config/runtime.js +13 -57
  184. package/.agents/scripts/lib/config/shared.js +2 -16
  185. package/.agents/scripts/lib/config/sync-agentrc.js +9 -50
  186. package/.agents/scripts/lib/config/temp-paths.js +40 -280
  187. package/.agents/scripts/lib/config/validate-orchestration.js +5 -17
  188. package/.agents/scripts/lib/config/worktree-isolation.js +9 -28
  189. package/.agents/scripts/lib/config-resolver.js +11 -52
  190. package/.agents/scripts/lib/config-schema-shared.js +1 -4
  191. package/.agents/scripts/lib/config-settings-schema-delivery.js +16 -291
  192. package/.agents/scripts/lib/config-settings-schema-quality.js +7 -219
  193. package/.agents/scripts/lib/config-settings-schema.js +37 -274
  194. package/.agents/scripts/lib/coverage-baseline.js +20 -110
  195. package/.agents/scripts/lib/coverage-capture-fullscope.js +18 -35
  196. package/.agents/scripts/lib/coverage-capture-incremental.js +15 -45
  197. package/.agents/scripts/lib/coverage-capture-usage.js +8 -25
  198. package/.agents/scripts/lib/coverage-capture.js +99 -224
  199. package/.agents/scripts/lib/coverage-utils.js +14 -79
  200. package/.agents/scripts/lib/cpu-pool.js +17 -123
  201. package/.agents/scripts/lib/crap-baseline-join.js +16 -88
  202. package/.agents/scripts/lib/crap-coordinates.js +6 -25
  203. package/.agents/scripts/lib/crap-engine.js +40 -153
  204. package/.agents/scripts/lib/crap-method-identity.js +16 -78
  205. package/.agents/scripts/lib/crap-utils.js +31 -155
  206. package/.agents/scripts/lib/cyclomatic-ceiling.js +14 -87
  207. package/.agents/scripts/lib/cyclomatic-scope.js +10 -50
  208. package/.agents/scripts/lib/dead-exports-knip.js +18 -56
  209. package/.agents/scripts/lib/dead-exports-mode.js +5 -24
  210. package/.agents/scripts/lib/degraded-mode.js +3 -26
  211. package/.agents/scripts/lib/dependency-parser.js +8 -40
  212. package/.agents/scripts/lib/dependency-version.js +13 -35
  213. package/.agents/scripts/lib/detect-package-manager.js +6 -36
  214. package/.agents/scripts/lib/doc-tiers.js +22 -124
  215. package/.agents/scripts/lib/duplicate-search.js +8 -72
  216. package/.agents/scripts/lib/env-loader.js +5 -27
  217. package/.agents/scripts/lib/error-redactor.js +6 -31
  218. package/.agents/scripts/lib/errors/index.js +2 -22
  219. package/.agents/scripts/lib/escomplex-ast-compat.js +22 -163
  220. package/.agents/scripts/lib/escomplex-kernel.js +21 -123
  221. package/.agents/scripts/lib/feedback-loop/graduator-core.js +94 -419
  222. package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +20 -98
  223. package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +27 -149
  224. package/.agents/scripts/lib/findings/audit-ledger.js +23 -97
  225. package/.agents/scripts/lib/findings/classify-finding.js +14 -69
  226. package/.agents/scripts/lib/findings/promote-finding.js +14 -112
  227. package/.agents/scripts/lib/findings/provenance-field.js +11 -52
  228. package/.agents/scripts/lib/findings/route-finding.js +37 -255
  229. package/.agents/scripts/lib/findings/semantic-issue-search.js +14 -59
  230. package/.agents/scripts/lib/findings/severity.js +18 -104
  231. package/.agents/scripts/lib/format-generated-json.js +12 -44
  232. package/.agents/scripts/lib/full-suite-lock.js +160 -429
  233. package/.agents/scripts/lib/full-suite-queue.js +213 -0
  234. package/.agents/scripts/lib/gates/baseline-store.js +5 -9
  235. package/.agents/scripts/lib/gates/friction.js +1 -3
  236. package/.agents/scripts/lib/generated/agentrc-validator.js +2 -2
  237. package/.agents/scripts/lib/gh-exec.js +123 -191
  238. package/.agents/scripts/lib/git/cached-fetch.js +9 -52
  239. package/.agents/scripts/lib/git/sync-from-base.js +15 -107
  240. package/.agents/scripts/lib/git-branch-cleanup.js +14 -61
  241. package/.agents/scripts/lib/git-branch-lifecycle.js +16 -87
  242. package/.agents/scripts/lib/git-utils.js +37 -161
  243. package/.agents/scripts/lib/github/framework-repo.js +8 -71
  244. package/.agents/scripts/lib/github-url.js +2 -17
  245. package/.agents/scripts/lib/import-graph.js +11 -38
  246. package/.agents/scripts/lib/install-cmd-parser.js +4 -13
  247. package/.agents/scripts/lib/json-utils.js +3 -18
  248. package/.agents/scripts/lib/label-constants.js +16 -111
  249. package/.agents/scripts/lib/label-taxonomy.js +4 -30
  250. package/.agents/scripts/lib/maintainability-engine.js +12 -80
  251. package/.agents/scripts/lib/maintainability-unscorable.js +5 -25
  252. package/.agents/scripts/lib/maintainability-utils.js +16 -92
  253. package/.agents/scripts/lib/mandrel-catalog.js +12 -70
  254. package/.agents/scripts/lib/notifications/notifier.js +13 -38
  255. package/.agents/scripts/lib/npm-scripts.js +4 -23
  256. package/.agents/scripts/lib/observability/metrics-ledger.js +16 -76
  257. package/.agents/scripts/lib/observability/runtime-friction.js +44 -286
  258. package/.agents/scripts/lib/observability/signal-validator.js +5 -37
  259. package/.agents/scripts/lib/observability/signals-writer.js +11 -121
  260. package/.agents/scripts/lib/observability/source-classifier.js +22 -203
  261. package/.agents/scripts/lib/observability/terse-result.js +14 -47
  262. package/.agents/scripts/lib/onboard/init-tail.js +13 -74
  263. package/.agents/scripts/lib/onboard/scaffold-docs.js +11 -34
  264. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +25 -139
  265. package/.agents/scripts/lib/orchestration/auto-merge-cwd.js +11 -66
  266. package/.agents/scripts/lib/orchestration/behind-recovery.js +10 -55
  267. package/.agents/scripts/lib/orchestration/ceremony-routing.js +28 -156
  268. package/.agents/scripts/lib/orchestration/change-set.js +7 -36
  269. package/.agents/scripts/lib/orchestration/check-baselines/phases/compare.js +9 -46
  270. package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +11 -44
  271. package/.agents/scripts/lib/orchestration/check-baselines/phases/floors.js +5 -24
  272. package/.agents/scripts/lib/orchestration/check-baselines/phases/friction.js +3 -12
  273. package/.agents/scripts/lib/orchestration/check-baselines/phases/parse-args.js +5 -38
  274. package/.agents/scripts/lib/orchestration/check-baselines/phases/pipeline.js +3 -8
  275. package/.agents/scripts/lib/orchestration/check-baselines/phases/refresh-ack.js +28 -136
  276. package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +3 -13
  277. package/.agents/scripts/lib/orchestration/check-state.js +92 -0
  278. package/.agents/scripts/lib/orchestration/ci-gap-intake.js +37 -144
  279. package/.agents/scripts/lib/orchestration/ci-rerun-guard.js +121 -157
  280. package/.agents/scripts/lib/orchestration/code-review.js +24 -128
  281. package/.agents/scripts/lib/orchestration/column-sync.js +23 -111
  282. package/.agents/scripts/lib/orchestration/complexity-gate.js +118 -462
  283. package/.agents/scripts/lib/orchestration/deliver-recover.js +36 -168
  284. package/.agents/scripts/lib/orchestration/dependency-analyzer.js +4 -35
  285. package/.agents/scripts/lib/orchestration/dependency-candidates.js +9 -41
  286. package/.agents/scripts/lib/orchestration/diff-magnitude.js +25 -115
  287. package/.agents/scripts/lib/orchestration/doc-reader.js +2 -6
  288. package/.agents/scripts/lib/orchestration/docs-digest.js +13 -51
  289. package/.agents/scripts/lib/orchestration/epic-candidates.js +13 -53
  290. package/.agents/scripts/lib/orchestration/epic-checklist.js +9 -33
  291. package/.agents/scripts/lib/orchestration/epic-container.js +41 -167
  292. package/.agents/scripts/lib/orchestration/epic-expansion.js +10 -40
  293. package/.agents/scripts/lib/orchestration/epic-rollup.js +55 -207
  294. package/.agents/scripts/lib/orchestration/file-assumption-enum.js +2 -22
  295. package/.agents/scripts/lib/orchestration/file-assumptions.js +45 -253
  296. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-detect.js +9 -46
  297. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-reap.js +7 -57
  298. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches.js +21 -126
  299. package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +2 -6
  300. package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +1 -4
  301. package/.agents/scripts/lib/orchestration/git-cleanup/phases/filters.js +1 -5
  302. package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes-ff.js +9 -34
  303. package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes.js +41 -190
  304. package/.agents/scripts/lib/orchestration/git-cleanup/phases/merged-tip.js +9 -45
  305. package/.agents/scripts/lib/orchestration/git-cleanup/phases/parse-args.js +1 -4
  306. package/.agents/scripts/lib/orchestration/git-cleanup/phases/phase-drivers.js +19 -85
  307. package/.agents/scripts/lib/orchestration/git-cleanup/phases/prompts.js +3 -17
  308. package/.agents/scripts/lib/orchestration/git-cleanup/phases/prune.js +1 -5
  309. package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +16 -100
  310. package/.agents/scripts/lib/orchestration/git-cleanup/phases/stashes.js +1 -4
  311. package/.agents/scripts/lib/orchestration/lease-guard-shared.js +16 -67
  312. package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +9 -33
  313. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +8 -29
  314. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +15 -68
  315. package/.agents/scripts/lib/orchestration/light-backstop.js +11 -49
  316. package/.agents/scripts/lib/orchestration/light-escalation.js +21 -89
  317. package/.agents/scripts/lib/orchestration/light-suitability.js +37 -307
  318. package/.agents/scripts/lib/orchestration/merge-block-class.js +39 -216
  319. package/.agents/scripts/lib/orchestration/merge-poll.js +104 -377
  320. package/.agents/scripts/lib/orchestration/pinned-identifier-lint.js +17 -57
  321. package/.agents/scripts/lib/orchestration/plan-context.js +55 -318
  322. package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +22 -79
  323. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +5 -31
  324. package/.agents/scripts/lib/orchestration/plan-metrics.js +29 -108
  325. package/.agents/scripts/lib/orchestration/plan-navigation.js +8 -27
  326. package/.agents/scripts/lib/orchestration/plan-persist/acceptance-handle-repair.js +12 -49
  327. package/.agents/scripts/lib/orchestration/plan-persist/audit-provenance.js +18 -73
  328. package/.agents/scripts/lib/orchestration/plan-persist/changes-repair.js +16 -78
  329. package/.agents/scripts/lib/orchestration/plan-persist/cross-plan-links.js +6 -30
  330. package/.agents/scripts/lib/orchestration/plan-persist/epic-adoption.js +14 -65
  331. package/.agents/scripts/lib/orchestration/plan-persist/epic-ops.js +21 -76
  332. package/.agents/scripts/lib/orchestration/plan-persist/external-deps.js +6 -43
  333. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +14 -68
  334. package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +9 -41
  335. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +71 -289
  336. package/.agents/scripts/lib/orchestration/plan-persist/soft-findings.js +2 -12
  337. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +96 -362
  338. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +9 -39
  339. package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +60 -186
  340. package/.agents/scripts/lib/orchestration/plan-persist/wave-collision-gate.js +9 -49
  341. package/.agents/scripts/lib/orchestration/plan-persist/wave-serialisation.js +7 -28
  342. package/.agents/scripts/lib/orchestration/plan-reachability.js +13 -42
  343. package/.agents/scripts/lib/orchestration/plan-run-labels/reap.js +16 -91
  344. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +16 -54
  345. package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +10 -52
  346. package/.agents/scripts/lib/orchestration/planning/authoring-context.js +14 -109
  347. package/.agents/scripts/lib/orchestration/planning/memory-pool-advisory.js +11 -83
  348. package/.agents/scripts/lib/orchestration/pr-watch.js +48 -306
  349. package/.agents/scripts/lib/orchestration/project-meta-cache.js +15 -80
  350. package/.agents/scripts/lib/orchestration/project-meta-resolver.js +10 -51
  351. package/.agents/scripts/lib/orchestration/reassert-status-column.js +12 -76
  352. package/.agents/scripts/lib/orchestration/remote-verifier.js +12 -36
  353. package/.agents/scripts/lib/orchestration/resolve-stories.js +33 -164
  354. package/.agents/scripts/lib/orchestration/retro-proposals.js +66 -361
  355. package/.agents/scripts/lib/orchestration/review-base-ref.js +9 -43
  356. package/.agents/scripts/lib/orchestration/review-depth.js +12 -91
  357. package/.agents/scripts/lib/orchestration/review-providers/codex.js +10 -111
  358. package/.agents/scripts/lib/orchestration/review-providers/degraded-gates.js +13 -71
  359. package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +7 -51
  360. package/.agents/scripts/lib/orchestration/review-providers/mi-exemptions.js +8 -53
  361. package/.agents/scripts/lib/orchestration/review-providers/native.js +30 -214
  362. package/.agents/scripts/lib/orchestration/review-providers/parse-findings.js +7 -52
  363. package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +4 -33
  364. package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +11 -71
  365. package/.agents/scripts/lib/orchestration/review-providers/scoped-lint.js +19 -131
  366. package/.agents/scripts/lib/orchestration/review-providers/security-review.js +6 -89
  367. package/.agents/scripts/lib/orchestration/review-providers/types.js +26 -56
  368. package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +3 -46
  369. package/.agents/scripts/lib/orchestration/run-epilogue.js +245 -326
  370. package/.agents/scripts/lib/orchestration/run-scoped-config.js +55 -159
  371. package/.agents/scripts/lib/orchestration/single-story-close/close-note.js +7 -34
  372. package/.agents/scripts/lib/orchestration/single-story-close/failed-terminal.js +16 -89
  373. package/.agents/scripts/lib/orchestration/single-story-close/gate-log.js +18 -109
  374. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +83 -239
  375. package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +20 -82
  376. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +103 -97
  377. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +8 -64
  378. package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +136 -486
  379. package/.agents/scripts/lib/orchestration/single-story-close/phases/conventional-subject.js +30 -134
  380. package/.agents/scripts/lib/orchestration/single-story-close/phases/graphql-preflight.js +96 -0
  381. package/.agents/scripts/lib/orchestration/single-story-close/phases/lock-wait-pending.js +49 -0
  382. package/.agents/scripts/lib/orchestration/single-story-close/phases/normalize-pr-title.js +13 -86
  383. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +20 -95
  384. package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +46 -203
  385. package/.agents/scripts/lib/orchestration/single-story-close/phases/pre-gate-steps.js +8 -50
  386. package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +12 -83
  387. package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +6 -39
  388. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +1 -6
  389. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-outcome.js +4 -28
  390. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-override.js +6 -51
  391. package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +6 -34
  392. package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +23 -121
  393. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +180 -273
  394. package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +15 -69
  395. package/.agents/scripts/lib/orchestration/story-body-gate.js +4 -23
  396. package/.agents/scripts/lib/orchestration/story-close/baseline-upward-writeback.js +50 -179
  397. package/.agents/scripts/lib/orchestration/story-close/context-budget-writeback.js +11 -41
  398. package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +23 -311
  399. package/.agents/scripts/lib/orchestration/story-close/phases/local-lens-review.js +22 -147
  400. package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +16 -67
  401. package/.agents/scripts/lib/orchestration/story-deliver-terminal-schema.js +12 -68
  402. package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +42 -200
  403. package/.agents/scripts/lib/orchestration/story-follow-ups.js +167 -252
  404. package/.agents/scripts/lib/orchestration/story-init-envelope.js +52 -0
  405. package/.agents/scripts/lib/orchestration/story-init-remote.js +2 -6
  406. package/.agents/scripts/lib/orchestration/story-reachability.js +3 -23
  407. package/.agents/scripts/lib/orchestration/task-body-validator.js +12 -135
  408. package/.agents/scripts/lib/orchestration/ticket-lease.js +28 -131
  409. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +15 -149
  410. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +5 -33
  411. package/.agents/scripts/lib/orchestration/ticket-validator.js +63 -344
  412. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +51 -244
  413. package/.agents/scripts/lib/orchestration/ticketing/reads.js +39 -261
  414. package/.agents/scripts/lib/orchestration/ticketing/state.js +14 -68
  415. package/.agents/scripts/lib/orchestration/ticketing/transition.js +46 -263
  416. package/.agents/scripts/lib/orchestration/ticketing.js +2 -26
  417. package/.agents/scripts/lib/orchestration/verify-credit.js +18 -79
  418. package/.agents/scripts/lib/orchestration/worktree-dirty.js +5 -30
  419. package/.agents/scripts/lib/path-security.js +3 -6
  420. package/.agents/scripts/lib/plan-phase-cleanup.js +9 -49
  421. package/.agents/scripts/lib/preflight-runner.js +13 -69
  422. package/.agents/scripts/lib/process-group.js +143 -0
  423. package/.agents/scripts/lib/project-root.js +2 -8
  424. package/.agents/scripts/lib/provider-factory.js +2 -25
  425. package/.agents/scripts/lib/qa/console-allowlist.js +10 -59
  426. package/.agents/scripts/lib/qa/qa-session.js +15 -69
  427. package/.agents/scripts/lib/qa/redact-evidence.js +18 -129
  428. package/.agents/scripts/lib/qa/resolve-qa-contract.js +26 -135
  429. package/.agents/scripts/lib/qa/resolve-selection.js +16 -84
  430. package/.agents/scripts/lib/reserved-test-ids.js +9 -47
  431. package/.agents/scripts/lib/runtime-deps/dep-resolution.js +13 -53
  432. package/.agents/scripts/lib/runtime-deps/ensure-installed.js +10 -44
  433. package/.agents/scripts/lib/runtime-deps/manifest.js +10 -30
  434. package/.agents/scripts/lib/runtime-deps/parser-major.js +15 -51
  435. package/.agents/scripts/lib/runtime-deps/preflight.js +4 -22
  436. package/.agents/scripts/lib/runtime-deps/scan-imports.js +11 -55
  437. package/.agents/scripts/lib/signals/detectors/common.js +12 -38
  438. package/.agents/scripts/lib/signals/index.js +2 -19
  439. package/.agents/scripts/lib/signals/schema.js +14 -109
  440. package/.agents/scripts/lib/signals/write.js +2 -11
  441. package/.agents/scripts/lib/single-story/confirm-merge.js +31 -72
  442. package/.agents/scripts/lib/single-story/story-merged-notify.js +8 -49
  443. package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +4 -26
  444. package/.agents/scripts/lib/single-story-sweep/protection.js +13 -100
  445. package/.agents/scripts/lib/single-story-sweep/sweep-lock.js +60 -258
  446. package/.agents/scripts/lib/single-story-sweep.js +14 -97
  447. package/.agents/scripts/lib/skills/parse-skill.js +13 -59
  448. package/.agents/scripts/lib/skills/skills-index.js +8 -29
  449. package/.agents/scripts/lib/skills/walk-skill-files.js +17 -78
  450. package/.agents/scripts/lib/source-extensions.js +11 -42
  451. package/.agents/scripts/lib/source-text/strip-js-comments.js +8 -41
  452. package/.agents/scripts/lib/stdio-flush.js +9 -36
  453. package/.agents/scripts/lib/story-adjacency.js +8 -40
  454. package/.agents/scripts/lib/story-body/body-format-lints.js +51 -66
  455. package/.agents/scripts/lib/story-body/footer-block.js +11 -44
  456. package/.agents/scripts/lib/story-body/story-body.js +123 -344
  457. package/.agents/scripts/lib/temp-retention.js +42 -143
  458. package/.agents/scripts/lib/templates/decomposer-prompts.js +18 -80
  459. package/.agents/scripts/lib/test-env.js +12 -65
  460. package/.agents/scripts/lib/test-run-credit.js +10 -65
  461. package/.agents/scripts/lib/test-runner-contract.js +19 -74
  462. package/.agents/scripts/lib/test-temp.js +38 -184
  463. package/.agents/scripts/lib/test-tiers.js +12 -96
  464. package/.agents/scripts/lib/ticket-body-sections.js +21 -96
  465. package/.agents/scripts/lib/transpile.js +15 -74
  466. package/.agents/scripts/lib/util/concurrent-map.js +6 -25
  467. package/.agents/scripts/lib/util/parse-id-list.js +8 -34
  468. package/.agents/scripts/lib/util/poll-loop.js +8 -28
  469. package/.agents/scripts/lib/util/with-timeout.js +2 -11
  470. package/.agents/scripts/lib/validation-evidence.js +21 -96
  471. package/.agents/scripts/lib/wave-runner/footprint.js +17 -70
  472. package/.agents/scripts/lib/wave-runner/live-probe.js +67 -209
  473. package/.agents/scripts/lib/wave-runner/ready-set.js +72 -301
  474. package/.agents/scripts/lib/workers/crap-worker.js +11 -64
  475. package/.agents/scripts/lib/workers/maintainability-report-worker.js +8 -45
  476. package/.agents/scripts/lib/workers/maintainability-worker.js +5 -21
  477. package/.agents/scripts/lib/workers/serve-worker-messages.js +2 -18
  478. package/.agents/scripts/lib/workflow-closure.js +22 -105
  479. package/.agents/scripts/lib/workspace-provisioner.js +16 -54
  480. package/.agents/scripts/lib/worktree/git-hooks.js +15 -60
  481. package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +20 -60
  482. package/.agents/scripts/lib/worktree/lifecycle/merge-reachability.js +10 -62
  483. package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +22 -86
  484. package/.agents/scripts/lib/worktree/lifecycle/reap.js +24 -126
  485. package/.agents/scripts/lib/worktree/lifecycle-manager.js +2 -20
  486. package/.agents/scripts/lib/worktree/node-modules-strategy.js +46 -180
  487. package/.agents/scripts/lib/worktree-manager.js +15 -40
  488. package/.agents/scripts/lint-issue-body.js +12 -68
  489. package/.agents/scripts/mandrel-update-preflight.js +10 -70
  490. package/.agents/scripts/merge-baseline.js +30 -105
  491. package/.agents/scripts/nav-registry-diff.js +22 -108
  492. package/.agents/scripts/notify.js +12 -69
  493. package/.agents/scripts/plan-context.js +97 -92
  494. package/.agents/scripts/plan-critics.js +12 -66
  495. package/.agents/scripts/plan-persist.js +71 -137
  496. package/.agents/scripts/plan-run-epilogue.js +20 -43
  497. package/.agents/scripts/pr-watch-with-update.js +79 -263
  498. package/.agents/scripts/providers/github/auth.js +3 -8
  499. package/.agents/scripts/providers/github/blocked-by-add.js +14 -61
  500. package/.agents/scripts/providers/github/board-add.js +5 -21
  501. package/.agents/scripts/providers/github/branch-protection.js +11 -43
  502. package/.agents/scripts/providers/github/cache.js +2 -14
  503. package/.agents/scripts/providers/github/comments.js +7 -40
  504. package/.agents/scripts/providers/github/compose.js +3 -19
  505. package/.agents/scripts/providers/github/errors.js +22 -125
  506. package/.agents/scripts/providers/github/issues.js +31 -123
  507. package/.agents/scripts/providers/github/labels.js +24 -124
  508. package/.agents/scripts/providers/github/mappers.js +5 -27
  509. package/.agents/scripts/providers/github/merge-methods.js +3 -22
  510. package/.agents/scripts/providers/github/project-board.js +2 -17
  511. package/.agents/scripts/providers/github/projects-v2-graphql.js +3 -6
  512. package/.agents/scripts/providers/github/request-helpers.js +5 -32
  513. package/.agents/scripts/providers/github/search-budget.js +9 -39
  514. package/.agents/scripts/providers/github/search-query.js +5 -26
  515. package/.agents/scripts/providers/github/sub-issue-add.js +15 -65
  516. package/.agents/scripts/providers/github/sub-issues.js +7 -36
  517. package/.agents/scripts/providers/github/tickets.js +32 -134
  518. package/.agents/scripts/providers/github.js +18 -59
  519. package/.agents/scripts/prune-plan-run-labels.js +12 -46
  520. package/.agents/scripts/quality-preview.js +35 -220
  521. package/.agents/scripts/resolve-doc-tiers.js +3 -26
  522. package/.agents/scripts/resolve-stories.js +16 -67
  523. package/.agents/scripts/resync-status-column.js +6 -25
  524. package/.agents/scripts/run-tests.js +29 -104
  525. package/.agents/scripts/single-story-close.js +23 -135
  526. package/.agents/scripts/single-story-confirm-merge.js +32 -139
  527. package/.agents/scripts/single-story-init.js +47 -259
  528. package/.agents/scripts/stories-wave-tick.js +179 -415
  529. package/.agents/scripts/sync-agentrc.js +3 -21
  530. package/.agents/scripts/sync-claude-agents.js +9 -55
  531. package/.agents/scripts/sync-claude-commands.js +20 -110
  532. package/.agents/scripts/test-wrapper.js +6 -43
  533. package/.agents/scripts/update-coverage-baseline.js +5 -22
  534. package/.agents/scripts/update-crap-baseline.js +7 -30
  535. package/.agents/scripts/update-duplication-baseline.js +16 -92
  536. package/.agents/scripts/update-maintainability-baseline.js +8 -62
  537. package/.agents/scripts/update-ticket-state.js +1 -7
  538. package/.agents/scripts/validate-skills.js +6 -26
  539. package/.agents/skills/core/gates-and-baselines/reference.md +0 -1
  540. package/.agents/skills/skills.index.json +2 -2
  541. package/.agents/skills/stack/qa/playwright/SKILL.md +26 -0
  542. package/.agents/templates/agent-protocol.md +2 -2
  543. package/.agents/templates/docs/audit-sweep-runbook.md +3 -4
  544. package/.agents/workflows/audit-accessibility.md +4 -7
  545. package/.agents/workflows/audit-adrs.md +3 -6
  546. package/.agents/workflows/audit-architecture.md +3 -11
  547. package/.agents/workflows/audit-baselines.md +6 -9
  548. package/.agents/workflows/audit-clean-code.md +8 -12
  549. package/.agents/workflows/audit-data-model.md +3 -7
  550. package/.agents/workflows/audit-dependencies.md +4 -7
  551. package/.agents/workflows/audit-devops.md +4 -8
  552. package/.agents/workflows/audit-documentation.md +1 -4
  553. package/.agents/workflows/audit-mobile.md +4 -7
  554. package/.agents/workflows/audit-navigability.md +3 -6
  555. package/.agents/workflows/audit-performance.md +2 -4
  556. package/.agents/workflows/audit-privacy.md +4 -7
  557. package/.agents/workflows/audit-quality.md +4 -7
  558. package/.agents/workflows/audit-security.md +4 -7
  559. package/.agents/workflows/audit-seo.md +4 -7
  560. package/.agents/workflows/audit-sre.md +4 -7
  561. package/.agents/workflows/audit-to-stories.md +17 -30
  562. package/.agents/workflows/audit-ux-ui.md +4 -7
  563. package/.agents/workflows/helpers/acceptance-self-eval.md +84 -157
  564. package/.agents/workflows/helpers/audit-lens-core.md +1 -1
  565. package/.agents/workflows/helpers/code-quality-guardrails.md +12 -15
  566. package/.agents/workflows/helpers/code-review.md +4 -2
  567. package/.agents/workflows/helpers/deliver-digest.md +37 -28
  568. package/.agents/workflows/helpers/deliver-light.md +92 -101
  569. package/.agents/workflows/helpers/deliver-reference.md +162 -220
  570. package/.agents/workflows/helpers/deliver-story-reference.md +197 -607
  571. package/.agents/workflows/helpers/deliver-story.md +17 -18
  572. package/.agents/workflows/helpers/plan-reference.md +125 -167
  573. package/.agents/workflows/helpers/qa-core.md +12 -0
  574. package/.agents/workflows/mandrel-deliver.md +47 -31
  575. package/.agents/workflows/mandrel-plan.md +22 -21
  576. package/.agents/workflows/mandrel-update.md +36 -21
  577. package/.agents/workflows/memory-consolidate.md +1 -1
  578. package/.agents/workflows/qa-assist.md +27 -71
  579. package/.agents/workflows/qa-explore.md +19 -59
  580. package/.agents/workflows/qa-run.md +11 -33
  581. package/README.md +1 -1
  582. package/bin/mandrel.js +5 -46
  583. package/bin/postinstall.js +18 -107
  584. package/docs/CHANGELOG.md +60 -0
  585. package/lib/cli/doctor.js +11 -71
  586. package/lib/cli/init.js +26 -165
  587. package/lib/cli/migrate.js +5 -64
  588. package/lib/cli/registry.js +84 -467
  589. package/lib/cli/sync-agents.js +4 -64
  590. package/lib/cli/sync-commands.js +11 -64
  591. package/lib/cli/sync.js +34 -213
  592. package/lib/cli/uninstall.js +40 -219
  593. package/lib/cli/update.js +326 -523
  594. package/lib/cli/version-check.js +8 -72
  595. package/lib/cli/version-helpers.js +14 -87
  596. package/lib/migrations/helpers/retire-agentrc-key.js +11 -52
  597. package/lib/migrations/index.js +17 -92
  598. package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +2 -15
  599. package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +1 -13
  600. package/lib/migrations/steps/2.11.0-retire-max-seed-words.js +2 -15
  601. package/lib/migrations/steps/2.2.0-retire-epic-ac-tags.js +9 -38
  602. package/lib/migrations/steps/2.20.0-retire-codebase-snapshot.js +1 -13
  603. package/lib/migrations/steps/2.32.0-retire-lint-baseline-command.js +2 -27
  604. package/lib/migrations/steps/2.57.0-retire-delivery-limit-knobs.js +2 -23
  605. package/lib/migrations/steps/2.57.0-retire-planning-limit-knobs.js +2 -27
  606. package/lib/migrations/steps/2.60.0-retire-audit-results-autofile.js +21 -0
  607. package/lib/migrations/steps/strip-removed-agentrc-keys.js +333 -0
  608. package/package.json +17 -14
  609. package/.agents/docs/SDLC.md +0 -590
  610. package/.agents/docs/quality-gates.md +0 -1179
  611. package/.agents/rules/known-tooling-behavior.md +0 -150
  612. package/.agents/rules/orchestration-error-handling.md +0 -61
  613. package/.agents/rules/test-seams.md +0 -59
  614. package/.agents/schemas/baselines/lighthouse.schema.json +0 -59
  615. package/.agents/schemas/baselines/lint.schema.json +0 -47
  616. package/.agents/schemas/model-attribution.schema.json +0 -53
  617. package/.agents/scripts/check-action-pinning.js +0 -260
  618. package/.agents/scripts/check-audit-attribution.js +0 -302
  619. package/.agents/scripts/check-baseline-drift.js +0 -211
  620. package/.agents/scripts/check-baseline-scope.js +0 -362
  621. package/.agents/scripts/check-generated-validator.js +0 -202
  622. package/.agents/scripts/check-knip-entries.js +0 -159
  623. package/.agents/scripts/check-lifecycle-lint.js +0 -294
  624. package/.agents/scripts/check-pinned-override-notes.js +0 -102
  625. package/.agents/scripts/check-schema-references.js +0 -366
  626. package/.agents/scripts/check-test-portability.js +0 -512
  627. package/.agents/scripts/check-workflow-citations.js +0 -332
  628. package/.agents/scripts/check-workflow-cli-lint.js +0 -299
  629. package/.agents/scripts/check-workflow-timeouts.js +0 -291
  630. package/.agents/scripts/install-matrix-assert.js +0 -326
  631. package/.agents/scripts/lib/audit-advisories.js +0 -195
  632. package/.agents/scripts/lib/audit-attribution.js +0 -134
  633. package/.agents/scripts/lib/baselines/drift-detector.js +0 -351
  634. package/.agents/scripts/lib/baselines/kinds/lighthouse.js +0 -87
  635. package/.agents/scripts/lib/baselines/kinds/lint.js +0 -184
  636. package/.agents/scripts/lib/baselines/orphan-pruner.js +0 -233
  637. package/.agents/scripts/lib/baselines/scope-assert.js +0 -223
  638. package/.agents/scripts/lib/baselines/scope-inventory.js +0 -314
  639. package/.agents/scripts/lib/c8-cli-path.js +0 -21
  640. package/.agents/scripts/lib/config/gates/lighthouse.schema.js +0 -51
  641. package/.agents/scripts/lib/config/gates/lint.schema.js +0 -18
  642. package/.agents/scripts/lib/dynamic-workflow/architecture-report-contract.js +0 -70
  643. package/.agents/scripts/lib/dynamic-workflow/audit-orchestrator.js +0 -284
  644. package/.agents/scripts/lib/dynamic-workflow/clean-code-report-contract.js +0 -80
  645. package/.agents/scripts/lib/dynamic-workflow/degraded-coverage.js +0 -81
  646. package/.agents/scripts/lib/dynamic-workflow/documentation-report-contract.js +0 -87
  647. package/.agents/scripts/lib/dynamic-workflow/performance-report-contract.js +0 -74
  648. package/.agents/scripts/lib/dynamic-workflow/quality-report-contract.js +0 -90
  649. package/.agents/scripts/lib/dynamic-workflow/report-contract-core.js +0 -43
  650. package/.agents/scripts/lib/dynamic-workflow/security-report-contract.js +0 -83
  651. package/.agents/scripts/lib/fs-walk.js +0 -52
  652. package/.agents/scripts/lib/knip-config-resolver.js +0 -181
  653. package/.agents/scripts/lib/knip-entry-sync.js +0 -452
  654. package/.agents/scripts/lib/orchestration/model-attribution.js +0 -418
  655. package/.agents/scripts/lib/orchestration/story-plan-state.js +0 -33
  656. package/.agents/scripts/lib/orchestration/structured-comment-parser.js +0 -67
  657. package/.agents/scripts/lib/pinned-override-notes.js +0 -88
  658. package/.agents/scripts/lib/pinned-override-resolve.js +0 -212
  659. package/.agents/scripts/lib/test-isolate/cli-options.js +0 -93
  660. package/.agents/scripts/lib/test-isolate/env-snapshot-loader.js +0 -52
  661. package/.agents/scripts/lib/test-isolate/list-files.js +0 -90
  662. package/.agents/scripts/lib/test-isolate/parse-tap.js +0 -75
  663. package/.agents/scripts/lib/test-isolate/progress-log.js +0 -45
  664. package/.agents/scripts/lib/test-isolate/render-report.js +0 -97
  665. package/.agents/scripts/lib/test-isolate/run-isolate.js +0 -87
  666. package/.agents/scripts/lib/test-isolate/runner.js +0 -483
  667. package/.agents/scripts/lib/test-profile/parse-tap.js +0 -136
  668. package/.agents/scripts/lib/test-profile/render-report.js +0 -45
  669. package/.agents/scripts/lint-label-vocabulary.js +0 -214
  670. package/.agents/scripts/post-structured-comment.js +0 -127
  671. package/.agents/scripts/provision-git-hooks.js +0 -85
  672. package/.agents/scripts/prune-baseline-orphans.js +0 -181
  673. package/.agents/scripts/run-coverage.js +0 -197
  674. package/.agents/scripts/run-lint.js +0 -133
  675. package/.agents/scripts/run-test-profile.js +0 -129
  676. package/.agents/scripts/run-verify.js +0 -118
  677. package/.agents/scripts/test-isolate.js +0 -55
  678. package/.agents/scripts/update-dead-exports-baseline.js +0 -321
@@ -10,14 +10,9 @@ caller: helpers/deliver-story.md
10
10
 
11
11
  # helpers/deliver-story — reference (lease, recovery, troubleshooting)
12
12
 
13
- > **Not a slash command, not the runtime path.** This file is the
14
- > reference companion to
15
- > [`deliver-story.md`](deliver-story.md). The core file
16
- > carries the step flow, commands, gate contracts, and the return contract a
17
- > standalone-Story run needs; this file holds the lease/sweep mechanics, the
18
- > worktree-scope safety warning, the CI-recovery procedures, and the
19
- > Status-column reconciliation the core points at with one-line pointers.
20
- > Read a section here only when the matching pointer in the core sends you.
13
+ > **Not a slash command, not the runtime path.** The reference companion to
14
+ > [`deliver-story.md`](deliver-story.md): read a section here only when the
15
+ > matching pointer in the core sends you.
21
16
 
22
17
  ---
23
18
 
@@ -28,17 +23,12 @@ caller: helpers/deliver-story.md
28
23
  Before any git mutation, init takes an exclusive, time-bounded **lease** on
29
24
  the Story ticket via the assignee-as-lease primitive
30
25
  (`lib/orchestration/ticket-lease.js`). The single assignee _is_ the lease
31
- owner (resolved from `github.operatorHandle`). The standalone path has no
32
- Epic-scoped dispatch manifest to serialise two operators driving the same
33
- Story, so this lease is the only guard against a concurrent
34
- `single-story-init` clobbering an in-flight run.
35
-
36
- **Fail-closed.** Unlike `/mandrel-deliver`, the standalone path
37
- has **no Epic-scoped lifecycle ledger** to read a per-owner
38
- `story.heartbeat` from, so there is no live-heartbeat source to decide
39
- whether a foreign claim is stale. Rather than silently reclaim every
40
- foreign assignee (which would leave the guard inert), the standalone lease
41
- **fails closed**: a foreign assignee is treated as a _live_ claim. Outcomes:
26
+ owner (resolved from `github.operatorHandle`), and it is the only guard
27
+ against a concurrent `single-story-init` clobbering an in-flight run.
28
+
29
+ **Fail-closed.** The standalone path has **no Epic-scoped lifecycle ledger**
30
+ to read a per-owner `story.heartbeat` from, so it cannot tell whether a
31
+ foreign claim is stale — a foreign assignee is treated as a _live_ claim:
42
32
 
43
33
  - **Unclaimed / self-held** → init proceeds (a self-held claim is
44
34
  re-affirmed without re-writing assignees).
@@ -51,111 +41,60 @@ runs in `single-story-close.js` (Step 3).
51
41
 
52
42
  ### Branch reuse
53
43
 
54
- When a `story-<id>` branch already exists locally, init **reuses** it rather
55
- than re-creating it (re-running `git branch` on an existing ref throws
56
- `branch already exists`). The seed decision (`reuse` / `fetch` / `create`)
57
- keys off local + remote ref presence, so re-running init on a
58
- partially-initialized Story is idempotent.
44
+ When a `story-<id>` branch already exists locally, init **reuses** it. The
45
+ seed decision (`reuse` / `fetch` / `create`) keys off local + remote ref
46
+ presence, so re-running init on a partially-initialized Story is idempotent.
59
47
 
60
48
  ### Merged-`story-*` sweep
61
49
 
62
- Between the fetch and the branch-seed step, the script runs a
63
- **merged-`story-*` sweep**: it invokes the same primitive as
64
- `<agentRoot>/scripts/git-cleanup.js` (`<agentRoot>` resolves
65
- from `project.paths.agentRoot`, default `.agents`) scoped to `story-*`
66
- only, in `--execute --remote` mode, with the current run's
67
- `story-<id>` branch excluded from the candidate list. Local refs, the
68
- matching `origin/` ref, and stale tracking refs for any merged sibling
69
- stories are reaped in one pass. The sweep never blocks init — failures
70
- are logged and the new story is initialized regardless.
71
-
72
- The sweep applies two hardening layers:
73
-
74
- - **Per-candidate protection.** Each merged-PR candidate is filtered
75
- through three guards before reaching `executeCleanup`:
76
- - `unpushed-work` — branch HEAD SHA differs from the PR's
77
- `headRefOid`, meaning the operator has commits the merge didn't
78
- capture.
79
- - `dirty-tree` — the attached worktree (if any) has uncommitted
80
- changes.
81
- - `ticket-not-done` — the parent Story ticket isn't closed and
82
- doesn't carry `agent::done`.
83
- Protected candidates are skipped, listed in the sweep result envelope
84
- under `protected[]`, and named in the `CLEANUP` log line so the
85
- operator can see what was preserved.
86
- - **Cross-session lock.** The sweep acquires a process-scoped lockfile
87
- at `<tempRoot>/single-story-sweep.lock` before planning. On
88
- contention (another `/deliver-story` already in the sweep
89
- step), this run's sweep is **skipped** with a warn log; init
90
- continues normally. Stale lockfiles (mtime older than the timeout)
91
- are treated as expired. The timeout defaults to 60 seconds and is
92
- overridable via `delivery.worktreeIsolation.sweepLockMs` in
93
- `.agentrc.json`.
94
-
95
- Both layers are non-fatal — sweep failure / skip never blocks init, and
96
- the new story is always created. `--dry-run` also skips the sweep.
50
+ Between the fetch and the branch seed, init runs the same primitive as
51
+ `<agentRoot>/scripts/git-cleanup.js` scoped to `story-*` in
52
+ `--execute --remote` mode, excluding this run's `story-<id>`, reaping merged
53
+ siblings' local refs, `origin/` refs and stale tracking refs in one pass.
54
+
55
+ - **Per-candidate protection.** A candidate is skipped — listed under
56
+ `protected[]` and named in the `CLEANUP` log line — on `unpushed-work`
57
+ (branch HEAD differs from the PR's `headRefOid`), `dirty-tree` (its
58
+ worktree has uncommitted changes) or `ticket-not-done` (the Story is
59
+ neither closed nor `agent::done`).
60
+ - **Cross-session lock.** The sweep takes `<tempRoot>/single-story-sweep.lock`
61
+ before planning. On contention this run's sweep is **skipped** with a warn
62
+ log; a lockfile older than the fixed 60-second timeout is treated as expired.
63
+
64
+ Sweep failure or skip never blocks init. `--dry-run` also skips the sweep.
97
65
 
98
66
  ### Worktree scope is not just the Bash cwd
99
67
 
100
68
  `cd <workCwd>` steers the **Bash** tool's working directory, but it does
101
69
  **not** scope the path-based **Edit/Write/Read** tools — those resolve
102
- **absolute paths** and ignore the shell cwd. On Windows especially, an agent
103
- whose shell sits in the worktree can still silently edit the **main
104
- checkout** if it resolves a main-checkout absolute path. To stay in the
105
- worktree you MUST prefix **every Edit/Write/Read path with the absolute
106
- worktree root** (the `workCwd` value from Step 0), not merely `cd` into it.
107
- Never edit files under the bare main-checkout root. `single-story-close.js`
108
- runs a **wrong-tree guard** that aborts close and posts a
109
- `friction` comment if it finds uncommitted tracked-path edits in the main
110
- checkout while the worktree is the active work tree — but that is a backstop,
111
- not a substitute for prefixing paths correctly.
70
+ **absolute paths** and ignore the shell cwd, so an agent whose shell sits in
71
+ the worktree can still silently edit the **main checkout**. You MUST prefix
72
+ **every Edit/Write/Read path with the absolute worktree root** (the `workCwd`
73
+ value from Step 0). Never edit files under the bare main-checkout root.
74
+ `single-story-close.js` runs a **wrong-tree guard** that aborts close and posts
75
+ a `friction` comment on uncommitted tracked-path edits in the main checkout —
76
+ a backstop, not a substitute for prefixing paths correctly.
112
77
 
113
78
  ---
114
79
 
115
- ## Engine invariants and the lite route
80
+ ## Engine invariants and ceremony
116
81
 
117
82
  **Prerequisites before Step 0.** A `type::story` issue, a clean
118
83
  `gh auth status`, and `project.baseBranch` present both locally and on
119
- `origin` — init seeds the Story branch from the base branch and probes the
120
- remote, so a missing or unauthenticated remote surfaces as a
121
- `remoteVerified: false` block rather than a useful error.
122
-
123
- The v2 engine's trait table:
124
-
125
- | Trait | v2 `/deliver-story` |
126
- | ------------- | ------------------------------------------------------------------------ |
127
- | Ticket type | `type::story` only |
128
- | Branch | `story-<id>` seeded from `project.baseBranch` (`main`) |
129
- | Merge target | `main` via PR (squash + required checks) |
130
- | Spec / slices | Folded `## Spec` + optional `## Slicing` checkpoints in-session |
131
- | Ceremony | Per-Story, routed off the derived change level via `ceremony-routing.js` |
132
-
133
- **Ceremony-lite Stories still land through this engine unchanged.** A
134
- lite-routed Story collapses only the _advisory_ plan/mandrel-deliver
135
- ceremony — the fresh-critic / Tech-Spec authoring a one-artifact scope does
136
- not earn. It does **not** get a cheaper landing: the close-validation gates
137
- (lint / test / format / coverage / CRAP / maintainability), the PR to `main`,
138
- and the `rules/security-baseline.md` MUSTs all run exactly as for a
139
- full-ceremony Story. The lite route's `preserves` field is the machine-readable
140
- record of those non-negotiables; there is no lite-specific gate bypass.
141
-
142
- **Ceremony comes from the landed diff; the dispatch mode comes from the
143
- run.** Persist stamps no route label (Story #5312 retired the plan-side lite
144
- claim with its `route::lite` hint). Ceremony is resolved from the **derived
145
- change level** (`deriveChangeLevel` over the computed change set — digest § 3),
146
- not from a body-shape read: a footprint intersecting a sensitive-path class
147
- derives `high`, so the Story keeps its fresh acceptance critic. The light path
148
- is the one caller that reads the authored body's shape, through
149
- `deriveStoryShape` (`lib/orchestration/complexity-gate.js`).
150
-
151
- That derived level sets ceremony. It does **not** set the dispatch mode,
152
- because `inline` names one indivisible resource — the router's own session —
153
- and only run topology can say whether it is free: a **single-Story run**
154
- executes inline, and every Story of a multi-Story run dispatches as a
155
- `story-worker` sub-agent whatever its shape — a lite shape makes the work
156
- cheap, it does not conjure a second session for a sibling. Inline
157
- execution changes the isolation only: the engine, every script gate, and the
158
- terminal envelope are byte-identical either way.
84
+ `origin` — a missing or unauthenticated remote surfaces as a
85
+ `remoteVerified: false` block rather than a useful error. The engine's trait
86
+ table is digest § 2.
87
+
88
+ **A cheap shape never buys a cheaper landing.** A small Story collapses only
89
+ the _advisory_ ceremony — the fresh-critic / Tech-Spec authoring a
90
+ one-artifact scope does not earn. The close-validation gates (lint / test /
91
+ format / coverage / CRAP / maintainability), the PR to `main`, and the
92
+ `rules/security-baseline.md` MUSTs run exactly as for any other Story. There
93
+ is no gate bypass to opt into, and nothing in the ticket can declare one.
94
+
95
+ **The ceremony rule has one home: digest § 3**, and the dispatch rule is
96
+ digest § 1. The light path is the one caller that reads the authored body's
97
+ shape, through `deriveStoryShape` (`lib/orchestration/complexity-gate.js`).
159
98
 
160
99
  ---
161
100
 
@@ -180,49 +119,30 @@ alone inside the `---` footer block declares an edge:
180
119
  blocked by #42
181
120
  ```
182
121
 
183
- Prose elsewhere in the body declares **nothing**, and this is a deliberate,
184
- user-visible change from the whole-body scan that preceded it. A sentence
185
- merely mentioning a blocker — an example, a changelog note, an acceptance
186
- criterion quoting the phrase — used to mint a real dispatch gate that withheld
187
- the Story until an unrelated issue closed. `plan-persist` has always
188
- serialized the canonical footer form, so no machine-authored body is affected;
189
- only a **hand-written prose edge** stops gating, and the fix is to move it into
190
- the footer block. The loose spellings never reached the footer grammar either:
191
- `depends on #N`, `Blocked by: #N`, and `blocked by #N once X lands` all declare
192
- nothing. One grammar serves both readers — the body parser and the
193
- dispatch-edge parser share it — so what a Story body round-trips and what gates
194
- dispatch cannot drift apart.
195
-
196
- **The native channel fails loud.** The read paginates to exhaustion (a
197
- first-page read silently truncated a Story's gates at GitHub's 30-item
198
- default), and **a 404 is not an empty result**. An issue with no dependencies
199
- answers `200 []`; a 404 is how GitHub also answers a token that cannot see the
200
- dependencies API, so treating it as "no edges" erased every native edge in the
201
- run under a mis-scoped token, silently, with a clean exit code. Any non-OK
202
- read now fails the resolution naming the Story — check the token's scopes
203
- first. The one degrade that is scoped rather than fatal is a **cross-repo
204
- edge**: another repository's issue number cannot be matched against this
205
- repo's same-numbered issue without risking a false match, so that edge is
122
+ Prose elsewhere in the body declares **nothing** — move a hand-written prose
123
+ edge into the footer block. The loose spellings `depends on #N`,
124
+ `Blocked by: #N`, and `blocked by #N once X lands` declare nothing either.
125
+
126
+ **The native channel fails loud.** The read paginates to exhaustion, and
127
+ **a 404 is not an empty result**: an issue with no dependencies answers
128
+ `200 []`, while a 404 is also how GitHub answers a token that cannot see the
129
+ dependencies API. Any non-OK read fails the resolution naming the Story —
130
+ check the token's scopes first. The one scoped degrade is a **cross-repo
131
+ edge**: it cannot be matched against this repo's same-numbered issue, so it is
206
132
  dropped with a warning naming the Story, and its siblings resolve normally.
207
133
 
208
- **Edges are monotone — retraction is not built.** Both channels only ever
209
- _add_ a gate for the current resolution. Removing a `blocked by` footer line
210
- or deleting a native relation makes the edge absent from the **next** resolve,
211
- but nothing reconciles an edge that a previous run already acted on, and the
212
- write path never deletes a native relation it did not need. In practice that
213
- means: re-resolve after editing edges, and treat a stale gate as a body/issue
214
- edit plus a fresh `resolve-stories.js` run, never as something delivery
215
- un-declares on your behalf. This is a known limitation, not an oversight.
134
+ **Edges are monotone — retraction is not built.** Removing a footer line or a
135
+ native relation makes the edge absent from the **next** resolve, but nothing
136
+ reconciles an edge a previous run already acted on: treat a stale gate as a
137
+ body/issue edit plus a fresh `resolve-stories.js` run.
216
138
 
217
139
  ---
218
140
 
219
141
  ## Step 1 — Implementation detail
220
142
 
221
143
  **Docs context — digest-first.** Read a full doc only when the Story's own
222
- context points you at one — do not ingest the whole
223
- `project.docsContextFiles` set up front. If the caller provides a
224
- `docsDigestPath`, prefer that compact outline and pull individual files on
225
- demand. See [`.agents/instructions.md` § 3](../../instructions.md).
144
+ context points you at one; prefer a caller-provided `docsDigestPath` and pull
145
+ individual files on demand. See [`.agents/instructions.md` § 3](../../instructions.md).
226
146
 
227
147
  **Write-time audit checklists.** When the caller provides a `checklistPath`
228
148
  (footprint-matched **local**-lens authoring checklists), read it before you
@@ -232,103 +152,25 @@ dispatch step produces `checklistPath` from the Story's predicted footprint
232
152
  before it spawns the worker — see [`/mandrel-deliver`](../mandrel-deliver.md).
233
153
 
234
154
  **Full-suite discipline (spine Step 2.5).** Repo-invariant guards —
235
- drift-guard and schema tests living outside the Story's scoped greps — are
236
- the failure class that actually bounces deliveries: close-validation
237
- discovers them only after the whole close pipeline has run, at several times
238
- the cost of one full-suite run in the worktree.
239
-
240
- **Run it once, last, through the depositor.** The run belongs **after** the
241
- self-eval loop's last fix commit; redraft rounds run scoped tests. Run it in
242
- the worktree on `story-<id>` as
243
-
244
- ```bash
245
- node <main-repo>/.agents/scripts/evidence-gate.js \
246
- --standalone --scope-id <storyId> --gate test \
247
- --worktree <workCwd> -- npm test
248
- ```
249
-
250
- The wrapper spawns the project's own `npm test` — whatever that resolves to —
251
- and records the pass into the Story evidence keyspace, so the credit is
252
- runner-agnostic by construction: it stamps only what it just ran. The record
253
- is keyed on HEAD and the tree fingerprint and hashed on the exact command
254
- close spawns, so close reports the gate as credited at unchanged HEAD instead
255
- of re-running the suite. The credit expires the moment it stops describing the
256
- tree: any later commit invalidates it and close re-runs the suite for real, so
257
- this never trades away the gate. The CRAP gate still runs
258
- `coverage-capture.js` itself when it needs a fresh artifact — the capture
259
- stamp is a claim about `coverage/coverage-final.json`, which `npm test` alone
260
- does not produce.
261
-
262
- **A bare `npm test` is a bonus, not the contract.** It deposits the same
263
- record only where the project's `test` script routes through mandrel's own
264
- runner (`run-tests.js` → `lib/test-run-credit.js`, Story #5313), which prints
265
- the outcome. A project whose `npm test` is `vitest run`, `jest` or any other
266
- runner never reaches that code, so it prints nothing and deposits nothing —
267
- silence is not a signal, and nothing here asks you to confirm the credit by
268
- reading for a line that cannot appear. `mandrel doctor`'s `test-credit-path`
269
- check reports which shape a project is and names the command above as its
270
- remedy.
271
-
272
- **`verify[]` reuses the same credit.** A `verify[]` entry that is itself a
273
- full-suite command is reported **credited** against that record rather than
274
- respawned (`resolveVerifyCredit` in
275
- [`verify-credit.js`](../../scripts/lib/orchestration/verify-credit.js)), and the
276
- self-eval gate warns when it sees one: the intended shape is scoped `verify[]`
277
- entries **plus** the single credited run.
155
+ drift-guard and schema tests outside the Story's scoped greps — are the
156
+ failure class that bounces deliveries, and close-validation discovers them
157
+ only after the whole close pipeline has run. The run itself is stated once,
158
+ in [`deliver-digest.md`](deliver-digest.md) § 5.
278
159
 
279
160
  **Conflict with `main` mid-implementation** → resolve as you would any branch
280
- rebase. There is no `epic/<id>` intermediate, so the rebase base is `main`
281
- directly.
161
+ rebase; the rebase base is `main` directly.
282
162
 
283
163
  ### Step 1a — self-eval mechanics
284
164
 
285
- **One verdict-owner per cluster.** The ceremony routing's
286
- resolved decision names each cluster's single verdict owner
287
- (`verdictOwner: 'fresh-critic' | 'inline-self-eval'` from
288
- `resolveCeremonyForRisk`): the fresh maker-blind critic when sensitivity
289
- routes the cluster `fresh`, the contract-identical inline self-eval when it
290
- routes `inline`. Exactly one pass authors the verdict — never both, and
291
- never a preliminary self-assessment pass before dispatching the fresh
292
- critic (the redundant pre-pass buys no measurable quality and roughly
293
- triples the acceptance-block cost). `acceptance-eval.js` is the
294
- deterministic **scorer** of that one authored verdict — schema validation,
295
- round cap, proceed / redraft / block — not an independent additional pass
296
- over the criteria. The M4-B floor holds: one verdict per cluster, with the
297
- cluster count owned by the dispatching caller and never by routing.
298
-
299
- **One round = N cluster critics → ONE merged verdict → ONE gate call** (fresh
300
- critics; an inline-owned verdict is one file scored in one call). The
301
- clusters are how a round is _authored_; they are not how it is _scored_.
302
- Concatenate every cluster's records into a single `criteria[]` ordered by
303
- `index` — exactly one per `acceptance[]` item, under one `storyId`,
304
- `schemaVersion`, `round` and `commitSha` — and hand that merged file to the
305
- gate once:
306
-
307
- ```bash
308
- node <main-repo>/.agents/scripts/acceptance-eval.js \
309
- --story <storyId> --verdict <merged-verdict-path>
310
- ```
311
-
312
- The gate reads the Story's `acceptance[]` count itself (Story #5313), so a
313
- single cluster's verdict handed over unmerged is rejected before scoring and
314
- consumes no round; `--expected-criteria` is accepted but redundant. Calling
315
- the gate once per cluster instead spends a round
316
- _per cluster_ — a Story past the cluster ceiling would burn its whole redraft
317
- budget on cluster arithmetic — and N concurrent calls race the Story-scoped
318
- round ledger. Full per-round mechanics, including the parallel dispatch and the
319
- merge shape: [`acceptance-self-eval.md`](acceptance-self-eval.md).
320
-
321
- **Critic evidence-share.** When the critic runs a `verify[]`
322
- command that is byte-identical to a close gate (`lint` / `typecheck`), it
323
- records the pass into the Story evidence keyspace via `--standalone` so
324
- close short-circuits the gate at unchanged HEAD. Run it in the **Story
325
- worktree** (`workCwd` from Step 0):
326
-
327
- ```bash
328
- node <main-repo>/.agents/scripts/evidence-gate.js \
329
- --standalone --scope-id <storyId> --gate lint \
330
- --worktree <workCwd> -- npm run lint
331
- ```
165
+ **One verdict owner per Story** — `verdictOwner: 'fresh-critic' |
166
+ 'inline-self-eval'` from `resolveCeremonyForRisk`, following the ceremony
167
+ profile alone (digest § 3). Exactly one pass authors the verdict — never both,
168
+ and never a preliminary self-assessment before dispatching a fresh critic.
169
+ `acceptance-eval.js` is the deterministic **scorer** of that one verdict —
170
+ schema validation, round cap, proceed / redraft / block — not an additional
171
+ pass over the criteria. The invocation and the one-verdict-one-call rule are
172
+ digest § 4; per-round mechanics are
173
+ [`acceptance-self-eval.md`](acceptance-self-eval.md).
332
174
 
333
175
  **On `decision: "block"`** — post a `friction` comment naming the unmet
334
176
  criteria, then transition the Story to `agent::blocked`:
@@ -343,40 +185,13 @@ node .agents/scripts/update-ticket-state.js --ticket <storyId> --state agent::bl
343
185
 
344
186
  ## Step 2 — Ceremony detail
345
187
 
346
- **Compute the change set once** with the shared enumerator — the same module
347
- close uses — and reuse that one list downstream. `ceremony-derive.js`
348
- (Story #5313) is that enumeration, the level derivation and the ceremony
349
- resolution in one call:
350
-
351
- ```bash
352
- node <main-repo>/.agents/scripts/ceremony-derive.js --story <storyId> --cwd <workCwd>
353
- ```
354
-
355
- Its `level` comes from
356
- [`deriveChangeLevel`](../../scripts/lib/orchestration/review-depth.js) over
357
- the one computed change-set list: a diff touching a sensitive path registered
358
- in `.agents/schemas/audit-rules.json` derives `high`, one touching none
359
- derives `low`, and an unenumerable diff (`files: null`) derives `null`.
360
- Hand the **same** `files` list to every acceptance critic you spawn (Step 1a)
361
- — a critic that re-ran its own `git diff` could score against a different
362
- set than the one that routed it.
363
-
364
- Its `mode` / `verdictOwner` come from
365
- [`resolveCeremonyForRisk`](../../scripts/lib/orchestration/ceremony-routing.js)
366
- (`minimal` → always inline; `strict` → always fresh; `standard` →
367
- `high`/`null` → `fresh`, `low` → `inline`). Review depth reads the same
368
- derived level via `review-depth.js` inside close, so the two decisions cannot
369
- disagree.
370
-
371
- **Inline-dispatch override.** When the Story dispatches
372
- `inline` (`resolveStoryDispatchMode` → `inline`, which is exactly a
373
- single-Story run — the function reads the resolved set size and nothing
374
- else), run
375
- every acceptance critic **inline** — do not spawn fresh-context critic
376
- sub-agents regardless of what the profile would otherwise resolve. The self-eval rigor
377
- (scoring each `acceptance[]` item against the one computed change set, with
378
- `verify[]` output as evidence) is unchanged; only the sub-agent boot is
379
- removed. Hard gates are untouched.
188
+ `ceremony-derive.js` (digest § 3) is the change-set enumeration, the level
189
+ derivation ([`deriveChangeLevel`](../../scripts/lib/orchestration/review-depth.js))
190
+ and the ceremony resolution
191
+ ([`resolveCeremonyForRisk`](../../scripts/lib/orchestration/ceremony-routing.js))
192
+ in one call. Hand the **same** `files` list to the verdict owner (Step 1a) —
193
+ an evaluator that re-ran its own `git diff` could score a different set than
194
+ the one that routed it.
380
195
 
381
196
  ---
382
197
 
@@ -384,16 +199,12 @@ removed. Hard gates are untouched.
384
199
 
385
200
  **Step 3 is the orchestrator's, and it is serialized.** A dispatched
386
201
  `story-worker` ends its turn at a pushed branch (spine § Step 2.5); the session
387
- that dispatched it runs close. Two reasons, both measured rather than
388
- theoretical:
202
+ that dispatched it runs close. Two reasons:
389
203
 
390
204
  1. **A sub-agent cannot resume itself.** It gets no notification when a
391
205
  backgrounded close finishes, so a worker that backgrounds close and ends its
392
- turn strands the envelope in a turn nobody reads — three of five workers in
393
- one measured wave did exactly that despite an explicit foreground-close
394
- instruction. Moving the seam removes the failure instead of re-wording the
395
- prohibition. The parent, by contrast, is still live and _does_ observe and
396
- retry its own close.
206
+ turn strands the envelope in a turn nobody reads. The parent, by contrast,
207
+ is still live and _does_ observe and retry its own close.
397
208
  2. **Closes contend; implementation does not.** Close syncs from
398
209
  `origin/<baseBranch>`, pushes, opens a PR and arms auto-merge — two of those
399
210
  in flight race on the base branch, the merge queue and the shared checkout.
@@ -407,16 +218,6 @@ envelope with a re-dispatch: `single-story-init.js` re-run under a live branch
407
218
  is how one Story ends up with two closes. Close the pushed branch, or probe with
408
219
  `deliver-recover.js` and run the one command it prints.
409
220
 
410
- **What close does internally.** The script runs the close-validation gates
411
- against `baseBranch`, syncs the Story branch from `origin/<baseBranch>`
412
- (the parallel-race defence), pushes `story-<id>`, opens (or
413
- reuses) a PR against `baseBranch` with a `Closes #<storyId>` footer, enables
414
- GitHub native auto-merge (`--auto --squash --delete-branch`) **when
415
- `delivery.ci.autoMerge` is `"trust-ci"` (the default)**, flips the Story to
416
- `agent::closing`, reaps the worktree, releases the lease, then **waits for
417
- the merge** and — on a confirmed merge — flips `agent::done` and runs the
418
- post-land tail.
419
-
420
221
  **The merge wait is bounded and resumable.** Two budgets, deliberately
421
222
  separate (`delivery.mergeWatch.*`):
422
223
 
@@ -430,38 +231,16 @@ separate (`delivery.mergeWatch.*`):
430
231
 
431
232
  The wait probes the checks every poll: a red required check fails fast as
432
233
  `checks-failed` instead of burning the budget, and a PR that falls behind its
433
- base is brought up to date within `updateAttempts` tries.
434
-
435
- **Async merge-confirm mode (`delivery.mergeWatch.mode: "async"`).** Under
436
- the default `"sync"` the merge wait runs in the foreground as described above.
234
+ base is brought up to date within 3 tries.
437
235
 
438
236
  **On a multi-Story run, async is the posture — pass `--merge-watch-mode async`
439
- on every close.** This is not a slow-CI opt-in. Implementation fans out, but
440
- the close tail is serialized one Story at a time, and under `sync` each close
441
- holds the foreground for its full merge wait before the next may start; that
442
- is the run's dominant serialized cost, paid once per sibling. Close sees one
443
- Story and cannot see run topology, so the orchestrator — which can — makes the
444
- call per invocation while the config default stays `"sync"`, which is right for
445
- a solo delivery with no sibling waiting behind it
446
- ([`deliver-reference.md`](deliver-reference.md) § Async merge-confirm mode).
447
- A slow-CI consumer reaches for the same mode for the separate reason that a
448
- foreground wait longer than the host tool ceiling (~10 min) almost always
449
- expires `pending` after burning ~5 minutes of the slot — `"async"` makes that
450
- confirm a designed ending instead of an expiry accident.
451
-
452
- In async mode the close arms auto-merge, runs one short **~60s
453
- probe window** (long enough to catch an instant merge and, via the
454
- head-anchored required-check predicate, an instantly-red required check),
455
- then returns the standard `pending` terminal with a `nextCommand`. When you
456
- receive that `pending` envelope, launch its `nextCommand`
457
- (`single-story-confirm-merge.js … --wait`) as a **background** invocation —
458
- host **background Bash** (`run_in_background`), whose completion re-invokes
459
- the agent — and continue; do **not** sit in a foreground poll the tool
460
- ceiling will kill. `single-story-confirm-merge.js` is already idempotent and
461
- owns the whole tail, so no new state holder is needed, and
462
- `deliver-recover.js` remains the recovery path for an orphaned confirm. The
463
- cumulative `maxBudgetSeconds` give-up is unchanged; `"sync"` behaviour is
464
- byte-compatible.
237
+ on every close.** The close tail is serialized, and under `sync` each close
238
+ holds the foreground for its full merge wait before the next may start. Close
239
+ cannot see run topology, so the orchestrator makes the call per invocation
240
+ (`deliver-run.js` renders it into every multi-Story `close[]` command) while
241
+ the config default stays `"sync"` — right for a solo delivery. What async does
242
+ and how to resume its `pending` is
243
+ [`deliver-reference.md`](deliver-reference.md) § Async merge-confirm mode.
465
244
 
466
245
  **`delivery.ci.autoMerge` policy.** Under the default `"trust-ci"`, GitHub
467
246
  native auto-merge is armed and the PR squash-merges once its **required**
@@ -501,10 +280,9 @@ judgment that help text cannot carry.
501
280
  - `--merge-watch-mode <sync|async>` — the per-invocation override of
502
281
  `delivery.mergeWatch.mode`. **Pass `async` on every close of a multi-Story
503
282
  run** (above); leave it off for a solo delivery. It composes with
504
- `--max-wait-seconds` — pass both and the explicit bound still wins over the
505
- async probe cap. An unrecognized value is refused before any phase runs, so a
506
- typo cannot silently drop the run back onto synchronous waiting; the refusal
507
- reports a `failed` terminal envelope at `phase: init`, mutating nothing.
283
+ `--max-wait-seconds` — the explicit bound still wins over the async probe
284
+ cap. An unrecognized value is refused before any phase runs, reporting a
285
+ `failed` terminal envelope at `phase: init` and mutating nothing.
508
286
 
509
287
  ---
510
288
 
@@ -513,15 +291,10 @@ judgment that help text cannot carry.
513
291
  The `single-story-close.js` script, in order:
514
292
 
515
293
  1. **Syncs the Story branch from `origin/<baseBranch>`** — before the gates,
516
- not after them. Runs `git fetch origin <baseBranch>` followed
517
- by `git merge --no-edit origin/<baseBranch>` inside the worktree. This
518
- defends against the parallel-`/deliver-story` race: when
519
- multiple sessions run in parallel, the Story that auto-merges first
520
- bumps `baseBranch`, and without this sync the lagging Stories open
521
- PRs that are "behind base" and stall against branch-protection's
522
- `up-to-date branch` rule. Running it first also means a conflict costs
523
- no gate run at all, and — the load-bearing half — the tree the gates
524
- validate is the tree the push sends. Outcomes:
294
+ so the tree the gates validate is the tree the push sends, and a conflict
295
+ costs no gate run. It runs `git fetch origin <baseBranch>` then
296
+ `git merge --no-edit origin/<baseBranch>` in the worktree, defending against
297
+ parallel Stories leaving a lagging PR "behind base". Outcomes:
525
298
  - **No-op / fast-forward / clean merge-commit** → close proceeds to
526
299
  push.
527
300
  - **Merge conflict** → the merge is aborted, a `friction` structured
@@ -533,75 +306,32 @@ The `single-story-close.js` script, in order:
533
306
  - **Fetch failed** → close throws with the git stderr; no label
534
307
  transition.
535
308
 
536
- Note: the merge queue (when enabled) re-tests each PR against the
537
- queue tip before merging, so this sync + merge queue is the complete
538
- defence against the parallel race. Without merge queue, the sync
539
- closes the PR-open-time race but a residual race remains between PR
540
- open and auto-merge fire.
541
-
542
- 2. Runs the close-validation gates against `baseBranch` as the baseline.
543
- On any gate failure it throws — the operator fixes and re-runs close.
544
- The chain fails cheapest-first: `typecheck`, `lint`, `format` and the
545
- coverage-independent half of the baselines gate
546
- (`check-baselines-independent`) run in parallel, and only once they are
547
- green does the serial walk pay for `coverage-capture` and the
548
- coverage-consuming half (`check-baselines-coverage`).
549
- **Gate output is captured, not streamed.** Every gate line
550
- goes to `temp/orchestration/close-gates-<storyId>.log`; a clean run reports
551
- one digest line naming that artifact, and a **failed** gate replays its
552
- captured tail inline so the evidence is in front of you without opening a
553
- file. Read the artifact when you need the full text — or re-run under
554
- `AGENT_LOG_LEVEL=verbose` for live streaming.
309
+ Without a merge queue a residual race remains between PR open and
310
+ auto-merge fire; the merge queue re-tests against the queue tip.
555
311
 
312
+ 2. Runs the close-validation gates against `baseBranch`; any failure throws —
313
+ fix and re-run close. The chain fails cheapest-first: `typecheck`, `lint`,
314
+ `format` and `check-baselines-independent` run in parallel, and only once
315
+ they are green does the serial walk pay for `coverage-capture` and
316
+ `check-baselines-coverage`. Gate output is captured (digest § 6).
556
317
  3. Pushes `story-<id>` to `origin`.
557
- 4. Probes for an existing open PR with `head = story-<id>`. If none
558
- exists, opens one via `gh pr create --base <baseBranch>`. The PR
559
- body carries `Closes #<storyId>` so the GitHub merge auto-closes the
560
- issue.
561
- 4a. **Enables GitHub native auto-merge by default** via
562
- `gh pr merge <prNumber> --auto --squash --delete-branch`. Once CI's
563
- required checks turn green, GitHub squash-merges the PR and deletes
564
- the source branch — the operator does not need to babysit the merge
565
- button. Mirrors the `/mandrel-deliver` finalize path. Failure is
566
- non-fatal: the operator retains the manual merge surface in the
567
- GitHub UI. Pass `--no-auto-merge` to opt out when the PR needs a
568
- pre-merge eyeball.
318
+ 4. Opens (or reuses) a PR with `head = story-<id>` against `<baseBranch>`,
319
+ carrying `Closes #<storyId>`, and arms native auto-merge
320
+ (`gh pr merge <prNumber> --auto --squash --delete-branch`) unless
321
+ `--no-auto-merge` or `autoMerge: "strict"`. An arm failure is non-fatal.
569
322
  5. Flips the Story to **`agent::closing`** (NOT `agent::done`) and leaves
570
- the GitHub issue **OPEN**. Auto-merge completes
571
- asynchronously _after_ this script exits, so closing the issue here
572
- would strand a CLOSED issue with no merged work if the PR later failed
573
- CI, went `BEHIND` base, or was closed without merging. The Story rests
574
- at `agent::closing` while the PR is open with auto-merge armed; the
575
- `agent::done` flip (which closes the issue) is deferred to Step 5's
576
- merge confirmation — `single-story-confirm-merge.js` on a
577
- `--no-wait-merge` run, or the in-close confirm phase on the
578
- close-and-land default. (Step 5.5 is the Status-column resync.) A Story
579
- only reaches `agent::done` once its PR to `main` is confirmed merged.
323
+ the issue **OPEN**: auto-merge completes after the arm, so closing here
324
+ would strand a CLOSED issue with no merged work if the PR failed CI, went
325
+ `BEHIND` base, or closed unmerged. A Story only reaches `agent::done` once
326
+ its PR to `main` is confirmed merged (Step 5).
580
327
  6. Reaps the worktree when `delivery.worktreeIsolation.reapOnSuccess`
581
328
  is enabled.
582
- 7. **Releases the Story lease.** Clears the Story assignment
583
- that init claimed so the next `/deliver-story` run sees an
584
- unclaimed ticket. The release is a no-op when the operator no longer
585
- holds the claim (a later run took over via reclaim/steal), so a late
586
- close never yanks a live claim away from its current owner. Best-effort:
587
- a release failure is logged but does not fail an otherwise-clean close.
588
- Note the lease does **not** expire on its own: the standalone lease is
589
- fail-closed by design (it anchors its heartbeat to now, so a foreign
590
- claim always reads as live regardless of the configured TTL), so a
591
- claim stranded by a failed release is cleared only by `--steal` or by
592
- de-assigning the ticket. The close result carries
593
- `leaseReleased: <boolean>`.
594
-
595
- `--skip-validation` bypasses the gate step. Use only when re-running
596
- close after a fixed gate failure that's already known to pass.
597
-
598
- `--skip-sync` bypasses the base-sync step. Use only when re-running
599
- close after a hand-resolved sync, or in tests. The two flags are
600
- independent: either, both or neither may be set, and each elides exactly
601
- its own phase.
602
-
603
- `--no-auto-merge` disables the auto-merge arm (step 4a). Use when the PR materially changes
604
- behaviour and warrants pre-merge review.
329
+ 7. **Releases the Story lease** — a no-op when the operator no longer holds
330
+ the claim, so a late close never yanks a live claim. Best-effort: a
331
+ release failure is logged, not fatal, and reported as
332
+ `leaseReleased: <boolean>`. The fail-closed lease never expires on its
333
+ own, so a claim stranded by a failed release is cleared only by `--steal`
334
+ or by de-assigning the ticket.
605
335
 
606
336
  ---
607
337
 
@@ -610,10 +340,9 @@ behaviour and warrants pre-merge review.
610
340
  Enter this step **only** when Step 3 returned `blocked` with
611
341
  `blockClass: "checks-failed"` (a required check went red), or when a
612
342
  `--no-wait-merge` run left the PR for you to shepherd. When a required check is
613
- red, the agent owns the green-CI outcome, not just the push: local
614
- close-validation gates pass on the dev host's environment; CI runs on a
343
+ red, the agent owns the green-CI outcome, not just the push: CI runs on a
615
344
  different OS and concurrency, and coverage rounding, platform-conditional
616
- branches, and timing-sensitive tests routinely drift between the two.
345
+ branches, and timing-sensitive tests routinely drift from the dev host.
617
346
 
618
347
  Fix the failure and push a new commit on `story-<storyId>` — the watcher
619
348
  **disarmed native auto-merge on the first red** and re-arms it
@@ -633,18 +362,11 @@ node <agentRoot>/scripts/pr-watch-with-update.js --pr <prNumber> --story <storyI
633
362
  (`temp/story-<id>-ci-digest.{json,md}` — failing check name, the PR head SHA,
634
363
  run id + run link, and a `gh run view --log-failed` tail). Omit it and a red
635
364
  check writes no digest — and with no digest the no-rerun guard has nothing to
636
- adjudicate the next green against, so always pass it.
637
- Poll cadence and caps come from `delivery.ci.watch.*` (`pollIntervalMs`,
638
- `maxPolls`, `maxResumes`, `attachWindowMs`); pass `--poll-interval-ms`,
639
- `--max-polls`, `--max-resumes`, or `--attach-window-ms` to override for one run.
640
- `attachWindowMs` (default 20 min) is how long the watch keeps re-resolving an
641
- **empty** required-check set before it stops waiting for a context to attach —
642
- a required context that is an aggregator job gated on every other tier is the
643
- last check to appear, measured at 16m52s on this repository.
644
-
645
- Add `--repo owner/repo` only when the cwd is not the target repository; it
646
- reaches `gh` as a real flag. There is no `<owner/repo>#<number>` ref form —
647
- `gh` parses that as a branch name.
365
+ adjudicate the next green against, so always pass it. Cadence, caps and the
366
+ attach window (how long an **empty** required-check set is re-resolved before
367
+ the watch stops waiting, default 20 min) are in `--help`. Add
368
+ `--repo owner/repo` only when the cwd is not the target repository; there is no
369
+ `<owner/repo>#<number>` ref form — `gh` parses that as a branch name.
648
370
 
649
371
  When the watch exits, branch on the exit code:
650
372
 
@@ -674,17 +396,14 @@ When the watch exits, branch on the exit code:
674
396
  and **no** required context ever attached, while the PR kept reading back
675
397
  fine. CI has not started; there is no failing check and no CI digest to
676
398
  read. Do **not** treat it as red — nothing needs fixing, and re-watching
677
- (or raising `attachWindowMs`) is the whole remediation.
399
+ (or raising `--attach-window-ms`) is the whole remediation.
678
400
  - **unresolved** (`reconciliation.reconciled: false`) — every observed
679
401
  required check is green but the repository still refuses the merge, so the
680
402
  green verdict is withheld.
681
403
 
682
404
  **Triage authority.** How to classify and remediate a red (or repeatedly slow)
683
- check — the root-cause-only decision tree for infra/transient and flaky failures
684
- (reproduce → check `main` → bisect env vs code → fix in-scope, or reach an
685
- Option-2 verdict and file the intake issue), the never-rerun / never-quarantine
686
- prohibitions, and the escalation criteria (three-strikes, the 30-minute
687
- wall-clock timebox, and the clearly-environmental fast path) — is defined once in
405
+ check — the root-cause-only decision tree, the never-rerun / never-quarantine
406
+ prohibitions, and the escalation criteria — is defined once in
688
407
  [`.agents/rules/ci-remediation.md`](../../rules/ci-remediation.md). Read it
689
408
  before remediating a red check.
690
409
 
@@ -705,22 +424,17 @@ planning pass, so the delivery never waits on planning.
705
424
 
706
425
  ### The auto-merge wait is an internally-blocking step
707
426
 
708
- This is the single most important contract of this workflow, and the seam
709
- where a worker most often misbehaves: it delivers up to arming auto-merge,
710
- then ends its turn with **free-form prose** — e.g. "I'll wait for the
711
- background watch task to complete" or "the next event will be its completion
712
- notification" — leaving the merge unconfirmed and the Story stranded at
713
- `agent::closing`. **Do not do this.**
427
+ A session that owns close must not arm auto-merge and then end its turn with
428
+ **free-form prose** ("I'll wait for the background watch task…"), leaving the
429
+ merge unconfirmed and the Story stranded at `agent::closing`.
714
430
  `pr-watch-with-update.js --pr <prNumber>` _blocks the current turn_ until CI
715
- resolves — that is the mechanism by which you wait. You MUST keep your turn alive
716
- across the wait: watch → (fix + push + re-watch on red) → confirm the merge
717
- (Step 5) → flip `agent::done` → run the post-merge steps → and only then
718
- return the terminal JSON status contract. The CI wait NEVER terminates your
719
- turn; **only** a confirmed-`MERGED` PR (→ `status: "done"`), an
720
- `agent::blocked` transition (→ `status: "blocked"`), or an unrecoverable
721
- failure (→ `status: "failed"`) does. Ending your turn with prose and an
722
- unconfirmed merge is a contract violation — it is the very bug this workflow
723
- exists to prevent.
431
+ resolves — that is the mechanism by which you wait. Keep your turn alive:
432
+ watch → (fix + push + re-watch on red) → confirm the merge (Step 5) → and only
433
+ then return the terminal status. **Only** a confirmed-`MERGED` PR
434
+ (→ `status: "landed"`), an `agent::blocked` transition (→ `status: "blocked"`),
435
+ or an unrecoverable failure (→ `status: "failed"`) ends the turn — or a
436
+ genuine `pending` (§ Step 7). The statuses are the shipped
437
+ [terminal schema](../../schemas/story-deliver-terminal.schema.json)'s.
724
438
 
725
439
  ### Resurrecting the worktree after `reapOnSuccess`
726
440
 
@@ -740,33 +454,22 @@ state and lose the close commit's structured comment.
740
454
 
741
455
  ### Diagnosing the failure
742
456
 
743
- Pull the failing job log via:
744
-
745
457
  ```bash
746
458
  gh run view <runId> --repo <owner>/<repo> --log-failed
747
459
  ```
748
460
 
749
- The `<runId>` is the run number that `gh pr checks` shows in the
750
- failing row's URL. Read the bottom of the log — the gate that exited
751
- non-zero is named there (e.g. `[Coverage] ❌ REGRESSION in …`).
461
+ The `<runId>` is in the failing row's URL from `gh pr checks`. The gate that
462
+ exited non-zero is named at the bottom of the log (e.g.
463
+ `[Coverage] ❌ REGRESSION in …`).
752
464
 
753
465
  ### Fixing without re-running close-validation
754
466
 
755
- For coverage / maintainability / CRAP regressions detected only on CI:
756
-
757
- 1. Update the relevant baseline file (`baselines/coverage.json`,
758
- `baselines/maintainability.json`, `baselines/crap.json`) to absorb
759
- CI's actual numbers. Edit by hand when CI's numbers are within the
760
- tolerance you'd otherwise accept — don't re-run `npm run … :update`
761
- locally, because Windows numbers will overwrite CI's Linux numbers
762
- and the cycle repeats.
763
- 2. Commit the baseline delta with a `chore(baselines):` message that
764
- names the CI run that produced the values.
765
- 3. `git push` to `origin/story-<storyId>` and re-watch.
766
-
767
- For genuine test failures (a flaky test, a platform-conditional bug):
768
- fix the code or test, commit, push, re-watch. Keep iterating until
769
- the watch exits clean.
467
+ For coverage / maintainability / CRAP regressions detected only on CI, update
468
+ the relevant `baselines/*.json` to CI's actual numbers by hand when they are
469
+ within the tolerance you would otherwise accept — a local `npm run … :update`
470
+ on another OS overwrites CI's numbers and the cycle repeats. Commit it as
471
+ `chore(baselines):` naming the CI run, push, and re-watch. For genuine test
472
+ failures: fix the code or test, commit, push, re-watch.
770
473
 
771
474
  ### When to stop iterating
772
475
 
@@ -799,27 +502,12 @@ the watch exits clean.
799
502
  node .agents/scripts/single-story-confirm-merge.js --story <storyId> --cwd <main-repo>
800
503
  ```
801
504
 
802
- This is the **same** shared land path Step 3 reaches: it flips
803
- `agent::closing → agent::done` on a confirmed merge (closing the issue) and runs
804
- the **same** post-land tail — so the two surfaces cannot diverge. It is
805
- idempotent, emits the same terminal envelope, and is safe to re-run while the PR
806
- is still open (returns `pending`).
807
-
808
- `single-story-confirm-merge.js` re-reads the live PR state (`gh pr view
809
- --json state,mergedAt`, probing `gh pr list --head story-<id> --state all`
810
- when `--pr` is omitted) and:
811
-
812
- - **PR `MERGED`** → flips `agent::closing → agent::done`, closing the
813
- issue, and fires the `story-merged` notify. Prints
814
- `{ action: 'done', merged: true, ... }`.
815
- - **PR still open / closed-without-merge** → leaves the Story at
816
- `agent::closing` (issue stays OPEN) and prints
817
- `{ action: 'pending', reason: 'pr-open' | 'pr-not-merged' | 'no-pr' }`.
818
- Re-run after the merge lands.
819
- - **Story already `agent::done` / issue already closed** → idempotent
820
- `{ action: 'noop', reason: 'already-done' }`.
821
-
822
- The issue closes exactly when the work has merged, never at PR-open.
505
+ This is the **same** shared land path Step 3 reaches: it re-reads the live PR
506
+ state, flips `agent::closing → agent::done` on a confirmed merge (closing the
507
+ issue) and runs the **same** post-land tail — so the two surfaces cannot
508
+ diverge. It is idempotent, emits the same terminal envelope, and is safe to
509
+ re-run while the PR is still open (returns `pending`). The issue closes exactly
510
+ when the work has merged, never at PR-open.
823
511
 
824
512
  ---
825
513
 
@@ -833,58 +521,22 @@ The issue closes exactly when the work has merged, never at PR-open.
833
521
  node .agents/scripts/resync-status-column.js --story <storyId>
834
522
  ```
835
523
 
836
- The helper re-fires the `ColumnSync` mutation and **polls for ~15 s** to win the
837
- race against the bot's late write. It is idempotent and
838
- no-op-safe (`no-project` / `not-on-project` exit 0).
839
-
840
- The GitHub Projects v2 built-in workflows `Pull request merged` and
841
- `Pull request linked to issue` are enabled by default on most boards
842
- and fire ~minutes _after_ auto-merge lands. They overwrite the Status
843
- field as a side-effect, clobbering the `Done` value
844
- `single-story-confirm-merge.js` set at the `agent::done` flip in Step 5
845
- and leaving closed Stories stuck at `In Progress` on the board. The
846
- confirmation step has already exited by then, so the bot gets the last
847
- write.
848
-
849
- `resync-status-column.js`:
850
-
851
- - Reads the ticket's current `agent::*` label set (now `agent::done`).
852
- - Re-fires the same `ColumnSync` mutation `transitionTicketState` used
853
- at close, overwriting the bot's late write.
854
- - **Polls the live Status for ~15 s after the initial write** and
855
- re-fires on drift. Without this loop, a one-shot
856
- mutation routinely lost the race against the bot's asynchronous
857
- fire.
858
- - Prints a single-line JSON envelope:
859
- `{ ticketId, status, column?, reason?, attempts? }`. `attempts > 1`
860
- means the helper had to fight a bot overwrite; `status: 'drifted'`
861
- means the bot won every attempt in the poll budget (rare; usually
862
- signals operator should reap the conflicting workflows).
863
-
864
- Tuning flags are rarely needed; the script enumerates them itself
865
- (`node .agents/scripts/resync-status-column.js --help`).
866
-
867
- Idempotent: re-running on a ticket whose Status already matches the
868
- target returns the same envelope. No-op skips (`no-project`,
869
- `no-meta`, `not-on-project`) exit 0 with the reason in the envelope
870
- so the workflow can continue.
871
-
872
- **Canonical operator fix:** run
524
+ It re-fires the `ColumnSync` mutation and polls to win the race against the
525
+ Projects v2 built-in `Pull request merged` / `Pull request linked to issue`
526
+ workflows, which overwrite Status minutes after the merge. Idempotent and
527
+ no-op-safe; its envelope and flags are in `--help`. `status: 'drifted'` means
528
+ the bot won every attempt. **Canonical operator fix:** run
873
529
  `node .agents/scripts/agents-bootstrap-github.js --reap-conflicting-workflows`
874
530
  once per project to delete the conflicting bot workflows entirely.
875
- This eliminates the race source; the poll loop becomes pure
876
- defense-in-depth against re-enabled or future workflows.
877
531
 
878
532
  ---
879
533
 
880
534
  ## Step 6 — Local branch cleanup detail
881
535
 
882
536
  > **The land tail already ran this** — it is `tail.refCleanup` and
883
- > `tail.baseFastForward` in the terminal envelope, done in-process against the
884
- > same planners this command drives. Run it by hand only when either step
885
- > reported `false` (a dirty shared checkout is the common, benign cause), or
886
- > after a manual merge on a `--no-wait-merge` run. To prune the story ref **and**
887
- > fast-forward local `main` (or `project.baseBranch`):
537
+ > `tail.baseFastForward` in the terminal envelope. Run it by hand only when
538
+ > either step reported `false` (a dirty shared checkout is the common, benign
539
+ > cause), or after a manual merge on a `--no-wait-merge` run:
888
540
 
889
541
  ```bash
890
542
  node .agents/scripts/git-cleanup.js \
@@ -896,51 +548,10 @@ node .agents/scripts/git-cleanup.js \
896
548
  --include "story-<storyId>"
897
549
  ```
898
550
 
899
- `--fast-forward-main` brings local `main` current (the next init seeds from it),
900
- `--branches` + `--include` reap only this Story's ref, and
901
- `--execute --remote --yes` run the deletes non-interactively. The sweep is
902
- idempotent and safe to run before `MERGED` confirms. Skip it only when the
903
- operator opted out via `--no-auto-merge` AND has not yet merged the PR — run the
904
- cleanup after the manual merge lands.
905
-
906
- GitHub deletes the **remote** branch on auto-merge (via the
907
- `--delete-branch` flag `single-story-close.js` passes to `gh pr merge`).
908
- The **local** `story-<storyId>` ref, however, lingers in the main
909
- checkout until something prunes it — `single-story-init.js` runs a
910
- merged-sweep at the start of every _subsequent_ `/deliver-story`
911
- invocation, but that's next-run cleanup, not end-of-run cleanup. Stale
912
- local refs accumulate between sessions, clutter `git branch`, and shadow
913
- the lessons the sweep is meant to surface.
914
-
915
- **Why local `main` goes stale:** `single-story-init.js` seeds new
916
- `story-<id>` branches from the **local** `baseBranch` ref (default
917
- `main`). Auto-merge updates **`origin/main`** on GitHub; nothing in
918
- close or the old Step 6 command updated **local `main`**. The next init
919
- then forked from a tip six merges behind until you manually pulled.
920
- `single-story-init` also attempts the same fast-forward after `git fetch`
921
- when the main checkout is clean (defense in depth if Step 6 was skipped).
922
- Step 6 must still run `--fast-forward-main` so local `main` is current
923
- before the next session — init may skip when the tree is dirty or the
924
- operator is mid-checkout on another branch.
925
-
926
- What the Step 6 cleanup command does:
927
-
928
- - **`--fast-forward-main`** fetches `origin/<baseBranch>` and
929
- `git merge --ff-only` on the main checkout when the tree is clean and
930
- the local base is strictly behind remote. Skipped when already current,
931
- dirty, or diverged (see `/git-cleanup`).
932
- - **`--branches`** reaps the merged `story-<storyId>` ref (worktree,
933
- local branch, stale `origin/` tracking ref). Does not run
934
- `--prune-remotes` or `--stashes` unless you add those flags.
935
- - **`--include "story-<storyId>"`** scopes the branch reap to this
936
- Story's ref only — sibling stories in flight are untouched.
937
- - **`--execute --remote --yes`** actually deletes the local ref, prunes
938
- the matching `origin/` tracking ref, and runs non-interactively.
939
-
940
- The sweep is idempotent. It is safe to run before `state: "MERGED"`
941
- confirms (it will skip a not-yet-merged branch), and safe to re-run
942
- after a successful cleanup (it reports "no merged branches to clean
943
- up").
551
+ It fast-forwards local `main` (the next init seeds from it) and reaps only
552
+ this Story's ref. Idempotent and safe before `MERGED` confirms (a
553
+ not-yet-merged branch is skipped); after an `--no-auto-merge` opt-out, run it
554
+ once the manual merge lands.
944
555
 
945
556
  ---
946
557
 
@@ -962,9 +573,8 @@ The four constraints the spine states without arguing for them:
962
573
  - **Never push the Story branch directly to `main`.** The PR is the only merge
963
574
  surface — a direct push bypasses required checks and the squash title
964
575
  release-please parses.
965
- - **Always prefix path-based tools with the absolute `workCwd` root.** `cd`
966
- scopes Bash, not Edit/Write/Read; close's wrong-tree guard is a backstop for
967
- the mistake, not a licence to make it.
576
+ - **Always prefix path-based tools with the absolute `workCwd` root** —
577
+ § Worktree scope.
968
578
  - **Report state, not process.** Mirror the close envelope's fields; step
969
579
  narration reads as progress while telling the caller nothing it can branch on.
970
580
  - **Drive every `agent::*` transition through `update-ticket-state.js`** so the
@@ -975,74 +585,57 @@ The four constraints the spine states without arguing for them:
975
585
  The field-level contract is the shipped schema
976
586
  [`story-deliver-terminal.schema.json`](../../schemas/story-deliver-terminal.schema.json)
977
587
  — not this file, and not
978
- [`agents/story-worker.md`](../../agents/story-worker.md). All three used to
979
- carry their own prose version; the schema is now the only definition. What
980
- follows is the _judgement_ around it, which a schema cannot express.
588
+ [`agents/story-worker.md`](../../agents/story-worker.md). What follows is the
589
+ _judgement_ around it, which a schema cannot express.
981
590
 
982
591
  ### `pending` is a real status — and it is not a park
983
592
 
984
593
  `pending` is a real terminal status with its own exit code (3) — the honest
985
594
  name for a close-and-land whose CI outlived the host's ~10-minute
986
- tool-invocation ceiling, which would otherwise park the Story at
987
- `agent::closing` with no event and no label:
595
+ tool-invocation ceiling:
988
596
 
989
597
  - It is **resumable**: no label was mutated, no `merge.unlanded` was emitted,
990
598
  and `nextCommand` names the one command that continues it. The cumulative
991
599
  budget is anchored at the PR's `createdAt`, so resuming does not restart the
992
- clock and the give-up bound still means something.
600
+ clock.
993
601
  - It is **not** a park. Returning `pending` because you would rather not wait
994
602
  is the no-park failure mode wearing a schema. Return it only
995
603
  when the bound genuinely expired, or a human owns the merge.
996
604
 
997
- The no-park rule holds: a turn that ends with prose ("I'll wait for the watch
998
- task…", "the next event will be its completion notification…") and an
999
- unconfirmed merge is a **contract violation** — the parent cannot distinguish
1000
- "still working" from "done but silent". `pending` is the honest,
1001
- machine-readable alternative: "not finished, here is exactly how to continue."
605
+ The no-park rule holds: a turn that ends with prose and an unconfirmed merge
606
+ is a **contract violation** — the parent cannot distinguish "still working"
607
+ from "done but silent". `pending` is the honest, machine-readable alternative.
1002
608
 
1003
609
  ### The envelope also lands on disk
1004
610
 
1005
- Stdout has exactly one reader — the turn that launched the close — and that
1006
- reader is not always still listening. A child that reports progress and ends
1007
- its turn while its close is mid-gate-chain is behaving reasonably, but the
1008
- envelope it never relayed is gone, and reconstructing the Story's state from
1009
- labels costs a recovery round trip plus a full resume of the child. Observed
1010
- four times across three workers in a single consumer run, on unrelated
1011
- footprints, and not new to that run.
1012
-
1013
- So `emitTerminalEnvelope` — the one writer behind every emit site — also
611
+ `emitTerminalEnvelope` — the one writer behind every emit site — also
1014
612
  persists the validated envelope to
1015
- `<tempRoot>/orchestration/story-deliver-terminal-<storyId>.json`:
613
+ `<tempRoot>/orchestration/story-deliver-terminal-<storyId>.json`, because
614
+ stdout's one reader is not always still listening:
1016
615
 
1017
616
  - **It is the same object**, not a summary. Read it and branch exactly as you
1018
617
  would on stdout; the copy is written before the markers are, so a caller
1019
618
  that saw them can rely on the file.
1020
619
  - **It is best-effort.** A failed write returns null and changes nothing about
1021
- the emitted envelope or the exit code — a landed PR must never become a
1022
- crash because a temp directory was unwritable.
620
+ the emitted envelope or the exit code.
1023
621
  - **It is a fallback, not a licence.** The orchestrator running close still
1024
622
  holds its turn until the envelope arrives; see § Step 3 above and
1025
623
  [`agents/story-worker.md`](../../agents/story-worker.md).
1026
624
 
1027
625
  `deliver-recover.js` reads the same artifact, plus the freshness of
1028
- `close-gates-<storyId>.log`, to split the one genuinely ambiguous row of its
1029
- table. `agent::executing` with no PR used to answer "Implementation never
1030
- finished" — false for the whole duration of a close, whose gates and push
1031
- happen before any PR exists, and actively hazardous, because acting on its
1032
- re-init suggestion can put a second close on one PR. It now answers
626
+ `close-gates-<storyId>.log`, to split `agent::executing` with no PR: it answers
1033
627
  `close-in-flight` (a gate log touched inside the window: wait, then re-probe)
1034
628
  or `close-envelope-on-disk` (the close already reached a verdict: relay it),
1035
- and falls back to the original verdict only when neither artifact exists.
629
+ and falls back to "Implementation never finished" only when neither artifact
630
+ exists — never re-init under a live close.
1036
631
 
1037
632
  ### Exit-code compatibility note (`--no-wait-merge`)
1038
633
 
1039
- Every close flag keeps its meaning, but the **exit code** of a
1040
- `--no-wait-merge` (or `--no-auto-merge` / `autoMerge: "strict"`) run changed:
1041
- it now exits **3** (`pending`) rather than 0, because the PR is open and a
1042
- human still owns the merge. Reporting `landed` would be a lie, and `landed` is
1043
- what exit 0 means. A wrapper that shells out and tests `exit == 0` to mean
1044
- "close finished" must be updated to treat 3 as the operator-merge success
1045
- path; `!= 0` no longer implies failure.
634
+ A `--no-wait-merge` (or `--no-auto-merge` / `autoMerge: "strict"`) run exits
635
+ **3** (`pending`), not 0: the PR is open and a human still owns the merge, and
636
+ `landed` is what exit 0 means. A wrapper testing `exit == 0` for "close
637
+ finished" must treat 3 as the operator-merge success path; `!= 0` does not
638
+ imply failure.
1046
639
 
1047
640
  ### Per-status judgement
1048
641
 
@@ -1060,10 +653,7 @@ path; `!= 0` no longer implies failure.
1060
653
 
1061
654
  > **Handoff discipline — report state, not process.** Populate the envelope
1062
655
  > with essential terminal state only (mirroring the fields
1063
- > `single-story-close.js` already emits). Do not narrate the
1064
- > steps you took, and do not prescribe how the next stage should work. Prose
1065
- > process commentary only bloats the hydrated prompt. When run **interactively** (no parent
1066
- > aggregator), this JSON envelope is optional — relay terminal state to the
1067
- > operator in prose instead — but the **no-park rule still holds**: never end
1068
- > an interactive turn with an unconfirmed merge either; block on the watch,
1069
- > confirm, and report the merged outcome.
656
+ > `single-story-close.js` already emits); do not narrate the steps you took.
657
+ > When run **interactively** (no parent aggregator), the JSON envelope is
658
+ > optional — relay terminal state in prose — but the **no-park rule still
659
+ > holds**: never end an interactive turn with an unconfirmed merge either.