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
@@ -1,57 +1,21 @@
1
1
  /**
2
- * merge-poll.js — merge-wait constants and check-rollup derivation owned by
3
- * the close path.
4
- *
5
- * Story #4545 — these three symbols used to live in the Epic-era
6
- * `lifecycle/listeners/merge-watcher.js`. That listener class had no
7
- * production caller after the v2.0.0 Story-only cutover, but it was not
8
- * importer-less: the live close path (`single-story-close/phases/confirm-merge.js`)
9
- * and `deliver-recover.js` both reached into it for the poll defaults and
10
- * `deriveChecksStatus`. Relocating them here lets the listener go without
11
- * leaving the close path importing a lifecycle module it does not otherwise
12
- * participate in.
13
- *
14
- * Sits beside `merge-block-class.js`, its sole consumer pairing:
15
- * `deriveChecksStatus` produces the `prProbe.checksStatus` value that
16
- * `classifyMergeBlock` reads.
2
+ * merge-poll.js — merge-wait constants and check-rollup derivation for the
3
+ * close path. `deriveChecksStatus` feeds `classifyMergeBlock`'s
4
+ * `prProbe.checksStatus`.
17
5
  */
18
6
 
19
- /**
20
- * Default poll interval and cumulative budget for the merge wait. The schema
21
- * in `.agents/schemas/agentrc.schema.json` exposes these as
22
- * `delivery.mergeWatch.intervalSeconds` (default 30) and
23
- * `delivery.mergeWatch.maxBudgetSeconds` (default 3600). Hard-coding the same
24
- * numbers here keeps the close path self-contained when no config is wired in
25
- * (e.g. unit tests).
26
- */
7
+ import { checkVerdict, classifyRollupEntry } from './check-state.js';
8
+
9
+ /** Fixed poll interval; default for `delivery.mergeWatch.maxBudgetSeconds`. */
27
10
  export const DEFAULT_INTERVAL_SECONDS = 30;
28
11
  export const DEFAULT_MAX_BUDGET_SECONDS = 3600;
29
12
 
30
- /**
31
- * Wall-clock bound for every `gh` subprocess the merge wait spawns (Story
32
- * #4710). The wait is now routinely unattended (`delivery.mergeWatch.mode:
33
- * "async"` runs it in a background invocation with no host tool ceiling), so
34
- * a hung `gh pr view` / `gh pr update-branch` used to strand the wait with no
35
- * terminal envelope, no label flip, and no friction record. Sixty seconds is
36
- * generous for a single API round-trip while staying inside the async probe
37
- * window; a timeout maps to the existing probe-error path, so the wait
38
- * degrades to conservative-pending / `api-race-other` semantics instead of
39
- * hanging. A framework constant by design — not config (Story #4710
40
- * Non-Goals).
41
- */
13
+ /** Bounds every `gh` spawn so a hang degrades to the probe-error path. */
42
14
  export const MERGE_WAIT_GH_TIMEOUT_MS = 60_000;
43
15
 
44
16
  /**
45
- * Pure: derive an aggregate `checksStatus` (`success` | `still-running` |
46
- * `failure` | `unknown`) from a `statusCheckRollup` array (`gh pr view --json
47
- * statusCheckRollup` shape: `{ status, conclusion }` per check). Mirrors the
48
- * values `classifyMergeBlock` expects on `prProbe.checksStatus`.
49
- *
50
- * **Scope: EVERY check reported on the PR, required or not.** The rollup
51
- * carries no required-vs-optional discriminator (`gh`'s projection has no
52
- * `isRequired` field), so `failure` here means "something on this PR is red",
53
- * NOT "the merge is blocked". Use {@link failingChecksBlockMerge} before
54
- * treating a `failure` as terminal.
17
+ * Aggregate over EVERY check (the rollup has no `isRequired`): `failure`
18
+ * means "something is red", not "blocked" — see {@link failingChecksBlockMerge}.
55
19
  */
56
20
  export function deriveChecksStatus(statusCheckRollup) {
57
21
  if (!Array.isArray(statusCheckRollup) || statusCheckRollup.length === 0) {
@@ -59,73 +23,26 @@ export function deriveChecksStatus(statusCheckRollup) {
59
23
  }
60
24
  let anyPending = false;
61
25
  for (const check of statusCheckRollup) {
62
- const conclusion = String(check?.conclusion ?? '').toUpperCase();
63
- const status = String(check?.status ?? '').toUpperCase();
64
- if (['FAILURE', 'CANCELLED', 'TIMED_OUT', 'ERROR'].includes(conclusion)) {
65
- return 'failure';
66
- }
67
- if (status !== 'COMPLETED') {
68
- anyPending = true;
69
- }
26
+ const verdict = checkVerdict(classifyRollupEntry(check));
27
+ if (verdict === 'fail') return 'failure';
28
+ if (verdict === 'pending') anyPending = true;
70
29
  }
71
30
  return anyPending ? 'still-running' : 'success';
72
31
  }
73
32
 
74
33
  /**
75
- * Pure: derive HEAD-ANCHORED per-run evidence from a `statusCheckRollup`
76
- * array, distinguishing a genuinely red required run from the pending /
77
- * superseded noise the aggregate {@link deriveChecksStatus} folds together.
78
- *
79
- * {@link deriveChecksStatus} returns `failure` the instant it sees ANY
80
- * non-passing conclusion — including a `CANCELLED` superseded-push run or a
81
- * sibling-invalidated run — even while the real required check is still
82
- * queued. Paired with `mergeStateStatus: BLOCKED` (the protected-branch steady
83
- * state while required checks run), that matched a merely *pending* PR and
84
- * hard-blocked Stories whose PRs merged untouched. This derivation reads the
85
- * two signals the fail-fast decision actually needs:
86
- *
87
- * - `requiredRunFailed` — a run on the head concluded `FAILURE` (or a
88
- * legacy status context is `FAILURE`/`ERROR`).
89
- * Deliberately NOT `CANCELLED`/`TIMED_OUT`/
90
- * `SKIPPED`: those are the superseded-push and
91
- * sibling-invalidated runs, not a red required
92
- * check.
93
- * - `requiredRunInFlight` — any run on the head is still QUEUED /
94
- * IN_PROGRESS (a CheckRun whose status is not
95
- * `COMPLETED`, or a legacy status context still
96
- * `PENDING`/`EXPECTED`).
97
- *
98
- * Returns `null` when the rollup is absent or empty — the evidence is
99
- * unavailable and the caller must fall back to the consecutive-probe path
100
- * (a single evidence-free failing snapshot must never fail-fast).
101
- *
102
- * **Contract honesty (Story #4710).** The `requiredRun*` field names describe
103
- * what the evidence is USED to establish, not what this function reads: the
104
- * `gh pr view` rollup projection carries no `isRequired` discriminator, so
105
- * this derivation reads EVERY run on the head, required or not. On its own,
106
- * `requiredRunFailed: true` therefore means "a head run genuinely concluded
107
- * failure", and required-ness attribution is supplied downstream by
108
- * {@link requiredCheckFailedBlocksMerge}, which admits the verdict only when
109
- * `mergeStateStatus: BLOCKED` says GitHub itself gates the merge AND no
110
- * review-required signal offers a competing explanation for that BLOCKED
111
- * state. Do not treat this function's output as a required-only reading.
34
+ * `mergedAt` counts even when `state` lags. A closed issue proves nothing.
112
35
  *
113
- * @param {Array<{status?: string, conclusion?: string, state?: string}>} statusCheckRollup
114
- * @returns {{ requiredRunFailed: boolean, requiredRunInFlight: boolean } | null}
36
+ * @param {{ state?: string|null, mergedAt?: string|null }|null|undefined} pr
37
+ * @returns {boolean}
115
38
  */
39
+ export function isPrMerged(pr) {
40
+ return pr?.state === 'MERGED' || Boolean(pr?.mergedAt);
41
+ }
42
+
116
43
  /**
117
- * Pure: the uppercase conclusion of a check that GENUINELY concluded red, or
118
- * `null` when it did not.
119
- *
120
- * Red means `FAILURE` / `ERROR` only — never `CANCELLED` / `TIMED_OUT` /
121
- * `SKIPPED`, which are the superseded-push and sibling-invalidated runs a bare
122
- * rollup read miscounts (the #4695 / #4710 trap). A CheckRun carries the
123
- * verdict on `conclusion`; a legacy StatusContext carries it on `state`, so
124
- * both are read and the one that is red is the one returned.
125
- *
126
- * Extracted (Story #5266) because {@link deriveRequiredRunEvidence} and
127
- * {@link deriveRedHeadRuns} were carrying byte-identical copies of this test:
128
- * two places that must agree about what "red" means, and nothing making them.
44
+ * Red is `FAILURE` / `ERROR` only; `CANCELLED` / `TIMED_OUT` / `SKIPPED` are
45
+ * superseded or sibling-invalidated runs.
129
46
  *
130
47
  * @param {{ conclusion?: string, state?: string }} [check]
131
48
  * @returns {string|null}
@@ -139,13 +56,7 @@ function redConclusionOf(check) {
139
56
  }
140
57
 
141
58
  /**
142
- * Pure: a check's display name — the CheckRun's `name`, falling back to a
143
- * legacy StatusContext's `context`, and `null` when the projection carries
144
- * neither.
145
- *
146
- * A run with no readable name can never match an allowlist entry, so it always
147
- * blocks. That is the conservative direction for a gate whose whole purpose is
148
- * to stop a silent landing.
59
+ * An unnamed run never matches an allowlist entry, so it always blocks.
149
60
  *
150
61
  * @param {{ name?: string, context?: string }} [check]
151
62
  * @returns {string|null}
@@ -157,6 +68,14 @@ function readRunName(check) {
157
68
  return null;
158
69
  }
159
70
 
71
+ /**
72
+ * Head-anchored evidence; `null` on an empty rollup (the caller falls back
73
+ * to consecutive probes). Reads EVERY run despite the names — required-ness
74
+ * is attributed via `BLOCKED` in {@link requiredCheckFailedBlocksMerge}.
75
+ *
76
+ * @param {Array<{status?: string, conclusion?: string, state?: string}>} statusCheckRollup
77
+ * @returns {{ requiredRunFailed: boolean, requiredRunInFlight: boolean } | null}
78
+ */
160
79
  export function deriveRequiredRunEvidence(statusCheckRollup) {
161
80
  if (!Array.isArray(statusCheckRollup) || statusCheckRollup.length === 0) {
162
81
  return null;
@@ -166,9 +85,7 @@ export function deriveRequiredRunEvidence(statusCheckRollup) {
166
85
  for (const check of statusCheckRollup) {
167
86
  const status = String(check?.status ?? '').toUpperCase();
168
87
  const state = String(check?.state ?? '').toUpperCase();
169
- // In flight: a CheckRun not yet COMPLETED, or a legacy StatusContext still
170
- // PENDING/EXPECTED. `status` is empty on a StatusContext, so it degrades to
171
- // the `state` branch rather than counting as in-flight.
88
+ // `status` is empty on a StatusContext, so it falls to the `state` branch.
172
89
  if (status && status !== 'COMPLETED') {
173
90
  requiredRunInFlight = true;
174
91
  } else if (state === 'PENDING' || state === 'EXPECTED') {
@@ -181,41 +98,13 @@ export function deriveRequiredRunEvidence(statusCheckRollup) {
181
98
  return { requiredRunFailed, requiredRunInFlight };
182
99
  }
183
100
 
184
- /**
185
- * The one `mergeStateStatus` value that means GitHub itself is gating the
186
- * merge. See {@link failingChecksBlockMerge}.
187
- */
101
+ /** The `mergeStateStatus` meaning GitHub itself gates the merge. */
188
102
  const MERGE_GATED_STATE = 'BLOCKED';
189
103
 
190
104
  /**
191
- * Pure: does the PR's RED check status actually gate the merge?
192
- *
193
- * `deriveChecksStatus` aggregates the whole rollup, so it reports `failure`
194
- * for a red check of any kind. Branch protection — and therefore GitHub
195
- * native auto-merge — gates only on REQUIRED checks. A red optional check
196
- * (an advisory bot, or a `CANCELLED` superseded workflow run, which the
197
- * rollup derivation counts as a failure) says nothing about whether the PR
198
- * will land: auto-merge lands it regardless. Treating that as terminal is
199
- * what stranded a Story `agent::blocked` on a PR that merged anyway.
200
- *
201
- * `mergeStateStatus` is GitHub's own verdict, computed against the live
202
- * branch-protection rules, so it supplies the required-vs-optional
203
- * discrimination the rollup lacks:
204
- *
205
- * - `BLOCKED` — merging is gated. With red checks observed, the red
206
- * required check is the gate.
207
- * - `UNSTABLE` — "mergeable with non-passing commit status": the red
208
- * checks are NOT required. Auto-merge will land it.
209
- * - `CLEAN` / `BEHIND` / `UNKNOWN` / absent — not evidence that the red
210
- * check gates the merge.
211
- *
212
- * Deliberately conservative: only `BLOCKED` returns `true`. A transient
213
- * `UNKNOWN` (GitHub has not finished computing the merge state) or a token
214
- * that cannot see the field degrades to "keep waiting" — the caller's poll
215
- * budget still bounds the wait and the budget-exhausted classification still
216
- * fires. The asymmetry is intentional: failing to fail fast costs poll time,
217
- * whereas failing fast wrongly costs a merged-but-`agent::blocked` strand
218
- * that only an operator can unpick.
105
+ * Does the red status gate the merge? Only `BLOCKED` (GitHub's verdict
106
+ * against live protection rules) says so; `UNKNOWN` keeps waiting, since a
107
+ * wrong fail-fast strands a merged PR while waiting only costs poll time.
219
108
  *
220
109
  * @param {{ checksStatus?: string, mergeStateStatus?: string }} [prProbe]
221
110
  * @returns {boolean}
@@ -228,39 +117,29 @@ export function failingChecksBlockMerge(prProbe) {
228
117
  }
229
118
 
230
119
  /**
231
- * Pure: does HEAD-ANCHORED evidence establish that a REQUIRED check is
232
- * genuinely red — enough to fail-fast the merge wait as `checks-failed`?
233
- *
234
- * This is the single gated decision Story #4695 adds, and the named predicate
235
- * a downstream async-confirm Story imports rather than reopening the poll
236
- * loop's classification internals. It layers on {@link failingChecksBlockMerge}
237
- * (the rollup-`failure` + `mergeStateStatus: BLOCKED` gate) the head-anchored
238
- * refinement the raw gate lacked: classify `checks-failed` ONLY when a run
239
- * genuinely concluded failure AND none is still in flight. A red rollup while
240
- * a required run is queued/in-progress is the protected-branch pending steady
241
- * state, not a failure.
120
+ * A missing review competes as the explanation for `BLOCKED`.
242
121
  *
243
- * The evidence is read from `prProbe.requiredRunEvidence` (the
244
- * {@link deriveRequiredRunEvidence} output threaded through the probe). When it
245
- * is absent — older `gh`, an API error, or a probe that never carried a rollup
246
- * — this returns `false`: the caller's consecutive-probe fallback owns that
247
- * path, because a single evidence-free failing snapshot must never fail-fast.
248
- *
249
- * **Review-required softening (Story #4710).** The rollup evidence cannot
250
- * prove the red run is a REQUIRED check (see
251
- * {@link deriveRequiredRunEvidence}), so when the probe carries a competing
252
- * explanation for the `BLOCKED` merge state — `reviewDecision:
253
- * 'REVIEW_REQUIRED'`, i.e. a required approval is missing — this predicate
254
- * declines the `checks-failed` verdict. A red *optional* check beside a
255
- * missing required review used to fail-fast as `checks-failed` and send the
256
- * operator to fix a check that was never gating the merge; with the review
257
- * signal present, classification falls through to the
258
- * `branch-protection-human-required` branch, which names the gate GitHub
259
- * actually attributes. When a genuinely red required check coexists with a
260
- * missing review, both are true blocks and the human-required verdict is
261
- * still an honest one — the conservative direction (see
262
- * {@link failingChecksBlockMerge} on why failing to fail fast is the cheap
263
- * error).
122
+ * @param {{ reviewDecision?: string }} [prProbe]
123
+ * @returns {boolean}
124
+ */
125
+ function reviewOwnsBlockedState(prProbe) {
126
+ return prProbe?.reviewDecision === 'REVIEW_REQUIRED';
127
+ }
128
+
129
+ export const CHECKS_FAILED_CLASS = 'checks-failed';
130
+
131
+ /**
132
+ * @param {{ mergeStateStatus?: string }} [prProbe]
133
+ * @param {string} [evidencePath]
134
+ * @returns {string}
135
+ */
136
+ export function formatChecksFailedReason(prProbe, evidencePath) {
137
+ return `a required check failed (mergeStateStatus=${prProbe?.mergeStateStatus ?? 'n/a'}${evidencePath ? `, evidence=${evidencePath}` : ''})`;
138
+ }
139
+
140
+ /**
141
+ * A genuinely red REQUIRED check: gated, no review owns `BLOCKED`, a run is
142
+ * red and none in flight. No evidence → false (consecutive-probe path).
264
143
  *
265
144
  * @param {{ checksStatus?: string, mergeStateStatus?: string,
266
145
  * reviewDecision?: string,
@@ -268,8 +147,9 @@ export function failingChecksBlockMerge(prProbe) {
268
147
  * @returns {boolean}
269
148
  */
270
149
  export function requiredCheckFailedBlocksMerge(prProbe) {
271
- if (!failingChecksBlockMerge(prProbe)) return false;
272
- if (prProbe?.reviewDecision === 'REVIEW_REQUIRED') return false;
150
+ if (!failingChecksBlockMerge(prProbe) || reviewOwnsBlockedState(prProbe)) {
151
+ return false;
152
+ }
273
153
  const evidence = prProbe?.requiredRunEvidence;
274
154
  if (!evidence || typeof evidence.requiredRunFailed !== 'boolean') {
275
155
  return false;
@@ -280,30 +160,15 @@ export function requiredCheckFailedBlocksMerge(prProbe) {
280
160
  }
281
161
 
282
162
  /**
283
- * The one `mergeStateStatus` value that means the PR is mergeable **despite**
284
- * red runs — GitHub's own words are "mergeable with non-passing commit
285
- * status". It is the required-vs-advisory discriminator the rollup itself
286
- * cannot supply: under `UNSTABLE` the red runs are, by definition, not
287
- * required, so native auto-merge will land the PR over them.
288
- *
289
- * The exact complement of {@link MERGE_GATED_STATE}: `BLOCKED` means the red
290
- * run gates the merge (`failingChecksBlockMerge`), `UNSTABLE` means it does
291
- * not and only mandrel can stop the landing.
163
+ * Red runs are not required: auto-merge lands over them unless mandrel stops it.
292
164
  */
293
165
  const MERGE_ADVISORY_STATE = 'UNSTABLE';
294
166
 
295
167
  /**
296
- * The fields a check projection can use to say, in its own words, WHY it went
297
- * red. A legacy StatusContext carries `description`; a GitHub Actions CheckRun
298
- * carries none of them in `gh pr view`'s fixed `statusCheckRollup` projection,
299
- * so the merge wait enriches the run with the check-run API's
300
- * `output.title` / `output.summary` before classifying (Story #5266). Both
301
- * shapes are read here so the projection has ONE text extractor.
168
+ * The run's own account of why it went red (rollup or enriched check-run).
302
169
  *
303
170
  * @param {object} [check] A rollup entry, or an enriched check-run record.
304
- * @returns {string|undefined} The joined text, or `undefined` when the record
305
- * carries none — which is itself the signal that the run cannot be
306
- * classified beyond "red".
171
+ * @returns {string|undefined} `undefined` when the record carries no text.
307
172
  */
308
173
  export function readRunSummary(check) {
309
174
  const parts = [];
@@ -316,11 +181,7 @@ export function readRunSummary(check) {
316
181
  }
317
182
 
318
183
  /**
319
- * Pure: the workflow run id behind a check run's `detailsUrl`
320
- * (`.../actions/runs/<runId>/job/<jobId>`), or `null` when the URL is absent
321
- * or shaped otherwise (a legacy StatusContext's `targetUrl`, a third-party
322
- * app's own page). A run with no id can never be re-run, which is why the
323
- * rerun path treats `null` as "nothing to re-run" rather than an error.
184
+ * `null` means "nothing to re-run".
324
185
  *
325
186
  * @param {string} [detailsUrl]
326
187
  * @returns {number|null}
@@ -334,30 +195,8 @@ export function parseWorkflowRunId(detailsUrl) {
334
195
  }
335
196
 
336
197
  /**
337
- * Pure: project the HEAD-ANCHORED runs that genuinely concluded red, naming
338
- * each one (Story #5096).
339
- *
340
- * Same red-ness test as {@link deriveRequiredRunEvidence} — `FAILURE` /
341
- * `ERROR` only, never `CANCELLED` / `TIMED_OUT` / `SKIPPED`, which are the
342
- * superseded-push and sibling-invalidated runs a bare rollup read miscounts
343
- * (the #4695 / #4710 trap) — but it returns the runs rather than a boolean, so
344
- * a block summary can name the offending job and the advisory allowlist can
345
- * match on it.
346
- *
347
- * `name` is the CheckRun's `name`, falling back to a legacy StatusContext's
348
- * `context`, and is `null` when the projection carries neither. A run with no
349
- * readable name can never match an allowlist entry, so it always blocks — the
350
- * conservative direction for a gate whose whole purpose is to stop a silent
351
- * landing.
352
- *
353
- * **Widened by Story #5266** from `{name, conclusion}` to carry what a red run
354
- * is classified and acted on by: `summary` (the run's own account of why it
355
- * failed — see {@link readRunSummary}), `runId` (the workflow run behind it,
356
- * so a rerun can be requested), and `completedAt` (the observation stamp that
357
- * tells a re-run's verdict apart from the stale pre-rerun one). Every added
358
- * field is OMITTED when the projection carries no value for it, so a run the
359
- * rollup describes as thinly as before still projects to exactly the old two
360
- * keys — and a thin run classifies as a violation, i.e. the pre-#5266 verdict.
198
+ * Red head runs. Optional fields are omitted when absent; `completedAt`
199
+ * separates a rerun's verdict from the stale one.
361
200
  *
362
201
  * @param {Array<{name?: string, context?: string, status?: string, conclusion?: string, state?: string, detailsUrl?: string, completedAt?: string, description?: string, output?: object}>} statusCheckRollup
363
202
  * @returns {Array<{ name: string|null, conclusion: string, summary?: string, runId?: number, completedAt?: string }>}
@@ -385,17 +224,13 @@ export function deriveRedHeadRuns(statusCheckRollup) {
385
224
  }
386
225
 
387
226
  /**
388
- * Pure: drop the red runs a consumer has exempted via
389
- * `delivery.ci.advisoryAllowlist`, returning the ones that still block.
390
- *
391
- * Matching is exact on the run name. An unnamed run never matches (see
392
- * {@link deriveRedHeadRuns}).
227
+ * Red runs not exempted by the allowlist (exact name match).
393
228
  *
394
229
  * @param {Array<{ name: string|null, conclusion: string }>} redHeadRuns
395
230
  * @param {string[]} [allowlist]
396
231
  * @returns {Array<{ name: string|null, conclusion: string }>}
397
232
  */
398
- export function selectBlockingRedRuns(redHeadRuns, allowlist = []) {
233
+ function selectBlockingRedRuns(redHeadRuns, allowlist = []) {
399
234
  if (!Array.isArray(redHeadRuns) || redHeadRuns.length === 0) return [];
400
235
  const exempt = new Set(
401
236
  (Array.isArray(allowlist) ? allowlist : [])
@@ -407,28 +242,14 @@ export function selectBlockingRedRuns(redHeadRuns, allowlist = []) {
407
242
  }
408
243
 
409
244
  /**
410
- * Pure: does this PR carry a genuinely red ADVISORY run — one that will NOT
411
- * stop GitHub from landing the PR, and therefore one only mandrel can act on?
412
- * (Story #5096.)
413
- *
414
- * The complement of {@link requiredCheckFailedBlocksMerge}. That predicate
415
- * answers "is a red REQUIRED check gating the merge" (`BLOCKED`); this one
416
- * answers "is a red NON-required check about to be merged straight past"
417
- * (`UNSTABLE`). The two are mutually exclusive by construction, so a red
418
- * required check keeps its existing `checks-failed` treatment untouched.
419
- *
420
- * **Fails OPEN by design.** `UNKNOWN`, `CLEAN`, `BEHIND`, or an absent
421
- * `mergeStateStatus` all return `false`. The asymmetry is the same one
422
- * {@link failingChecksBlockMerge} documents and is deliberate: failing to
423
- * block costs an unattended landing the operator can still revert, whereas
424
- * blocking wrongly strands a mergeable PR at `agent::blocked` that only an
425
- * operator can unpick. A transient `UNKNOWN` must never do the latter.
245
+ * A red advisory run about to be merged past (`UNSTABLE`). Fails open on any
246
+ * other state: a wrong block strands a PR; a miss is a revertable landing.
426
247
  *
427
248
  * @param {{ mergeStateStatus?: string, redHeadRuns?: Array<{name: string|null, conclusion: string}> }} [prProbe]
428
249
  * @param {string[]} [allowlist] `delivery.ci.advisoryAllowlist`.
429
250
  * @returns {boolean}
430
251
  */
431
- export function advisoryCheckFailedBlocksArm(prProbe, allowlist = []) {
252
+ function advisoryCheckFailedBlocksArm(prProbe, allowlist = []) {
432
253
  if (
433
254
  String(prProbe?.mergeStateStatus ?? '').toUpperCase() !==
434
255
  MERGE_ADVISORY_STATE
@@ -439,31 +260,15 @@ export function advisoryCheckFailedBlocksArm(prProbe, allowlist = []) {
439
260
  }
440
261
 
441
262
  /**
442
- * The two advisory-gate block classes (Story #5266). Both BLOCK — the gate's
443
- * verdict on whether to land is unchanged — but they authorise different acts,
444
- * which is the whole reason they are two:
445
- *
446
- * - `advisory-gate-red` A red advisory run that REPORTED a
447
- * violation. The change is implicated;
448
- * landing over it is a deliberate override.
449
- * - `advisory-gate-inconclusive` A red advisory run that never finished — a
450
- * scan or navigation timeout that reported
451
- * no violation at all. Nothing here says the
452
- * change is bad, so the proportionate remedy
453
- * is to re-run the job, not to grant the
454
- * permanent global exemption
455
- * `advisoryAllowlist` is.
263
+ * Both block; `-inconclusive` (never finished, e.g. a timeout) warrants a
264
+ * rerun rather than a permanent allowlist exemption.
456
265
  */
457
266
  export const ADVISORY_GATE_RED_CLASS = 'advisory-gate-red';
458
267
  export const ADVISORY_GATE_INCONCLUSIVE_CLASS = 'advisory-gate-inconclusive';
459
268
 
460
269
  /**
461
- * Text signatures of a run that FAILED WITHOUT FINISHING. Deliberately narrow:
462
- * the observed shape (Story #5266) is a `Navigation timeout of NNNN ms
463
- * exceeded` line with an empty violation set, and anything this list does not
464
- * recognise keeps the pre-#5266 `advisory-gate-red` verdict — the conservative
465
- * direction, since misreading a real violation as a timeout would offer the
466
- * operator a rerun for a finding that will come back every time.
270
+ * Deliberately narrow: misreading a violation as a timeout offers a rerun
271
+ * that fails every time.
467
272
  */
468
273
  const INCONCLUSIVE_MARKERS = Object.freeze([
469
274
  /navigation timeout/i,
@@ -477,19 +282,10 @@ const INCONCLUSIVE_MARKERS = Object.freeze([
477
282
  /** A counted finding — `0 violations` is explicitly NOT one. */
478
283
  const VIOLATION_COUNT =
479
284
  /\b(\d+)\s+(?:violation|error|issue|failure|problem|finding)s?\b/i;
480
- /** An uncounted finding — enough on its own, because it names a verdict. */
481
285
  const VIOLATION_WORD = /\bviolations?\b|\bfailed assertion/i;
482
286
 
483
287
  /**
484
- * Pure: does this red run's own text report a VIOLATION (as opposed to saying
485
- * nothing, or saying it never got that far)?
486
- *
487
- * A counted phrase wins over the bare word so `0 violations found` — a scan
488
- * that completed cleanly and then died — is not read as a finding.
489
- *
490
- * Takes the text, not the run: its one caller has already established the
491
- * run says something, so a second empty-text guard here would be a branch no
492
- * input can reach.
288
+ * A counted phrase wins over the bare word.
493
289
  *
494
290
  * @param {string} text A non-empty run summary.
495
291
  * @returns {boolean}
@@ -501,12 +297,7 @@ function reportsViolations(text) {
501
297
  }
502
298
 
503
299
  /**
504
- * Pure: classify ONE red advisory run as a genuine violation or an
505
- * unfinished job (Story #5266).
506
- *
507
- * A run whose projection carries no text at all classifies as `violation`:
508
- * absence of evidence is not evidence the job timed out, and `violation` is
509
- * the verdict every red advisory run already got before this Story.
300
+ * No text is a `violation`: absence of evidence is not a timeout.
510
301
  *
511
302
  * @param {{ summary?: string }} [run]
512
303
  * @returns {'violation'|'inconclusive'}
@@ -520,16 +311,8 @@ function classifyAdvisoryRedRun(run) {
520
311
  }
521
312
 
522
313
  /**
523
- * Pure: the block class for a whole set of blocking runs.
524
- *
525
- * `advisory-gate-inconclusive` requires EVERY blocking run to be inconclusive.
526
- * One genuine violation beside a timeout is still a genuine violation, and the
527
- * operator must not be offered a rerun as the remedy for it.
528
- *
529
- * Module-private: {@link resolveAdvisoryGateVerdict} is the one door, so a
530
- * caller cannot take the class without the reason that matches it — and, being
531
- * the one door, it is also what normalises `blockingRuns` to an array, so
532
- * neither this nor {@link formatAdvisoryGateReason} re-guards the shape.
314
+ * Inconclusive only when EVERY run is. Private: the class travels with its
315
+ * reason via {@link resolveAdvisoryGateVerdict}.
533
316
  *
534
317
  * @param {Array<{ summary?: string }>} runs
535
318
  * @returns {string} one of the two advisory classes above
@@ -542,10 +325,6 @@ function deriveAdvisoryGateClass(runs) {
542
325
  }
543
326
 
544
327
  /**
545
- * Pure: the advisory gate's whole verdict — class AND the reason text that
546
- * matches it (Story #5266). One function so a caller can never pair an
547
- * inconclusive class with the violation wording.
548
- *
549
328
  * @param {{ blockingRuns?: Array<object>, rerunAllowance?: number }} [args]
550
329
  * @returns {{ blockClass: string, blockingRuns: Array<object>, reason: string }}
551
330
  */
@@ -563,22 +342,8 @@ export function resolveAdvisoryGateVerdict({
563
342
  }
564
343
 
565
344
  /**
566
- * Pure: the merge wait's advisory-gate decision, the sibling of
567
- * {@link decideMergeWaitFailFast} (Story #5096).
568
- *
569
- * Encapsulates the whole policy — the knob, the predicate, and the allowlist
570
- * projection — so the poll body carries a single assignment rather than three
571
- * decision points. `runMergePoll` sits above `check-cyclomatic`'s ceiling
572
- * already; every branch added inline there is a real regression, and this
573
- * policy has a natural home beside the predicate it consumes.
574
- *
575
- * Returns `null` when the wait should keep polling — the knob is off, the PR
576
- * is not in the advisory-red state, or every red run is allowlisted.
577
- *
578
- * The verdict it returns is provisional on the text the ROLLUP carried
579
- * (Story #5266): the caller may enrich the blocking runs with the check-run
580
- * API's output and re-resolve via {@link resolveAdvisoryGateVerdict} before
581
- * recording the block.
345
+ * `null` means keep polling. Reflects rollup text only; the caller may enrich
346
+ * and re-resolve.
582
347
  *
583
348
  * @param {object} args
584
349
  * @returns {{ blockingRuns: Array<object>, reason: string, blockClass: string } | null}
@@ -599,19 +364,6 @@ export function decideAdvisoryGateBlock({
599
364
  }
600
365
 
601
366
  /**
602
- * Format the one-line reason a `merge.unlanded` record and the operator-facing
603
- * block carry for an advisory-gate verdict, naming each offending job and its
604
- * conclusion.
605
- *
606
- * Story #5266 splits the wording by class: an unfinished job is reported as
607
- * one, because telling an operator a timed-out scan "concluded red" invites
608
- * them to grant a permanent `advisoryAllowlist` exemption for a transient
609
- * failure. Both wordings name the same three remedies — rerun, hand-merge,
610
- * allowlist — in the order proportionate to the class.
611
- *
612
- * Module-private for the same reason {@link deriveAdvisoryGateClass} is: the
613
- * class and the wording must travel together.
614
- *
615
367
  * @param {Array<{ name: string|null, conclusion: string }>} runs
616
368
  * @param {{ blockClass: string, rerunAllowance: number }} options
617
369
  * @returns {string}
@@ -652,33 +404,16 @@ function formatAdvisoryGateReason(runs, { blockClass, rerunAllowance }) {
652
404
  }
653
405
 
654
406
  /**
655
- * Pure: the merge wait's single fail-fast decision (Story #4710 — extracted
656
- * from the two near-verbatim inline blocks in `runConfirmMergePhase`'s poll
657
- * loop, beside its sibling predicates).
658
- *
659
- * Encapsulates the Story #4695 evidence policy in one place:
660
- *
661
- * - **Per-run evidence available** — decide on this single probe via
662
- * {@link requiredCheckFailedBlocksMerge}; a required run still in flight
663
- * (or only superseded / non-required noise red) resets the counter and
664
- * keeps polling.
665
- * - **Evidence unavailable** (older `gh`, API error, empty rollup) — require
666
- * TWO consecutive failing probes at least one poll interval apart, then
667
- * synthesize the evidence shape the classifier's gate reads so both paths
668
- * classify `checks-failed` through the same predicate.
669
- *
670
- * Returns the next counter value alongside the verdict; the caller owns the
671
- * mutable counter and the terminal side effects. When `failFast` is `true`,
672
- * `prProbe` is the evidence-stamped probe to hand to the classifier and
673
- * `evidencePath` names which path fired (`per-run` | `consecutive-probe`) for
674
- * the `merge.unlanded` telemetry.
407
+ * Fail-fast: decide on per-run evidence, else require two consecutive
408
+ * failing probes. The verdict is carried to the terminal, never re-derived.
675
409
  *
676
410
  * @param {object} args
677
411
  * @param {object} args.probe The current poll's {@code readPrWaitProbe} result.
678
412
  * @param {number} args.consecutiveRequiredFailSnapshots Evidence-free failing
679
413
  * probes observed so far.
680
414
  * @returns {{ failFast: boolean, consecutiveRequiredFailSnapshots: number,
681
- * prProbe?: object, evidencePath?: 'per-run'|'consecutive-probe' }}
415
+ * blockClass?: string, reason?: string, prProbe?: object,
416
+ * evidencePath?: 'per-run'|'consecutive-probe' }}
682
417
  */
683
418
  export function decideMergeWaitFailFast({
684
419
  probe,
@@ -689,37 +424,29 @@ export function decideMergeWaitFailFast({
689
424
  }
690
425
  if (probe?.requiredRunEvidence) {
691
426
  if (requiredCheckFailedBlocksMerge(probe)) {
692
- return {
693
- failFast: true,
694
- consecutiveRequiredFailSnapshots: 0,
695
- evidencePath: 'per-run',
696
- prProbe: { ...probe, evidencePath: 'per-run' },
697
- };
427
+ return checksFailedVerdict(probe, 'per-run', 0);
698
428
  }
699
- // A required run is still in flight, only non-required / superseded runs
700
- // are red, or a missing required review owns the BLOCKED state: the
701
- // protected-branch steady state, not a failure. Keep polling.
429
+ // In flight, only non-required red, or review owns BLOCKED: keep polling.
702
430
  return { failFast: false, consecutiveRequiredFailSnapshots: 0 };
703
431
  }
704
432
  const next = consecutiveRequiredFailSnapshots + 1;
705
- // Synthesize the evidence the classifier's gate reads, so the
706
- // consecutive-probe path classifies `checks-failed` through the SAME
707
- // predicate as the per-run path (including its review-required softening).
708
- const synthesized = {
709
- ...probe,
710
- requiredRunEvidence: {
711
- requiredRunFailed: true,
712
- requiredRunInFlight: false,
713
- },
714
- evidencePath: 'consecutive-probe',
715
- };
716
- if (next >= 2 && requiredCheckFailedBlocksMerge(synthesized)) {
717
- return {
718
- failFast: true,
719
- consecutiveRequiredFailSnapshots: next,
720
- evidencePath: 'consecutive-probe',
721
- prProbe: synthesized,
722
- };
433
+ if (next >= 2 && !reviewOwnsBlockedState(probe)) {
434
+ return checksFailedVerdict(probe, 'consecutive-probe', next);
723
435
  }
724
436
  return { failFast: false, consecutiveRequiredFailSnapshots: next };
725
437
  }
438
+
439
+ function checksFailedVerdict(
440
+ probe,
441
+ evidencePath,
442
+ consecutiveRequiredFailSnapshots,
443
+ ) {
444
+ return {
445
+ failFast: true,
446
+ consecutiveRequiredFailSnapshots,
447
+ evidencePath,
448
+ blockClass: CHECKS_FAILED_CLASS,
449
+ reason: formatChecksFailedReason(probe, evidencePath),
450
+ prProbe: { ...probe, evidencePath },
451
+ };
452
+ }