mandrel 2.59.0 → 2.61.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (678) hide show
  1. package/.agents/README.md +21 -19
  2. package/.agents/agents/acceptance-critic.md +24 -43
  3. package/.agents/agents/story-worker.md +20 -21
  4. package/.agents/docs/agentrc-reference.json +5 -84
  5. package/.agents/docs/configuration.md +48 -132
  6. package/.agents/docs/workflows.md +2 -2
  7. package/.agents/instructions.md +5 -8
  8. package/.agents/rules/ci-remediation.md +41 -8
  9. package/.agents/rules/gherkin-standards.md +4 -0
  10. package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
  11. package/.agents/schemas/agentrc.schema.json +16 -496
  12. package/.agents/schemas/story-deliver-terminal.schema.json +13 -3
  13. package/.agents/schemas/validation-evidence.schema.json +2 -1
  14. package/.agents/scripts/README.md +23 -13
  15. package/.agents/scripts/acceptance-eval.js +35 -169
  16. package/.agents/scripts/agents-bootstrap-github.js +27 -129
  17. package/.agents/scripts/apply-quality-bootstrap.js +4 -40
  18. package/.agents/scripts/audit-baselines.js +6 -27
  19. package/.agents/scripts/audit-labels-bootstrap.js +5 -29
  20. package/.agents/scripts/audit-to-stories.js +91 -361
  21. package/.agents/scripts/boot-sweep.js +19 -72
  22. package/.agents/scripts/bootstrap.js +74 -395
  23. package/.agents/scripts/ceremony-derive.js +10 -41
  24. package/.agents/scripts/check-arch-cycles.js +14 -64
  25. package/.agents/scripts/check-baselines.js +8 -48
  26. package/.agents/scripts/check-context-budget.js +105 -311
  27. package/.agents/scripts/check-cyclomatic.js +12 -44
  28. package/.agents/scripts/check-dead-exports.js +13 -64
  29. package/.agents/scripts/check-doc-links.js +38 -186
  30. package/.agents/scripts/check-gherkin-corpus.js +24 -127
  31. package/.agents/scripts/check-test-temp-hygiene.js +28 -169
  32. package/.agents/scripts/coverage-capture.js +34 -98
  33. package/.agents/scripts/deliver-light.js +25 -171
  34. package/.agents/scripts/deliver-recover.js +6 -42
  35. package/.agents/scripts/deliver-run.js +534 -0
  36. package/.agents/scripts/diagnose-friction.js +24 -116
  37. package/.agents/scripts/drain-pending-cleanup.js +1 -1
  38. package/.agents/scripts/evidence-gate.js +23 -85
  39. package/.agents/scripts/file-ci-gap.js +57 -49
  40. package/.agents/scripts/generate-config-docs.js +30 -170
  41. package/.agents/scripts/generate-lens-checklists.js +8 -52
  42. package/.agents/scripts/generate-skills-index.js +14 -112
  43. package/.agents/scripts/generate-workflows-doc.js +10 -70
  44. package/.agents/scripts/git-cleanup.js +2 -34
  45. package/.agents/scripts/lib/Graph.js +24 -81
  46. package/.agents/scripts/lib/ITicketingProvider.js +47 -143
  47. package/.agents/scripts/lib/Logger.js +14 -76
  48. package/.agents/scripts/lib/audit-baselines/engine.js +11 -31
  49. package/.agents/scripts/lib/audit-baselines/gate-surface.js +3 -17
  50. package/.agents/scripts/lib/audit-baselines/headroom.js +4 -20
  51. package/.agents/scripts/lib/audit-baselines/hotspots.js +3 -15
  52. package/.agents/scripts/lib/audit-baselines/kinds.js +23 -89
  53. package/.agents/scripts/lib/audit-baselines/outliers.js +6 -23
  54. package/.agents/scripts/lib/audit-baselines/read.js +3 -16
  55. package/.agents/scripts/lib/audit-baselines/staleness.js +7 -26
  56. package/.agents/scripts/lib/audit-baselines/surface-entry.js +7 -28
  57. package/.agents/scripts/lib/audit-baselines/trend.js +7 -20
  58. package/.agents/scripts/lib/audit-baselines/weights.js +9 -37
  59. package/.agents/scripts/lib/audit-suite/audit-rules-reader.js +3 -18
  60. package/.agents/scripts/lib/audit-suite/checklist-threading.js +26 -124
  61. package/.agents/scripts/lib/audit-suite/dispatch-checklist.js +14 -45
  62. package/.agents/scripts/lib/audit-suite/findings.js +12 -52
  63. package/.agents/scripts/lib/audit-suite/frontmatter.js +5 -29
  64. package/.agents/scripts/lib/audit-suite/index.js +1 -15
  65. package/.agents/scripts/lib/audit-suite/lens-checklist.js +10 -45
  66. package/.agents/scripts/lib/audit-suite/lens-diff-floor.js +11 -76
  67. package/.agents/scripts/lib/audit-suite/runner.js +13 -43
  68. package/.agents/scripts/lib/audit-suite/selector.js +49 -349
  69. package/.agents/scripts/lib/audit-suite/substitutions.js +12 -40
  70. package/.agents/scripts/lib/audit-suite/workflow-loader.js +3 -15
  71. package/.agents/scripts/lib/audit-to-stories/audit-label-taxonomy.js +11 -73
  72. package/.agents/scripts/lib/audit-to-stories/audit-lenses.js +8 -37
  73. package/.agents/scripts/lib/audit-to-stories/build-story-body.js +25 -143
  74. package/.agents/scripts/lib/audit-to-stories/dedupe-against-github.js +14 -80
  75. package/.agents/scripts/lib/audit-to-stories/epic-grouping-directive.js +4 -18
  76. package/.agents/scripts/lib/audit-to-stories/finding-adapter.js +7 -40
  77. package/.agents/scripts/lib/audit-to-stories/group-findings.js +9 -39
  78. package/.agents/scripts/lib/audit-to-stories/issue-corpus.js +10 -66
  79. package/.agents/scripts/lib/audit-to-stories/issue-index.js +6 -30
  80. package/.agents/scripts/lib/audit-to-stories/issues-file.js +6 -36
  81. package/.agents/scripts/lib/audit-to-stories/ledger-commit.js +17 -69
  82. package/.agents/scripts/lib/audit-to-stories/ledger-pr.js +17 -85
  83. package/.agents/scripts/lib/audit-to-stories/ledger-record.js +10 -48
  84. package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +38 -146
  85. package/.agents/scripts/lib/audit-to-stories/seed-from-findings.js +7 -42
  86. package/.agents/scripts/lib/audit-to-stories/wire-dependencies.js +10 -57
  87. package/.agents/scripts/lib/baseline-loader.js +12 -51
  88. package/.agents/scripts/lib/baseline-schema-registry.js +5 -22
  89. package/.agents/scripts/lib/baselines/component-matcher.js +3 -12
  90. package/.agents/scripts/lib/baselines/components.js +10 -61
  91. package/.agents/scripts/lib/baselines/coverage-updater-cli.js +7 -36
  92. package/.agents/scripts/lib/baselines/crap-preview-incremental.js +7 -19
  93. package/.agents/scripts/lib/baselines/crap-preview-scan.js +19 -45
  94. package/.agents/scripts/lib/baselines/crap-updater-cli.js +16 -65
  95. package/.agents/scripts/lib/baselines/diff-scope-cli.js +5 -33
  96. package/.agents/scripts/lib/baselines/duplication-scanner.js +11 -60
  97. package/.agents/scripts/lib/baselines/env-overrides.js +12 -67
  98. package/.agents/scripts/lib/baselines/envelope.js +13 -129
  99. package/.agents/scripts/lib/baselines/exit-codes.js +6 -49
  100. package/.agents/scripts/lib/baselines/git-base.js +23 -142
  101. package/.agents/scripts/lib/baselines/kernel.js +11 -111
  102. package/.agents/scripts/lib/baselines/kinds/_crap-new-method-gate.js +9 -47
  103. package/.agents/scripts/lib/baselines/kinds/_crap-read.js +8 -51
  104. package/.agents/scripts/lib/baselines/kinds/_shared-metric.js +7 -62
  105. package/.agents/scripts/lib/baselines/kinds/bundle-size.js +8 -29
  106. package/.agents/scripts/lib/baselines/kinds/coverage.js +3 -15
  107. package/.agents/scripts/lib/baselines/kinds/crap.js +94 -415
  108. package/.agents/scripts/lib/baselines/kinds/duplication.js +4 -30
  109. package/.agents/scripts/lib/baselines/kinds/kind-factory.js +7 -53
  110. package/.agents/scripts/lib/baselines/kinds/maintainability.js +15 -80
  111. package/.agents/scripts/lib/baselines/kinds/mutation.js +12 -72
  112. package/.agents/scripts/lib/baselines/maintainability-baseline-io.js +4 -11
  113. package/.agents/scripts/lib/baselines/merge-envelopes.js +30 -146
  114. package/.agents/scripts/lib/baselines/path-canon.js +19 -128
  115. package/.agents/scripts/lib/baselines/preview-gates.js +8 -37
  116. package/.agents/scripts/lib/baselines/reader.js +14 -107
  117. package/.agents/scripts/lib/baselines/refresh-service.js +35 -252
  118. package/.agents/scripts/lib/baselines/scope.js +11 -135
  119. package/.agents/scripts/lib/baselines/writer.js +16 -149
  120. package/.agents/scripts/lib/bdd-runner-detect.js +18 -113
  121. package/.agents/scripts/lib/bdd-scenario-budget.js +9 -36
  122. package/.agents/scripts/lib/bdd-scenario-scanner.js +11 -73
  123. package/.agents/scripts/lib/bdd-step-index.js +26 -100
  124. package/.agents/scripts/lib/bootstrap/baseline-merge-driver.js +23 -103
  125. package/.agents/scripts/lib/bootstrap/branch-protection.js +2 -5
  126. package/.agents/scripts/lib/bootstrap/commit-push.js +12 -50
  127. package/.agents/scripts/lib/bootstrap/gh-preflight.js +14 -101
  128. package/.agents/scripts/lib/bootstrap/hitl-confirm.js +5 -30
  129. package/.agents/scripts/lib/bootstrap/install-ledger.js +17 -73
  130. package/.agents/scripts/lib/bootstrap/issue-forms-template.js +17 -121
  131. package/.agents/scripts/lib/bootstrap/manifest.js +15 -86
  132. package/.agents/scripts/lib/bootstrap/merge-methods.js +4 -33
  133. package/.agents/scripts/lib/bootstrap/preflight.js +12 -61
  134. package/.agents/scripts/lib/bootstrap/project-bootstrap.js +34 -235
  135. package/.agents/scripts/lib/bootstrap/prompt.js +21 -129
  136. package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +27 -141
  137. package/.agents/scripts/lib/bootstrap/summary.js +1 -8
  138. package/.agents/scripts/lib/bootstrap/workflow-audit.js +11 -84
  139. package/.agents/scripts/lib/branch-name-guard.js +4 -23
  140. package/.agents/scripts/lib/changed-files.js +39 -121
  141. package/.agents/scripts/lib/checks/core-bare-clean.js +4 -24
  142. package/.agents/scripts/lib/checks/index.js +18 -101
  143. package/.agents/scripts/lib/checks/loop-health.js +11 -53
  144. package/.agents/scripts/lib/checks/state.js +16 -91
  145. package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +10 -61
  146. package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +14 -83
  147. package/.agents/scripts/lib/child-exec.js +39 -108
  148. package/.agents/scripts/lib/cli/standard-args.js +9 -116
  149. package/.agents/scripts/lib/cli-args.js +31 -146
  150. package/.agents/scripts/lib/cli-usage.js +5 -27
  151. package/.agents/scripts/lib/cli-utils.js +2 -12
  152. package/.agents/scripts/lib/close-validation/commands.js +13 -76
  153. package/.agents/scripts/lib/close-validation/gates.js +92 -331
  154. package/.agents/scripts/lib/close-validation/process.js +121 -151
  155. package/.agents/scripts/lib/close-validation/projections/advisories.js +5 -31
  156. package/.agents/scripts/lib/close-validation/projections/crap.js +19 -67
  157. package/.agents/scripts/lib/close-validation/projections/head-sha.js +1 -17
  158. package/.agents/scripts/lib/close-validation/projections/inputs.js +4 -34
  159. package/.agents/scripts/lib/close-validation/projections/maintainability.js +11 -58
  160. package/.agents/scripts/lib/close-validation/runner.js +53 -110
  161. package/.agents/scripts/lib/command-header.js +6 -28
  162. package/.agents/scripts/lib/config/acceptance-eval.js +4 -30
  163. package/.agents/scripts/lib/config/baselines.js +3 -14
  164. package/.agents/scripts/lib/config/ci.js +8 -38
  165. package/.agents/scripts/lib/config/commands.js +1 -15
  166. package/.agents/scripts/lib/config/defaults.js +4 -33
  167. package/.agents/scripts/lib/config/delivery-routing.js +6 -34
  168. package/.agents/scripts/lib/config/explain.js +10 -83
  169. package/.agents/scripts/lib/config/gates/coverage.schema.js +0 -12
  170. package/.agents/scripts/lib/config/gates/crap-incremental-coverage.schema.js +3 -31
  171. package/.agents/scripts/lib/config/gates/crap.schema.js +1 -34
  172. package/.agents/scripts/lib/config/gates/duplication.schema.js +1 -8
  173. package/.agents/scripts/lib/config/gates/index.js +2 -17
  174. package/.agents/scripts/lib/config/gates/maintainability.schema.js +1 -20
  175. package/.agents/scripts/lib/config/gates/mutation.schema.js +1 -7
  176. package/.agents/scripts/lib/config/gates/shared.js +4 -64
  177. package/.agents/scripts/lib/config/github.js +4 -22
  178. package/.agents/scripts/lib/config/limits.js +4 -57
  179. package/.agents/scripts/lib/config/paths.js +2 -21
  180. package/.agents/scripts/lib/config/qa.js +4 -38
  181. package/.agents/scripts/lib/config/quality.js +76 -432
  182. package/.agents/scripts/lib/config/runners.js +12 -56
  183. package/.agents/scripts/lib/config/runtime.js +13 -57
  184. package/.agents/scripts/lib/config/shared.js +2 -16
  185. package/.agents/scripts/lib/config/sync-agentrc.js +9 -50
  186. package/.agents/scripts/lib/config/temp-paths.js +40 -280
  187. package/.agents/scripts/lib/config/validate-orchestration.js +5 -17
  188. package/.agents/scripts/lib/config/worktree-isolation.js +9 -28
  189. package/.agents/scripts/lib/config-resolver.js +11 -52
  190. package/.agents/scripts/lib/config-schema-shared.js +1 -4
  191. package/.agents/scripts/lib/config-settings-schema-delivery.js +16 -291
  192. package/.agents/scripts/lib/config-settings-schema-quality.js +7 -219
  193. package/.agents/scripts/lib/config-settings-schema.js +37 -274
  194. package/.agents/scripts/lib/coverage-baseline.js +20 -110
  195. package/.agents/scripts/lib/coverage-capture-fullscope.js +18 -35
  196. package/.agents/scripts/lib/coverage-capture-incremental.js +15 -45
  197. package/.agents/scripts/lib/coverage-capture-usage.js +8 -25
  198. package/.agents/scripts/lib/coverage-capture.js +99 -224
  199. package/.agents/scripts/lib/coverage-utils.js +14 -79
  200. package/.agents/scripts/lib/cpu-pool.js +17 -123
  201. package/.agents/scripts/lib/crap-baseline-join.js +16 -88
  202. package/.agents/scripts/lib/crap-coordinates.js +6 -25
  203. package/.agents/scripts/lib/crap-engine.js +40 -153
  204. package/.agents/scripts/lib/crap-method-identity.js +16 -78
  205. package/.agents/scripts/lib/crap-utils.js +31 -155
  206. package/.agents/scripts/lib/cyclomatic-ceiling.js +14 -87
  207. package/.agents/scripts/lib/cyclomatic-scope.js +10 -50
  208. package/.agents/scripts/lib/dead-exports-knip.js +18 -56
  209. package/.agents/scripts/lib/dead-exports-mode.js +5 -24
  210. package/.agents/scripts/lib/degraded-mode.js +3 -26
  211. package/.agents/scripts/lib/dependency-parser.js +8 -40
  212. package/.agents/scripts/lib/dependency-version.js +13 -35
  213. package/.agents/scripts/lib/detect-package-manager.js +6 -36
  214. package/.agents/scripts/lib/doc-tiers.js +22 -124
  215. package/.agents/scripts/lib/duplicate-search.js +8 -72
  216. package/.agents/scripts/lib/env-loader.js +5 -27
  217. package/.agents/scripts/lib/error-redactor.js +6 -31
  218. package/.agents/scripts/lib/errors/index.js +2 -22
  219. package/.agents/scripts/lib/escomplex-ast-compat.js +22 -163
  220. package/.agents/scripts/lib/escomplex-kernel.js +21 -123
  221. package/.agents/scripts/lib/feedback-loop/graduator-core.js +94 -419
  222. package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +20 -98
  223. package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +27 -149
  224. package/.agents/scripts/lib/findings/audit-ledger.js +23 -97
  225. package/.agents/scripts/lib/findings/classify-finding.js +14 -69
  226. package/.agents/scripts/lib/findings/promote-finding.js +14 -112
  227. package/.agents/scripts/lib/findings/provenance-field.js +11 -52
  228. package/.agents/scripts/lib/findings/route-finding.js +37 -255
  229. package/.agents/scripts/lib/findings/semantic-issue-search.js +14 -59
  230. package/.agents/scripts/lib/findings/severity.js +18 -104
  231. package/.agents/scripts/lib/format-generated-json.js +12 -44
  232. package/.agents/scripts/lib/full-suite-lock.js +160 -429
  233. package/.agents/scripts/lib/full-suite-queue.js +213 -0
  234. package/.agents/scripts/lib/gates/baseline-store.js +5 -9
  235. package/.agents/scripts/lib/gates/friction.js +1 -3
  236. package/.agents/scripts/lib/generated/agentrc-validator.js +2 -2
  237. package/.agents/scripts/lib/gh-exec.js +123 -191
  238. package/.agents/scripts/lib/git/cached-fetch.js +9 -52
  239. package/.agents/scripts/lib/git/sync-from-base.js +15 -107
  240. package/.agents/scripts/lib/git-branch-cleanup.js +14 -61
  241. package/.agents/scripts/lib/git-branch-lifecycle.js +16 -87
  242. package/.agents/scripts/lib/git-utils.js +37 -161
  243. package/.agents/scripts/lib/github/framework-repo.js +8 -71
  244. package/.agents/scripts/lib/github-url.js +2 -17
  245. package/.agents/scripts/lib/import-graph.js +11 -38
  246. package/.agents/scripts/lib/install-cmd-parser.js +4 -13
  247. package/.agents/scripts/lib/json-utils.js +3 -18
  248. package/.agents/scripts/lib/label-constants.js +16 -111
  249. package/.agents/scripts/lib/label-taxonomy.js +4 -30
  250. package/.agents/scripts/lib/maintainability-engine.js +12 -80
  251. package/.agents/scripts/lib/maintainability-unscorable.js +5 -25
  252. package/.agents/scripts/lib/maintainability-utils.js +16 -92
  253. package/.agents/scripts/lib/mandrel-catalog.js +12 -70
  254. package/.agents/scripts/lib/notifications/notifier.js +13 -38
  255. package/.agents/scripts/lib/npm-scripts.js +4 -23
  256. package/.agents/scripts/lib/observability/metrics-ledger.js +16 -76
  257. package/.agents/scripts/lib/observability/runtime-friction.js +44 -286
  258. package/.agents/scripts/lib/observability/signal-validator.js +5 -37
  259. package/.agents/scripts/lib/observability/signals-writer.js +11 -121
  260. package/.agents/scripts/lib/observability/source-classifier.js +22 -203
  261. package/.agents/scripts/lib/observability/terse-result.js +14 -47
  262. package/.agents/scripts/lib/onboard/init-tail.js +13 -74
  263. package/.agents/scripts/lib/onboard/scaffold-docs.js +11 -34
  264. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +25 -139
  265. package/.agents/scripts/lib/orchestration/auto-merge-cwd.js +11 -66
  266. package/.agents/scripts/lib/orchestration/behind-recovery.js +10 -55
  267. package/.agents/scripts/lib/orchestration/ceremony-routing.js +28 -156
  268. package/.agents/scripts/lib/orchestration/change-set.js +7 -36
  269. package/.agents/scripts/lib/orchestration/check-baselines/phases/compare.js +9 -46
  270. package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +11 -44
  271. package/.agents/scripts/lib/orchestration/check-baselines/phases/floors.js +5 -24
  272. package/.agents/scripts/lib/orchestration/check-baselines/phases/friction.js +3 -12
  273. package/.agents/scripts/lib/orchestration/check-baselines/phases/parse-args.js +5 -38
  274. package/.agents/scripts/lib/orchestration/check-baselines/phases/pipeline.js +3 -8
  275. package/.agents/scripts/lib/orchestration/check-baselines/phases/refresh-ack.js +28 -136
  276. package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +3 -13
  277. package/.agents/scripts/lib/orchestration/check-state.js +92 -0
  278. package/.agents/scripts/lib/orchestration/ci-gap-intake.js +37 -144
  279. package/.agents/scripts/lib/orchestration/ci-rerun-guard.js +121 -157
  280. package/.agents/scripts/lib/orchestration/code-review.js +24 -128
  281. package/.agents/scripts/lib/orchestration/column-sync.js +23 -111
  282. package/.agents/scripts/lib/orchestration/complexity-gate.js +118 -462
  283. package/.agents/scripts/lib/orchestration/deliver-recover.js +36 -168
  284. package/.agents/scripts/lib/orchestration/dependency-analyzer.js +4 -35
  285. package/.agents/scripts/lib/orchestration/dependency-candidates.js +9 -41
  286. package/.agents/scripts/lib/orchestration/diff-magnitude.js +25 -115
  287. package/.agents/scripts/lib/orchestration/doc-reader.js +2 -6
  288. package/.agents/scripts/lib/orchestration/docs-digest.js +13 -51
  289. package/.agents/scripts/lib/orchestration/epic-candidates.js +13 -53
  290. package/.agents/scripts/lib/orchestration/epic-checklist.js +9 -33
  291. package/.agents/scripts/lib/orchestration/epic-container.js +41 -167
  292. package/.agents/scripts/lib/orchestration/epic-expansion.js +10 -40
  293. package/.agents/scripts/lib/orchestration/epic-rollup.js +55 -207
  294. package/.agents/scripts/lib/orchestration/file-assumption-enum.js +2 -22
  295. package/.agents/scripts/lib/orchestration/file-assumptions.js +45 -253
  296. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-detect.js +9 -46
  297. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-reap.js +7 -57
  298. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches.js +21 -126
  299. package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +2 -6
  300. package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +1 -4
  301. package/.agents/scripts/lib/orchestration/git-cleanup/phases/filters.js +1 -5
  302. package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes-ff.js +9 -34
  303. package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes.js +41 -190
  304. package/.agents/scripts/lib/orchestration/git-cleanup/phases/merged-tip.js +9 -45
  305. package/.agents/scripts/lib/orchestration/git-cleanup/phases/parse-args.js +1 -4
  306. package/.agents/scripts/lib/orchestration/git-cleanup/phases/phase-drivers.js +19 -85
  307. package/.agents/scripts/lib/orchestration/git-cleanup/phases/prompts.js +3 -17
  308. package/.agents/scripts/lib/orchestration/git-cleanup/phases/prune.js +1 -5
  309. package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +16 -100
  310. package/.agents/scripts/lib/orchestration/git-cleanup/phases/stashes.js +1 -4
  311. package/.agents/scripts/lib/orchestration/lease-guard-shared.js +16 -67
  312. package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +9 -33
  313. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +8 -29
  314. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +15 -68
  315. package/.agents/scripts/lib/orchestration/light-backstop.js +11 -49
  316. package/.agents/scripts/lib/orchestration/light-escalation.js +21 -89
  317. package/.agents/scripts/lib/orchestration/light-suitability.js +37 -307
  318. package/.agents/scripts/lib/orchestration/merge-block-class.js +39 -216
  319. package/.agents/scripts/lib/orchestration/merge-poll.js +104 -377
  320. package/.agents/scripts/lib/orchestration/pinned-identifier-lint.js +17 -57
  321. package/.agents/scripts/lib/orchestration/plan-context.js +55 -318
  322. package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +22 -79
  323. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +5 -31
  324. package/.agents/scripts/lib/orchestration/plan-metrics.js +29 -108
  325. package/.agents/scripts/lib/orchestration/plan-navigation.js +8 -27
  326. package/.agents/scripts/lib/orchestration/plan-persist/acceptance-handle-repair.js +12 -49
  327. package/.agents/scripts/lib/orchestration/plan-persist/audit-provenance.js +18 -73
  328. package/.agents/scripts/lib/orchestration/plan-persist/changes-repair.js +16 -78
  329. package/.agents/scripts/lib/orchestration/plan-persist/cross-plan-links.js +6 -30
  330. package/.agents/scripts/lib/orchestration/plan-persist/epic-adoption.js +14 -65
  331. package/.agents/scripts/lib/orchestration/plan-persist/epic-ops.js +21 -76
  332. package/.agents/scripts/lib/orchestration/plan-persist/external-deps.js +6 -43
  333. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +14 -68
  334. package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +9 -41
  335. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +71 -289
  336. package/.agents/scripts/lib/orchestration/plan-persist/soft-findings.js +2 -12
  337. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +96 -362
  338. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +9 -39
  339. package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +60 -186
  340. package/.agents/scripts/lib/orchestration/plan-persist/wave-collision-gate.js +9 -49
  341. package/.agents/scripts/lib/orchestration/plan-persist/wave-serialisation.js +7 -28
  342. package/.agents/scripts/lib/orchestration/plan-reachability.js +13 -42
  343. package/.agents/scripts/lib/orchestration/plan-run-labels/reap.js +16 -91
  344. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +16 -54
  345. package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +10 -52
  346. package/.agents/scripts/lib/orchestration/planning/authoring-context.js +14 -109
  347. package/.agents/scripts/lib/orchestration/planning/memory-pool-advisory.js +11 -83
  348. package/.agents/scripts/lib/orchestration/pr-watch.js +48 -306
  349. package/.agents/scripts/lib/orchestration/project-meta-cache.js +15 -80
  350. package/.agents/scripts/lib/orchestration/project-meta-resolver.js +10 -51
  351. package/.agents/scripts/lib/orchestration/reassert-status-column.js +12 -76
  352. package/.agents/scripts/lib/orchestration/remote-verifier.js +12 -36
  353. package/.agents/scripts/lib/orchestration/resolve-stories.js +33 -164
  354. package/.agents/scripts/lib/orchestration/retro-proposals.js +66 -361
  355. package/.agents/scripts/lib/orchestration/review-base-ref.js +9 -43
  356. package/.agents/scripts/lib/orchestration/review-depth.js +12 -91
  357. package/.agents/scripts/lib/orchestration/review-providers/codex.js +10 -111
  358. package/.agents/scripts/lib/orchestration/review-providers/degraded-gates.js +13 -71
  359. package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +7 -51
  360. package/.agents/scripts/lib/orchestration/review-providers/mi-exemptions.js +8 -53
  361. package/.agents/scripts/lib/orchestration/review-providers/native.js +30 -214
  362. package/.agents/scripts/lib/orchestration/review-providers/parse-findings.js +7 -52
  363. package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +4 -33
  364. package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +11 -71
  365. package/.agents/scripts/lib/orchestration/review-providers/scoped-lint.js +19 -131
  366. package/.agents/scripts/lib/orchestration/review-providers/security-review.js +6 -89
  367. package/.agents/scripts/lib/orchestration/review-providers/types.js +26 -56
  368. package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +3 -46
  369. package/.agents/scripts/lib/orchestration/run-epilogue.js +245 -326
  370. package/.agents/scripts/lib/orchestration/run-scoped-config.js +55 -159
  371. package/.agents/scripts/lib/orchestration/single-story-close/close-note.js +7 -34
  372. package/.agents/scripts/lib/orchestration/single-story-close/failed-terminal.js +16 -89
  373. package/.agents/scripts/lib/orchestration/single-story-close/gate-log.js +18 -109
  374. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +83 -239
  375. package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +20 -82
  376. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +103 -97
  377. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +8 -64
  378. package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +136 -486
  379. package/.agents/scripts/lib/orchestration/single-story-close/phases/conventional-subject.js +30 -134
  380. package/.agents/scripts/lib/orchestration/single-story-close/phases/graphql-preflight.js +96 -0
  381. package/.agents/scripts/lib/orchestration/single-story-close/phases/lock-wait-pending.js +49 -0
  382. package/.agents/scripts/lib/orchestration/single-story-close/phases/normalize-pr-title.js +13 -86
  383. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +20 -95
  384. package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +46 -203
  385. package/.agents/scripts/lib/orchestration/single-story-close/phases/pre-gate-steps.js +8 -50
  386. package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +12 -83
  387. package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +6 -39
  388. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +1 -6
  389. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-outcome.js +4 -28
  390. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-override.js +6 -51
  391. package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +6 -34
  392. package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +23 -121
  393. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +180 -273
  394. package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +15 -69
  395. package/.agents/scripts/lib/orchestration/story-body-gate.js +4 -23
  396. package/.agents/scripts/lib/orchestration/story-close/baseline-upward-writeback.js +50 -179
  397. package/.agents/scripts/lib/orchestration/story-close/context-budget-writeback.js +11 -41
  398. package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +23 -311
  399. package/.agents/scripts/lib/orchestration/story-close/phases/local-lens-review.js +22 -147
  400. package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +16 -67
  401. package/.agents/scripts/lib/orchestration/story-deliver-terminal-schema.js +12 -68
  402. package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +42 -200
  403. package/.agents/scripts/lib/orchestration/story-follow-ups.js +167 -252
  404. package/.agents/scripts/lib/orchestration/story-init-envelope.js +52 -0
  405. package/.agents/scripts/lib/orchestration/story-init-remote.js +2 -6
  406. package/.agents/scripts/lib/orchestration/story-reachability.js +3 -23
  407. package/.agents/scripts/lib/orchestration/task-body-validator.js +12 -135
  408. package/.agents/scripts/lib/orchestration/ticket-lease.js +28 -131
  409. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +15 -149
  410. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +5 -33
  411. package/.agents/scripts/lib/orchestration/ticket-validator.js +63 -344
  412. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +51 -244
  413. package/.agents/scripts/lib/orchestration/ticketing/reads.js +39 -261
  414. package/.agents/scripts/lib/orchestration/ticketing/state.js +14 -68
  415. package/.agents/scripts/lib/orchestration/ticketing/transition.js +46 -263
  416. package/.agents/scripts/lib/orchestration/ticketing.js +2 -26
  417. package/.agents/scripts/lib/orchestration/verify-credit.js +18 -79
  418. package/.agents/scripts/lib/orchestration/worktree-dirty.js +5 -30
  419. package/.agents/scripts/lib/path-security.js +3 -6
  420. package/.agents/scripts/lib/plan-phase-cleanup.js +9 -49
  421. package/.agents/scripts/lib/preflight-runner.js +13 -69
  422. package/.agents/scripts/lib/process-group.js +143 -0
  423. package/.agents/scripts/lib/project-root.js +2 -8
  424. package/.agents/scripts/lib/provider-factory.js +2 -25
  425. package/.agents/scripts/lib/qa/console-allowlist.js +10 -59
  426. package/.agents/scripts/lib/qa/qa-session.js +15 -69
  427. package/.agents/scripts/lib/qa/redact-evidence.js +18 -129
  428. package/.agents/scripts/lib/qa/resolve-qa-contract.js +26 -135
  429. package/.agents/scripts/lib/qa/resolve-selection.js +16 -84
  430. package/.agents/scripts/lib/reserved-test-ids.js +9 -47
  431. package/.agents/scripts/lib/runtime-deps/dep-resolution.js +13 -53
  432. package/.agents/scripts/lib/runtime-deps/ensure-installed.js +10 -44
  433. package/.agents/scripts/lib/runtime-deps/manifest.js +10 -30
  434. package/.agents/scripts/lib/runtime-deps/parser-major.js +15 -51
  435. package/.agents/scripts/lib/runtime-deps/preflight.js +4 -22
  436. package/.agents/scripts/lib/runtime-deps/scan-imports.js +11 -55
  437. package/.agents/scripts/lib/signals/detectors/common.js +12 -38
  438. package/.agents/scripts/lib/signals/index.js +2 -19
  439. package/.agents/scripts/lib/signals/schema.js +14 -109
  440. package/.agents/scripts/lib/signals/write.js +2 -11
  441. package/.agents/scripts/lib/single-story/confirm-merge.js +31 -72
  442. package/.agents/scripts/lib/single-story/story-merged-notify.js +8 -49
  443. package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +4 -26
  444. package/.agents/scripts/lib/single-story-sweep/protection.js +13 -100
  445. package/.agents/scripts/lib/single-story-sweep/sweep-lock.js +60 -258
  446. package/.agents/scripts/lib/single-story-sweep.js +14 -97
  447. package/.agents/scripts/lib/skills/parse-skill.js +13 -59
  448. package/.agents/scripts/lib/skills/skills-index.js +8 -29
  449. package/.agents/scripts/lib/skills/walk-skill-files.js +17 -78
  450. package/.agents/scripts/lib/source-extensions.js +11 -42
  451. package/.agents/scripts/lib/source-text/strip-js-comments.js +8 -41
  452. package/.agents/scripts/lib/stdio-flush.js +9 -36
  453. package/.agents/scripts/lib/story-adjacency.js +8 -40
  454. package/.agents/scripts/lib/story-body/body-format-lints.js +51 -66
  455. package/.agents/scripts/lib/story-body/footer-block.js +11 -44
  456. package/.agents/scripts/lib/story-body/story-body.js +123 -344
  457. package/.agents/scripts/lib/temp-retention.js +42 -143
  458. package/.agents/scripts/lib/templates/decomposer-prompts.js +18 -80
  459. package/.agents/scripts/lib/test-env.js +12 -65
  460. package/.agents/scripts/lib/test-run-credit.js +10 -65
  461. package/.agents/scripts/lib/test-runner-contract.js +19 -74
  462. package/.agents/scripts/lib/test-temp.js +38 -184
  463. package/.agents/scripts/lib/test-tiers.js +12 -96
  464. package/.agents/scripts/lib/ticket-body-sections.js +21 -96
  465. package/.agents/scripts/lib/transpile.js +15 -74
  466. package/.agents/scripts/lib/util/concurrent-map.js +6 -25
  467. package/.agents/scripts/lib/util/parse-id-list.js +8 -34
  468. package/.agents/scripts/lib/util/poll-loop.js +8 -28
  469. package/.agents/scripts/lib/util/with-timeout.js +2 -11
  470. package/.agents/scripts/lib/validation-evidence.js +21 -96
  471. package/.agents/scripts/lib/wave-runner/footprint.js +17 -70
  472. package/.agents/scripts/lib/wave-runner/live-probe.js +67 -209
  473. package/.agents/scripts/lib/wave-runner/ready-set.js +72 -301
  474. package/.agents/scripts/lib/workers/crap-worker.js +11 -64
  475. package/.agents/scripts/lib/workers/maintainability-report-worker.js +8 -45
  476. package/.agents/scripts/lib/workers/maintainability-worker.js +5 -21
  477. package/.agents/scripts/lib/workers/serve-worker-messages.js +2 -18
  478. package/.agents/scripts/lib/workflow-closure.js +22 -105
  479. package/.agents/scripts/lib/workspace-provisioner.js +16 -54
  480. package/.agents/scripts/lib/worktree/git-hooks.js +15 -60
  481. package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +20 -60
  482. package/.agents/scripts/lib/worktree/lifecycle/merge-reachability.js +10 -62
  483. package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +22 -86
  484. package/.agents/scripts/lib/worktree/lifecycle/reap.js +24 -126
  485. package/.agents/scripts/lib/worktree/lifecycle-manager.js +2 -20
  486. package/.agents/scripts/lib/worktree/node-modules-strategy.js +46 -180
  487. package/.agents/scripts/lib/worktree-manager.js +15 -40
  488. package/.agents/scripts/lint-issue-body.js +12 -68
  489. package/.agents/scripts/mandrel-update-preflight.js +10 -70
  490. package/.agents/scripts/merge-baseline.js +30 -105
  491. package/.agents/scripts/nav-registry-diff.js +22 -108
  492. package/.agents/scripts/notify.js +12 -69
  493. package/.agents/scripts/plan-context.js +97 -92
  494. package/.agents/scripts/plan-critics.js +12 -66
  495. package/.agents/scripts/plan-persist.js +71 -137
  496. package/.agents/scripts/plan-run-epilogue.js +20 -43
  497. package/.agents/scripts/pr-watch-with-update.js +79 -263
  498. package/.agents/scripts/providers/github/auth.js +3 -8
  499. package/.agents/scripts/providers/github/blocked-by-add.js +14 -61
  500. package/.agents/scripts/providers/github/board-add.js +5 -21
  501. package/.agents/scripts/providers/github/branch-protection.js +11 -43
  502. package/.agents/scripts/providers/github/cache.js +2 -14
  503. package/.agents/scripts/providers/github/comments.js +7 -40
  504. package/.agents/scripts/providers/github/compose.js +3 -19
  505. package/.agents/scripts/providers/github/errors.js +22 -125
  506. package/.agents/scripts/providers/github/issues.js +31 -123
  507. package/.agents/scripts/providers/github/labels.js +24 -124
  508. package/.agents/scripts/providers/github/mappers.js +5 -27
  509. package/.agents/scripts/providers/github/merge-methods.js +3 -22
  510. package/.agents/scripts/providers/github/project-board.js +2 -17
  511. package/.agents/scripts/providers/github/projects-v2-graphql.js +3 -6
  512. package/.agents/scripts/providers/github/request-helpers.js +5 -32
  513. package/.agents/scripts/providers/github/search-budget.js +9 -39
  514. package/.agents/scripts/providers/github/search-query.js +5 -26
  515. package/.agents/scripts/providers/github/sub-issue-add.js +15 -65
  516. package/.agents/scripts/providers/github/sub-issues.js +7 -36
  517. package/.agents/scripts/providers/github/tickets.js +32 -134
  518. package/.agents/scripts/providers/github.js +18 -59
  519. package/.agents/scripts/prune-plan-run-labels.js +12 -46
  520. package/.agents/scripts/quality-preview.js +35 -220
  521. package/.agents/scripts/resolve-doc-tiers.js +3 -26
  522. package/.agents/scripts/resolve-stories.js +16 -67
  523. package/.agents/scripts/resync-status-column.js +6 -25
  524. package/.agents/scripts/run-tests.js +29 -104
  525. package/.agents/scripts/single-story-close.js +23 -135
  526. package/.agents/scripts/single-story-confirm-merge.js +32 -139
  527. package/.agents/scripts/single-story-init.js +47 -259
  528. package/.agents/scripts/stories-wave-tick.js +179 -415
  529. package/.agents/scripts/sync-agentrc.js +3 -21
  530. package/.agents/scripts/sync-claude-agents.js +9 -55
  531. package/.agents/scripts/sync-claude-commands.js +20 -110
  532. package/.agents/scripts/test-wrapper.js +6 -43
  533. package/.agents/scripts/update-coverage-baseline.js +5 -22
  534. package/.agents/scripts/update-crap-baseline.js +7 -30
  535. package/.agents/scripts/update-duplication-baseline.js +16 -92
  536. package/.agents/scripts/update-maintainability-baseline.js +8 -62
  537. package/.agents/scripts/update-ticket-state.js +1 -7
  538. package/.agents/scripts/validate-skills.js +6 -26
  539. package/.agents/skills/core/gates-and-baselines/reference.md +0 -1
  540. package/.agents/skills/skills.index.json +2 -2
  541. package/.agents/skills/stack/qa/playwright/SKILL.md +26 -0
  542. package/.agents/templates/agent-protocol.md +2 -2
  543. package/.agents/templates/docs/audit-sweep-runbook.md +3 -4
  544. package/.agents/workflows/audit-accessibility.md +4 -7
  545. package/.agents/workflows/audit-adrs.md +3 -6
  546. package/.agents/workflows/audit-architecture.md +3 -11
  547. package/.agents/workflows/audit-baselines.md +6 -9
  548. package/.agents/workflows/audit-clean-code.md +8 -12
  549. package/.agents/workflows/audit-data-model.md +3 -7
  550. package/.agents/workflows/audit-dependencies.md +4 -7
  551. package/.agents/workflows/audit-devops.md +4 -8
  552. package/.agents/workflows/audit-documentation.md +1 -4
  553. package/.agents/workflows/audit-mobile.md +4 -7
  554. package/.agents/workflows/audit-navigability.md +3 -6
  555. package/.agents/workflows/audit-performance.md +2 -4
  556. package/.agents/workflows/audit-privacy.md +4 -7
  557. package/.agents/workflows/audit-quality.md +4 -7
  558. package/.agents/workflows/audit-security.md +4 -7
  559. package/.agents/workflows/audit-seo.md +4 -7
  560. package/.agents/workflows/audit-sre.md +4 -7
  561. package/.agents/workflows/audit-to-stories.md +17 -30
  562. package/.agents/workflows/audit-ux-ui.md +4 -7
  563. package/.agents/workflows/helpers/acceptance-self-eval.md +84 -157
  564. package/.agents/workflows/helpers/audit-lens-core.md +1 -1
  565. package/.agents/workflows/helpers/code-quality-guardrails.md +12 -15
  566. package/.agents/workflows/helpers/code-review.md +4 -2
  567. package/.agents/workflows/helpers/deliver-digest.md +37 -28
  568. package/.agents/workflows/helpers/deliver-light.md +92 -101
  569. package/.agents/workflows/helpers/deliver-reference.md +162 -220
  570. package/.agents/workflows/helpers/deliver-story-reference.md +197 -607
  571. package/.agents/workflows/helpers/deliver-story.md +17 -18
  572. package/.agents/workflows/helpers/plan-reference.md +125 -167
  573. package/.agents/workflows/helpers/qa-core.md +12 -0
  574. package/.agents/workflows/mandrel-deliver.md +47 -31
  575. package/.agents/workflows/mandrel-plan.md +22 -21
  576. package/.agents/workflows/mandrel-update.md +36 -21
  577. package/.agents/workflows/memory-consolidate.md +1 -1
  578. package/.agents/workflows/qa-assist.md +27 -71
  579. package/.agents/workflows/qa-explore.md +19 -59
  580. package/.agents/workflows/qa-run.md +11 -33
  581. package/README.md +1 -1
  582. package/bin/mandrel.js +5 -46
  583. package/bin/postinstall.js +18 -107
  584. package/docs/CHANGELOG.md +60 -0
  585. package/lib/cli/doctor.js +11 -71
  586. package/lib/cli/init.js +26 -165
  587. package/lib/cli/migrate.js +5 -64
  588. package/lib/cli/registry.js +84 -467
  589. package/lib/cli/sync-agents.js +4 -64
  590. package/lib/cli/sync-commands.js +11 -64
  591. package/lib/cli/sync.js +34 -213
  592. package/lib/cli/uninstall.js +40 -219
  593. package/lib/cli/update.js +326 -523
  594. package/lib/cli/version-check.js +8 -72
  595. package/lib/cli/version-helpers.js +14 -87
  596. package/lib/migrations/helpers/retire-agentrc-key.js +11 -52
  597. package/lib/migrations/index.js +17 -92
  598. package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +2 -15
  599. package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +1 -13
  600. package/lib/migrations/steps/2.11.0-retire-max-seed-words.js +2 -15
  601. package/lib/migrations/steps/2.2.0-retire-epic-ac-tags.js +9 -38
  602. package/lib/migrations/steps/2.20.0-retire-codebase-snapshot.js +1 -13
  603. package/lib/migrations/steps/2.32.0-retire-lint-baseline-command.js +2 -27
  604. package/lib/migrations/steps/2.57.0-retire-delivery-limit-knobs.js +2 -23
  605. package/lib/migrations/steps/2.57.0-retire-planning-limit-knobs.js +2 -27
  606. package/lib/migrations/steps/2.60.0-retire-audit-results-autofile.js +21 -0
  607. package/lib/migrations/steps/strip-removed-agentrc-keys.js +333 -0
  608. package/package.json +17 -14
  609. package/.agents/docs/SDLC.md +0 -590
  610. package/.agents/docs/quality-gates.md +0 -1179
  611. package/.agents/rules/known-tooling-behavior.md +0 -150
  612. package/.agents/rules/orchestration-error-handling.md +0 -61
  613. package/.agents/rules/test-seams.md +0 -59
  614. package/.agents/schemas/baselines/lighthouse.schema.json +0 -59
  615. package/.agents/schemas/baselines/lint.schema.json +0 -47
  616. package/.agents/schemas/model-attribution.schema.json +0 -53
  617. package/.agents/scripts/check-action-pinning.js +0 -260
  618. package/.agents/scripts/check-audit-attribution.js +0 -302
  619. package/.agents/scripts/check-baseline-drift.js +0 -211
  620. package/.agents/scripts/check-baseline-scope.js +0 -362
  621. package/.agents/scripts/check-generated-validator.js +0 -202
  622. package/.agents/scripts/check-knip-entries.js +0 -159
  623. package/.agents/scripts/check-lifecycle-lint.js +0 -294
  624. package/.agents/scripts/check-pinned-override-notes.js +0 -102
  625. package/.agents/scripts/check-schema-references.js +0 -366
  626. package/.agents/scripts/check-test-portability.js +0 -512
  627. package/.agents/scripts/check-workflow-citations.js +0 -332
  628. package/.agents/scripts/check-workflow-cli-lint.js +0 -299
  629. package/.agents/scripts/check-workflow-timeouts.js +0 -291
  630. package/.agents/scripts/install-matrix-assert.js +0 -326
  631. package/.agents/scripts/lib/audit-advisories.js +0 -195
  632. package/.agents/scripts/lib/audit-attribution.js +0 -134
  633. package/.agents/scripts/lib/baselines/drift-detector.js +0 -351
  634. package/.agents/scripts/lib/baselines/kinds/lighthouse.js +0 -87
  635. package/.agents/scripts/lib/baselines/kinds/lint.js +0 -184
  636. package/.agents/scripts/lib/baselines/orphan-pruner.js +0 -233
  637. package/.agents/scripts/lib/baselines/scope-assert.js +0 -223
  638. package/.agents/scripts/lib/baselines/scope-inventory.js +0 -314
  639. package/.agents/scripts/lib/c8-cli-path.js +0 -21
  640. package/.agents/scripts/lib/config/gates/lighthouse.schema.js +0 -51
  641. package/.agents/scripts/lib/config/gates/lint.schema.js +0 -18
  642. package/.agents/scripts/lib/dynamic-workflow/architecture-report-contract.js +0 -70
  643. package/.agents/scripts/lib/dynamic-workflow/audit-orchestrator.js +0 -284
  644. package/.agents/scripts/lib/dynamic-workflow/clean-code-report-contract.js +0 -80
  645. package/.agents/scripts/lib/dynamic-workflow/degraded-coverage.js +0 -81
  646. package/.agents/scripts/lib/dynamic-workflow/documentation-report-contract.js +0 -87
  647. package/.agents/scripts/lib/dynamic-workflow/performance-report-contract.js +0 -74
  648. package/.agents/scripts/lib/dynamic-workflow/quality-report-contract.js +0 -90
  649. package/.agents/scripts/lib/dynamic-workflow/report-contract-core.js +0 -43
  650. package/.agents/scripts/lib/dynamic-workflow/security-report-contract.js +0 -83
  651. package/.agents/scripts/lib/fs-walk.js +0 -52
  652. package/.agents/scripts/lib/knip-config-resolver.js +0 -181
  653. package/.agents/scripts/lib/knip-entry-sync.js +0 -452
  654. package/.agents/scripts/lib/orchestration/model-attribution.js +0 -418
  655. package/.agents/scripts/lib/orchestration/story-plan-state.js +0 -33
  656. package/.agents/scripts/lib/orchestration/structured-comment-parser.js +0 -67
  657. package/.agents/scripts/lib/pinned-override-notes.js +0 -88
  658. package/.agents/scripts/lib/pinned-override-resolve.js +0 -212
  659. package/.agents/scripts/lib/test-isolate/cli-options.js +0 -93
  660. package/.agents/scripts/lib/test-isolate/env-snapshot-loader.js +0 -52
  661. package/.agents/scripts/lib/test-isolate/list-files.js +0 -90
  662. package/.agents/scripts/lib/test-isolate/parse-tap.js +0 -75
  663. package/.agents/scripts/lib/test-isolate/progress-log.js +0 -45
  664. package/.agents/scripts/lib/test-isolate/render-report.js +0 -97
  665. package/.agents/scripts/lib/test-isolate/run-isolate.js +0 -87
  666. package/.agents/scripts/lib/test-isolate/runner.js +0 -483
  667. package/.agents/scripts/lib/test-profile/parse-tap.js +0 -136
  668. package/.agents/scripts/lib/test-profile/render-report.js +0 -45
  669. package/.agents/scripts/lint-label-vocabulary.js +0 -214
  670. package/.agents/scripts/post-structured-comment.js +0 -127
  671. package/.agents/scripts/provision-git-hooks.js +0 -85
  672. package/.agents/scripts/prune-baseline-orphans.js +0 -181
  673. package/.agents/scripts/run-coverage.js +0 -197
  674. package/.agents/scripts/run-lint.js +0 -133
  675. package/.agents/scripts/run-test-profile.js +0 -129
  676. package/.agents/scripts/run-verify.js +0 -118
  677. package/.agents/scripts/test-isolate.js +0 -55
  678. package/.agents/scripts/update-dead-exports-baseline.js +0 -321
@@ -2,129 +2,38 @@
2
2
 
3
3
  /**
4
4
  * stories-wave-tick.js — continuous ready-set planner for the standalone
5
- * `/mandrel-deliver` story-list path.
5
+ * `/mandrel-deliver` story-list path: a thin adapter over
6
+ * `lib/wave-runner/ready-set.js#planReadySet` (no wave barrier; a Story is
7
+ * dispatchable the instant its own dependencies are done).
6
8
  *
7
- * Thin **adapter** over the path-agnostic ready-set scheduling core
8
- * (`lib/wave-runner/ready-set.js#planReadySet`). It emits the set of
9
- * Stories safe to dispatch **on this beat** — a Story becomes dispatchable
10
- * the instant its own dependencies are done, under the same global
11
- * concurrency cap and the same file-overlap co-dispatch guard
12
- * `lib/wave-runner/ready-set.js` applies everywhere. There is no wave barrier: this no longer batches
13
- * Stories into fully-draining waves; it selects continuously.
9
+ * Probe mode (`--stories --probe-live`) derives graph, done set and in-flight
10
+ * count from live state; flag mode (`--dag` + `--done`/`--in-flight`) takes
11
+ * them from the caller. They are mutually exclusive: a supplied `--done` under
12
+ * probe mode would reintroduce hand-maintained state. `--dispatched` is
13
+ * additive and live-state-filtered, never authoritative.
14
14
  *
15
- * The previous static wave-batch plan (group N must fully drain before
16
- * group N+1 opens, via `Graph.js#assignLayers`) is gone. The scheduling
17
- * kernel — adjacency derivation, the done-predicate classifier, the
18
- * eligibility rule, and the overlap guard — lives once in `planReadySet`;
19
- * this file only gathers input, resolves the cap, and renders the envelope.
15
+ * The cap comes from `delivery.deliverRunner.concurrencyCap`; `--concurrency`
16
+ * overrides it, except that worktree isolation off clamps it to 1 (a shared
17
+ * checkout makes concurrent workers contend for HEAD). `capPrecedence` names
18
+ * the winning source so no override is silent.
20
19
  *
21
- * **Two modes, one kernel.**
22
- *
23
- * - **Probe mode** (`--stories <csv> --probe-live [--dispatched <csv>]`) is
24
- * the canonical `/mandrel-deliver` beat: the graph, the done set, and the in-flight
25
- * count are resolved from **live state** via `lib/wave-runner/live-probe.js`.
26
- * The caller supplies ids, so there is no accounting to hand-maintain
27
- * across beats — the seed-the-first-beat's-`--done` footgun the workflow
28
- * used to warn about is structurally impossible rather than merely
29
- * documented. `--dispatched` is the one fact live state cannot yet report
30
- * ("I spawned this id; its label has not appeared"); it is additive and
31
- * live-state-filtered, never authoritative (Story #4601).
32
- * - **Flag mode** (`--dag`/`--dag-file` + `--done`/`--in-flight`) keeps the
33
- * caller-supplied contract byte-compatible for tests and hand-driven
34
- * runs. The two are mutually exclusive: honouring a supplied `--done`
35
- * under `--probe-live` would silently reintroduce exactly the
36
- * hand-maintained state probe mode retires.
37
- *
38
- * Usage:
39
- * node .agents/scripts/stories-wave-tick.js --stories 101,102 --probe-live
40
- * node .agents/scripts/stories-wave-tick.js --dag '<json>'
41
- * node .agents/scripts/stories-wave-tick.js --dag-file <path>
42
- * node .agents/scripts/stories-wave-tick.js --dag '<json>' --concurrency 5
43
- * node .agents/scripts/stories-wave-tick.js --dag '<json>' --done 101,103 --in-flight 1
44
- *
45
- * DAG input format (JSON):
46
- * Array of { id: number, dependsOn: number[] } objects where id is a Story
47
- * ticket number and dependsOn lists Story IDs that must complete first.
48
- *
49
- * Output: one JSON object on stdout with shape:
50
- * {
51
- * kind: 'stories-ready-set',
52
- * ready: number[], // Story IDs safe to dispatch on this beat
53
- * totalStories: number,
54
- * concurrencyCap: number,
55
- * inFlight: number,
56
- * cycleError: string | null,
57
- * wedged: { reason, stories: [{ id, unmetBlockers }] } | null,
58
- * inFlightReservation: { available, withheld: [{ id, blockedBy, reason, source, paths }], note },
59
- * footprintGuard: { mode, withheld: [{ id, blockedBy, scope, source, paths }], advisory, note }
60
- * }
61
- *
62
- * `inFlightReservation` reports the cross-beat half of the co-dispatch guard
63
- * (Story #4950 made it reserve; Story #5313 narrowed the footprint back to
64
- * the declared `changes[]`). Under
65
- * `--probe-live` the in-flight Stories' own records are handed to the kernel,
66
- * so a candidate sharing a CONCRETE path with a Story dispatched on an EARLIER
67
- * beat is withheld and named here with its blocker and a `reason`
68
- * (`in-flight-earlier-beat` or `foreign-lease`). A glob / UNKNOWN footprint
69
- * reserves nothing across beats — it would withhold the whole run for one
70
- * blocker's entire implementation window — while still serializing its own
71
- * beat (Story #4960). Flag mode carries a count and no records, so it reports
72
- * `available: false` rather than an empty — and therefore indistinguishable —
73
- * result.
74
- *
75
- * `footprintGuard` reports the **beat-local** half, which until Story #5044 was
76
- * reported nowhere: a same-beat overlap skip was a bare `continue` inside
77
- * `planReadySet`, so the Story vanished from `ready[]` with no field anywhere
78
- * naming the collision. Every entry in either report now also carries the
79
- * colliding `paths` and a `source` tag — `declared-overlap`, the one class
80
- * left since Story #5313: both Stories' `changes[]` named the path (intended
81
- * serialization: two Stories really do rewrite the same generated baseline)
82
- * or one declared a glob. `mode` names the `footprintGuard` config value;
83
- * under `advisory` the collisions are detected and listed in `advisory[]` but
84
- * dispatch follows the declared `depends_on` edges alone.
85
- *
86
- * Probe mode adds fields the caller can no longer compute for itself:
87
- * `done: number[]` (the resolved done set, in-set ∪ satisfied foreign
88
- * blockers), `epilogueDue: boolean` (true exactly when every listed Story
89
- * is done — the run-end signal for `plan-run-epilogue.js`), and `blocked:
90
- * number[]` + `blockedReason: string|null` (Story #4601 — the `agent::blocked`
91
- * HITL pause, which ends the loop rather than being polled).
92
- *
93
- * The standalone loop calls this once per beat and dispatches the returned
94
- * `ready` set (already capped at `concurrencyCap − inFlight` by the core).
95
- * Under `--probe-live` each beat re-reads reality, so the run is complete
96
- * when `epilogueDue` is true; under flag mode the caller re-supplies `--done`
97
- * and `--in-flight` itself, and the run is complete when every Story is in
98
- * `--done` and `ready` is empty.
99
- *
100
- * The per-beat concurrency cap is resolved from the same config seam
101
- * `/mandrel-deliver` uses — `resolveConfig` + `getRunners` reading
102
- * `delivery.deliverRunner.concurrencyCap` (default 3) — so a
103
- * `.agentrc.local.json` override is honored. A `--concurrency <n>` CLI flag
104
- * overrides the config-resolved value for that run only, and the envelope's
105
- * `capPrecedence` names which source won so the override is never silent
106
- * (Story #4875). This shares one
107
- * deterministic config source (`delivery.deliverRunner.concurrencyCap`) and
108
- * one scheduling kernel with every `/mandrel-deliver` multi-Story invocation.
109
- *
110
- * Exit codes: 0 ok · 1 input error · 2 dependency cycle (`cycleError`) ·
111
- * 3 wedged (`wedged`) — ready is empty, nothing is in flight, and undone
112
- * Stories are waiting on blockers that are not done · 4 blocked (`blocked`) —
113
- * a Story carries `agent::blocked`. A cycle is a self-referential DAG the
114
- * operator must fix; a wedge is a well-formed DAG whose gates cannot be
115
- * satisfied from the supplied `--done` set (usually a blocker outside the
116
- * delivered set that has not landed); a block is the protocol's HITL pause,
117
- * where a human owes a decision no beat can supply. All three are distinct
118
- * from the ordinary `ready: []` that means "waiting on in-flight work" — and
119
- * that distinction is the point: each of them previously presented AS that
120
- * ordinary empty set, so the loop polled a state that could never improve.
20
+ * Exit codes (see HELP): 0 ok, 1 input error, 2 cycle, 3 wedged, 4 blocked.
21
+ * Each non-zero case is distinct from the ordinary `ready: []` that means
22
+ * "waiting on in-flight work", so the loop never polls a state that cannot
23
+ * improve.
121
24
  */
122
25
 
123
26
  import { readFileSync } from 'node:fs';
124
27
  import { parseArgs } from 'node:util';
125
28
 
126
29
  import { runAsCli } from './lib/cli-utils.js';
127
- import { getPaths, getRunners, resolveConfig } from './lib/config-resolver.js';
30
+ import {
31
+ getPaths,
32
+ getRunners,
33
+ getWorktreeIsolation,
34
+ resolveConfig,
35
+ resolveWorktreeEnabled,
36
+ } from './lib/config-resolver.js';
128
37
  import { detectCycle } from './lib/Graph.js';
129
38
  import { Logger } from './lib/Logger.js';
130
39
  import { AGENT_LABELS } from './lib/label-constants.js';
@@ -143,20 +52,12 @@ import {
143
52
  WITHHOLD_SCOPES,
144
53
  } from './lib/wave-runner/ready-set.js';
145
54
 
146
- /**
147
- * Exit code for a wedged run — deliberately distinct from the cycle exit (2)
148
- * so a caller can tell "your DAG is self-referential" from "your DAG is fine
149
- * but its gates can never be satisfied from this `--done` set".
150
- */
55
+ /** Wedged run: a well-formed DAG whose gates cannot be satisfied from `--done`. */
151
56
  export const WEDGED_EXIT_CODE = 3;
152
57
 
153
58
  /**
154
- * Exit code for a run holding an `agent::blocked` Story — distinct from the
155
- * cycle (2) and wedge (3) exits because the remediation is categorically
156
- * different: a cycle is a malformed DAG and a wedge is an unlanded blocker,
157
- * whereas this is the protocol's one runtime HITL pause. A human must decide
158
- * something before any beat can help. Probe-mode only: flag-mode nodes carry
159
- * no labels, so nothing there can classify blocked.
59
+ * A Story carries `agent::blocked` — the HITL pause no beat can clear.
60
+ * Probe mode only: flag-mode nodes carry no labels.
160
61
  */
161
62
  export const BLOCKED_EXIT_CODE = 4;
162
63
 
@@ -206,6 +107,13 @@ Options:
206
107
  WINS over the configured value, and the envelope's
207
108
  capPrecedence records that it did — including when the
208
109
  request exceeds the configured cap.
110
+ ONE EXCEPTION: when worktree isolation resolves off
111
+ (CLAUDE_CODE_REMOTE=true, AP_WORKTREE_ENABLED=false, or
112
+ delivery.worktreeIsolation.enabled: false), the cap is
113
+ clamped to 1 and the clamp outranks this flag — every
114
+ Story would otherwise run in the same checkout and two
115
+ workers would contend for HEAD. capPrecedence reports
116
+ source "worktree-clamp" with the requested value.
209
117
  --done <csv> Comma-separated Story IDs already completed this run.
210
118
  Their dependents become eligible; they are never
211
119
  re-dispatched. Defaults to empty.
@@ -287,10 +195,6 @@ Exit codes:
287
195
  `;
288
196
 
289
197
  /**
290
- * Build the exit-1 input-error result. Shared by both modes so a malformed
291
- * `--concurrency` reports identically whether it arrived alongside `--dag` or
292
- * `--probe-live`.
293
- *
294
198
  * @param {string} message
295
199
  * @param {number|null} [concurrencyCap]
296
200
  * @param {number} [inFlightValue]
@@ -315,48 +219,18 @@ function inputErrorResult(message, concurrencyCap = null, inFlightValue = 0) {
315
219
  };
316
220
  }
317
221
 
318
- /**
319
- * Why a reservation withheld a Story. Machine-readable companion to the
320
- * operator-facing `note`, so a consumer never has to parse prose to tell an
321
- * earlier-beat blocker from a foreign-lease one (Story #4960).
322
- */
222
+ /** Machine-readable reason a reservation withheld a Story. */
323
223
  const RESERVATION_REASONS = Object.freeze({
324
224
  EARLIER_BEAT: 'in-flight-earlier-beat',
325
225
  FOREIGN_LEASE: 'foreign-lease',
326
226
  });
327
227
 
328
228
  /**
329
- * Describe this beat's in-flight footprint reservation for the envelope
330
- * (Story #4950).
331
- *
332
- * The reservation needs the in-flight Stories' **records** — their footprints
333
- * — not just how many there are, so its availability is a property of the
334
- * mode rather than of the run:
335
- *
336
- * - **Probe mode** hands over the records `live-probe.js` already fetched,
337
- * so `inFlightRecords` is an array (possibly empty) and reservation is
338
- * `available: true`.
339
- * - **Flag mode** (`--dag` + `--in-flight <n>`) supplies a graph and a
340
- * count; no node carries a label, so nothing there can even classify as
341
- * in-flight. There is no footprint to reserve against, and selection is
342
- * unchanged from before #4950. Saying so explicitly is the point: a
343
- * silently-absent guard reads exactly like a guard that found nothing.
344
- *
345
- * A reservation is held either by a Story **this run** dispatched on an
346
- * earlier beat or by one **another operator's lease** holds — `live-probe.js`
347
- * folds both into the in-flight set, and they reserve identically but read
348
- * very differently to an operator. Reporting a foreign-held peer as "still in
349
- * flight from an earlier beat" is simply false: this run never dispatched it
350
- * and no later beat of this run will clear it. `foreignHeldIds` splits the two
351
- * so each carries its own reason (Story #4960).
352
- *
353
- * Each entry also carries the **colliding paths** and an
354
- * `OVERLAP_SOURCES` tag (Story #5044). A withhold that names no path is one an
355
- * operator cannot act on, and `declared-overlap` vs `scraped-overlap` is the
356
- * difference between "these two Stories both declared this generated baseline,
357
- * serializing them is the point" and "one Story's body happened to mention a
358
- * path the other declared" — the same unfilled slot for two very different
359
- * reasons.
229
+ * Report the cross-beat footprint reservation. It needs the in-flight
230
+ * Stories' records, which only probe mode has; flag mode reports
231
+ * `available: false` explicitly, since an absent guard reads like one that
232
+ * found nothing. Foreign-lease holders get their own reason because no beat
233
+ * of this run clears them.
360
234
  *
361
235
  * @param {object[]|null|undefined} inFlightRecords
362
236
  * @param {Array<{id: number, blockedBy: number, source?: string, paths?: string[]}>} withheld
@@ -401,21 +275,9 @@ export function buildReservationReport(
401
275
  }
402
276
 
403
277
  /**
404
- * Report the **beat-local** half of the footprint guard, plus the guard mode
405
- * itself (Story #5044).
406
- *
407
- * Until now a same-beat overlap skip was an anonymous `continue` inside
408
- * `planReadySet`: the Story simply did not appear in `ready[]` and no field
409
- * anywhere said why. That is the same unexplained-unfilled-slot failure the
410
- * cross-beat `inFlightReservation` report was built to remove, left standing on
411
- * the other half of the guard — and it is how a plan whose siblings collided
412
- * only on machine-generated footer text ran fully serial without leaving a
413
- * trace to notice.
414
- *
415
- * `withheld` and `advisory` are disjoint by construction: under `enforce` every
416
- * detection withheld, under `advisory` none did. Reporting them as separate
417
- * lists rather than one flagged list means a consumer counting withheld
418
- * dispatches never has to inspect a boolean to get the count right.
278
+ * Report the beat-local half of the footprint guard and its mode. `withheld`
279
+ * and `advisory` are disjoint: under `enforce` every detection withheld,
280
+ * under `advisory` none did.
419
281
  *
420
282
  * @param {Array<object>} footprintWithholds The kernel's complete ledger.
421
283
  * @param {'enforce'|'advisory'} mode
@@ -443,10 +305,6 @@ export function buildFootprintGuardReport(footprintWithholds, mode) {
443
305
  }
444
306
 
445
307
  /**
446
- * Render the operator-facing note for the beat-local guard, naming the
447
- * colliding path(s) for every entry. `null` when the guard neither withheld nor
448
- * waved anything through.
449
- *
450
308
  * @param {object[]} beat
451
309
  * @param {object[]} advisory
452
310
  * @param {string} mode
@@ -482,9 +340,7 @@ function footprintGuardNote(beat, advisory, mode) {
482
340
  }
483
341
 
484
342
  /**
485
- * Render the operator-facing reservation note, one sentence per reason class
486
- * present. Neither class is a failure or a wedge, but they clear by different
487
- * events, so each names its own.
343
+ * One sentence per reason class present; they clear by different events.
488
344
  *
489
345
  * @param {Array<{id: number, blockedBy: number, reason: string}>} withheld
490
346
  * @returns {string}
@@ -519,14 +375,8 @@ function reservationNote(withheld) {
519
375
  }
520
376
 
521
377
  /**
522
- * Parse and validate the raw DAG input array.
523
- *
524
- * Each entry must carry `{ id, dependsOn }`. An optional `files` string
525
- * array (the canonical footprint shape) is preserved and forwarded to the
526
- * ready-set core so the file-overlap co-dispatch guard the Epic path uses is
527
- * genuinely active on the standalone path too: two ready Stories that
528
- * declare an intersecting footprint are never dispatched onto parallel
529
- * `story-<id>` branches in the same beat.
378
+ * Validate the raw DAG array. An optional `files` footprint is forwarded so
379
+ * the overlap guard is active in flag mode too.
530
380
  *
531
381
  * @param {unknown} raw Parsed JSON value from --dag or --dag-file.
532
382
  * @returns {{ nodes: Array<{id: number, dependsOn: number[], files?: string[]}>, error: string|null }}
@@ -589,14 +439,8 @@ export function parseDag(raw) {
589
439
  }
590
440
 
591
441
  /**
592
- * Parse a comma-separated list of Story IDs — singles or `A-B` dash ranges —
593
- * into a deduped set of positive integers. Empty / absent input yields an
594
- * empty set. Rejects any token that is not a positive integer or a valid
595
- * range, so a typo never silently drops a dependency gate (`--done`) or a
596
- * held dispatch slot (`--dispatched`).
597
- *
598
- * Ranges are accepted here for the same reason `--stories` accepts them: an
599
- * operator delivering `4922-4926` writes the dispatched set back the same way.
442
+ * Parse a CSV of ids or `A-B` ranges into a deduped set. Rejects any bad
443
+ * token so a typo never silently drops a gate or a held slot.
600
444
  *
601
445
  * @param {string|undefined} raw
602
446
  * @param {string} flag Flag name, for the error message.
@@ -608,8 +452,6 @@ export function parseIdCsv(raw, flag) {
608
452
  }
609
453
 
610
454
  /**
611
- * Parse the `--done` CSV of already-completed Story IDs (flag mode).
612
- *
613
455
  * @param {string|undefined} raw
614
456
  * @returns {{ ids: Set<number>|null, error: string|null }}
615
457
  */
@@ -618,10 +460,7 @@ export function parseDoneIds(raw) {
618
460
  }
619
461
 
620
462
  /**
621
- * Parse the raw `--in-flight` value into a non-negative integer. Absent
622
- * input defaults to 0. Rejects negatives and non-integers.
623
- *
624
- * @param {unknown} raw
463
+ * @param {unknown} raw Absent defaults to 0.
625
464
  * @returns {{ value: number|null, error: string|null }}
626
465
  */
627
466
  export function parseInFlight(raw) {
@@ -639,11 +478,12 @@ export function parseInFlight(raw) {
639
478
  }
640
479
 
641
480
  /**
642
- * Validate a raw `--concurrency` value into a positive integer.
643
- *
644
- * Accepts a number or a numeric string (from the CLI). Rejects anything that
645
- * is not a positive integer (zero, negative, fractional, non-numeric).
646
- *
481
+ * Cap when worktree isolation resolves off — a safety floor, so it outranks
482
+ * even an explicit `--concurrency`.
483
+ */
484
+ export const WORKTREE_DISABLED_CONCURRENCY_CAP = 1;
485
+
486
+ /**
647
487
  * @param {unknown} raw
648
488
  * @returns {{ value: number|null, error: string|null }}
649
489
  */
@@ -662,100 +502,110 @@ export function parseConcurrencyOverride(raw) {
662
502
  }
663
503
 
664
504
  /**
665
- * Resolve the per-beat concurrency cap.
666
- *
667
- * Mirrors the `/mandrel-deliver` multi-Story seam (`helpers/deliver-story.md`): resolve the
668
- * project config (which deep-merges `.agentrc.local.json` over `.agentrc.json`)
669
- * then read `delivery.deliverRunner.concurrencyCap` via `getRunners` (default
670
- * 3). An explicit `override` (the `--concurrency <n>` CLI flag) wins over
671
- * config for that run only.
672
- *
673
505
  * @param {object} [opts]
674
- * @param {string} [opts.cwd] Repo root for config resolution.
675
- * @param {object} [opts.config] Pre-resolved config (injected by tests so
676
- * they never depend on a real `.agentrc`).
677
- * @param {number} [opts.override] Validated positive integer from
678
- * `--concurrency`; wins over config.
679
- * @returns {number} The resolved positive-integer concurrency cap.
506
+ * @param {string} [opts.cwd]
507
+ * @param {object} [opts.config] Pre-resolved config (test injection).
508
+ * @param {number} [opts.override] Validated `--concurrency`.
509
+ * @param {NodeJS.ProcessEnv} [opts.env]
510
+ * @returns {number}
680
511
  */
681
512
  export function resolveConcurrencyCap(opts = {}) {
682
513
  return resolveCapPrecedence(opts).cap;
683
514
  }
684
515
 
685
516
  /**
686
- * Resolve the per-beat cap **and the precedence that produced it** (Story
687
- * #4875).
688
- *
689
- * `--concurrency` wins over `delivery.deliverRunner.concurrencyCap`, and that
690
- * is the intended contract — a flag an operator typed for one run should not be
691
- * outranked by a checked-in default. What was wrong is that it won *silently*:
692
- * the envelope reported a single `concurrencyCap` number with no record of
693
- * which source set it, so a run at 8 when the project configured 3 was
694
- * indistinguishable from a project configured at 8. A reader could not tell an
695
- * override from a default, and an override that ran the repo above its own
696
- * configured ceiling left no trace at all.
697
- *
698
- * So the flag still wins, but never quietly: the source is named, the
699
- * configured value is carried alongside the requested one, and a request that
700
- * exceeds the configured cap is called out as such. Reporting rather than
701
- * refusing is deliberate — the configured cap is a project default, not a
702
- * safety limit, and refusing a deliberate operator escalation would trade a
703
- * silent override for a silent stall.
517
+ * Resolve the per-beat cap and the precedence that produced it. The flag wins
518
+ * over config but never silently: a request above the configured cap is
519
+ * reported, not refused (the configured cap is a default, not a safety
520
+ * limit). The worktree clamp outranks both.
704
521
  *
705
522
  * @param {object} [opts]
706
- * @param {string} [opts.cwd] Repo root for config resolution.
523
+ * @param {string} [opts.cwd]
707
524
  * @param {object} [opts.config] Pre-resolved config (test injection).
708
- * @param {number} [opts.override] Validated positive integer from
709
- * `--concurrency`.
525
+ * @param {number} [opts.override] Validated `--concurrency`.
526
+ * @param {NodeJS.ProcessEnv} [opts.env]
710
527
  * @returns {{
711
528
  * cap: number,
712
- * source: 'flag'|'config',
529
+ * source: 'flag'|'config'|'worktree-clamp',
713
530
  * configuredCap: number,
714
531
  * requestedCap: number|null,
715
532
  * exceedsConfigured: boolean,
716
533
  * note: string,
717
534
  * }}
718
535
  */
719
- export function resolveCapPrecedence({ cwd, config, override } = {}) {
536
+ export function resolveCapPrecedence({ cwd, config, override, env } = {}) {
720
537
  const resolved = config ?? resolveConfig({ cwd });
721
538
  const { deliverRunner } = getRunners(resolved);
722
539
  const configuredCap = deliverRunner.concurrencyCap;
723
- if (override == null) {
724
- return {
725
- cap: configuredCap,
726
- source: 'config',
727
- configuredCap,
728
- requestedCap: null,
729
- exceedsConfigured: false,
730
- note: `cap ${configuredCap} from delivery.deliverRunner.concurrencyCap (no --concurrency given)`,
731
- };
732
- }
733
- const exceedsConfigured = override > configuredCap;
540
+ const requested =
541
+ override == null
542
+ ? {
543
+ cap: configuredCap,
544
+ source: 'config',
545
+ configuredCap,
546
+ requestedCap: null,
547
+ exceedsConfigured: false,
548
+ note: `cap ${configuredCap} from delivery.deliverRunner.concurrencyCap (no --concurrency given)`,
549
+ }
550
+ : {
551
+ cap: override,
552
+ source: 'flag',
553
+ configuredCap,
554
+ requestedCap: override,
555
+ exceedsConfigured: override > configuredCap,
556
+ note:
557
+ override > configuredCap
558
+ ? `cap ${override} from --concurrency, which OVERRIDES and EXCEEDS the configured delivery.deliverRunner.concurrencyCap ${configuredCap} — this run is deliberately above the project default`
559
+ : `cap ${override} from --concurrency, which overrides the configured delivery.deliverRunner.concurrencyCap ${configuredCap}`,
560
+ };
561
+
562
+ return resolveWorktreeClamp({ requested, config: resolved, env });
563
+ }
564
+
565
+ /**
566
+ * Apply the worktree-isolation floor. Keyed off `resolveWorktreeEnabled` so
567
+ * every route to isolation-off is covered. The config is normalised through
568
+ * `getWorktreeIsolation` first: a raw read of an omitted block is `false` and
569
+ * would clamp as if isolation had been disabled. The clamp record is emitted
570
+ * even when the requested cap was already 1, so sequentiality is attributable.
571
+ *
572
+ * @param {object} args
573
+ * @param {{cap: number, source: string, configuredCap: number, requestedCap: number|null, exceedsConfigured: boolean, note: string}} args.requested
574
+ * @param {object|null} [args.config]
575
+ * @param {NodeJS.ProcessEnv} [args.env]
576
+ * @returns {typeof args.requested}
577
+ */
578
+ export function resolveWorktreeClamp({ requested, config, env } = {}) {
579
+ const worktreeEnabled = resolveWorktreeEnabled(
580
+ {
581
+ config: { delivery: { worktreeIsolation: getWorktreeIsolation(config) } },
582
+ },
583
+ env ?? process.env,
584
+ );
585
+ if (worktreeEnabled) return requested;
586
+
587
+ const from =
588
+ requested.source === 'flag'
589
+ ? '--concurrency'
590
+ : 'delivery.deliverRunner.concurrencyCap';
734
591
  return {
735
- cap: override,
736
- source: 'flag',
737
- configuredCap,
738
- requestedCap: override,
739
- exceedsConfigured,
740
- note: exceedsConfigured
741
- ? `cap ${override} from --concurrency, which OVERRIDES and EXCEEDS the configured delivery.deliverRunner.concurrencyCap ${configuredCap} — this run is deliberately above the project default`
742
- : `cap ${override} from --concurrency, which overrides the configured delivery.deliverRunner.concurrencyCap ${configuredCap}`,
592
+ cap: WORKTREE_DISABLED_CONCURRENCY_CAP,
593
+ source: 'worktree-clamp',
594
+ configuredCap: requested.configuredCap,
595
+ requestedCap: requested.cap,
596
+ // The escalation never took effect.
597
+ exceedsConfigured: false,
598
+ note: `cap clamped to ${WORKTREE_DISABLED_CONCURRENCY_CAP} because worktree isolation resolved OFF — requested ${requested.cap} from ${from}. Concurrent dispatch shares one checkout without per-Story worktrees, so two workers would contend for HEAD; this floor outranks an explicit --concurrency.`,
743
599
  };
744
600
  }
745
601
 
746
602
  /**
747
- * Resolve the two footprint-guard inputs from the same config seam the cap
748
- * comes from (Story #5044).
749
- *
750
- * `tempRoot` is threaded rather than hardcoded because the evidence scrape must
751
- * exclude the project's *configured* scratch root: a consumer that sets
752
- * `project.paths.tempRoot: '.scratch'` would otherwise have every sibling
753
- * citing a report under it collide, which is the exact defect this Story
754
- * removes for the default `temp/`.
603
+ * `tempRoot` is the configured one, not a hardcoded `temp/`, so the overlap
604
+ * guard excludes the project's actual scratch root.
755
605
  *
756
606
  * @param {object} [opts]
757
- * @param {string} [opts.cwd] Repo root for config resolution.
758
- * @param {object} [opts.config] Pre-resolved config (test injection).
607
+ * @param {string} [opts.cwd]
608
+ * @param {object} [opts.config]
759
609
  * @returns {{ footprintGuard: 'enforce'|'advisory', tempRoot: string }}
760
610
  */
761
611
  export function resolveFootprintGuardSettings({ cwd, config } = {}) {
@@ -767,32 +617,18 @@ export function resolveFootprintGuardSettings({ cwd, config } = {}) {
767
617
  }
768
618
 
769
619
  /**
770
- * Build the per-beat ready-set envelope from a validated DAG.
771
- *
772
- * Maps each operator-DAG node onto a Story record the ready-set core
773
- * understands (`{ id, dependsOn }`), tags any node already in the done set
774
- * as `agent::done` so the core's classifier excludes it from the dispatch
775
- * set **and** counts it as a satisfied dependency, then delegates the
776
- * scheduling decision to `planReadySet`. A cyclic operator DAG is a
777
- * planning error (the core would silently never schedule the cycle), so we
778
- * detect it up front via the shared `detectCycle` kernel and short-circuit
779
- * with a `cycleError` and exit code 2.
620
+ * Build the per-beat envelope. A cyclic DAG is rejected up front (exit 2)
621
+ * because the core would silently never schedule it.
780
622
  *
781
623
  * @param {Array<{id: number, dependsOn: number[]}>} nodes
782
624
  * @param {object} args
783
- * @param {number} args.concurrencyCap Resolved per-beat concurrency cap.
784
- * @param {object|null} [args.capPrecedence] The {@link resolveCapPrecedence}
785
- * record explaining which source set the cap.
786
- * @param {Set<number>} [args.doneIds] Story IDs already completed this run.
787
- * @param {number} [args.inFlight] Stories already occupying a slot.
788
- * @param {object[]|null} [args.inFlightRecords] Records for the Stories
789
- * already in flight, so the kernel reserves their footprints instead of
790
- * merely counting them (Story #4950). `null` (flag mode) means reservation
791
- * is structurally unavailable — see {@link buildReservationReport}.
792
- * @param {number[]} [args.foreignHeldIds] Ids among `inFlightRecords` that a
793
- * **foreign operator's lease** holds rather than this run's own earlier
794
- * beat, so a withholding against one is reported for what it is
795
- * (Story #4960). Flag mode has no lease view and passes none.
625
+ * @param {number} args.concurrencyCap
626
+ * @param {object|null} [args.capPrecedence]
627
+ * @param {Set<number>} [args.doneIds]
628
+ * @param {number} [args.inFlight]
629
+ * @param {object[]|null} [args.inFlightRecords] `null` (flag mode) means
630
+ * reservation is unavailable, not empty.
631
+ * @param {number[]} [args.foreignHeldIds] Ids held by a foreign lease.
796
632
  * @returns {{
797
633
  * envelope: {
798
634
  * kind: 'stories-ready-set',
@@ -825,21 +661,13 @@ export function buildReadySetEnvelope(
825
661
  ready: [],
826
662
  totalStories,
827
663
  concurrencyCap,
828
- // Which source set `concurrencyCap`, and whether it outranks the project's
829
- // configured value (Story #4875). Never omitted on a resolved beat: a
830
- // missing precedence record is what made a silent override possible.
664
+ // The reports below are never omitted: an absent report reads like an
665
+ // empty one.
831
666
  capPrecedence,
832
667
  inFlight,
833
668
  cycleError: null,
834
669
  wedged: null,
835
- // Whether this beat could reserve the in-flight Stories' footprints, and
836
- // which Stories a reservation withheld (Story #4950). Never omitted on a
837
- // resolved beat: an absent report reads exactly like an empty one.
838
670
  inFlightReservation: buildReservationReport(inFlightRecords, []),
839
- // The beat-local half of the same guard, plus the mode it ran in (Story
840
- // #5044). Also never omitted: a same-beat skip used to be reported nowhere
841
- // at all, which is precisely how an evidence-widening artifact could
842
- // serialize a whole run unnoticed.
843
671
  footprintGuard: buildFootprintGuardReport([], footprintGuard),
844
672
  };
845
673
 
@@ -847,10 +675,7 @@ export function buildReadySetEnvelope(
847
675
  return { envelope: base, exitCode: 0 };
848
676
  }
849
677
 
850
- // Cycle detection before scheduling — a cycle is a planning error the
851
- // operator must fix. dropForeign:false preserves the operator-DAG contract
852
- // (a dependency on an id outside the supplied set is honored, not pruned),
853
- // matching the same builder seam planReadySet uses internally.
678
+ // dropForeign:false: a dependency outside the supplied set is honored.
854
679
  const adjacency = buildStoryAdjacency(nodes, { dropForeign: false });
855
680
  const cycle = detectCycle(adjacency);
856
681
  if (cycle) {
@@ -863,26 +688,16 @@ export function buildReadySetEnvelope(
863
688
  };
864
689
  }
865
690
 
866
- // Map DAG nodes → Story records. Tag done nodes as agent::done so the
867
- // core's classifier (a) excludes them from the dispatch set and (b) folds
868
- // them into the satisfied-dependency set, making their dependents eligible.
869
- // Forward any declared file footprint so the core's overlap guard fires.
691
+ // Done nodes are tagged agent::done so the core both excludes them and
692
+ // counts them as satisfied dependencies. Probe-mode live labels are kept so
693
+ // an in-flight Story is never re-dispatched onto a second branch.
870
694
  const records = nodes.map((node) => {
871
695
  const rec = {
872
696
  id: node.id,
873
697
  dependsOn: node.dependsOn,
874
- // A node's own live labels (probe mode) are preserved so the core's
875
- // classifier withholds an in-flight `agent::executing` / `agent::closing`
876
- // Story rather than re-dispatching it onto a second branch. Flag-mode
877
- // nodes carry none — `parseDag` accepts no labels — so this is inert
878
- // there and the legacy contract is unchanged.
879
698
  labels: doneIds.has(node.id) ? [AGENT_LABELS.DONE] : (node.labels ?? []),
880
699
  };
881
700
  if (node.files !== undefined) rec.files = node.files;
882
- // Probe-mode nodes carry the Story body so the overlap guard can widen a
883
- // declared footprint from the paths the Story's own text names (Story
884
- // #4875). Flag-mode nodes carry none — `parseDag` accepts no body — so
885
- // this is inert there and the legacy contract is unchanged.
886
701
  if (typeof node.body === 'string') rec.body = node.body;
887
702
  return rec;
888
703
  });
@@ -892,17 +707,11 @@ export function buildReadySetEnvelope(
892
707
  doneIds,
893
708
  inFlight,
894
709
  globalCap: concurrencyCap,
895
- // Flag mode has no in-flight records at all; `?? []` keeps the kernel's
896
- // contract (an array) while `base.inFlightReservation` reports that the
897
- // reservation itself was unavailable rather than merely empty.
898
710
  inFlightRecords: inFlightRecords ?? [],
899
711
  footprintGuard,
900
712
  tempRoot,
901
713
  });
902
714
  const ready = selected.map((rec) => rec.id);
903
- // The cross-beat report reads the enforced in-flight slice of the kernel's
904
- // ledger rather than the legacy `withheldByInFlight` list, so it carries the
905
- // colliding paths and the overlap source through to the operator.
906
715
  const reservation = buildReservationReport(
907
716
  inFlightRecords,
908
717
  footprintWithholds.filter(
@@ -912,17 +721,6 @@ export function buildReadySetEnvelope(
912
721
  );
913
722
  const guardReport = buildFootprintGuardReport(footprintWithholds, guardMode);
914
723
 
915
- // Wedge detection (Story #4540). `ready: []` is normal while work is in
916
- // flight — the loop is simply waiting. But ready-empty AND nothing in
917
- // flight AND undone Stories remaining means no beat can ever make
918
- // progress: the run is stuck, and the previous behaviour was to return
919
- // exit 0 with an empty ready set forever, indistinguishable from
920
- // "waiting". Name the stuck ids and their unmet blockers.
921
- //
922
- // Distinct from `cycleError`/exit 2: a cycle is a self-referential DAG,
923
- // whereas this is a DAG whose gates are real but unsatisfiable from the
924
- // supplied `done` set (typically a blocker outside the delivered set that
925
- // has not landed).
926
724
  const wedge = detectWedge({ nodes, doneIds, ready, inFlight });
927
725
  if (wedge) {
928
726
  return {
@@ -968,9 +766,7 @@ export function detectWedge({ nodes, doneIds, ready, inFlight }) {
968
766
  }))
969
767
  .filter((s) => s.unmetBlockers.length > 0);
970
768
 
971
- // Undone work with no unmet blockers would have been dispatched; if that
972
- // is the whole set, the cap or in-flight accounting explains the empty
973
- // ready set rather than a wedge.
769
+ // Undone work with no unmet blockers is capacity-limited, not wedged.
974
770
  if (stories.length === 0) return null;
975
771
 
976
772
  const detail = stories
@@ -986,20 +782,17 @@ export function detectWedge({ nodes, doneIds, ready, inFlight }) {
986
782
  }
987
783
 
988
784
  /**
989
- * Core logic: parse DAG input, resolve the concurrency cap, validate, and
990
- * compute the per-beat ready set via the shared scheduling core.
991
- *
992
- * Exported for unit tests; the CLI `main` function is a thin wrapper. Tests
993
- * inject `config` so they never depend on a real `.agentrc`.
785
+ * Flag-mode beat.
994
786
  *
995
787
  * @param {object} args
996
- * @param {string} [args.dagJson] Raw JSON string from --dag.
997
- * @param {string} [args.dagFile] Path to a JSON file from --dag-file.
998
- * @param {string|number} [args.concurrency] Raw --concurrency override.
999
- * @param {string} [args.done] Raw --done CSV of completed Story IDs.
1000
- * @param {string|number} [args.inFlight] Raw --in-flight count.
1001
- * @param {string} [args.cwd] Repo root for config resolution.
1002
- * @param {object} [args.config] Pre-resolved config (test injection).
788
+ * @param {string} [args.dagJson]
789
+ * @param {string} [args.dagFile]
790
+ * @param {string|number} [args.concurrency]
791
+ * @param {string} [args.done]
792
+ * @param {string|number} [args.inFlight]
793
+ * @param {string} [args.cwd]
794
+ * @param {object} [args.config] Pre-resolved config (test injection).
795
+ * @param {NodeJS.ProcessEnv} [args.env]
1003
796
  * @returns {{
1004
797
  * envelope: {kind: string, ready: number[], totalStories: number, concurrencyCap: number, inFlight: number, cycleError: string|null},
1005
798
  * exitCode: number
@@ -1013,9 +806,8 @@ export function runStoriesWaveTick({
1013
806
  inFlight,
1014
807
  cwd,
1015
808
  config,
809
+ env,
1016
810
  } = {}) {
1017
- // Validate the --concurrency override before resolving config so an invalid
1018
- // value fails fast with exit code 1 regardless of DAG validity.
1019
811
  const { value: override, error: concurrencyError } =
1020
812
  parseConcurrencyOverride(concurrency);
1021
813
  if (concurrencyError) {
@@ -1033,7 +825,7 @@ export function runStoriesWaveTick({
1033
825
  return inputErrorResult(doneError, null, inFlightValue);
1034
826
  }
1035
827
 
1036
- const capPrecedence = resolveCapPrecedence({ cwd, config, override });
828
+ const capPrecedence = resolveCapPrecedence({ cwd, config, override, env });
1037
829
  const concurrencyCap = capPrecedence.cap;
1038
830
 
1039
831
  let rawJson;
@@ -1084,32 +876,22 @@ export function runStoriesWaveTick({
1084
876
  }
1085
877
 
1086
878
  /**
1087
- * Probe mode: resolve the graph and the run's progress from **live state**,
1088
- * then run the same scheduling kernel the flag mode does.
1089
- *
1090
- * This is the flag-free beat. The caller supplies only the Story ids it was
1091
- * asked to deliver; `done` and `inFlight` are probed rather than transcribed,
1092
- * which is what makes the `/mandrel-deliver` loop's old seed-the-first-beat footgun
1093
- * structurally impossible instead of merely documented.
1094
- *
1095
- * The envelope is the flag mode's, plus three probe-only fields the caller can
1096
- * no longer compute for itself:
1097
- * - `done` — the resolved done set (in-set ∪ satisfied foreign blockers).
1098
- * - `epilogueDue` — true exactly when every listed Story is done, which is
1099
- * the run-end signal for `plan-run-epilogue.js`.
1100
- * - `blocked` — ids carrying `agent::blocked` (Story #4601). Non-empty means
1101
- * the loop must END, not poll: see `BLOCKED_EXIT_CODE`.
879
+ * Probe-mode beat: graph and progress from live state. Adds `done`,
880
+ * `epilogueDue` (every listed Story done — the run-end signal), `blocked`
881
+ * (non-empty ends the loop) and `stalledDispatch` (`--dispatched` ids still
882
+ * `agent::ready`, which only the caller can tell from a dead spawn).
1102
883
  *
1103
884
  * @param {object} args
1104
- * @param {string} args.stories Raw `--stories` CSV of Story ids.
1105
- * @param {string|number} [args.concurrency] Raw `--concurrency` override.
1106
- * @param {string} [args.dispatched] Raw `--dispatched` CSV of ids the host
1107
- * has spawned but may not yet have observed labelled.
1108
- * @param {string} [args.cwd] Repo root for config resolution.
1109
- * @param {object} [args.config] Pre-resolved config (test injection).
1110
- * @param {Function} [args.probe] Probe seam (test injection).
1111
- * @param {Function} [args.context] Provider-context seam (test injection).
1112
- * @returns {Promise<{ envelope: object, exitCode: number }>}
885
+ * @param {string} args.stories
886
+ * @param {string|number} [args.concurrency]
887
+ * @param {string} [args.dispatched]
888
+ * @param {string} [args.cwd]
889
+ * @param {object} [args.config]
890
+ * @param {NodeJS.ProcessEnv} [args.env]
891
+ * @param {Function} [args.probe] Test seam.
892
+ * @param {Function} [args.context] Test seam.
893
+ * @returns {Promise<{ envelope: object, exitCode: number, records: object[] }>}
894
+ * `records` are the probed nodes, kept off stdout.
1113
895
  */
1114
896
  export async function runProbedStoriesWaveTick({
1115
897
  stories,
@@ -1117,6 +899,7 @@ export async function runProbedStoriesWaveTick({
1117
899
  dispatched,
1118
900
  cwd,
1119
901
  config,
902
+ env,
1120
903
  probe = probeLiveState,
1121
904
  context = createProbeContext,
1122
905
  } = {}) {
@@ -1141,7 +924,7 @@ export async function runProbedStoriesWaveTick({
1141
924
  return inputErrorResult(dispatchedError);
1142
925
  }
1143
926
 
1144
- const capPrecedence = resolveCapPrecedence({ cwd, config, override });
927
+ const capPrecedence = resolveCapPrecedence({ cwd, config, override, env });
1145
928
  const concurrencyCap = capPrecedence.cap;
1146
929
 
1147
930
  let probed;
@@ -1157,9 +940,7 @@ export async function runProbedStoriesWaveTick({
1157
940
  warn: (m) => Logger.warn(m),
1158
941
  });
1159
942
  } catch (err) {
1160
- // A failed probe must never degrade into "nothing is ready" — that is
1161
- // indistinguishable from a healthy waiting beat and would silently stall
1162
- // the run. Fail loud with the input-error contract instead.
943
+ // Never degrade into "nothing is ready": that reads as a healthy wait.
1163
944
  return inputErrorResult(
1164
945
  `Could not probe live state: ${err?.message ?? err}`,
1165
946
  concurrencyCap,
@@ -1171,6 +952,7 @@ export async function runProbedStoriesWaveTick({
1171
952
  doneIds,
1172
953
  inFlight,
1173
954
  blockedIds = [],
955
+ stalledDispatch = [],
1174
956
  foreignHeld = [],
1175
957
  inFlightRecords = [],
1176
958
  } = probed;
@@ -1179,11 +961,7 @@ export async function runProbedStoriesWaveTick({
1179
961
  capPrecedence,
1180
962
  doneIds,
1181
963
  inFlight,
1182
- // Probe mode is the only mode that HAS the in-flight Stories' records, so
1183
- // it is the only mode that can reserve their footprints (Story #4950).
1184
964
  inFlightRecords,
1185
- // ...and the only mode that can tell a foreign lease-holder apart from
1186
- // this run's own earlier-beat dispatch (Story #4960).
1187
965
  foreignHeldIds: foreignHeld.map((h) => h.id),
1188
966
  ...resolveFootprintGuardSettings({ cwd, config }),
1189
967
  });
@@ -1198,16 +976,13 @@ export async function runProbedStoriesWaveTick({
1198
976
  epilogueDue,
1199
977
  blocked: blockedIds,
1200
978
  blockedReason: blockedReasonFor(blockedIds),
1201
- // Stories another operator's lease holds — withheld from dispatch this
1202
- // beat (folded into in-flight) and surfaced so the run can report
1203
- // "#<id> held by @<holder>" instead of dispatching into an init refusal.
979
+ stalledDispatch,
1204
980
  foreignHeld,
1205
981
  foreignHeldReason: foreignHeldReasonFor(foreignHeld),
1206
982
  },
1207
- // A blocked Story outranks the scheduler's own verdict — including a
1208
- // wedge, whose named blockers are moot while a human owes a decision.
1209
- // A cycle (2) does not yield: a self-referential DAG is a planning error
1210
- // that must be fixed before any of this run's state means anything.
983
+ records: nodes,
984
+ // Blocked outranks a wedge (its blockers are moot while a human owes a
985
+ // decision) but not a cycle, which invalidates the run's state.
1211
986
  exitCode:
1212
987
  blockedIds.length > 0 && !envelope.cycleError
1213
988
  ? BLOCKED_EXIT_CODE
@@ -1216,9 +991,6 @@ export async function runProbedStoriesWaveTick({
1216
991
  }
1217
992
 
1218
993
  /**
1219
- * Render the operator-facing reason for a blocked run, or `null` when nothing
1220
- * is blocked.
1221
- *
1222
994
  * @param {number[]} blockedIds
1223
995
  * @returns {string|null}
1224
996
  */
@@ -1235,14 +1007,6 @@ function blockedReasonFor(blockedIds) {
1235
1007
  }
1236
1008
 
1237
1009
  /**
1238
- * Render the operator-facing note for Stories held by another operator's
1239
- * lease, or `null` when none are held.
1240
- *
1241
- * These are not errors and not a wedge: the holder's run is progressing
1242
- * normally, this run simply must not join it on the same branch. The Story
1243
- * stays withheld and re-probes each beat, so it dispatches on its own the
1244
- * moment the holder's lease clears (their run lands or is stolen).
1245
- *
1246
1010
  * @param {Array<{id: number, holder: string}>} foreignHeld
1247
1011
  * @returns {string|null}
1248
1012
  */