mandrel 2.60.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 (661) hide show
  1. package/.agents/README.md +10 -10
  2. package/.agents/agents/story-worker.md +1 -1
  3. package/.agents/docs/agentrc-reference.json +4 -82
  4. package/.agents/docs/configuration.md +20 -87
  5. package/.agents/docs/workflows.md +1 -1
  6. package/.agents/instructions.md +1 -3
  7. package/.agents/rules/gherkin-standards.md +4 -0
  8. package/.agents/schemas/agentrc.schema.json +11 -486
  9. package/.agents/schemas/story-deliver-terminal.schema.json +10 -0
  10. package/.agents/schemas/validation-evidence.schema.json +2 -1
  11. package/.agents/scripts/README.md +14 -14
  12. package/.agents/scripts/acceptance-eval.js +32 -164
  13. package/.agents/scripts/agents-bootstrap-github.js +27 -129
  14. package/.agents/scripts/apply-quality-bootstrap.js +4 -40
  15. package/.agents/scripts/audit-baselines.js +6 -27
  16. package/.agents/scripts/audit-labels-bootstrap.js +5 -29
  17. package/.agents/scripts/audit-to-stories.js +91 -361
  18. package/.agents/scripts/boot-sweep.js +19 -72
  19. package/.agents/scripts/bootstrap.js +74 -395
  20. package/.agents/scripts/ceremony-derive.js +9 -45
  21. package/.agents/scripts/check-arch-cycles.js +14 -64
  22. package/.agents/scripts/check-baselines.js +8 -48
  23. package/.agents/scripts/check-context-budget.js +46 -172
  24. package/.agents/scripts/check-cyclomatic.js +12 -44
  25. package/.agents/scripts/check-dead-exports.js +13 -64
  26. package/.agents/scripts/check-doc-links.js +38 -186
  27. package/.agents/scripts/check-gherkin-corpus.js +24 -127
  28. package/.agents/scripts/check-test-temp-hygiene.js +28 -169
  29. package/.agents/scripts/coverage-capture.js +32 -99
  30. package/.agents/scripts/deliver-light.js +14 -101
  31. package/.agents/scripts/deliver-recover.js +6 -42
  32. package/.agents/scripts/deliver-run.js +36 -133
  33. package/.agents/scripts/diagnose-friction.js +24 -116
  34. package/.agents/scripts/drain-pending-cleanup.js +1 -1
  35. package/.agents/scripts/evidence-gate.js +23 -85
  36. package/.agents/scripts/file-ci-gap.js +10 -50
  37. package/.agents/scripts/generate-config-docs.js +30 -170
  38. package/.agents/scripts/generate-lens-checklists.js +8 -52
  39. package/.agents/scripts/generate-skills-index.js +14 -112
  40. package/.agents/scripts/generate-workflows-doc.js +10 -70
  41. package/.agents/scripts/git-cleanup.js +2 -34
  42. package/.agents/scripts/lib/Graph.js +24 -81
  43. package/.agents/scripts/lib/ITicketingProvider.js +47 -143
  44. package/.agents/scripts/lib/Logger.js +14 -76
  45. package/.agents/scripts/lib/audit-baselines/engine.js +11 -31
  46. package/.agents/scripts/lib/audit-baselines/gate-surface.js +3 -17
  47. package/.agents/scripts/lib/audit-baselines/headroom.js +4 -20
  48. package/.agents/scripts/lib/audit-baselines/hotspots.js +3 -15
  49. package/.agents/scripts/lib/audit-baselines/kinds.js +23 -89
  50. package/.agents/scripts/lib/audit-baselines/outliers.js +6 -23
  51. package/.agents/scripts/lib/audit-baselines/read.js +3 -16
  52. package/.agents/scripts/lib/audit-baselines/staleness.js +7 -26
  53. package/.agents/scripts/lib/audit-baselines/surface-entry.js +7 -28
  54. package/.agents/scripts/lib/audit-baselines/trend.js +7 -20
  55. package/.agents/scripts/lib/audit-baselines/weights.js +9 -37
  56. package/.agents/scripts/lib/audit-suite/audit-rules-reader.js +3 -18
  57. package/.agents/scripts/lib/audit-suite/checklist-threading.js +26 -124
  58. package/.agents/scripts/lib/audit-suite/dispatch-checklist.js +14 -45
  59. package/.agents/scripts/lib/audit-suite/findings.js +12 -52
  60. package/.agents/scripts/lib/audit-suite/frontmatter.js +5 -29
  61. package/.agents/scripts/lib/audit-suite/index.js +1 -15
  62. package/.agents/scripts/lib/audit-suite/lens-checklist.js +10 -45
  63. package/.agents/scripts/lib/audit-suite/lens-diff-floor.js +11 -76
  64. package/.agents/scripts/lib/audit-suite/runner.js +13 -43
  65. package/.agents/scripts/lib/audit-suite/selector.js +49 -349
  66. package/.agents/scripts/lib/audit-suite/substitutions.js +12 -40
  67. package/.agents/scripts/lib/audit-suite/workflow-loader.js +3 -15
  68. package/.agents/scripts/lib/audit-to-stories/audit-label-taxonomy.js +11 -73
  69. package/.agents/scripts/lib/audit-to-stories/audit-lenses.js +8 -37
  70. package/.agents/scripts/lib/audit-to-stories/build-story-body.js +25 -143
  71. package/.agents/scripts/lib/audit-to-stories/dedupe-against-github.js +14 -80
  72. package/.agents/scripts/lib/audit-to-stories/epic-grouping-directive.js +4 -18
  73. package/.agents/scripts/lib/audit-to-stories/finding-adapter.js +7 -40
  74. package/.agents/scripts/lib/audit-to-stories/group-findings.js +9 -39
  75. package/.agents/scripts/lib/audit-to-stories/issue-corpus.js +10 -66
  76. package/.agents/scripts/lib/audit-to-stories/issue-index.js +6 -30
  77. package/.agents/scripts/lib/audit-to-stories/issues-file.js +6 -36
  78. package/.agents/scripts/lib/audit-to-stories/ledger-commit.js +17 -69
  79. package/.agents/scripts/lib/audit-to-stories/ledger-pr.js +17 -85
  80. package/.agents/scripts/lib/audit-to-stories/ledger-record.js +10 -48
  81. package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +38 -146
  82. package/.agents/scripts/lib/audit-to-stories/seed-from-findings.js +7 -42
  83. package/.agents/scripts/lib/audit-to-stories/wire-dependencies.js +10 -57
  84. package/.agents/scripts/lib/baseline-loader.js +12 -51
  85. package/.agents/scripts/lib/baseline-schema-registry.js +5 -22
  86. package/.agents/scripts/lib/baselines/component-matcher.js +3 -12
  87. package/.agents/scripts/lib/baselines/components.js +10 -61
  88. package/.agents/scripts/lib/baselines/coverage-updater-cli.js +7 -36
  89. package/.agents/scripts/lib/baselines/crap-preview-incremental.js +5 -21
  90. package/.agents/scripts/lib/baselines/crap-preview-scan.js +19 -45
  91. package/.agents/scripts/lib/baselines/crap-updater-cli.js +16 -65
  92. package/.agents/scripts/lib/baselines/diff-scope-cli.js +5 -33
  93. package/.agents/scripts/lib/baselines/duplication-scanner.js +11 -60
  94. package/.agents/scripts/lib/baselines/env-overrides.js +12 -67
  95. package/.agents/scripts/lib/baselines/envelope.js +13 -129
  96. package/.agents/scripts/lib/baselines/exit-codes.js +6 -49
  97. package/.agents/scripts/lib/baselines/git-base.js +23 -142
  98. package/.agents/scripts/lib/baselines/kernel.js +11 -111
  99. package/.agents/scripts/lib/baselines/kinds/_crap-new-method-gate.js +9 -47
  100. package/.agents/scripts/lib/baselines/kinds/_crap-read.js +8 -51
  101. package/.agents/scripts/lib/baselines/kinds/_shared-metric.js +7 -62
  102. package/.agents/scripts/lib/baselines/kinds/bundle-size.js +8 -29
  103. package/.agents/scripts/lib/baselines/kinds/coverage.js +3 -15
  104. package/.agents/scripts/lib/baselines/kinds/crap.js +94 -415
  105. package/.agents/scripts/lib/baselines/kinds/duplication.js +4 -30
  106. package/.agents/scripts/lib/baselines/kinds/kind-factory.js +7 -53
  107. package/.agents/scripts/lib/baselines/kinds/maintainability.js +15 -80
  108. package/.agents/scripts/lib/baselines/kinds/mutation.js +12 -72
  109. package/.agents/scripts/lib/baselines/maintainability-baseline-io.js +4 -11
  110. package/.agents/scripts/lib/baselines/merge-envelopes.js +30 -146
  111. package/.agents/scripts/lib/baselines/path-canon.js +19 -128
  112. package/.agents/scripts/lib/baselines/preview-gates.js +8 -37
  113. package/.agents/scripts/lib/baselines/reader.js +14 -107
  114. package/.agents/scripts/lib/baselines/refresh-service.js +35 -252
  115. package/.agents/scripts/lib/baselines/scope.js +11 -135
  116. package/.agents/scripts/lib/baselines/writer.js +16 -149
  117. package/.agents/scripts/lib/bdd-runner-detect.js +18 -113
  118. package/.agents/scripts/lib/bdd-scenario-budget.js +9 -36
  119. package/.agents/scripts/lib/bdd-scenario-scanner.js +11 -73
  120. package/.agents/scripts/lib/bdd-step-index.js +26 -100
  121. package/.agents/scripts/lib/bootstrap/baseline-merge-driver.js +23 -103
  122. package/.agents/scripts/lib/bootstrap/branch-protection.js +2 -5
  123. package/.agents/scripts/lib/bootstrap/commit-push.js +12 -50
  124. package/.agents/scripts/lib/bootstrap/gh-preflight.js +14 -101
  125. package/.agents/scripts/lib/bootstrap/hitl-confirm.js +5 -30
  126. package/.agents/scripts/lib/bootstrap/install-ledger.js +17 -73
  127. package/.agents/scripts/lib/bootstrap/issue-forms-template.js +17 -121
  128. package/.agents/scripts/lib/bootstrap/manifest.js +15 -86
  129. package/.agents/scripts/lib/bootstrap/merge-methods.js +4 -33
  130. package/.agents/scripts/lib/bootstrap/preflight.js +12 -61
  131. package/.agents/scripts/lib/bootstrap/project-bootstrap.js +34 -235
  132. package/.agents/scripts/lib/bootstrap/prompt.js +21 -129
  133. package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +27 -141
  134. package/.agents/scripts/lib/bootstrap/summary.js +1 -8
  135. package/.agents/scripts/lib/bootstrap/workflow-audit.js +11 -84
  136. package/.agents/scripts/lib/branch-name-guard.js +4 -23
  137. package/.agents/scripts/lib/changed-files.js +31 -143
  138. package/.agents/scripts/lib/checks/core-bare-clean.js +4 -24
  139. package/.agents/scripts/lib/checks/index.js +18 -101
  140. package/.agents/scripts/lib/checks/loop-health.js +11 -53
  141. package/.agents/scripts/lib/checks/state.js +16 -91
  142. package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +10 -61
  143. package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +14 -83
  144. package/.agents/scripts/lib/child-exec.js +39 -108
  145. package/.agents/scripts/lib/cli/standard-args.js +9 -116
  146. package/.agents/scripts/lib/cli-args.js +31 -146
  147. package/.agents/scripts/lib/cli-usage.js +5 -27
  148. package/.agents/scripts/lib/cli-utils.js +2 -12
  149. package/.agents/scripts/lib/close-validation/commands.js +13 -76
  150. package/.agents/scripts/lib/close-validation/gates.js +92 -331
  151. package/.agents/scripts/lib/close-validation/process.js +121 -151
  152. package/.agents/scripts/lib/close-validation/projections/advisories.js +5 -31
  153. package/.agents/scripts/lib/close-validation/projections/crap.js +19 -67
  154. package/.agents/scripts/lib/close-validation/projections/head-sha.js +1 -17
  155. package/.agents/scripts/lib/close-validation/projections/inputs.js +4 -34
  156. package/.agents/scripts/lib/close-validation/projections/maintainability.js +11 -58
  157. package/.agents/scripts/lib/close-validation/runner.js +53 -110
  158. package/.agents/scripts/lib/command-header.js +6 -28
  159. package/.agents/scripts/lib/config/acceptance-eval.js +4 -30
  160. package/.agents/scripts/lib/config/baselines.js +3 -14
  161. package/.agents/scripts/lib/config/ci.js +8 -38
  162. package/.agents/scripts/lib/config/commands.js +1 -15
  163. package/.agents/scripts/lib/config/defaults.js +4 -33
  164. package/.agents/scripts/lib/config/delivery-routing.js +6 -35
  165. package/.agents/scripts/lib/config/explain.js +9 -80
  166. package/.agents/scripts/lib/config/gates/coverage.schema.js +0 -12
  167. package/.agents/scripts/lib/config/gates/crap-incremental-coverage.schema.js +2 -30
  168. package/.agents/scripts/lib/config/gates/crap.schema.js +1 -34
  169. package/.agents/scripts/lib/config/gates/duplication.schema.js +1 -8
  170. package/.agents/scripts/lib/config/gates/index.js +2 -17
  171. package/.agents/scripts/lib/config/gates/maintainability.schema.js +1 -20
  172. package/.agents/scripts/lib/config/gates/mutation.schema.js +1 -7
  173. package/.agents/scripts/lib/config/gates/shared.js +4 -64
  174. package/.agents/scripts/lib/config/github.js +4 -22
  175. package/.agents/scripts/lib/config/limits.js +4 -57
  176. package/.agents/scripts/lib/config/paths.js +2 -21
  177. package/.agents/scripts/lib/config/qa.js +4 -38
  178. package/.agents/scripts/lib/config/quality.js +76 -432
  179. package/.agents/scripts/lib/config/runners.js +12 -56
  180. package/.agents/scripts/lib/config/runtime.js +13 -57
  181. package/.agents/scripts/lib/config/shared.js +2 -16
  182. package/.agents/scripts/lib/config/sync-agentrc.js +9 -50
  183. package/.agents/scripts/lib/config/temp-paths.js +40 -280
  184. package/.agents/scripts/lib/config/validate-orchestration.js +5 -17
  185. package/.agents/scripts/lib/config/worktree-isolation.js +9 -28
  186. package/.agents/scripts/lib/config-resolver.js +10 -52
  187. package/.agents/scripts/lib/config-schema-shared.js +1 -4
  188. package/.agents/scripts/lib/config-settings-schema-delivery.js +12 -294
  189. package/.agents/scripts/lib/config-settings-schema-quality.js +7 -219
  190. package/.agents/scripts/lib/config-settings-schema.js +37 -274
  191. package/.agents/scripts/lib/coverage-baseline.js +20 -110
  192. package/.agents/scripts/lib/coverage-capture-fullscope.js +12 -37
  193. package/.agents/scripts/lib/coverage-capture-incremental.js +12 -43
  194. package/.agents/scripts/lib/coverage-capture-usage.js +4 -24
  195. package/.agents/scripts/lib/coverage-capture.js +99 -224
  196. package/.agents/scripts/lib/coverage-utils.js +14 -79
  197. package/.agents/scripts/lib/cpu-pool.js +17 -123
  198. package/.agents/scripts/lib/crap-baseline-join.js +16 -88
  199. package/.agents/scripts/lib/crap-coordinates.js +6 -25
  200. package/.agents/scripts/lib/crap-engine.js +40 -153
  201. package/.agents/scripts/lib/crap-method-identity.js +16 -78
  202. package/.agents/scripts/lib/crap-utils.js +31 -155
  203. package/.agents/scripts/lib/cyclomatic-ceiling.js +14 -87
  204. package/.agents/scripts/lib/cyclomatic-scope.js +10 -50
  205. package/.agents/scripts/lib/dead-exports-knip.js +18 -56
  206. package/.agents/scripts/lib/dead-exports-mode.js +5 -24
  207. package/.agents/scripts/lib/degraded-mode.js +3 -26
  208. package/.agents/scripts/lib/dependency-parser.js +8 -40
  209. package/.agents/scripts/lib/dependency-version.js +13 -35
  210. package/.agents/scripts/lib/detect-package-manager.js +6 -36
  211. package/.agents/scripts/lib/doc-tiers.js +22 -126
  212. package/.agents/scripts/lib/duplicate-search.js +8 -72
  213. package/.agents/scripts/lib/env-loader.js +5 -27
  214. package/.agents/scripts/lib/error-redactor.js +6 -31
  215. package/.agents/scripts/lib/errors/index.js +2 -22
  216. package/.agents/scripts/lib/escomplex-ast-compat.js +22 -163
  217. package/.agents/scripts/lib/escomplex-kernel.js +21 -123
  218. package/.agents/scripts/lib/feedback-loop/graduator-core.js +93 -419
  219. package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +20 -98
  220. package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +27 -151
  221. package/.agents/scripts/lib/findings/audit-ledger.js +23 -97
  222. package/.agents/scripts/lib/findings/classify-finding.js +14 -69
  223. package/.agents/scripts/lib/findings/promote-finding.js +14 -112
  224. package/.agents/scripts/lib/findings/provenance-field.js +11 -52
  225. package/.agents/scripts/lib/findings/route-finding.js +37 -255
  226. package/.agents/scripts/lib/findings/semantic-issue-search.js +14 -59
  227. package/.agents/scripts/lib/findings/severity.js +18 -104
  228. package/.agents/scripts/lib/format-generated-json.js +12 -44
  229. package/.agents/scripts/lib/full-suite-lock.js +160 -429
  230. package/.agents/scripts/lib/full-suite-queue.js +213 -0
  231. package/.agents/scripts/lib/gates/baseline-store.js +5 -9
  232. package/.agents/scripts/lib/gates/friction.js +1 -3
  233. package/.agents/scripts/lib/generated/agentrc-validator.js +2 -2
  234. package/.agents/scripts/lib/gh-exec.js +31 -259
  235. package/.agents/scripts/lib/git/cached-fetch.js +9 -52
  236. package/.agents/scripts/lib/git/sync-from-base.js +15 -107
  237. package/.agents/scripts/lib/git-branch-cleanup.js +14 -61
  238. package/.agents/scripts/lib/git-branch-lifecycle.js +16 -87
  239. package/.agents/scripts/lib/git-utils.js +37 -161
  240. package/.agents/scripts/lib/github/framework-repo.js +8 -71
  241. package/.agents/scripts/lib/github-url.js +2 -17
  242. package/.agents/scripts/lib/import-graph.js +11 -38
  243. package/.agents/scripts/lib/install-cmd-parser.js +4 -13
  244. package/.agents/scripts/lib/json-utils.js +3 -18
  245. package/.agents/scripts/lib/label-constants.js +16 -111
  246. package/.agents/scripts/lib/label-taxonomy.js +4 -30
  247. package/.agents/scripts/lib/maintainability-engine.js +12 -80
  248. package/.agents/scripts/lib/maintainability-unscorable.js +5 -25
  249. package/.agents/scripts/lib/maintainability-utils.js +16 -92
  250. package/.agents/scripts/lib/mandrel-catalog.js +12 -70
  251. package/.agents/scripts/lib/notifications/notifier.js +13 -38
  252. package/.agents/scripts/lib/npm-scripts.js +4 -23
  253. package/.agents/scripts/lib/observability/metrics-ledger.js +16 -76
  254. package/.agents/scripts/lib/observability/runtime-friction.js +44 -286
  255. package/.agents/scripts/lib/observability/signal-validator.js +5 -37
  256. package/.agents/scripts/lib/observability/signals-writer.js +11 -121
  257. package/.agents/scripts/lib/observability/source-classifier.js +21 -203
  258. package/.agents/scripts/lib/observability/terse-result.js +14 -47
  259. package/.agents/scripts/lib/onboard/init-tail.js +13 -74
  260. package/.agents/scripts/lib/onboard/scaffold-docs.js +11 -34
  261. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +25 -139
  262. package/.agents/scripts/lib/orchestration/auto-merge-cwd.js +11 -66
  263. package/.agents/scripts/lib/orchestration/behind-recovery.js +10 -55
  264. package/.agents/scripts/lib/orchestration/ceremony-routing.js +5 -75
  265. package/.agents/scripts/lib/orchestration/change-set.js +7 -36
  266. package/.agents/scripts/lib/orchestration/check-baselines/phases/compare.js +9 -46
  267. package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +11 -44
  268. package/.agents/scripts/lib/orchestration/check-baselines/phases/floors.js +5 -24
  269. package/.agents/scripts/lib/orchestration/check-baselines/phases/friction.js +3 -12
  270. package/.agents/scripts/lib/orchestration/check-baselines/phases/parse-args.js +5 -38
  271. package/.agents/scripts/lib/orchestration/check-baselines/phases/pipeline.js +3 -8
  272. package/.agents/scripts/lib/orchestration/check-baselines/phases/refresh-ack.js +28 -136
  273. package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +3 -13
  274. package/.agents/scripts/lib/orchestration/check-state.js +92 -0
  275. package/.agents/scripts/lib/orchestration/ci-gap-intake.js +37 -144
  276. package/.agents/scripts/lib/orchestration/ci-rerun-guard.js +42 -189
  277. package/.agents/scripts/lib/orchestration/code-review.js +24 -128
  278. package/.agents/scripts/lib/orchestration/column-sync.js +23 -111
  279. package/.agents/scripts/lib/orchestration/complexity-gate.js +42 -214
  280. package/.agents/scripts/lib/orchestration/deliver-recover.js +36 -168
  281. package/.agents/scripts/lib/orchestration/dependency-analyzer.js +4 -35
  282. package/.agents/scripts/lib/orchestration/dependency-candidates.js +9 -41
  283. package/.agents/scripts/lib/orchestration/diff-magnitude.js +25 -115
  284. package/.agents/scripts/lib/orchestration/doc-reader.js +2 -6
  285. package/.agents/scripts/lib/orchestration/docs-digest.js +13 -51
  286. package/.agents/scripts/lib/orchestration/epic-candidates.js +13 -53
  287. package/.agents/scripts/lib/orchestration/epic-checklist.js +9 -33
  288. package/.agents/scripts/lib/orchestration/epic-container.js +41 -167
  289. package/.agents/scripts/lib/orchestration/epic-expansion.js +10 -40
  290. package/.agents/scripts/lib/orchestration/epic-rollup.js +55 -207
  291. package/.agents/scripts/lib/orchestration/file-assumption-enum.js +2 -22
  292. package/.agents/scripts/lib/orchestration/file-assumptions.js +45 -253
  293. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-detect.js +9 -46
  294. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-reap.js +7 -57
  295. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches.js +21 -126
  296. package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +2 -6
  297. package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +1 -4
  298. package/.agents/scripts/lib/orchestration/git-cleanup/phases/filters.js +1 -5
  299. package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes-ff.js +9 -34
  300. package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes.js +41 -190
  301. package/.agents/scripts/lib/orchestration/git-cleanup/phases/merged-tip.js +9 -45
  302. package/.agents/scripts/lib/orchestration/git-cleanup/phases/parse-args.js +1 -4
  303. package/.agents/scripts/lib/orchestration/git-cleanup/phases/phase-drivers.js +19 -85
  304. package/.agents/scripts/lib/orchestration/git-cleanup/phases/prompts.js +3 -17
  305. package/.agents/scripts/lib/orchestration/git-cleanup/phases/prune.js +1 -5
  306. package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +16 -100
  307. package/.agents/scripts/lib/orchestration/git-cleanup/phases/stashes.js +1 -4
  308. package/.agents/scripts/lib/orchestration/lease-guard-shared.js +16 -67
  309. package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +9 -33
  310. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +8 -29
  311. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +15 -68
  312. package/.agents/scripts/lib/orchestration/light-backstop.js +11 -49
  313. package/.agents/scripts/lib/orchestration/light-escalation.js +21 -89
  314. package/.agents/scripts/lib/orchestration/light-suitability.js +26 -231
  315. package/.agents/scripts/lib/orchestration/merge-block-class.js +39 -216
  316. package/.agents/scripts/lib/orchestration/merge-poll.js +104 -377
  317. package/.agents/scripts/lib/orchestration/pinned-identifier-lint.js +17 -57
  318. package/.agents/scripts/lib/orchestration/plan-context.js +52 -303
  319. package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +22 -79
  320. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +5 -31
  321. package/.agents/scripts/lib/orchestration/plan-metrics.js +29 -108
  322. package/.agents/scripts/lib/orchestration/plan-navigation.js +8 -27
  323. package/.agents/scripts/lib/orchestration/plan-persist/acceptance-handle-repair.js +12 -49
  324. package/.agents/scripts/lib/orchestration/plan-persist/audit-provenance.js +18 -73
  325. package/.agents/scripts/lib/orchestration/plan-persist/changes-repair.js +14 -78
  326. package/.agents/scripts/lib/orchestration/plan-persist/cross-plan-links.js +6 -30
  327. package/.agents/scripts/lib/orchestration/plan-persist/epic-adoption.js +14 -65
  328. package/.agents/scripts/lib/orchestration/plan-persist/epic-ops.js +21 -76
  329. package/.agents/scripts/lib/orchestration/plan-persist/external-deps.js +6 -43
  330. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +14 -68
  331. package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +9 -41
  332. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +49 -248
  333. package/.agents/scripts/lib/orchestration/plan-persist/soft-findings.js +2 -12
  334. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +85 -368
  335. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +8 -38
  336. package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +30 -190
  337. package/.agents/scripts/lib/orchestration/plan-persist/wave-collision-gate.js +9 -49
  338. package/.agents/scripts/lib/orchestration/plan-persist/wave-serialisation.js +7 -28
  339. package/.agents/scripts/lib/orchestration/plan-reachability.js +13 -42
  340. package/.agents/scripts/lib/orchestration/plan-run-labels/reap.js +16 -91
  341. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +16 -54
  342. package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +10 -52
  343. package/.agents/scripts/lib/orchestration/planning/authoring-context.js +14 -109
  344. package/.agents/scripts/lib/orchestration/planning/memory-pool-advisory.js +11 -83
  345. package/.agents/scripts/lib/orchestration/pr-watch.js +48 -306
  346. package/.agents/scripts/lib/orchestration/project-meta-cache.js +15 -80
  347. package/.agents/scripts/lib/orchestration/project-meta-resolver.js +10 -51
  348. package/.agents/scripts/lib/orchestration/reassert-status-column.js +12 -76
  349. package/.agents/scripts/lib/orchestration/remote-verifier.js +12 -36
  350. package/.agents/scripts/lib/orchestration/resolve-stories.js +33 -164
  351. package/.agents/scripts/lib/orchestration/retro-proposals.js +66 -361
  352. package/.agents/scripts/lib/orchestration/review-base-ref.js +9 -43
  353. package/.agents/scripts/lib/orchestration/review-depth.js +12 -94
  354. package/.agents/scripts/lib/orchestration/review-providers/codex.js +10 -111
  355. package/.agents/scripts/lib/orchestration/review-providers/degraded-gates.js +13 -71
  356. package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +7 -51
  357. package/.agents/scripts/lib/orchestration/review-providers/mi-exemptions.js +8 -53
  358. package/.agents/scripts/lib/orchestration/review-providers/native.js +30 -214
  359. package/.agents/scripts/lib/orchestration/review-providers/parse-findings.js +7 -52
  360. package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +4 -33
  361. package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +11 -71
  362. package/.agents/scripts/lib/orchestration/review-providers/scoped-lint.js +19 -131
  363. package/.agents/scripts/lib/orchestration/review-providers/security-review.js +6 -89
  364. package/.agents/scripts/lib/orchestration/review-providers/types.js +26 -56
  365. package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +3 -46
  366. package/.agents/scripts/lib/orchestration/run-epilogue.js +40 -199
  367. package/.agents/scripts/lib/orchestration/run-scoped-config.js +13 -81
  368. package/.agents/scripts/lib/orchestration/single-story-close/close-note.js +7 -34
  369. package/.agents/scripts/lib/orchestration/single-story-close/failed-terminal.js +16 -89
  370. package/.agents/scripts/lib/orchestration/single-story-close/gate-log.js +18 -109
  371. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +83 -239
  372. package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +18 -80
  373. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +103 -97
  374. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +8 -64
  375. package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +136 -486
  376. package/.agents/scripts/lib/orchestration/single-story-close/phases/conventional-subject.js +30 -134
  377. package/.agents/scripts/lib/orchestration/single-story-close/phases/graphql-preflight.js +9 -50
  378. package/.agents/scripts/lib/orchestration/single-story-close/phases/lock-wait-pending.js +49 -0
  379. package/.agents/scripts/lib/orchestration/single-story-close/phases/normalize-pr-title.js +13 -86
  380. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +20 -95
  381. package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +46 -203
  382. package/.agents/scripts/lib/orchestration/single-story-close/phases/pre-gate-steps.js +8 -50
  383. package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +12 -83
  384. package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +6 -39
  385. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +1 -6
  386. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-outcome.js +4 -28
  387. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-override.js +6 -51
  388. package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +6 -34
  389. package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +23 -121
  390. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +110 -290
  391. package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +15 -69
  392. package/.agents/scripts/lib/orchestration/story-body-gate.js +4 -23
  393. package/.agents/scripts/lib/orchestration/story-close/baseline-upward-writeback.js +50 -179
  394. package/.agents/scripts/lib/orchestration/story-close/context-budget-writeback.js +11 -41
  395. package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +23 -311
  396. package/.agents/scripts/lib/orchestration/story-close/phases/local-lens-review.js +22 -147
  397. package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +16 -67
  398. package/.agents/scripts/lib/orchestration/story-deliver-terminal-schema.js +12 -68
  399. package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +42 -201
  400. package/.agents/scripts/lib/orchestration/story-follow-ups.js +43 -245
  401. package/.agents/scripts/lib/orchestration/story-init-envelope.js +4 -23
  402. package/.agents/scripts/lib/orchestration/story-init-remote.js +2 -6
  403. package/.agents/scripts/lib/orchestration/story-reachability.js +3 -23
  404. package/.agents/scripts/lib/orchestration/task-body-validator.js +12 -126
  405. package/.agents/scripts/lib/orchestration/ticket-lease.js +28 -131
  406. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +15 -149
  407. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +5 -33
  408. package/.agents/scripts/lib/orchestration/ticket-validator.js +39 -181
  409. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +51 -244
  410. package/.agents/scripts/lib/orchestration/ticketing/reads.js +39 -250
  411. package/.agents/scripts/lib/orchestration/ticketing/state.js +14 -68
  412. package/.agents/scripts/lib/orchestration/ticketing/transition.js +46 -263
  413. package/.agents/scripts/lib/orchestration/ticketing.js +2 -26
  414. package/.agents/scripts/lib/orchestration/verify-credit.js +18 -79
  415. package/.agents/scripts/lib/orchestration/worktree-dirty.js +5 -30
  416. package/.agents/scripts/lib/path-security.js +3 -6
  417. package/.agents/scripts/lib/plan-phase-cleanup.js +9 -49
  418. package/.agents/scripts/lib/preflight-runner.js +13 -69
  419. package/.agents/scripts/lib/process-group.js +143 -0
  420. package/.agents/scripts/lib/project-root.js +2 -8
  421. package/.agents/scripts/lib/provider-factory.js +2 -25
  422. package/.agents/scripts/lib/qa/console-allowlist.js +10 -59
  423. package/.agents/scripts/lib/qa/qa-session.js +15 -69
  424. package/.agents/scripts/lib/qa/redact-evidence.js +18 -129
  425. package/.agents/scripts/lib/qa/resolve-qa-contract.js +26 -135
  426. package/.agents/scripts/lib/qa/resolve-selection.js +16 -84
  427. package/.agents/scripts/lib/reserved-test-ids.js +9 -47
  428. package/.agents/scripts/lib/runtime-deps/dep-resolution.js +13 -53
  429. package/.agents/scripts/lib/runtime-deps/ensure-installed.js +10 -44
  430. package/.agents/scripts/lib/runtime-deps/manifest.js +10 -30
  431. package/.agents/scripts/lib/runtime-deps/parser-major.js +15 -51
  432. package/.agents/scripts/lib/runtime-deps/preflight.js +4 -22
  433. package/.agents/scripts/lib/runtime-deps/scan-imports.js +11 -55
  434. package/.agents/scripts/lib/signals/detectors/common.js +12 -38
  435. package/.agents/scripts/lib/signals/index.js +2 -19
  436. package/.agents/scripts/lib/signals/schema.js +14 -109
  437. package/.agents/scripts/lib/signals/write.js +2 -11
  438. package/.agents/scripts/lib/single-story/confirm-merge.js +31 -72
  439. package/.agents/scripts/lib/single-story/story-merged-notify.js +8 -49
  440. package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +4 -26
  441. package/.agents/scripts/lib/single-story-sweep/protection.js +13 -100
  442. package/.agents/scripts/lib/single-story-sweep/sweep-lock.js +60 -258
  443. package/.agents/scripts/lib/single-story-sweep.js +14 -97
  444. package/.agents/scripts/lib/skills/parse-skill.js +13 -59
  445. package/.agents/scripts/lib/skills/skills-index.js +8 -29
  446. package/.agents/scripts/lib/skills/walk-skill-files.js +17 -78
  447. package/.agents/scripts/lib/source-extensions.js +11 -42
  448. package/.agents/scripts/lib/source-text/strip-js-comments.js +8 -41
  449. package/.agents/scripts/lib/stdio-flush.js +9 -36
  450. package/.agents/scripts/lib/story-adjacency.js +8 -40
  451. package/.agents/scripts/lib/story-body/body-format-lints.js +22 -83
  452. package/.agents/scripts/lib/story-body/footer-block.js +11 -44
  453. package/.agents/scripts/lib/story-body/story-body.js +83 -358
  454. package/.agents/scripts/lib/temp-retention.js +42 -143
  455. package/.agents/scripts/lib/templates/decomposer-prompts.js +11 -65
  456. package/.agents/scripts/lib/test-env.js +12 -65
  457. package/.agents/scripts/lib/test-run-credit.js +10 -65
  458. package/.agents/scripts/lib/test-runner-contract.js +19 -74
  459. package/.agents/scripts/lib/test-temp.js +38 -184
  460. package/.agents/scripts/lib/test-tiers.js +12 -96
  461. package/.agents/scripts/lib/ticket-body-sections.js +21 -96
  462. package/.agents/scripts/lib/transpile.js +15 -74
  463. package/.agents/scripts/lib/util/concurrent-map.js +6 -25
  464. package/.agents/scripts/lib/util/parse-id-list.js +8 -34
  465. package/.agents/scripts/lib/util/poll-loop.js +8 -28
  466. package/.agents/scripts/lib/util/with-timeout.js +2 -11
  467. package/.agents/scripts/lib/validation-evidence.js +21 -96
  468. package/.agents/scripts/lib/wave-runner/footprint.js +17 -70
  469. package/.agents/scripts/lib/wave-runner/live-probe.js +53 -221
  470. package/.agents/scripts/lib/wave-runner/ready-set.js +72 -301
  471. package/.agents/scripts/lib/workers/crap-worker.js +11 -64
  472. package/.agents/scripts/lib/workers/maintainability-report-worker.js +8 -45
  473. package/.agents/scripts/lib/workers/maintainability-worker.js +5 -21
  474. package/.agents/scripts/lib/workers/serve-worker-messages.js +2 -18
  475. package/.agents/scripts/lib/workflow-closure.js +22 -105
  476. package/.agents/scripts/lib/workspace-provisioner.js +16 -54
  477. package/.agents/scripts/lib/worktree/git-hooks.js +15 -60
  478. package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +20 -60
  479. package/.agents/scripts/lib/worktree/lifecycle/merge-reachability.js +10 -62
  480. package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +22 -86
  481. package/.agents/scripts/lib/worktree/lifecycle/reap.js +24 -126
  482. package/.agents/scripts/lib/worktree/lifecycle-manager.js +2 -20
  483. package/.agents/scripts/lib/worktree/node-modules-strategy.js +46 -180
  484. package/.agents/scripts/lib/worktree-manager.js +15 -40
  485. package/.agents/scripts/lint-issue-body.js +12 -68
  486. package/.agents/scripts/mandrel-update-preflight.js +10 -70
  487. package/.agents/scripts/merge-baseline.js +30 -104
  488. package/.agents/scripts/nav-registry-diff.js +22 -108
  489. package/.agents/scripts/notify.js +12 -69
  490. package/.agents/scripts/plan-context.js +27 -111
  491. package/.agents/scripts/plan-critics.js +12 -66
  492. package/.agents/scripts/plan-persist.js +31 -148
  493. package/.agents/scripts/plan-run-epilogue.js +11 -37
  494. package/.agents/scripts/pr-watch-with-update.js +76 -267
  495. package/.agents/scripts/providers/github/auth.js +3 -8
  496. package/.agents/scripts/providers/github/blocked-by-add.js +14 -61
  497. package/.agents/scripts/providers/github/board-add.js +5 -21
  498. package/.agents/scripts/providers/github/branch-protection.js +11 -43
  499. package/.agents/scripts/providers/github/cache.js +2 -14
  500. package/.agents/scripts/providers/github/comments.js +7 -40
  501. package/.agents/scripts/providers/github/compose.js +3 -19
  502. package/.agents/scripts/providers/github/errors.js +22 -125
  503. package/.agents/scripts/providers/github/issues.js +31 -123
  504. package/.agents/scripts/providers/github/labels.js +24 -124
  505. package/.agents/scripts/providers/github/mappers.js +5 -27
  506. package/.agents/scripts/providers/github/merge-methods.js +3 -22
  507. package/.agents/scripts/providers/github/project-board.js +2 -17
  508. package/.agents/scripts/providers/github/projects-v2-graphql.js +3 -6
  509. package/.agents/scripts/providers/github/request-helpers.js +5 -32
  510. package/.agents/scripts/providers/github/search-budget.js +9 -39
  511. package/.agents/scripts/providers/github/search-query.js +5 -26
  512. package/.agents/scripts/providers/github/sub-issue-add.js +15 -65
  513. package/.agents/scripts/providers/github/sub-issues.js +7 -36
  514. package/.agents/scripts/providers/github/tickets.js +32 -134
  515. package/.agents/scripts/providers/github.js +18 -59
  516. package/.agents/scripts/prune-plan-run-labels.js +12 -46
  517. package/.agents/scripts/quality-preview.js +35 -220
  518. package/.agents/scripts/resolve-doc-tiers.js +3 -26
  519. package/.agents/scripts/resolve-stories.js +16 -67
  520. package/.agents/scripts/resync-status-column.js +6 -25
  521. package/.agents/scripts/run-tests.js +29 -104
  522. package/.agents/scripts/single-story-close.js +23 -135
  523. package/.agents/scripts/single-story-confirm-merge.js +32 -139
  524. package/.agents/scripts/single-story-init.js +47 -209
  525. package/.agents/scripts/stories-wave-tick.js +102 -472
  526. package/.agents/scripts/sync-agentrc.js +3 -21
  527. package/.agents/scripts/sync-claude-agents.js +9 -55
  528. package/.agents/scripts/sync-claude-commands.js +20 -110
  529. package/.agents/scripts/test-wrapper.js +6 -43
  530. package/.agents/scripts/update-coverage-baseline.js +5 -22
  531. package/.agents/scripts/update-crap-baseline.js +7 -30
  532. package/.agents/scripts/update-duplication-baseline.js +16 -92
  533. package/.agents/scripts/update-maintainability-baseline.js +8 -62
  534. package/.agents/scripts/update-ticket-state.js +1 -7
  535. package/.agents/scripts/validate-skills.js +6 -26
  536. package/.agents/templates/agent-protocol.md +2 -2
  537. package/.agents/templates/docs/audit-sweep-runbook.md +3 -4
  538. package/.agents/workflows/audit-accessibility.md +4 -7
  539. package/.agents/workflows/audit-adrs.md +3 -6
  540. package/.agents/workflows/audit-architecture.md +3 -11
  541. package/.agents/workflows/audit-baselines.md +6 -9
  542. package/.agents/workflows/audit-clean-code.md +8 -12
  543. package/.agents/workflows/audit-data-model.md +3 -7
  544. package/.agents/workflows/audit-dependencies.md +4 -7
  545. package/.agents/workflows/audit-devops.md +4 -8
  546. package/.agents/workflows/audit-documentation.md +1 -4
  547. package/.agents/workflows/audit-mobile.md +4 -7
  548. package/.agents/workflows/audit-navigability.md +3 -6
  549. package/.agents/workflows/audit-performance.md +2 -4
  550. package/.agents/workflows/audit-privacy.md +4 -7
  551. package/.agents/workflows/audit-quality.md +4 -7
  552. package/.agents/workflows/audit-security.md +4 -7
  553. package/.agents/workflows/audit-seo.md +4 -7
  554. package/.agents/workflows/audit-sre.md +4 -7
  555. package/.agents/workflows/audit-to-stories.md +17 -30
  556. package/.agents/workflows/audit-ux-ui.md +4 -7
  557. package/.agents/workflows/helpers/audit-lens-core.md +1 -1
  558. package/.agents/workflows/helpers/code-quality-guardrails.md +12 -15
  559. package/.agents/workflows/helpers/deliver-digest.md +6 -4
  560. package/.agents/workflows/helpers/deliver-reference.md +114 -188
  561. package/.agents/workflows/helpers/deliver-story-reference.md +189 -533
  562. package/.agents/workflows/helpers/plan-reference.md +86 -139
  563. package/.agents/workflows/helpers/qa-core.md +12 -0
  564. package/.agents/workflows/memory-consolidate.md +1 -1
  565. package/.agents/workflows/qa-assist.md +27 -71
  566. package/.agents/workflows/qa-explore.md +19 -59
  567. package/.agents/workflows/qa-run.md +11 -33
  568. package/README.md +1 -1
  569. package/bin/mandrel.js +5 -46
  570. package/bin/postinstall.js +18 -107
  571. package/docs/CHANGELOG.md +25 -0
  572. package/lib/cli/doctor.js +11 -71
  573. package/lib/cli/init.js +26 -165
  574. package/lib/cli/migrate.js +5 -64
  575. package/lib/cli/registry.js +84 -467
  576. package/lib/cli/sync-agents.js +4 -64
  577. package/lib/cli/sync-commands.js +11 -64
  578. package/lib/cli/sync.js +34 -213
  579. package/lib/cli/uninstall.js +40 -219
  580. package/lib/cli/update.js +105 -661
  581. package/lib/cli/version-check.js +8 -72
  582. package/lib/cli/version-helpers.js +14 -87
  583. package/lib/migrations/helpers/retire-agentrc-key.js +11 -52
  584. package/lib/migrations/index.js +15 -92
  585. package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +2 -15
  586. package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +1 -13
  587. package/lib/migrations/steps/2.11.0-retire-max-seed-words.js +2 -15
  588. package/lib/migrations/steps/2.2.0-retire-epic-ac-tags.js +9 -38
  589. package/lib/migrations/steps/2.20.0-retire-codebase-snapshot.js +1 -13
  590. package/lib/migrations/steps/2.32.0-retire-lint-baseline-command.js +2 -27
  591. package/lib/migrations/steps/2.57.0-retire-delivery-limit-knobs.js +2 -23
  592. package/lib/migrations/steps/2.57.0-retire-planning-limit-knobs.js +2 -27
  593. package/lib/migrations/steps/2.60.0-retire-audit-results-autofile.js +2 -21
  594. package/lib/migrations/steps/strip-removed-agentrc-keys.js +333 -0
  595. package/package.json +16 -14
  596. package/.agents/docs/SDLC.md +0 -590
  597. package/.agents/docs/quality-gates.md +0 -1183
  598. package/.agents/rules/known-tooling-behavior.md +0 -200
  599. package/.agents/rules/orchestration-error-handling.md +0 -61
  600. package/.agents/rules/test-seams.md +0 -59
  601. package/.agents/schemas/baselines/lighthouse.schema.json +0 -59
  602. package/.agents/schemas/baselines/lint.schema.json +0 -47
  603. package/.agents/scripts/check-action-pinning.js +0 -260
  604. package/.agents/scripts/check-audit-attribution.js +0 -302
  605. package/.agents/scripts/check-baseline-drift.js +0 -211
  606. package/.agents/scripts/check-baseline-scope.js +0 -362
  607. package/.agents/scripts/check-generated-validator.js +0 -202
  608. package/.agents/scripts/check-knip-entries.js +0 -159
  609. package/.agents/scripts/check-lifecycle-lint.js +0 -294
  610. package/.agents/scripts/check-pinned-override-notes.js +0 -102
  611. package/.agents/scripts/check-schema-references.js +0 -368
  612. package/.agents/scripts/check-test-portability.js +0 -512
  613. package/.agents/scripts/check-workflow-citations.js +0 -218
  614. package/.agents/scripts/check-workflow-cli-lint.js +0 -299
  615. package/.agents/scripts/check-workflow-timeouts.js +0 -291
  616. package/.agents/scripts/install-matrix-assert.js +0 -326
  617. package/.agents/scripts/lib/audit-advisories.js +0 -195
  618. package/.agents/scripts/lib/audit-attribution.js +0 -134
  619. package/.agents/scripts/lib/baselines/drift-detector.js +0 -351
  620. package/.agents/scripts/lib/baselines/kinds/lighthouse.js +0 -87
  621. package/.agents/scripts/lib/baselines/kinds/lint.js +0 -184
  622. package/.agents/scripts/lib/baselines/orphan-pruner.js +0 -233
  623. package/.agents/scripts/lib/baselines/scope-assert.js +0 -223
  624. package/.agents/scripts/lib/baselines/scope-inventory.js +0 -314
  625. package/.agents/scripts/lib/c8-cli-path.js +0 -21
  626. package/.agents/scripts/lib/config/gates/lighthouse.schema.js +0 -51
  627. package/.agents/scripts/lib/config/gates/lint.schema.js +0 -18
  628. package/.agents/scripts/lib/dynamic-workflow/architecture-report-contract.js +0 -70
  629. package/.agents/scripts/lib/dynamic-workflow/audit-orchestrator.js +0 -284
  630. package/.agents/scripts/lib/dynamic-workflow/clean-code-report-contract.js +0 -80
  631. package/.agents/scripts/lib/dynamic-workflow/degraded-coverage.js +0 -81
  632. package/.agents/scripts/lib/dynamic-workflow/documentation-report-contract.js +0 -87
  633. package/.agents/scripts/lib/dynamic-workflow/performance-report-contract.js +0 -74
  634. package/.agents/scripts/lib/dynamic-workflow/quality-report-contract.js +0 -90
  635. package/.agents/scripts/lib/dynamic-workflow/report-contract-core.js +0 -43
  636. package/.agents/scripts/lib/dynamic-workflow/security-report-contract.js +0 -83
  637. package/.agents/scripts/lib/fs-walk.js +0 -52
  638. package/.agents/scripts/lib/knip-config-resolver.js +0 -181
  639. package/.agents/scripts/lib/knip-entry-sync.js +0 -452
  640. package/.agents/scripts/lib/pinned-override-notes.js +0 -88
  641. package/.agents/scripts/lib/pinned-override-resolve.js +0 -212
  642. package/.agents/scripts/lib/test-isolate/cli-options.js +0 -93
  643. package/.agents/scripts/lib/test-isolate/env-snapshot-loader.js +0 -52
  644. package/.agents/scripts/lib/test-isolate/list-files.js +0 -90
  645. package/.agents/scripts/lib/test-isolate/parse-tap.js +0 -75
  646. package/.agents/scripts/lib/test-isolate/progress-log.js +0 -45
  647. package/.agents/scripts/lib/test-isolate/render-report.js +0 -97
  648. package/.agents/scripts/lib/test-isolate/run-isolate.js +0 -87
  649. package/.agents/scripts/lib/test-isolate/runner.js +0 -483
  650. package/.agents/scripts/lib/test-profile/parse-tap.js +0 -136
  651. package/.agents/scripts/lib/test-profile/render-report.js +0 -45
  652. package/.agents/scripts/lint-label-vocabulary.js +0 -214
  653. package/.agents/scripts/post-structured-comment.js +0 -127
  654. package/.agents/scripts/provision-git-hooks.js +0 -85
  655. package/.agents/scripts/prune-baseline-orphans.js +0 -181
  656. package/.agents/scripts/run-coverage.js +0 -197
  657. package/.agents/scripts/run-lint.js +0 -133
  658. package/.agents/scripts/run-test-profile.js +0 -129
  659. package/.agents/scripts/run-verify.js +0 -125
  660. package/.agents/scripts/test-isolate.js +0 -55
  661. 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
+ }