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
@@ -33,12 +33,8 @@ export async function handleRemoteVerificationFailure({
33
33
  `[single-story-init] failed to post remote-verification friction: ${err?.message ?? err}`,
34
34
  );
35
35
  }
36
- // Story #4539 — the canonical mutator. This is the path where the
37
- // skipped Projects v2 column sync (Story #2548) visibly drifts: the
38
- // Story is still agent::ready (To Do) when the remote probe fails, so
39
- // a direct label write leaves the board reading To Do for a blocked
40
- // Story. single-story-init.js's own comment explains exactly why this
41
- // must not bypass the mutator.
36
+ // Use the canonical mutator: a direct label write skips the Projects v2
37
+ // column sync and leaves the board reading To Do for a blocked Story.
42
38
  try {
43
39
  await transitionTicketState(provider, storyId, STATE_LABELS.BLOCKED, {});
44
40
  } catch (err) {
@@ -1,30 +1,10 @@
1
1
  /**
2
- * lib/orchestration/story-reachability.js — Story `depends_on` graph walk.
3
- *
4
- * Houses the transitive-predecessor closure over the story-level
5
- * `depends_on` graph. Extracted from `./ticket-validator-conflicts.js`
6
- * under Story #3995 to break the `file-assumptions.js ↔
7
- * ticket-validator-conflicts.js` import cycle: both the conflict gate and
8
- * the wave-aware file-assumption gate need this graph traversal, so
9
- * pulling it down into a dependency-free leaf lets both import it from
10
- * below rather than from each other.
11
- *
12
- * This is a pure graph utility — no I/O, no policy. Its behaviour is
13
- * unchanged from the original `computeStoryReachability`.
2
+ * Dependency-free leaf (breaks a conflicts ↔ file-assumptions import cycle).
14
3
  */
15
4
 
16
5
  /**
17
- * Compute transitive predecessor sets over the story-level `depends_on`
18
- * graph. The returned map is `Map<storySlug, Set<storySlug>>`, where the
19
- * set contains every story reachable by following `depends_on` edges from
20
- * the key (i.e. every story the key transitively depends on).
21
- *
22
- * BFS, no cycles assumed — callers must run `assertAcyclic` first.
23
- *
24
- * Exported so both the conflict gate (`ticket-validator-conflicts.js`)
25
- * and the wave-aware file-assumption gate (`file-assumptions.js`) can
26
- * reuse the same transitive-predecessor walk rather than re-deriving the
27
- * `depends_on` closure.
6
+ * `Map<storySlug, Set<storySlug>>` of every Story each key transitively
7
+ * depends on. Assumes an acyclic graph — run `assertAcyclic` first.
28
8
  */
29
9
  export function computeStoryReachability(stories) {
30
10
  const reach = new Map();
@@ -1,54 +1,8 @@
1
1
  /**
2
- * Story body schema validator (v5.33+).
3
- *
4
- * Enforces the four-section structured body shape on 2-tier Stories emitted
5
- * by the decomposer. The canonical decomposition serializes every Story
6
- * `body` to a **markdown string** via `serialize()` from
7
- * `lib/story-body/story-body.js` (the decompose-author skill mandates this,
8
- * and `createOp` in `epic-spec-reconciler-ops.js` throws on an object body —
9
- * Story #3302). So at plan-time validation the Story body is a string, not an
10
- * object. To make the rules below actually fire on canonical plans, a string
11
- * body is **parsed** back into its structured form via `parseStoryBody`
12
- * before the section checks run (Story #3906 — previously the validator
13
- * `shouldSkipTicket`-skipped every string body, so the vague-verb check and
14
- * non-empty-goal check never ran on any real decomposition). A still-structured object body (e.g. a caller that passes
15
- * the pre-serialize shape directly) is validated as-is.
16
- *
17
- * Only `type: 'story'` tickets are validated; Feature/Epic tickets and
18
- * null/empty bodies pass through. There is no `type::task` ticket layer in
19
- * the 2-tier hierarchy (Epic → Story).
20
- *
21
- * Required after parse/normalize: a non-empty `goal`, and non-empty
22
- * `changes`, `acceptance`, and `verify` arrays — and `changes` items must
23
- * name at least one path-shaped token so vague verbs ("clean up",
24
- * "refactor") can't slip through.
25
- *
26
- * `acceptance` / `verify` are the **top-level machine contract** (Story
27
- * #4541). The decomposer prompt tells authors to write those lists once at
28
- * the ticket's top level and omit the matching body sections; persist syncs
29
- * them into the body at assemble time. Validation runs *before* that sync,
30
- * so this validator resolves each contract field from the parsed body and
31
- * falls back to the ticket's top-level array when the body section is
32
- * absent. Without that fallback the validator rejected the very shape its
33
- * own prompt prescribes.
34
- *
35
- * `body.changes` items must be object-form `{ path: string, assumption: enum }`
36
- * entries (Story #2636 shape). Plain string bullets are rejected at parse
37
- * time and by this validator.
38
- *
39
- * Object-form items must declare an `assumption` ∈ `creates |
40
- * refactors-existing | exists | deletes`. The optional `body.references`
41
- * array uses the same object shape and is the home for paths the Story
42
- * reads but does not modify (test fixtures, sibling modules, etc.).
43
- *
44
- * `body.verify` entries are commands, nothing more: Story #5312 deleted the
45
- * `(<tier>)` suffix, the `manual:<reason>` escape and the repair pass that
46
- * appended the suffix for the author. The only verify rule left is that the
47
- * list is non-empty.
48
- *
49
- * The errors are batched and surfaced as a single thrown Error so the
50
- * planner can see every offending slug in one pass instead of fixing one
51
- * at a time.
2
+ * Story body schema validator. String bodies (the canonical serialized form)
3
+ * are parsed before checking. Requires a non-empty `goal`, `acceptance`, and
4
+ * `changes` of `{ path, assumption }` objects; `references` is optional, same
5
+ * shape. `verify` is not scored. Errors are batched into one throw.
52
6
  */
53
7
 
54
8
  import { suggestPathEntryFix } from '../story-body/body-format-lints.js';
@@ -59,48 +13,23 @@ import {
59
13
  import { FILE_ASSUMPTION_VALUES } from './file-assumption-enum.js';
60
14
 
61
15
  /**
62
- * Predicate: should the validator skip this ticket entirely? Skip when:
63
- * - it is not a Story (only `type: 'story'` tickets are validated here),
64
- * - it has no body (null / undefined / empty-or-whitespace string — there
65
- * is nothing to inspect).
66
- *
67
- * Under the 2-tier hierarchy (Epic → Story), Stories carry the
68
- * implementation scope inline. A canonical decomposition serializes the
69
- * Story body to a markdown string, so a *string* body is NOT skipped here
70
- * (Story #3906) — `validateTaskBodyShape` parses it back into structured
71
- * form via `parseStoryBody` before applying the section rules. This is what
72
- * makes the non-empty-verify / vague-verb / non-empty-goal checks actually fire
73
- * on real plans. Features (and everything else) use narrative string bodies
74
- * and are skipped by the `type !== 'story'` guard.
75
- *
76
- * Returns `true` when the ticket should be ignored by
77
- * `collectTaskBodyErrors`, `false` when the body should be inspected.
16
+ * Non-Stories and empty bodies are skipped; string bodies are NOT.
78
17
  *
79
18
  * @param {object} ticket
80
19
  * @returns {boolean}
81
20
  */
82
21
  function shouldSkipTicket(ticket) {
83
22
  if (!ticket) return true;
84
- // Only Stories carry an inline implementation contract in the 2-tier
85
- // world. Features (and everything else) use narrative bodies.
86
23
  if (ticket.type !== 'story') return true;
87
24
  const body = ticket.body;
88
25
  if (body == null) return true;
89
- // An empty / whitespace-only string body carries no contract to inspect.
90
26
  if (typeof body === 'string' && body.trim() === '') return true;
91
27
  return false;
92
28
  }
93
29
 
94
30
  /**
95
- * Resolve a Story ticket's body to the structured object the section rules
96
- * operate on. A string body is the canonical serialized form — parse it via
97
- * `parseStoryBody` (Story #3906). An object body is already structured and
98
- * is returned verbatim (a caller may pass the pre-serialize shape directly).
99
- *
100
31
  * @param {object} ticket Story whose body passed `shouldSkipTicket`.
101
- * @returns {{ body: object|null, error: string|null }} `body` is the
102
- * structured object when resolvable; `error` is a single message when a
103
- * string body could not be parsed (mutually exclusive with `body`).
32
+ * @returns {{ body: object|null, error: string|null }} Mutually exclusive.
104
33
  */
105
34
  function resolveStructuredBody(ticket) {
106
35
  const raw = ticket.body;
@@ -120,25 +49,15 @@ function resolveStructuredBody(ticket) {
120
49
  }
121
50
  }
122
51
 
123
- /**
124
- * The two contract fields that live at the ticket's top level and are
125
- * synced into the body by `plan-persist` at assemble time.
126
- */
127
52
  const CONTRACT_FIELDS = Object.freeze(['acceptance', 'verify']);
128
53
 
129
54
  /**
130
- * Resolve the body's contract fields against the ticket's top-level arrays
131
- * (Story #4541). The decomposer prompt prescribes authoring `acceptance[]`
132
- * / `verify[]` **once** at top level and omitting the matching body
133
- * sections; `assemblePlanStories#syncContractFieldFromTopLevel` performs
134
- * the sync, but it runs *after* validation. So an absent body section is
135
- * not a violation when the ticket carries the list at top level — it is the
136
- * preferred shape. A body section that is present and disagrees with the
137
- * top level is left alone here: the sync itself fails closed on that
138
- * mismatch, and duplicating the check would report it twice.
55
+ * Fall back to top-level `acceptance[]` / `verify[]` (the preferred authoring
56
+ * shape): assembly syncs them into the body only after validation. A
57
+ * disagreeing body section is left to the sync, which fails closed.
139
58
  *
140
59
  * @param {object} ticket
141
- * @param {object} bodyObject Parsed / structured body.
60
+ * @param {object} bodyObject
142
61
  * @returns {object} A copy of `bodyObject` with the contract fields resolved.
143
62
  */
144
63
  function resolveContractFieldsFromTopLevel(ticket, bodyObject) {
@@ -154,19 +73,7 @@ function resolveContractFieldsFromTopLevel(ticket, bodyObject) {
154
73
  }
155
74
 
156
75
  /**
157
- * Validate one Story body and return every violation it exhibits. Empty
158
- * array means clean. Splits the per-ticket cascade out of
159
- * `collectTaskBodyErrors` so the iteration stays straight-line and so
160
- * each section's defensive checks are independently testable.
161
- *
162
- * Accepts both the canonical **serialized string** body (parsed back into
163
- * structured form via `parseStoryBody` — Story #3906) and the
164
- * pre-serialize **structured object** body. A string body that cannot be
165
- * parsed surfaces a single error.
166
- *
167
- * @param {object} ticket Story whose `body` has already passed the
168
- * `shouldSkipTicket` filter (i.e. `body` is a non-empty string or an
169
- * object).
76
+ * @param {object} ticket Story whose `body` passed `shouldSkipTicket`.
170
77
  * @returns {string[]}
171
78
  */
172
79
  export function validateTaskBodyShape(ticket) {
@@ -185,18 +92,11 @@ export function validateTaskBodyShape(ticket) {
185
92
  }
186
93
  errors.push(...collectChangesErrors(prefix, body.changes));
187
94
  errors.push(...collectAcceptanceErrors(prefix, body.acceptance));
188
- errors.push(...collectVerifyErrors(prefix, body.verify));
189
95
  errors.push(...collectReferencesErrors(prefix, body.references));
190
96
  return errors;
191
97
  }
192
98
 
193
99
  /**
194
- * Predicate: is `entry` a well-formed object-form path entry? Returns
195
- * `true` only when it carries a non-empty `path` string and an
196
- * `assumption` from the canonical enum. Bare objects without these
197
- * fields surface as errors via `collectChangesErrors` /
198
- * `collectReferencesErrors`.
199
- *
200
100
  * @param {unknown} entry
201
101
  * @returns {entry is { path: string, assumption: typeof FILE_ASSUMPTION_VALUES[number] }}
202
102
  */
@@ -208,10 +108,7 @@ export function isObjectPathEntry(entry) {
208
108
  }
209
109
 
210
110
  /**
211
- * Predicate: is `entry` an object that *looks* like the new shape but
212
- * has at least one invalid field? Distinct from `isObjectPathEntry` so
213
- * we can route bad objects through a specific error message instead of
214
- * silently collapsing them into the "name no path-shaped token" bucket.
111
+ * An object that is not a valid entry, so it gets a specific error message.
215
112
  *
216
113
  * @param {unknown} entry
217
114
  * @returns {boolean}
@@ -219,8 +116,6 @@ export function isObjectPathEntry(entry) {
219
116
  export function isMalformedObjectPathEntry(entry) {
220
117
  if (entry === null || typeof entry !== 'object') return false;
221
118
  if (isObjectPathEntry(entry)) return false;
222
- // Anything that's an object and isn't a valid entry is malformed —
223
- // string-form bullets fall through this predicate (they're not objects).
224
119
  return true;
225
120
  }
226
121
 
@@ -268,7 +163,6 @@ function collectChangesErrors(prefix, rawChanges) {
268
163
  * @returns {string[]}
269
164
  */
270
165
  function collectReferencesErrors(prefix, rawReferences) {
271
- // `body.references` is optional — absent / null / undefined is fine.
272
166
  if (rawReferences === undefined || rawReferences === null) return [];
273
167
  if (!Array.isArray(rawReferences)) {
274
168
  return [
@@ -306,21 +200,7 @@ function collectAcceptanceErrors(prefix, rawAcceptance) {
306
200
  * @param {unknown} rawVerify
307
201
  * @returns {string[]}
308
202
  */
309
- function collectVerifyErrors(prefix, rawVerify) {
310
- const verify = Array.isArray(rawVerify) ? rawVerify : [];
311
- if (verify.length === 0) {
312
- return [
313
- `${prefix}: verify must list at least one entry — author it at the ticket's top level (preferred) or in the body's ## Verify section.`,
314
- ];
315
- }
316
- return [];
317
- }
318
-
319
203
  /**
320
- * Validate every 2-tier Story in `tickets` whose `body` is a structured
321
- * object. Returns an array of error strings (one per offending slug); empty
322
- * array means clean.
323
- *
324
204
  * @param {object[]} tickets
325
205
  * @returns {string[]}
326
206
  */
@@ -334,9 +214,6 @@ export function collectTaskBodyErrors(tickets) {
334
214
  }
335
215
 
336
216
  /**
337
- * Throw a single batched error if any Story body is malformed; otherwise
338
- * return `tickets` unchanged.
339
- *
340
217
  * @param {object[]} tickets
341
218
  * @returns {object[]}
342
219
  */
@@ -1,49 +1,13 @@
1
1
  /**
2
- * ticket-lease.js — assignee-as-lease primitive (Story #3480, Epic #3457).
3
- *
4
- * The workflow-guards Feature (#3478) needs a way for one operator to take an
5
- * exclusive claim on a ticket so two concurrent runs do not both drive the
6
- * same Story. Rather than invent a new state column, the lease rides the
7
- * ticket's existing **assignees** surface: the single assignee *is* the lease
8
- * owner.
9
- *
10
- * **A foreign claim is a refusal, full stop (Story #5006).** The lease shipped
11
- * with a TTL: a claim whose owner's last heartbeat was older than
12
- * `delivery.lease.ttlMs` counted as stale and was silently reclaimed. The
13
- * `story.heartbeat` emitter that would have fed it was structurally inert (it
14
- * demanded an `epicId >= 1` that v2, which has no Epics, never supplies) and
15
- * was deleted, after which every guard pinned `heartbeatAt` to `now` so the
16
- * liveness test always answered "live" — the TTL, the heartbeat parameter and
17
- * the reclaim branch were an elaborate way of writing `true`. They are gone.
18
- * A stranded claim is cleared with `--steal`, which is now the only way past
19
- * a foreign owner.
20
- *
21
- * The two exported operations are deliberately thin and provider-agnostic:
22
- *
23
- * - `acquireLease` — claim an unassigned ticket, re-affirm a self-held
24
- * claim, or — with `steal: true` — forcibly transfer a
25
- * foreign claim.
26
- * - `releaseLease` — clear the assignment, but only when the operator
27
- * still holds it (a no-op once the ticket was
28
- * reassigned elsewhere, so a late release never steals
29
- * a claim back from whoever took over).
30
- *
31
- * Provider contract (a subset of `ITicketingProvider`):
32
- * - `getTicket(id)` → `{ assignees: string[], ... }`
33
- * - `updateTicket(id, { assignees })` replaces the assignee list.
34
- * - `updateTicket(id, { addAssignees })` appends to it (Story #5112).
2
+ * Assignee-as-lease: the ticket's single assignee is the lease owner. A
3
+ * foreign claim is always refused; `steal: true` (`--steal`) is the only way
4
+ * past one. Provider needs `getTicket` and `updateTicket` with `assignees`
5
+ * (replace) or `addAssignees` (append).
35
6
  */
36
7
 
37
8
  /**
38
- * The shipped, non-personal operator-identity placeholder (and its bare,
39
- * post-normalise form). The committed `.agentrc.json` and the distributed
40
- * templates carry this sentinel so `github.operatorHandle` is schema-present
41
- * without naming a real person; each contributor overrides it with their own
42
- * handle in the gitignored `.agentrc.local.json`. It is NOT a usable lease
43
- * owner: `normalizeOperatorHandle` maps it to `null` so the guards fail closed
44
- * (a contributor who never set their handle is loudly refused, never silently
45
- * coordinated under a shared identity) and no assignee PATCH ever writes a
46
- * literal `[USERNAME]` (HTTP 422).
9
+ * Shipped placeholder handle. Normalizes to `null` so an unset handle fails
10
+ * closed and no PATCH writes a literal `[USERNAME]` (HTTP 422).
47
11
  */
48
12
  // kept (dead-export allowlist): public config sentinel — the distributed
49
13
  // `.agentrc.json` / templates carry this literal; exported so consumers and
@@ -52,17 +16,8 @@ export const OPERATOR_HANDLE_PLACEHOLDER = '@[USERNAME]';
52
16
  const OPERATOR_HANDLE_PLACEHOLDER_BARE = '[USERNAME]';
53
17
 
54
18
  /**
55
- * Normalise an operator handle into the bare login GitHub writes to (and
56
- * returns from) a ticket's `assignees`. Trims surrounding whitespace and
57
- * strips a single leading `@` so an `@`-prefixed `operatorHandle` matches a
58
- * bare assignee login (otherwise the assignee PATCH is rejected HTTP 422 and
59
- * the self-held-claim comparison `owner === operator` never matches).
60
- *
61
- * Returns `null` for a non-string, empty, whitespace-only, or placeholder
62
- * handle (`@[USERNAME]`) so each caller can apply its own absent-handling
63
- * (degrade to a no-op, or throw). Treating the placeholder as unset is what
64
- * makes the shipped sentinel safe: a contributor who never overrode it is
65
- * indistinguishable from one who set nothing, so the guards fail closed.
19
+ * Bare login (trimmed, one leading `@` stripped) so it matches assignee
20
+ * logins. `null` for empty or placeholder input; callers decide how to fail.
66
21
  *
67
22
  * @param {unknown} raw
68
23
  * @returns {string|null}
@@ -77,9 +32,7 @@ export function normalizeOperatorHandle(raw) {
77
32
  }
78
33
 
79
34
  /**
80
- * Normalise the assignee list into a single current owner. The lease model is
81
- * single-holder: the first assignee is authoritative. Returns `null` for an
82
- * unassigned ticket.
35
+ * The first assignee is authoritative.
83
36
  *
84
37
  * @param {string[]|undefined|null} assignees
85
38
  * @returns {string|null}
@@ -90,8 +43,6 @@ export function currentOwner(assignees) {
90
43
  }
91
44
 
92
45
  /**
93
- * Validate and normalise the shared option bag for the lease operations.
94
- *
95
46
  * @param {string} op
96
47
  * @param {object} opts
97
48
  * @returns {{ provider: object, ticketId: number, operator: string }}
@@ -113,34 +64,13 @@ function normaliseOpts(op, opts) {
113
64
  }
114
65
 
115
66
  /**
116
- * Acquire (or re-affirm) a lease on a ticket for `operator`.
117
- *
118
- * Outcomes:
119
- * - Unassigned ticket → assign operator, `acquired: true`,
120
- * `reason: 'unclaimed'`.
121
- * - Operator already holds it → no write, `acquired: true`,
122
- * `reason: 'already-held'`.
123
- * - Foreign claim, no steal → no write, `acquired: false`,
124
- * `owner: <foreign>`, `reason: 'held'`.
125
- * - Foreign claim + `steal:true` → reassign operator, `acquired: true`,
126
- * `reason: 'stolen'`.
127
- * - Lost a write race → a foreign login co-assigned between our
128
- * PATCH and the verify re-read; back the
129
- * operator out, `acquired: false`,
130
- * `owner: <foreign>`, `reason: 'lost-race'`.
131
- *
132
- * Every claiming write is verified: GitHub's assignee write is not a
133
- * compare-and-set, so two runs that both read the ticket unassigned will both
134
- * write themselves. {@link claimAndVerify} re-reads after the write and refuses
135
- * (fail-closed) when a foreign login is present, so the loser of a simultaneous
136
- * claim never proceeds as though it holds the lease. Story #5112 made the
137
- * first claim **additive** so that verify can actually see the collision —
138
- * see {@link claimAndVerify}.
67
+ * Every claiming write is verified by re-read, since assignee writes are not
68
+ * compare-and-set; a co-assigned foreign login yields `lost-race`.
139
69
  *
140
70
  * @param {object} opts
141
- * @param {object} opts.provider Ticketing provider.
142
- * @param {number} opts.ticketId Ticket to claim.
143
- * @param {string} opts.operator Operator acquiring the lease.
71
+ * @param {object} opts.provider
72
+ * @param {number} opts.ticketId
73
+ * @param {string} opts.operator
144
74
  * @param {boolean} [opts.steal=false] Transfer a foreign claim.
145
75
  * @returns {Promise<{
146
76
  * acquired: boolean,
@@ -156,7 +86,6 @@ export async function acquireLease(opts) {
156
86
  const ticket = await provider.getTicket(ticketId);
157
87
  const owner = currentOwner(ticket?.assignees);
158
88
 
159
- // Unclaimed → take it.
160
89
  if (owner === null) {
161
90
  return claimAndVerify({
162
91
  provider,
@@ -167,7 +96,6 @@ export async function acquireLease(opts) {
167
96
  });
168
97
  }
169
98
 
170
- // Already ours → no write needed.
171
99
  if (owner === operator) {
172
100
  return {
173
101
  acquired: true,
@@ -177,7 +105,6 @@ export async function acquireLease(opts) {
177
105
  };
178
106
  }
179
107
 
180
- // Foreign claim — refuse unless the operator explicitly steals it.
181
108
  if (!steal) {
182
109
  return {
183
110
  acquired: false,
@@ -197,44 +124,21 @@ export async function acquireLease(opts) {
197
124
  }
198
125
 
199
126
  /**
200
- * Write the operator to a ticket's assignees, then re-read to confirm the
201
- * claim actually stuck before reporting success.
202
- *
203
- * The assignee write is not atomic — GitHub offers no compare-and-set on the
204
- * assignees surface — so two runs that both observed the ticket unassigned (or
205
- * a stale foreign claim) will both write themselves in. Without a check the
206
- * loser of that race returns `acquired: true` and marches into the worktree
207
- * the winner is already building. The verify closes that window: it re-reads
208
- * with `fresh: true` (bypassing any provider cache so it sees the other run's
209
- * write, not our own), and if a foreign login is present it concedes — removes
210
- * the operator from the assignee set so no phantom co-owner lingers, and
211
- * returns `acquired: false` / `reason: 'lost-race'` so the fail-closed caller
212
- * refuses. A clean read (assignees exactly `[operator]`) confirms the claim.
213
- *
214
- * **The write must be additive for the verify to work (Story #5112).** With
215
- * the replacing PATCH this used unconditionally, a simultaneous claim
216
- * *evicted* the other operator rather than joining it, so the co-assignment
217
- * the `lost-race` branch keys on was a state the PATCH could never produce:
218
- * each run read a clean `[self]` on verify and both proceeded. Claiming an
219
- * unowned ticket therefore goes through the additive assignees endpoint
220
- * (`addAssignees`), which makes the collision observable and lets exactly one
221
- * claimer survive. The replacing form stays for the two cases that genuinely
222
- * mean "replace": the `--steal` transfer of a foreign claim, and the loser's
223
- * own back-out below.
127
+ * Write, then re-read with `fresh: true`; on a foreign co-assignee, back out
128
+ * and report `lost-race` so the loser never builds the winner's worktree.
224
129
  *
225
130
  * @param {object} args
226
- * @param {object} args.provider Ticketing provider.
227
- * @param {number} args.ticketId Ticket being claimed.
228
- * @param {string} args.operator Operator acquiring the lease.
229
- * @param {string|null} args.previousOwner Owner before this write (for the result).
131
+ * @param {object} args.provider
132
+ * @param {number} args.ticketId
133
+ * @param {string} args.operator
134
+ * @param {string|null} args.previousOwner
230
135
  * @param {string} args.reason Success reason when the claim holds.
231
136
  * @returns {Promise<{ acquired: boolean, owner: string, previousOwner: string|null, reason: string }>}
232
137
  */
233
138
  /**
234
- * The assignee mutation a claim writes. Additive when the ticket has no
235
- * previous owner — that is what makes a simultaneous claim show up as a
236
- * co-assignment {@link claimAndVerify} can detect. Replacing only for a
237
- * steal, where evicting the previous owner *is* the intent.
139
+ * Additive for an unowned ticket — a replacing PATCH would evict a
140
+ * simultaneous claimer, hiding the collision verify keys on. Replacing only
141
+ * for a steal.
238
142
  *
239
143
  * @param {string} operator
240
144
  * @param {string|null} previousOwner
@@ -262,9 +166,7 @@ async function claimAndVerify({
262
166
  return { acquired: true, owner: operator, previousOwner, reason };
263
167
  }
264
168
 
265
- // A foreign login co-assigned after our write — we lost a simultaneous
266
- // claim. Back ourselves out so the winner is the sole assignee, and report
267
- // the loss so the fail-closed caller refuses rather than double-delivering.
169
+ // Lost the race: leave the winner as sole assignee.
268
170
  await provider
269
171
  .updateTicket(ticketId, { assignees: foreign })
270
172
  .catch(() => undefined);
@@ -277,17 +179,12 @@ async function claimAndVerify({
277
179
  }
278
180
 
279
181
  /**
280
- * Release a lease the operator currently holds.
281
- *
282
- * Clears the ticket's assignees only when `operator` is still the recorded
283
- * owner. If the ticket has since been reassigned (or was never held by this
284
- * operator), the call is a no-op — a stale release must never yank a claim
285
- * away from whoever legitimately holds it now.
182
+ * No-op unless `operator` still owns it — a stale release never yanks a claim.
286
183
  *
287
184
  * @param {object} opts
288
- * @param {object} opts.provider Ticketing provider.
289
- * @param {number} opts.ticketId Ticket to release.
290
- * @param {string} opts.operator Operator releasing the lease.
185
+ * @param {object} opts.provider
186
+ * @param {number} opts.ticketId
187
+ * @param {string} opts.operator
291
188
  * @returns {Promise<{
292
189
  * released: boolean,
293
190
  * owner: string|null,