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