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,13 +1,6 @@
1
1
  /**
2
- * kinds/crap.js — per-kind module for the CRAP baseline (Story #1891).
3
- *
4
- * Row shape: `{ path, method, startLine, crap }`. The per-kind v2 envelope
5
- * schema settles on `path` to match every other kind; the on-disk
6
- * baseline carries canonical `path:` rows end-to-end.
7
- *
8
- * `kernelVersion()` returns the installed `typhonjs-escomplex` package
9
- * version — the CRAP score depends on escomplex's cyclomatic-complexity
10
- * output, so drift in that dependency invalidates every committed row.
2
+ * Per-kind module for the CRAP baseline. Row shape:
3
+ * `{ path, method, startLine, crap }`.
11
4
  */
12
5
 
13
6
  import fs from 'node:fs';
@@ -45,37 +38,18 @@ import {
45
38
  export const name = 'crap';
46
39
  export const keyField = 'path';
47
40
 
48
- // The CRAP baseline read path (Story #5002) lives in `_crap-read.js` — the ONE
49
- // door, re-exported here so `preview-gates.js` and every existing importer keep
50
- // reaching it through this module.
51
41
  export { loadCrapBaseline } from './_crap-read.js';
52
42
 
53
43
  const __filename = fileURLToPath(import.meta.url);
54
44
 
55
- /**
56
- * Package whose resolved version is stamped as the CRAP scorer identity.
57
- *
58
- * `escomplex-plugin-metrics-module` owns the Halstead and cyclomatic math. The
59
- * displaced `typhonjs-escomplex` shell contributed a parser and a plugin bus
60
- * and never computed a metric, so stamping it described the shell.
61
- */
45
+ /** The package that computes the metrics; its version stamps the scorer identity. */
62
46
  const SCORER_PACKAGE = 'escomplex-plugin-metrics-module';
63
47
 
64
48
  /**
65
- * Resolve the running scorer's version by walking up from this module's
66
- * directory and reading the nearest `node_modules/<SCORER_PACKAGE>/package.json`.
67
- *
68
- * The package read is `escomplex-plugin-metrics-module`, which computes the
69
- * metrics. It was `typhonjs-escomplex` until Story #5336 replaced that shell's
70
- * parse and dispatch layers; reading a package that no longer exists would
71
- * yield the sentinel below on every fresh install, and the writer would refuse
72
- * to persist a baseline. (Locally it can look fine anyway — the walk-up escapes
73
- * a worktree into the parent checkout, whose `node_modules` may still hold the
74
- * removed package. CI's fresh clone has no such parent.)
75
- *
76
- * Returns `'0.0.0'` when the dependency cannot be found — callers treat that
77
- * sentinel as "unknown environment" and the writer refuses to persist a
78
- * baseline.
49
+ * Resolve the scorer version from the nearest `node_modules/<SCORER_PACKAGE>`,
50
+ * walking up. Returns the `'0.0.0'` "unknown environment" sentinel when not
51
+ * found, which makes the writer refuse to persist. The walk-up can escape a
52
+ * worktree into the parent checkout, so a local pass does not prove CI's.
79
53
  *
80
54
  * @returns {string}
81
55
  */
@@ -108,56 +82,21 @@ export function kernelVersion() {
108
82
  }
109
83
 
110
84
  /**
111
- * Scoring-semantics stamp (Story #4775, fix part 5).
112
- *
113
- * `kernelVersion()` above tracks the `typhonjs-escomplex` package and
114
- * `escomplexVersion` tracks the same dependency — so a change in how THIS
115
- * repo joins escomplex methods to istanbul coverage moves neither. Rows
116
- * scored by the pre-#4775 join (exact transpiled-line equality, methods
117
- * dropped when unresolved) are not comparable to rows scored by the join
118
- * that replaced it (original-source coordinates, containment matching,
119
- * honest `requireCoverage: false`): the same method can carry a different
120
- * `crap`, a different `startLine`, or exist in one baseline and not the
121
- * other. Comparing across that boundary produces phantom regressions and,
122
- * worse, phantom passes.
123
- *
124
- * The stamp makes the boundary explicit and fails closed. Bump it whenever
125
- * the coverage join, the line coordinate system, the unresolved-method policy,
126
- * or the **method identity rule** changes.
127
- *
128
- * Story #4969 bumped it to `method-identity-v3` for the last of those. An
129
- * anonymous method used to be keyed by escomplex's `<anon method-N>` ordinal
130
- * and is now keyed by its enclosing-scope path; 34.6% of rows changed identity
131
- * in one step. Rows keyed the old way and rows keyed the new way describe the
132
- * same functions under different names, so pairing them is exactly the
133
- * mis-keyed join this stamp exists to refuse — hence the bump, which is what
134
- * makes the migration report nothing rather than a wall of phantom verdicts.
135
- *
136
- * Deliberately module-local: `envelopeExtras()` is the single production door
137
- * to this value, so exporting the bare constant would add a second entry
138
- * point that nothing in production reaches. Callers and tests that need the
139
- * string read it off `envelopeExtras().scoringSemantics`.
85
+ * Scoring-semantics stamp. The scorer version does not move when this repo's
86
+ * coverage join changes, yet rows scored under different joins are not
87
+ * comparable (phantom regressions and phantom passes), so the stamp fails
88
+ * closed across that boundary. Bump it whenever the coverage join, the line
89
+ * coordinate system, the unresolved-method policy, or the method identity
90
+ * rule changes. Module-local: read it via `envelopeExtras().scoringSemantics`.
140
91
  */
141
92
  const SCORING_SEMANTICS = 'method-identity-v3';
142
93
 
143
94
  /**
144
- * Envelope-level stamps this kind contributes beyond the shared envelope
145
- * keys. Consumed by `writer.write` via the kind-module protocol.
146
- *
147
- * `tsTranspilerVersion` joined the stamp set in Story #4866. A TS row's
148
- * `startLine` is only an original-source coordinate because a sourcemap said
149
- * so, and that map is the transpiler's output — so a transpiler change can
150
- * move every TS row's coordinate, which is half the row identity key. Without
151
- * the stamp on disk the `ts-transpiler-drift` axis had nothing to compare and
152
- * passed vacuously.
153
- *
154
- * `provenanceStamped` joined in Story #4901 as a **positive** marker: the
155
- * writer asserting it recorded per-row provenance at all. Absence is the only
156
- * evidence a pre-#4866 baseline leaves, and no other stamp detects it —
157
- * `kernelVersion` / `escomplexVersion` track the escomplex package (unmoved
158
- * by the fix), `scoringSemantics` did not change, and `tsTranspilerVersion`
159
- * is unreliable in the negative (the `'0.0.0'` sentinel). See the
160
- * `provenance-unstamped` axis.
95
+ * Envelope stamps this kind adds, consumed by `writer.write`. A transpiler
96
+ * change can move every TS row's `startLine` (half the row identity key), so
97
+ * `tsTranspilerVersion` is stamped for the `ts-transpiler-drift` axis.
98
+ * `provenanceStamped` is a positive marker that per-row provenance was
99
+ * recorded; no other stamp can detect its absence.
161
100
  *
162
101
  * @returns {{scoringSemantics: string, tsTranspilerVersion: string,
163
102
  * provenanceStamped: boolean}}
@@ -171,13 +110,9 @@ export function envelopeExtras() {
171
110
  }
172
111
 
173
112
  /**
174
- * Project a scan row onto the persisted baseline row shape.
175
- *
176
- * `coordinateSystem` is written **only** when it is not the default
177
- * `original` (Story #4866). A pure-JavaScript scan therefore emits the exact
178
- * four-key row it always did — byte-identical baselines, no refresh — while a
179
- * row that kept transpiled coordinates is distinguishable on disk from one
180
- * whose sourcemap lookup resolved.
113
+ * Project a scan row onto the persisted row shape. `coordinateSystem` and
114
+ * `anonymous` are written only when non-default, so a plain JS row stays the
115
+ * four-key row and existing baselines stay byte-identical.
181
116
  */
182
117
  export function projectRow(row) {
183
118
  const projected = {
@@ -189,9 +124,7 @@ export function projectRow(row) {
189
124
  if (row.coordinateSystem === COORDINATE_TRANSPILED) {
190
125
  projected.coordinateSystem = COORDINATE_TRANSPILED;
191
126
  }
192
- // Story #4969, same write-only-when-non-default idiom: `anonymous` marks a
193
- // `method` that is a derived scope-path identity rather than a name the
194
- // source carries. A named row stays the exact four-key row it always was.
127
+ // `anonymous`: `method` is a derived scope-path identity, not a source name.
195
128
  if (row.anonymous === true) {
196
129
  projected.anonymous = true;
197
130
  }
@@ -199,12 +132,8 @@ export function projectRow(row) {
199
132
  }
200
133
 
201
134
  /**
202
- * Read a row's coordinate provenance, defaulting to `original`.
203
- *
204
- * A baseline written before Story #4866 carries no stamp at all, and every
205
- * such row IS an original-source coordinate — un-remapped rows could not
206
- * reach a `requireCoverage: true` baseline, and the pure-JavaScript case was
207
- * never affected. Defaulting is therefore back-compatible, not a guess.
135
+ * A row's coordinate provenance. An unstamped row is always an
136
+ * original-source coordinate, so the default is sound, not a guess.
208
137
  *
209
138
  * @param {{coordinateSystem?: string}|null|undefined} row
210
139
  * @returns {string}
@@ -221,8 +150,6 @@ export function sortRows(rows) {
221
150
  });
222
151
  }
223
152
 
224
- // Re-export percentile so existing consumers that imported it from crap.js
225
- // keep working without an import path change.
226
153
  export { percentile };
227
154
 
228
155
  const aggregate = makeAggregate({
@@ -241,23 +168,9 @@ const aggregate = makeAggregate({
241
168
  export const rollup = makeRollup({ aggregate });
242
169
 
243
170
  /**
244
- * Pure compare(head, base) for the CRAP kind. Diffs rows by the
245
- * `path::method@startLine` composite identity (per-method granularity).
246
- *
247
- * Higher CRAP = worse. A row regresses when its crap score increases vs
248
- * base; improves when it decreases; unchanged when equal. New methods
249
- * land in the `additions` bucket; absolute-ceiling enforcement is the
250
- * unified `check-baselines` gate's job (the per-method ceiling is a
251
- * different concern from regression vs base). Removed methods with
252
- * prior crap > 0 count as improvements.
253
- *
254
- * Story #2012 — sibling fix to maintainability.compare. The prior
255
- * behaviour treated any new method with crap > 0 as a regression, which
256
- * conflated "new code with a non-zero score" with "existing code that
257
- * got worse". New methods are now `additions` so a Story that lands a
258
- * new file no longer fails close-validation through the regression arm.
259
- *
260
- * No I/O. No process exit. No friction emission.
171
+ * Pure compare(head, base) keyed by `path::method@startLine`; higher CRAP is
172
+ * worse. New methods are `additions`, not regressions — the new-method
173
+ * ceiling is `check-baselines`' job.
261
174
  */
262
175
  export const compare = makeCompare({
263
176
  identity: rowIdentity,
@@ -268,17 +181,9 @@ export const compare = makeCompare({
268
181
  });
269
182
 
270
183
  /**
271
- * Canonical CRAP row identity (Story #5215) — the composite
272
- * `path::method@startLine`, exported under the protocol name every kind
273
- * module answers to.
274
- *
275
- * This kind is the reason identity is a separate concept from `keyField`.
276
- * `keyField` is `'path'` because the rollup groups by file, but a file
277
- * ships one row per method, so a merge keyed on `keyField` would collapse
278
- * every method in a file to one row and drop the rest. `compare`,
279
- * `applyEpsilon` and `mergeRows` have always keyed on this composite;
280
- * exporting it makes the same identity available to callers that used to
281
- * have no choice but to guess from `keyField`.
184
+ * Canonical row identity. Distinct from `keyField` (`'path'`, the rollup
185
+ * grouping): a file has one row per method, so keying a merge on `keyField`
186
+ * would collapse them.
282
187
  *
283
188
  * @param {{path: string, method: string, startLine: number}} row
284
189
  * @returns {string}
@@ -287,17 +192,8 @@ export function rowIdentity(row) {
287
192
  return `${row.path}::${row.method}@${row.startLine}`;
288
193
  }
289
194
 
290
- // `methodIdentityKey` / `indexBaselineRowsByFile` (Story #4981) are now
291
- // module-local to `crap-baseline-join.js` (Story #5002): after that module
292
- // absorbed the per-file queue wiring, both callers are inside it, so the
293
- // exports — and the re-export that used to live here — were reachable from
294
- // tests alone. `resolveIncrementalContext` is the production door to the
295
- // index; `rowIdentity` above is the composite key it halves.
296
-
297
195
  /**
298
- * Pure stabilizer for s-stability-epsilon (Story #1964). CRAP rows match
299
- * by the composite `path::method@startLine` identity. Sub-epsilon CRAP
300
- * deltas resolve to the prior row bytes; missing-prior rows fall through.
196
+ * Sub-epsilon CRAP deltas resolve to the prior row bytes.
301
197
  *
302
198
  * @param {Array<{path: string, method: string, startLine: number, crap: number}>} prior
303
199
  * @param {Array<{path: string, method: string, startLine: number, crap: number}>} regenerated
@@ -310,12 +206,8 @@ export const applyEpsilon = makeEpsilon({
310
206
  });
311
207
 
312
208
  /**
313
- * Pure scope-aware merge for s-diff-scoped-writes (Story #1974). CRAP rows
314
- * match identity by the composite `path::method@startLine`, but the scope
315
- * filter applies on `path` alone (a Story diff identifies files, not
316
- * methods). In diff mode, rows whose `path` is OUTSIDE `scope.files` are
317
- * preserved from `prior` verbatim — including every method on that file.
318
- * In full mode (or no scope), regenerated wins everywhere.
209
+ * Scope-aware merge: identity is per method, but scope filters on `path`
210
+ * alone (a diff names files), so out-of-scope files keep every prior row.
319
211
  *
320
212
  * @param {Array<{path: string, method: string, startLine: number, crap: number}>} prior
321
213
  * @param {Array<{path: string, method: string, startLine: number, crap: number}>} regenerated
@@ -332,20 +224,11 @@ export function mergeRows(prior, regenerated, scope) {
332
224
  });
333
225
  }
334
226
 
335
- // ---------------------------------------------------------------------------
336
- // CLI-facing pure helpers (Story #1981, Task #1989).
337
- // Hoisted from `.agents/scripts/check-crap.js` so the per-kind module owns
338
- // the loader / comparator / report-builder / floor-enforcer surface and the
339
- // CLI shell is reduced to argv parsing + orchestration. Behavior preserved
340
- // byte-for-byte vs the CLI version; only the import path changed.
341
- // ---------------------------------------------------------------------------
227
+ // CLI-facing pure helpers for `check-crap.js`.
342
228
 
343
229
  /**
344
- * Pure helper: narrow a list of rows to the ones whose `file` field is in
345
- * `scopeSet`. Shared between scan-row filtering and baseline-row filtering
346
- * so the `--changed-since` code path treats both sides of the comparison
347
- * the same way (otherwise every baseline row for an untouched file would
348
- * surface as "removed" on every diff-scoped run).
230
+ * Narrow rows to those whose `file` is in `scopeSet`. Apply to both scan and
231
+ * baseline rows, or untouched files surface as "removed" on a scoped run.
349
232
  *
350
233
  * @template {{file: string}} R
351
234
  * @param {R[]} rows
@@ -358,18 +241,10 @@ export function filterRowsByFileScope(rows, scopeSet) {
358
241
  }
359
242
 
360
243
  /**
361
- * Pure helper: decide whether a single (current, baseline) row pair counts
362
- * as a CRAP regression. Returns the violation object to push, or `null`
363
- * when the row passes (within tolerance, or exempted).
364
- *
365
- * Trivial (cyclomatic=1) methods are exempted from the regression check.
366
- * Their CRAP score collapses to a pure coverage proxy in [1, 2] — under
367
- * non-deterministic Node 22 V8 instrumentation on Windows CI, single-
368
- * statement wrappers like `deleteComment(ctx, id)` flap between cov=1.00
369
- * (crap=1) and cov=0.17 (crap≈1.58) across runs of identical source. A
370
- * real regression on a c=1 method requires it to gain branches, at which
371
- * point row.cyclomatic is no longer 1 and this exemption no longer
372
- * applies. New-method ceiling enforcement is unaffected.
244
+ * The violation for a (current, baseline) pair, or `null` when it passes.
245
+ * Cyclomatic-1 methods are exempt: their CRAP is a pure coverage proxy that
246
+ * flaps under non-deterministic V8 instrumentation on Windows CI, and a real
247
+ * regression would add branches and lose the exemption anyway.
373
248
  *
374
249
  * @param {{cyclomatic: number, crap: number}} row
375
250
  * @param {{crap: number, startLine: number}} baseline
@@ -389,51 +264,18 @@ export function checkCrapRegression(row, baseline, tolerance, kind) {
389
264
  }
390
265
 
391
266
  /**
392
- * Pure comparator. Given scanned `currentRows` and committed
393
- * `baselineRows`, produce a structured verdict covering all five match
394
- * paths:
395
- *
396
- * 1. **exact** — same (file, method, startLine). Regresses if
397
- * current crap > baseline crap + tolerance.
398
- * 2. **drifted** — same (file, method) but startLine shifted. Uses
399
- * the closest line-drifted baseline row under the
400
- * same no-regression rule. A drift without
401
- * regression is reported informationally.
402
- * 3. **incomparable** — same (file, method), but the two rows express
403
- * their startLine in DIFFERENT coordinate systems
404
- * (Story #4866). Reported, never scored.
405
- * 4. **new** — no baseline match. Violates if crap > ceiling.
406
- * 5. **removed** — baseline rows not seen in the current scan.
407
- * Surfaced only; never a failure.
408
- *
409
- * **Why the incomparable bucket exists.** The drift heuristic assumes both
410
- * rows measure the same axis and the method simply moved along it. When one
411
- * row's line is an original-source coordinate and the other's is a transpiled
412
- * one, the "distance" it minimises over is the gap between two coordinate
413
- * systems, not a code movement — so it pairs rows arbitrarily and then scores
414
- * the pairing. That is precisely how a scan that changed nothing reports a
415
- * regression no edit can satisfy. Refusing is the only sound answer: a row
416
- * whose provenance differs from every candidate's is counted and surfaced,
417
- * and it does NOT fall through to the new-method arm (it is not new; it is
418
- * unmeasurable against this baseline).
419
- *
420
- * **`provenanceMismatched` is captured BEFORE the provenance filter runs**
421
- * (Story #4871). `incomparable` only counts rows where *every* candidate
422
- * disagreed on coordinates; a row with one agreeing candidate and three
423
- * disagreeing ones scores normally and leaves no trace. That made the
424
- * evidence of coordinate mixing strictly narrower than the mixing itself —
425
- * and the unsound-basis backstop, which needs exactly that evidence, had
426
- * nothing sound to read. The counter below is incremented for **any** row
427
- * with at least one provenance-mismatched candidate, whichever arm then
428
- * resolves it.
429
- *
430
- * **Unscorable rows never reach an arm.** A row the scan could not score
431
- * (`crap: null` / `coverage: null`, or an explicit `unscorable: true`) carries
432
- * no measurement to compare. It is bucketed and counted, and it is excluded
433
- * from `comparable` so it cannot dilute any ratio derived from this result.
434
- *
435
- * **A new method in a wholly-uncovered file is gated on complexity alone**
436
- * (Story #5002) — see `newMethodGateScore`.
267
+ * Compare scanned rows to baseline rows. Match arms: **exact** (same file,
268
+ * method, startLine), **drifted** (same method, nearest startLine),
269
+ * **incomparable** (every candidate is in a different coordinate system),
270
+ * **new** (gated against the ceiling), **removed** (surfaced only).
271
+ *
272
+ * Across coordinate systems the drift heuristic would pair rows arbitrarily
273
+ * and report regressions no edit can satisfy, so such rows are counted, not
274
+ * scored, and never fall through to the new-method arm.
275
+ * `provenanceMismatched` counts any row with at least one mismatched
276
+ * candidate, captured before the filter discards that evidence — it feeds the
277
+ * unsound-basis backstop. Unscorable rows (null crap/coverage) are bucketed
278
+ * and excluded from `comparable` so they cannot dilute a ratio.
437
279
  */
438
280
  export function compareCrap({
439
281
  currentRows,
@@ -469,7 +311,6 @@ export function compareCrap({
469
311
  const methodKey = `${row.file}::${row.method}`;
470
312
  const rowCoords = coordinateSystemOf(row);
471
313
  const candidates = methodIndex.get(methodKey) ?? [];
472
- // Evidence first, filtering second — see the block comment above.
473
314
  if (candidates.some((c) => coordinateSystemOf(c) !== rowCoords)) {
474
315
  provenanceMismatched += 1;
475
316
  }
@@ -486,9 +327,6 @@ export function compareCrap({
486
327
  }
487
328
 
488
329
  if (candidates.length > 0) {
489
- // Only rows expressed in the SAME coordinate system are comparable;
490
- // everything else would be resolved through a line-distance heuristic
491
- // that cannot mean anything across two coordinate systems.
492
330
  const comparable = candidates.filter(
493
331
  (c) => coordinateSystemOf(c) === rowCoords,
494
332
  );
@@ -531,8 +369,7 @@ export function compareCrap({
531
369
  const total = currentRows?.length ?? 0;
532
370
  return {
533
371
  total,
534
- // Rows that carried a measurement and therefore *could* be compared. The
535
- // denominator of every ratio derived from this result.
372
+ // Denominator of every ratio derived from this result.
536
373
  comparable: total - unscorableRows.length,
537
374
  regressions,
538
375
  newViolations,
@@ -549,12 +386,8 @@ export function compareCrap({
549
386
  }
550
387
 
551
388
  /**
552
- * True when a scanned row carries no measurement to compare.
553
- *
554
- * Deliberately strict on `null`: a scan row always sets `crap`, and the
555
- * scorer's own contract is that an unresolved method yields `crap: null` /
556
- * `coverage: null` rather than an inferred zero. A caller-built row that
557
- * simply omits `coverage` is not making that claim and stays scorable.
389
+ * Strict on `null` (the scorer's "unresolved" value); a row merely omitting
390
+ * `coverage` stays scorable.
558
391
  *
559
392
  * @param {{crap?: number|null, coverage?: number|null, unscorable?: boolean}} row
560
393
  * @returns {boolean}
@@ -566,10 +399,8 @@ function isUnscorableRow(row) {
566
399
  }
567
400
 
568
401
  /**
569
- * Pick the baseline row a drifted method should be scored against: the
570
- * closest un-seen candidate by `startLine` distance, falling back to the
571
- * first when every candidate has already been claimed (duplicate method
572
- * names in one file).
402
+ * Closest unclaimed candidate by `startLine`; the first when all are claimed
403
+ * (duplicate method names in one file).
573
404
  *
574
405
  * @param {Array<{file: string, method: string, startLine: number}>} comparable
575
406
  * @param {{startLine: number}} row
@@ -592,62 +423,24 @@ function pickDriftCandidate(comparable, row, seenBaselineKeys) {
592
423
  }
593
424
 
594
425
  /**
595
- * Fraction of a compare's comparable rows that hit a coordinate-provenance
596
- * mismatch before the comparison basis is judged self-evidently unsound
597
- * (Story #4866, numerator corrected in Story #4871).
598
- *
599
- * **What this ratio must measure.** The backstop exists for one condition: the
600
- * scan and the baseline expressing `startLine` in different coordinate
601
- * systems, which makes the nearest-line drift heuristic pair rows arbitrarily
602
- * and then score the pairing. The only quantity that evidences that condition
603
- * is a provenance disagreement between a row and its baseline candidates.
604
- *
605
- * **Why `drifted` was the wrong numerator.** A row reaches the drift arm only
606
- * *after* passing the provenance filter, so every drifted row is one whose
607
- * coordinate system **agreed** with its baseline's. Counting agreements as
608
- * evidence of disagreement is not a mis-calibration, it is the wrong
609
- * measurement: on this pure-JavaScript repository — where a coordinate mix is
610
- * structurally impossible — it read 56–68% across every diff scope, which
611
- * suppressed the gate's per-method verdicts on every commit while the gate
612
- * still reported success. `startLine` is half the row identity key, so any
613
- * insertion re-keys every method below it; ordinary drift is the normal
614
- * operating state, not an anomaly.
615
- *
616
- * Deliberately module-local, like `SCORING_SEMANTICS` above: the three
617
- * tuning values below are reachable through `assessComparisonBasis` — which
618
- * takes them as overridable options — so exporting the bare constants would
619
- * add entry points nothing in production reaches.
426
+ * Share of comparable rows with a provenance mismatch above which the basis
427
+ * is unsound. The numerator must be provenance mismatch, never `drifted`:
428
+ * drifted rows passed the provenance filter, and ordinary insertions drift
429
+ * most rows.
620
430
  */
621
431
  const UNSOUND_BASIS_MISMATCH_RATIO = 0.5;
622
432
 
623
- /**
624
- * Minimum comparable rows before the unsound-basis check is allowed to fire.
625
- * A diff-scoped preview can legitimately score three methods, two of which
626
- * moved; that is a normal edit, not a broken basis. Mirrors the
627
- * minimum-sample discipline the coverage-join resolution floor already uses.
628
- */
433
+ /** Small diff-scoped samples legitimately drift; don't judge them. */
629
434
  const UNSOUND_BASIS_MIN_SAMPLE = 20;
630
435
 
631
- /** Diagnostic name for an unsound comparison basis. */
632
436
  const UNSOUND_BASIS_DIAGNOSTIC = 'crap-unsound-comparison-basis';
633
437
 
634
- /** Diagnostic name for a baseline the running scorer refuses to compare. */
635
438
  export const INCOMPATIBLE_BASELINE_DIAGNOSTIC = 'crap-baseline-incompatible';
636
439
 
637
440
  /**
638
- * Pure verdict on whether a `compareCrap` result rests on a sound basis.
639
- *
640
- * The numerator is `provenanceMismatched` — rows whose baseline candidates
641
- * included at least one expressed in a different coordinate system, counted
642
- * by `compareCrap` **before** its provenance filter discards that evidence.
643
- * The denominator is `comparable`: rows that carried a measurement at all, so
644
- * a method the scan could not score cannot dilute the ratio into silence.
645
- *
646
- * Above the ratio the per-method verdicts are noise derived from a mis-keyed
647
- * join, and reporting them as regressions asks the operator to fix code that
648
- * is not broken. Below it — including a scan where every row drifted, which
649
- * is what an ordinary insertion produces — the verdicts stand.
650
- *
441
+ * Whether a `compareCrap` result rests on a sound basis
442
+ * (`provenanceMismatched / comparable`). Above the ratio the per-method
443
+ * verdicts come from a mis-keyed join and must be suppressed.
651
444
  * Returns `{ sound: true }` or `{ sound: false, diagnostic: {name, message} }`.
652
445
  *
653
446
  * @param {{total?: number, comparable?: number, provenanceMismatched?: number,
@@ -663,8 +456,7 @@ export function assessComparisonBasis(compareResult, opts = {}) {
663
456
  : UNSOUND_BASIS_MIN_SAMPLE;
664
457
  const comparable = compareResult?.comparable ?? compareResult?.total ?? 0;
665
458
  if (comparable < minSample) return { sound: true };
666
- // `incomparable` is the total-mismatch subset of `provenanceMismatched`, so
667
- // it is already counted; the max guards a caller that supplies only one.
459
+ // `incomparable` is a subset; max guards a caller supplying only one.
668
460
  const mismatched = Math.max(
669
461
  compareResult?.provenanceMismatched ?? 0,
670
462
  compareResult?.incomparable ?? 0,
@@ -692,51 +484,19 @@ export function assessComparisonBasis(compareResult, opts = {}) {
692
484
  };
693
485
  }
694
486
 
695
- /**
696
- * Declarative axis table for `evaluateBaselineCompatibility` (Story #2467).
697
- *
698
- * Each axis is a pure `{ name, severity, check }` triple. `check` receives
699
- * the compat context `{ baseline, runningKernelVersion,
700
- * runningEscomplexVersion, runningTsTranspilerVersion }` and returns either
701
- * `null` (axis passed) or a `string` message describing the failure.
702
- *
703
- * - `severity: 'fatal'` — first match short-circuits the reduce and the
704
- * function returns `{ ok: false, exitCode: 1, kind, message }`.
705
- * - `severity: 'warn'` — every match accumulates into `warnings[]` and the
706
- * function still returns `{ ok: true, warnings }`.
707
- *
708
- * Story #791 retired the transitional `bootstrap` exit-0 path: a missing
709
- * baseline still fails closed. Story #829 (5.29.0) softened `kernelVersion`
710
- * drift to **warn**, not fail, and did the same for `tsTranspilerVersion` —
711
- * but that second half was re-escalated to **fatal** once Story #4866 made a
712
- * TS row's `startLine` an original-source coordinate resolved through the
713
- * transpiler's sourcemap. `startLine` is half the row identity key, so a
714
- * transpiler change makes the rows incomparable rather than merely stale; see
715
- * the `ts-transpiler-drift` axis below for the two exemptions that bound it.
716
- *
717
- * There is no `escomplexVersion` axis. One existed, declared `fatal`, and
718
- * could not fire in either direction: the v2 envelope does not carry the
719
- * field, so the loaded-envelope pass excluded it as vacuous, and the peer pass
720
- * back-filled the value from the running scorer before comparing it against
721
- * the running scorer. A gate that presents as fatal and cannot fail is worse
722
- * than an absent one, so it was removed rather than repaired — `scoringSemantics`
723
- * is the axis that actually rejects an incompatible scorer.
724
- */
725
- /**
726
- * The one re-seed recipe every coordinate-invalidating axis ends on. Three
727
- * axes and the unsound-basis diagnostic previously carried their own copy of
728
- * this sentence; a single constant keeps them from drifting apart on the
729
- * command an operator is told to run.
730
- */
731
487
  const RESEED_REMEDY =
732
488
  "Re-derive the baseline: run 'npm run test:coverage' then " +
733
489
  "'npm run crap:update -- --full-scope' and commit the result with a " +
734
490
  "'baseline-refresh:' subject.";
735
491
 
492
+ /**
493
+ * Compat axes for `evaluateBaselineCompatibility`: `{ name, severity, check }`,
494
+ * where `check(ctx)` returns null or a failure message. The first `fatal`
495
+ * match fails; `warn` matches accumulate. Kernel drift only warns; a
496
+ * transpiler change is fatal because it moves `startLine`, half the row
497
+ * identity key.
498
+ */
736
499
  export const CRAP_COMPAT_AXES = [
737
- // Universal axes hoisted into envelope.js (Story #2467, Task #2492). The
738
- // missing-baseline and kernel-drift checks live in exactly one place;
739
- // each per-kind table composes them in with its own kind label.
740
500
  missingBaselineAxis('CRAP'),
741
501
  kernelDriftAxis('CRAP'),
742
502
  {
@@ -761,15 +521,10 @@ export const CRAP_COMPAT_AXES = [
761
521
  if (!baseline) return null;
762
522
  if (!isKnownVersion(runningTsTranspilerVersion)) return null;
763
523
  const baselineTs = baseline.tsTranspilerVersion;
764
- // An unstamped (or sentinel) baseline has nothing to compare — the
765
- // stamp landed in Story #4866 and comparing against its absence would
766
- // fail every pre-existing baseline closed for no evidence at all.
524
+ // Unstamped: no evidence either way (see `provenance-unstamped`).
767
525
  if (!isKnownVersion(baselineTs)) return null;
768
526
  if (baselineTs === runningTsTranspilerVersion) return null;
769
- // Scoped to baselines that actually contain transpiled sources: a
770
- // transpiler change moves TS row coordinates and nothing else. A
771
- // pure-JavaScript tree has no coordinate to move, so a TS bump there is
772
- // not a coordinate-invalidating event and must not fail its gate.
527
+ // A pure-JS baseline has no transpiled coordinate to move.
773
528
  if (!hasTranspiledRows(baseline)) return null;
774
529
  return (
775
530
  `[CRAP] tsTranspilerVersion changed: baseline=${baselineTs} running=${runningTsTranspilerVersion}. ` +
@@ -780,15 +535,9 @@ export const CRAP_COMPAT_AXES = [
780
535
  },
781
536
  },
782
537
  {
783
- // Story #4901. Closes the exemption directly above: `ts-transpiler-drift`
784
- // returns null for an unstamped baseline rather than fail every
785
- // pre-existing one for want of evidence — and a pre-#4866 baseline is
786
- // exactly that shape, so the one door that could catch it lets it through
787
- // while it asserts by omission that all its rows are original coordinates.
788
- // Keyed on a positive marker because absence alone cannot separate
789
- // "written before provenance existed" from "typescript was unresolvable".
790
- // Scoped like `ts-transpiler-drift`: a pure-JavaScript baseline's two
791
- // coordinate systems coincide, so it was never affected and must not fail.
538
+ // Closes the unstamped exemption above. Keyed on a positive marker, since
539
+ // absence can't separate "no provenance" from "typescript unresolvable";
540
+ // scoped to transpiled rows because pure-JS coordinates coincide.
792
541
  name: 'provenance-unstamped',
793
542
  severity: 'fatal',
794
543
  check: ({ baseline }) =>
@@ -804,20 +553,10 @@ export const CRAP_COMPAT_AXES = [
804
553
  : null,
805
554
  },
806
555
  {
807
- // Story #4969. The `scoring-semantics-drift` axis above rejects a baseline
808
- // stamped with the OLD semantics wholesale, which covers a clean migration.
809
- // It cannot see a HALF-migrated one: a diff-scoped refresh preserves
810
- // out-of-scope rows verbatim, so a baseline can carry ordinal-keyed rows
811
- // for the files that were never re-scored while the writer stamps the
812
- // envelope with the current semantics — the stamp says v3, some rows are
813
- // still v2, and the one axis that would catch it has already passed.
814
- //
815
- // Such a row cannot be paired with anything: its `<anon method-N>` label
816
- // matches no scope-path identity, so the comparator files the live method
817
- // as NEW (scored against the ceiling, not its own baseline) and the stale
818
- // row as removed. Keyed on the positive `anonymous` marker for the same
819
- // reason `provenance-unstamped` is: absence is the only trace the old
820
- // writer leaves.
556
+ // Catches a half-migrated baseline: a diff-scoped refresh keeps
557
+ // out-of-scope ordinal-keyed anonymous rows under a current-semantics
558
+ // stamp, and those rows pair with nothing. Keyed on the positive
559
+ // `anonymous` marker.
821
560
  name: 'anon-identity-unstamped',
822
561
  severity: 'fatal',
823
562
  check: ({ baseline }) => {
@@ -843,10 +582,7 @@ export const CRAP_COMPAT_AXES = [
843
582
  const TRANSPILED_SOURCE_RE = /\.(?:ts|tsx|mts|cts)$/i;
844
583
 
845
584
  /**
846
- * `'0.0.0'` is this codebase's established "unknown environment" sentinel for
847
- * a resolved dependency version, not a real release. Treating it as a
848
- * comparable value would turn "we could not resolve typescript" into
849
- * "typescript changed".
585
+ * `'0.0.0'` is the "unknown environment" sentinel, not a comparable version.
850
586
  *
851
587
  * @param {unknown} version
852
588
  * @returns {boolean}
@@ -856,9 +592,6 @@ function isKnownVersion(version) {
856
592
  }
857
593
 
858
594
  /**
859
- * True when a baseline contains at least one row derived from a transpiled
860
- * source — the only rows a transpiler-version change can move.
861
- *
862
595
  * @param {{rows?: Array<{path?: string, file?: string}>}|null} baseline
863
596
  * @returns {boolean}
864
597
  */
@@ -868,32 +601,13 @@ function hasTranspiledRows(baseline) {
868
601
  );
869
602
  }
870
603
 
871
- /**
872
- * Pure decision helper for the missing-baseline / kernel-mismatch /
873
- * escomplex-mismatch / tsTranspiler-mismatch gate paths. Lets tests
874
- * assert the exact operator-facing message without spawning a child
875
- * process.
876
- *
877
- * Story #2467 rewrote the body as a reduce over `CRAP_COMPAT_AXES` to
878
- * collapse the cyclomatic complexity below the project ceiling. Behavior
879
- * is preserved byte-for-byte vs the prior imperative implementation.
880
- */
881
604
  export function evaluateBaselineCompatibility(ctx) {
882
605
  return reduceCompatAxes(CRAP_COMPAT_AXES, ctx);
883
606
  }
884
607
 
885
608
  /**
886
- * The compat axes a *loaded* envelope can be judged against on its own,
887
- * without a second baseline to diff. Each invalidates one half of the row
888
- * identity key. Three are about the `startLine` half: one names the join that
889
- * produced the rows, one names the transpiler whose sourcemap decided what a
890
- * TS row's `startLine` even means, and one (Story #4901) catches a baseline
891
- * predating both questions. The fourth (Story #4969) is about the `method`
892
- * half — a baseline still carrying ordinal-keyed anonymous rows.
893
- *
894
- * `kernel-drift` stays out: it is a warn-level axis, and this pass turns a
895
- * message into a fail-closed error. (`escomplex-mismatch` was the other
896
- * exclusion until it was removed outright — see `CRAP_COMPAT_AXES`.)
609
+ * Axes a loaded envelope can be judged on alone. `kernel-drift` is excluded:
610
+ * it only warns, and this pass fails closed on any message.
897
611
  */
898
612
  const LOADED_ENVELOPE_AXES = [
899
613
  'scoring-semantics-drift',
@@ -903,21 +617,11 @@ const LOADED_ENVELOPE_AXES = [
903
617
  ];
904
618
 
905
619
  /**
906
- * Kind-module hook (Story #4775, extended by Story #4866): judge a *loaded*
907
- * v2 envelope against the axes that need no peer baseline. The unified
908
- * `check-baselines` gate calls it straight after `reader.load` and turns a
909
- * message into a fail-closed schema-class error, so a baseline written by
910
- * incompatible scoring semantics — or by a different transpiler, which moves
911
- * the coordinates that are half the row identity key — can never be silently
912
- * compared against current scores.
913
- *
914
- * This is the *production* door for `ts-transpiler-drift`. Before #4866 the
915
- * axis was reachable only from its own unit test: nothing in production called
916
- * `evaluateBaselineCompatibility`, and this function deliberately excluded it.
620
+ * Kind-module hook: `check-baselines` calls it after `reader.load` and fails
621
+ * closed on a message, so an incompatible baseline is never silently compared.
917
622
  *
918
623
  * @param {object|null} baseline A loaded v2 baseline envelope.
919
- * @param {{runningTsTranspilerVersion?: string}} [ctx] Injectable running
920
- * versions; resolved from the environment when omitted.
624
+ * @param {{runningTsTranspilerVersion?: string}} [ctx]
921
625
  * @returns {string|null} Operator-facing message, or null when compatible.
922
626
  */
923
627
  export function assertBaselineCompatible(baseline, ctx = {}) {
@@ -933,13 +637,8 @@ export function assertBaselineCompatible(baseline, ctx = {}) {
933
637
  }
934
638
 
935
639
  /**
936
- * Build the structured `--json` report envelope.
937
- *
938
- * Violations carry the same fields the stdout printer emits plus a
939
- * deterministic `fixGuidance` block derived from the formula: target is
940
- * the baseline for regressions and the ceiling for new-method
941
- * violations. Rows are deep-cloned so callers can safely mutate the
942
- * envelope without corrupting the live comparator result.
640
+ * Build the `--json` report. `fixGuidance` targets the baseline for a
641
+ * regression and the ceiling for a new method.
943
642
  */
944
643
  export function buildCrapReport({
945
644
  compareResult,
@@ -971,9 +670,7 @@ export function buildCrapReport({
971
670
  fixGuidance,
972
671
  };
973
672
  });
974
- // Story #1394: tag the envelope with the scope used to produce it so
975
- // downstream tooling can detect whether the diff was scoped or
976
- // full-repo before merging this envelope with the peer MI envelope.
673
+ // Consumers merging with the peer MI envelope need to know the scope.
977
674
  const scope = scopeInfo?.scope === 'full' ? 'full' : 'diff';
978
675
  const diffRef = scope === 'full' ? null : (scopeInfo?.diffRef ?? null);
979
676
  return {
@@ -984,16 +681,9 @@ export function buildCrapReport({
984
681
  regressions: compareResult.regressions,
985
682
  newViolations: compareResult.newViolations,
986
683
  drifted: compareResult.drifted,
987
- // Story #4866: rows the compare refused to resolve because their
988
- // coordinate provenance differs from the baseline's.
989
684
  incomparable: compareResult.incomparable ?? 0,
990
- // Story #4871: rows whose baseline candidates included at least one in a
991
- // different coordinate system — the evidence the unsound-basis backstop
992
- // reads, captured before the provenance filter discards it.
993
685
  provenanceMismatched: compareResult.provenanceMismatched ?? 0,
994
- // Story #4871: methods carrying no measurement to compare — the scan
995
- // found no coverage artifact for them. Reported, never scored from an
996
- // assumed zero, and never part of a ratio's denominator.
686
+ // Never scored from an assumed zero coverage.
997
687
  unscorable: (compareResult.unscorable ?? 0) + skippedNoCoverage,
998
688
  removed: compareResult.removed,
999
689
  skippedNoCoverage,
@@ -1005,14 +695,8 @@ export function buildCrapReport({
1005
695
  }
1006
696
 
1007
697
  /**
1008
- * Rebuild a CRAP envelope with its per-method verdicts suppressed and one
1009
- * named diagnostic in their place (Story #4866).
1010
- *
1011
- * Used by the preview gate on the two conditions under which a per-method
1012
- * verdict cannot mean anything: a baseline the running scorer refuses to
1013
- * compare, and a comparison basis whose drifted-row ratio proves the two
1014
- * sides disagree on coordinates. The counts stay so the operator can see the
1015
- * evidence; only the accusations go.
698
+ * Replace per-method verdicts with one diagnostic, keeping the counts as
699
+ * evidence. Used when the baseline is incompatible or the basis unsound.
1016
700
  *
1017
701
  * @param {object} envelope
1018
702
  * @param {{name: string, message: string}} diagnostic
@@ -1031,11 +715,6 @@ export function suppressVerdicts(envelope, diagnostic) {
1031
715
  };
1032
716
  }
1033
717
 
1034
- /**
1035
- * Logger-only printers hoisted from `check-crap.js`. Kept here so the
1036
- * CLI shell stays thin and the printers can be exercised in unit tests
1037
- * without spawning the CLI.
1038
- */
1039
718
  export function printSummaryHeader(result, scanSummary) {
1040
719
  Logger.info('\n--- CRAP Report ---');
1041
720
  Logger.info(`Total methods scanned: ${result.total}`);