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,22 +1,6 @@
1
1
  /**
2
- * lib/findings/provenance-field.js — the per-Story `provenance` field.
3
- *
4
- * An audit-seeded plan carries dedup identities forward so the next sweep
5
- * recognises what it already planned. The optional top-level `provenance`
6
- * field on a `stories.json` entry says **which of them that Story owns**:
7
- *
8
- * ```jsonc
9
- * { "fingerprints": ["<40-char sha1>"], "semanticKeys": ["architecture␟lib/a.js"] }
10
- * ```
11
- *
12
- * Two callers, deliberately split from
13
- * [`route-finding.js`](route-finding.js): the ticket validator shape-checks
14
- * the authored field, and plan-persist's assembly renders the owned identities
15
- * into the footer source it stamps. Neither is dedup *routing*, which is what
16
- * `route-finding.js` is for — this module reads its identity vocabulary
17
- * (`SHA1_RE`, `SEMANTIC_KEY_RE`, and the two footer renderers) from there so
18
- * there is exactly one definition of what a fingerprint or a semantic key
19
- * looks like.
2
+ * lib/findings/provenance-field.js — the optional per-Story `provenance`
3
+ * field naming the audit identities that Story owns.
20
4
  *
21
5
  * @module lib/findings/provenance-field
22
6
  */
@@ -28,10 +12,8 @@ import {
28
12
  semanticKeyFooter,
29
13
  } from './route-finding.js';
30
14
 
31
- /** Human-readable rendering of the `provenance` field's two lists. */
32
15
  const PROVENANCE_SHAPE = 'fingerprints[] / semanticKeys[]';
33
16
 
34
- /** What each `provenance` list accepts, and how to say so when it does not. */
35
17
  const PROVENANCE_FIELDS = Object.freeze({
36
18
  fingerprints: { pattern: SHA1_RE, expected: 'a 40-char sha1 hex string' },
37
19
  semanticKeys: {
@@ -41,8 +23,6 @@ const PROVENANCE_FIELDS = Object.freeze({
41
23
  });
42
24
 
43
25
  /**
44
- * Validate one authored `provenance` list into its normalized form.
45
- *
46
26
  * @param {unknown} list
47
27
  * @param {{ where: string, field: string, pattern: RegExp, expected: string }} spec
48
28
  * @returns {string[]} Trimmed, de-duplicated, first-seen order.
@@ -66,25 +46,13 @@ function normalizeList(list, { where, field, pattern, expected }) {
66
46
  }
67
47
 
68
48
  /**
69
- * Normalize the optional per-Story `provenance` field a plan may author —
70
- * the identities of the findings **that Story owns**.
71
- *
72
- * Absence is meaningful and must stay cheap: `undefined` / `null` returns
73
- * `null`, which is the caller's signal to fall back to the whole-seed union
74
- * carry. That fallback is not vestigial — leaving the authoring agent to
75
- * hand-carry provenance out of the seed's HTML comments was measured to fail,
76
- * and the mechanical union is what closed it. Attribution is **additive**: a
77
- * plan that attributes gets exact stamping, a plan that does not keeps recall.
78
- *
79
- * An empty object is therefore *not* the same as an absent field: it means
80
- * "this Story owns nothing", and stamps nothing.
81
- *
82
- * Present-but-malformed is a hard error rather than a silent drop, because a
83
- * dropped identity is invisible until the next sweep re-files work that was
84
- * already planned.
49
+ * Absent → `null`: the caller falls back to carrying the whole seed's union
50
+ * (hand-carrying was measured to fail). An empty object means "owns nothing"
51
+ * and stamps nothing. Malformed throws — a dropped identity is invisible until
52
+ * the next sweep re-files planned work.
85
53
  *
86
54
  * @param {unknown} raw
87
- * @param {string} [label] Identifier for the error message (a Story slug).
55
+ * @param {string} [label]
88
56
  * @returns {{ fingerprints: string[], semanticKeys: string[] }|null}
89
57
  * @throws {Error} On any shape the stamper cannot honour exactly.
90
58
  */
@@ -108,19 +76,10 @@ export function normalizeOwnedProvenance(raw, label = 'story') {
108
76
  }
109
77
 
110
78
  /**
111
- * Render the provenance **source document** for a set of owned identities, in
112
- * the same footer vocabulary `carryProvenanceFooters` harvests from an audit
113
- * seed. That reuse is the point: attribution changes *which* identities reach
114
- * a Story body, never how they are stamped, so the carry stays additive,
115
- * union-preserving and idempotent for an attributed plan exactly as it is for
116
- * an un-attributed one.
117
- *
118
- * An empty (or absent) set renders the empty string, which the carry treats as
119
- * nothing-to-do — so a Story that owns no findings is stamped with none rather
120
- * than inheriting its siblings'.
121
- *
122
- * Expects the normalized shape {@link normalizeOwnedProvenance} returns; the
123
- * validator runs first on every production path.
79
+ * Render owned identities in the same footer vocabulary
80
+ * `carryProvenanceFooters` harvests, so attribution changes which identities
81
+ * are stamped, never how. An empty set renders `''` (nothing inherited from
82
+ * siblings). Expects {@link normalizeOwnedProvenance}'s shape.
124
83
  *
125
84
  * @param {{ fingerprints?: string[], semanticKeys?: string[] }|null} [provenance]
126
85
  * @returns {string}
@@ -1,32 +1,6 @@
1
1
  /**
2
- * lib/findings/route-finding.js — Shared dedup/route helper for findings.
3
- *
4
- * This module is the single dedup/route implementation that both
5
- * `audit-to-stories` and `qa-explore` consume. It does three things:
6
- *
7
- * 1. `fingerprintFinding(finding)` — a stable sha1 over the finding's
8
- * identity fields (`title`, `area`, `primaryFile`, `severity`,
9
- * `labels`). Two runs over the same finding MUST produce the same
10
- * sha, and unrelated prose drift MUST NOT change it.
11
- * 2. `fingerprintFooter(sha)` / `parseFingerprintFooter(body)` — round-trip
12
- * the machine-readable `<!-- audit-fingerprints: sha,sha,... -->` marker
13
- * stamped into Issue bodies.
14
- * 3. `routeFinding(finding, { searchIssues, searchCandidates })` — classify a
15
- * finding against existing Issues into one of `new | update-existing |
16
- * duplicate | regression-of-closed`. Routing gathers a candidate pool,
17
- * then confirms identity against it. **Every wired port runs, and their
18
- * results union** (Story #5079): the exact `searchIssues(sha)` lookup is
19
- * what reliably retrieves an Issue by its footer sha, while the
20
- * meaning-first `searchCandidates` pass (wired to
21
- * `semantic-issue-search.js`) widens that pool to catch a reworded
22
- * finding whose sha has drifted. The semantic pass **adds** to the
23
- * fingerprint lookup; it never replaces it. Whichever ports are wired
24
- * query BOTH open and closed issues; a closed fingerprint match yields
25
- * `regression-of-closed`.
26
- *
27
- * Pure orchestration: no network I/O lives here. The `searchIssues` /
28
- * `searchCandidates` ports are injected by the caller (production wires them
29
- * to the GitHub provider; tests pass an in-memory stub).
2
+ * lib/findings/route-finding.js — the one dedup/route implementation: finding
3
+ * fingerprints, Issue-body footers, and `routeFinding`. Ports are injected.
30
4
  */
31
5
 
32
6
  import crypto from 'node:crypto';
@@ -38,13 +12,10 @@ const MARKER = 'audit-fingerprints:';
38
12
  const SEMANTIC_MARKER = 'audit-semantic-keys:';
39
13
  const LABEL_MARKER = 'audit-labels:';
40
14
  export const SHA1_RE = /^[0-9a-f]{40}$/;
41
- // A semantic key round-trips through a comma-joined footer, so it must not
42
- // carry a comma or a `>` (which would truncate the HTML comment). Both are
43
- // stripped when the key is built, so this guard is defence-in-depth.
15
+ // No `,` or `>`: keys round-trip through a comma-joined HTML-comment footer.
44
16
  export const SEMANTIC_KEY_RE = /^[^,>]+$/;
45
17
 
46
18
  /**
47
- * Normalise a single scalar identity field to a stable string.
48
19
  * @param {unknown} value
49
20
  * @returns {string}
50
21
  */
@@ -54,7 +25,6 @@ function normaliseField(value) {
54
25
  }
55
26
 
56
27
  /**
57
- * Normalise the `labels` array into a stable, order-independent string.
58
28
  * @param {unknown} labels
59
29
  * @returns {string}
60
30
  */
@@ -68,20 +38,8 @@ function normaliseLabels(labels) {
68
38
  }
69
39
 
70
40
  /**
71
- * Compute the stable identity payload for a finding.
72
- *
73
- * **Severity is projected, not raw (Story #4877).** The severity vocabulary was
74
- * normalised onto the canonical five-level scale in the same change that wrote
75
- * this comment, and severity is an identity field — so a naive
76
- * `normaliseField(finding.severity)` here would have re-minted the fingerprint
77
- * of every finding whose spelling the normalisation touched, silently breaking
78
- * dedup against every Issue already filed. {@link fingerprintSeverity} is the
79
- * projection that makes the hash **invariant** under that normalisation: it
80
- * resolves aliases onto their canonical level, keeps an absent severity as the
81
- * empty string (what the raw call produced), and passes an unrecognised value
82
- * through verbatim. Labels are deliberately left on the raw
83
- * lower-case/trim/sort path for the same reason — order- and case-insensitive
84
- * already, and any further folding would move existing shas.
41
+ * Any change to this folding moves existing shas and breaks dedup against
42
+ * filed Issues.
85
43
  *
86
44
  * @param {object} finding
87
45
  * @returns {{ title: string, area: string, primaryFile: string, severity: string, labels: string }}
@@ -97,8 +55,6 @@ function fingerprintComponents(finding) {
97
55
  }
98
56
 
99
57
  /**
100
- * Stable per-finding fingerprint over {title, area, primaryFile, severity, labels}.
101
- *
102
58
  * @param {object} finding
103
59
  * @returns {{ short: string, full: string, components: object }}
104
60
  */
@@ -116,20 +72,10 @@ export function fingerprintFinding(finding) {
116
72
  }
117
73
 
118
74
  /**
119
- * Compute the **location-based semantic key** for a finding. Unlike the
120
- * fingerprint (which folds in the title, so any prose rewording mints a fresh
121
- * sha), the semantic key is stable across a reworded title and a re-severitied
122
- * finding: it is derived solely from the finding's identity *location* —
123
- * `area` (the audit dimension) plus `primaryFile`. Two scans that describe the
124
- * same problem at the same location produce the same semantic key even when
125
- * their titles diverge, so a reworded finding still confirms against the Issue
126
- * that already tracks that location.
75
+ * Location key (`area` + `primaryFile`), stable across rewording. Empty when
76
+ * the location is unknown; an empty key never confirms a match.
127
77
  *
128
- * Returns the empty string when the location is unknown (no `area` and no
129
- * `primaryFile`) — an empty key never confirms a match, exactly as an absent
130
- * fingerprint footer never does.
131
- *
132
- * @param {object} finding — canonical finding ({ area, primaryFile, ... }).
78
+ * @param {object} finding
133
79
  * @returns {string}
134
80
  */
135
81
  export function semanticKeyFor(finding) {
@@ -141,13 +87,7 @@ export function semanticKeyFor(finding) {
141
87
  }
142
88
 
143
89
  /**
144
- * Render the machine-readable semantic-key footer for one or more keys
145
- * (`<!-- audit-semantic-keys: key,key,... -->`). Stamped alongside the
146
- * fingerprint footer by the audit filers so a later reworded finding can
147
- * confirm identity by location when its fingerprint has drifted. Round-trips
148
- * through {@link parseSemanticKeyFooter}. Empty keys are dropped.
149
- *
150
- * @param {string | string[]} keys — one semantic key or an array of them.
90
+ * @param {string | string[]} keys
151
91
  * @returns {string}
152
92
  */
153
93
  export function semanticKeyFooter(keys) {
@@ -159,12 +99,6 @@ export function semanticKeyFooter(keys) {
159
99
  }
160
100
 
161
101
  /**
162
- * Extract semantic keys from an Issue body carrying the semantic-key footer.
163
- * The audit filers stamp the footer via {@link semanticKeyFooter}; the
164
- * confirmation path here, {@link carryProvenanceFooters} and the audit dedup's
165
- * local issue index read it back. Exported alongside its writer so an indexer
166
- * cannot drift into a second parse of the same footer.
167
- *
168
102
  * @param {string} body
169
103
  * @returns {string[]}
170
104
  */
@@ -177,15 +111,8 @@ export function parseSemanticKeyFooter(body) {
177
111
  }
178
112
 
179
113
  /**
180
- * Render the machine-readable audit-label footer
181
- * (`<!-- audit-labels: audit::x,audit::y -->`).
182
- *
183
- * The dedup corpus is listed by `audit::*` label, so a Story carrying none is
184
- * absent from the pool an indexed run matches against — and with an index in
185
- * play the exact lookup is answered locally and never reaches the provider, so
186
- * a fingerprint footer alone cannot rescue it. Carrying the labels through the
187
- * seed is what lets the planning path stamp them without the authoring agent
188
- * being asked to notice them (Story #5307).
114
+ * The dedup corpus is listed by `audit::*` label; this footer lets planning
115
+ * stamp them so the Story stays visible to indexed dedup.
189
116
  *
190
117
  * @param {string | string[]} labels
191
118
  * @returns {string}
@@ -200,8 +127,6 @@ export function auditLabelFooter(labels) {
200
127
  }
201
128
 
202
129
  /**
203
- * Read every `audit-labels` footer out of a body, de-duplicated.
204
- *
205
130
  * @param {string} body
206
131
  * @returns {string[]}
207
132
  */
@@ -214,16 +139,7 @@ export function parseAuditLabelFooter(body) {
214
139
  }
215
140
 
216
141
  /**
217
- * Render the machine-readable fingerprint footer for one or more shas.
218
- *
219
- * Accepts either a single 40-char sha1 or an array of them, so a footer
220
- * can carry every finding sha that a grouped Issue tracks
221
- * (`<!-- audit-fingerprints: sha,sha,... -->`). The comma-joined form
222
- * round-trips through {@link parseFingerprintFooter}. This is the single
223
- * footer renderer shared by `audit-to-stories` and `qa-explore`; neither
224
- * consumer defines its own marker.
225
- *
226
- * @param {string | string[]} shas — full 40-char sha1, or an array of them.
142
+ * @param {string | string[]} shas
227
143
  * @returns {string}
228
144
  */
229
145
  export function fingerprintFooter(shas) {
@@ -239,8 +155,6 @@ export function fingerprintFooter(shas) {
239
155
  }
240
156
 
241
157
  /**
242
- * Extract fingerprint sha1s from an Issue body carrying the footer marker.
243
- *
244
158
  * @param {string} body
245
159
  * @returns {string[]}
246
160
  */
@@ -253,20 +167,11 @@ export function parseFingerprintFooter(body) {
253
167
  }
254
168
 
255
169
  /**
256
- * Collect the comma-separated values out of **every** occurrence of a footer
257
- * marker in `text`, de-duplicated, in first-seen order.
258
- *
259
- * Scanning every occurrence rather than only the first matters for the
260
- * provenance carry (Story #4877): the audit Single-plan seed stamps one footer
261
- * pair per MVP Scope bullet, so a multi-group seed carries several. A
262
- * first-match-only parse silently dropped every group but the first, which
263
- * would have made the carry look wired while leaking most of the provenance.
264
- * Reading all footers is also strictly more correct for issue-body confirmation
265
- * — a body that accumulated two footer lines confirms against either.
170
+ * Values from every occurrence of a footer (a multi-group seed carries
171
+ * several), de-duplicated.
266
172
  *
267
173
  * @param {unknown} text
268
- * @param {RegExp} pattern — a global regex whose first capture group is the
269
- * comma-separated value list.
174
+ * @param {RegExp} pattern — global; capture group 1 is the value list.
270
175
  * @param {(value: string) => boolean} isValid
271
176
  * @returns {string[]}
272
177
  */
@@ -286,34 +191,12 @@ function parseAllFooterValues(text, pattern, isValid) {
286
191
  }
287
192
 
288
193
  /**
289
- * Carry audit dedup provenance from a source document into a target body
290
- * (Story #4877).
291
- *
292
- * The audit sweep's Single-plan path emits a `/mandrel-plan` seed whose MVP Scope
293
- * bullets already carry the `audit-fingerprints` / `audit-semantic-keys`
294
- * footers (Story #4626). Nothing then copied them into the Story `/mandrel-plan`
295
- * actually persisted, so the recommended path filed Stories that the next
296
- * sweep could not recognise and re-filed as new. It was left to the authoring
297
- * agent to notice HTML comments in a one-pager and hand-carry them — a
298
- * remembered step, which is to say no step at all.
299
- *
300
- * This is that carry, as a function: harvest both footers out of `from`, and
301
- * append whichever provenance `into` is missing. It is deliberately:
194
+ * Append the seed's provenance footers missing from `into`, so the next
195
+ * sweep recognises the Story. Additive and idempotent.
302
196
  *
303
- * - **Additive.** Shas and keys already present in `into` are never duplicated,
304
- * and a footer `into` already carries is left exactly as authored.
305
- * - **Union-preserving.** When both sides carry footers the result carries the
306
- * union, so a hand-authored fingerprint is not dropped in favour of the seed's.
307
- * - **Idempotent.** Re-running over its own output is a no-op, so a resumed
308
- * persist cannot stack footers.
309
- * - **Silent on nothing-to-do.** No provenance in `from` returns `into`
310
- * unchanged with `carried: false`, so a non-audit plan run is untouched.
311
- *
312
- * @param {{ from?: string, into?: string }} args — `from` is the provenance
313
- * source (the seed markdown); `into` is the body being persisted.
197
+ * @param {{ from?: string, into?: string }} args
314
198
  * @returns {{ body: string, carried: boolean, fingerprints: string[], semanticKeys: string[] }}
315
- * `body` is the augmented text; `fingerprints` / `semanticKeys` are the values
316
- * newly carried (empty when there was nothing to carry).
199
+ * The arrays hold only newly carried values.
317
200
  */
318
201
  export function carryProvenanceFooters({ from = '', into = '' } = {}) {
319
202
  const body = typeof into === 'string' ? into : '';
@@ -346,9 +229,8 @@ export function carryProvenanceFooters({ from = '', into = '' } = {}) {
346
229
  }
347
230
 
348
231
  /**
349
- * Confirm an issue body's footer actually carries the target sha. Guards
350
- * against a false-positive search hit (e.g. a body that mentions the sha in
351
- * prose rather than in the fingerprint footer).
232
+ * Rejects a hit that mentions the sha only in prose; a body-less issue is
233
+ * trusted.
352
234
  *
353
235
  * @param {{ body?: string }} issue
354
236
  * @param {string} sha
@@ -360,10 +242,7 @@ function issueCarriesFingerprint(issue, sha) {
360
242
  }
361
243
 
362
244
  /**
363
- * Confirm an issue body's footer carries the target semantic key. Unlike
364
- * {@link issueCarriesFingerprint}, this is strict on a missing body — a
365
- * location match is only meaningful when the issue actually carries a
366
- * semantic-key footer to compare against.
245
+ * Strict on a missing body: a location match needs a footer to compare.
367
246
  *
368
247
  * @param {{ body?: string }} issue
369
248
  * @param {string} key
@@ -375,7 +254,6 @@ function issueCarriesSemanticKey(issue, key) {
375
254
  }
376
255
 
377
256
  /**
378
- * Decide the route decision from a confirmed matched issue's state.
379
257
  * @param {{ state?: string }} issue
380
258
  * @returns {'update-existing'|'regression-of-closed'}
381
259
  */
@@ -385,23 +263,8 @@ function decisionForIssue(issue) {
385
263
  }
386
264
 
387
265
  /**
388
- * Resolve the pool that **attributes** a finding, out of everything that
389
- * confirmed it (Story #5045).
390
- *
391
- * Confirmation admits two different strengths of claim, and collapsing them
392
- * was the source of two wrong routes:
393
- *
394
- * - An issue carrying the finding's exact **fingerprint** owns it. That is
395
- * identity: this issue tracks *this* finding.
396
- * - An issue matching only on the location-based **semantic key** is merely
397
- * adjacent: it tracks *a* finding at the same `area␟primaryFile`.
398
- *
399
- * Owners win outright when any exist. Location-only matches are not discarded
400
- * — they are the whole point of the semantic key and remain the pool when
401
- * nothing carries the fingerprint (a reworded finding at an unchanged
402
- * location). The pool is sorted by issue number so a genuine tie resolves to
403
- * the earliest-filed issue rather than to whatever order the search port
404
- * happened to return.
266
+ * Fingerprint owners win outright over location-only neighbours. Sorted so a
267
+ * tie resolves to the earliest-filed issue, not search order.
405
268
  *
406
269
  * @param {Array<{ number: number, state: string, body?: string }>} confirmed
407
270
  * @param {string} sha
@@ -415,28 +278,8 @@ function attributedPool(confirmed, sha) {
415
278
  }
416
279
 
417
280
  /**
418
- * Decide the final route from a confirmed-match pool (issues that both
419
- * surfaced in the candidate/search pass AND carry a confirming footer).
420
- * Shared by both the semantic-first and fingerprint-only code paths so the
421
- * decision enum is identical regardless of how candidates were gathered.
422
- *
423
- * **Attribution decides, not array order (Story #5045).** The pool used to be
424
- * read flat, which produced two wrong answers whenever more than one issue
425
- * confirmed:
426
- *
427
- * 1. Two open matches routed `duplicate` pinned to `open[0]` — whichever
428
- * issue the search port happened to return first. With per-Story
429
- * provenance that pick is answerable rather than arbitrary: the issue
430
- * carrying the finding's own fingerprint owns it, and a sibling matching
431
- * only by location does not.
432
- * 2. Any open match at all masked a closed one, so a finding whose
433
- * fingerprint is owned by a **closed** Story routed `update-existing`
434
- * against an open neighbour — a genuine regression filed as a
435
- * business-as-usual update. Attribution restores it: state is read off the
436
- * owning issue, not off whatever else shares its location.
437
- *
438
- * {@link attributedPool} owns that selection; the decision below reads only
439
- * the pool it returns.
281
+ * State is read off the attributed issue, so an open neighbour cannot mask a
282
+ * regression of the closed owner.
440
283
  *
441
284
  * @param {Array<{ number: number, state: string }>} confirmed
442
285
  * @param {string} sha
@@ -469,15 +312,8 @@ function decideFromConfirmed(confirmed, sha) {
469
312
  }
470
313
 
471
314
  /**
472
- * Keep only the issue records that have the right wire shape AND carry a
473
- * confirming footer. Confirmation is by the exact **fingerprint** footer and,
474
- * when a `semanticKey` is supplied (audit dedup opts in via
475
- * `options.semanticKeyConfirm`), ALSO by the location-based **semantic-key**
476
- * footer. A semantic candidate that merely *looks* similar but carries neither
477
- * footer is dropped here — semantic similarity widens the net; a deterministic
478
- * footer (fingerprint or semantic key) is what confirms identity. The semantic
479
- * key catches a reworded finding whose fingerprint has drifted but whose
480
- * location is unchanged.
315
+ * Only a deterministic footer (fingerprint, or semantic key when supplied)
316
+ * confirms identity.
481
317
  *
482
318
  * @param {Array<unknown>} hits
483
319
  * @param {{ sha: string, semanticKey?: string }} identity
@@ -496,13 +332,7 @@ function confirmCandidates(hits, { sha, semanticKey = '' }) {
496
332
  }
497
333
 
498
334
  /**
499
- * Union candidate pools into one flat pool, keeping first-seen order and
500
- * dropping an issue number an earlier pool already contributed.
501
- *
502
- * The fingerprint pool is passed first, so when both ports return the same
503
- * Issue it is that pool's record — the one retrieved by exact identity — that
504
- * survives into confirmation. Records without a usable number are left for
505
- * {@link confirmCandidates} to reject, exactly as a single port's would be.
335
+ * First-seen wins, so the fingerprint pool's record survives a tie.
506
336
  *
507
337
  * @param {Array<unknown>} pools
508
338
  * @returns {Array<object>}
@@ -519,18 +349,10 @@ function unionCandidatePools(pools) {
519
349
  }
520
350
 
521
351
  /**
522
- * Gather the candidate pool for a finding from every wired port.
523
- *
524
- * A run with a single wired port returns that port's result **verbatim**, so
525
- * the fingerprint-only wiring (`qa-explore`, and every caller that injects no
526
- * semantic port) keeps its behaviour exactly — including how a non-array
527
- * return is handled downstream by {@link confirmCandidates}.
528
- *
529
- * Both ports are awaited together; a rejection from either propagates rather
530
- * than degrading silently to a partial pool.
352
+ * A single port's result is returned verbatim; a rejection propagates.
531
353
  *
532
354
  * @param {object} finding
533
- * @param {string} sha — the finding's full fingerprint.
355
+ * @param {string} sha
534
356
  * @param {{ searchIssues?: Function, searchCandidates?: Function }} ports
535
357
  * @returns {Promise<Array<object>|unknown>}
536
358
  */
@@ -544,55 +366,18 @@ async function gatherCandidates(finding, sha, ports) {
544
366
  }
545
367
 
546
368
  /**
547
- * Route a finding against existing Issues: gather candidates, then confirm.
548
- *
549
- * **Gather — every wired port runs, and their pools union (Story #5079).** The
550
- * two ports answer different questions and neither subsumes the other:
551
- *
552
- * - `searchIssues(sha)` is the **exact** lookup. A fingerprint sha is one
553
- * high-signal term, so it retrieves the Issue whose footer carries it.
554
- * - `searchCandidates(finding)` is the **meaning-first** pass. It widens the
555
- * pool to Issues describing the same problem under a different title, so a
556
- * reworded finding or a moved file still confirms by semantic key.
557
- *
558
- * This was a ternary until Story #5079: an injected semantic port *replaced*
559
- * the fingerprint lookup instead of widening it. Production always injects
560
- * one, so `searchIssues` was dead code on the live path and dedup rested
561
- * entirely on a ~20-token bag-of-words query that does not reliably retrieve
562
- * the Issue. The audit loop consequently re-filed Stories it had already
563
- * filed, against the workflow's "Never open a duplicate Issue" constraint.
564
- * Running both ports and unioning their pools is what closes that loop.
565
- *
566
- * A port that rejects **propagates**. A pool gathered from only some of its
567
- * sources is not a smaller pool, it is an unknown one, so the caller
568
- * (`classifyGroupsAgainstGitHub`) must record a degraded lookup rather than
569
- * report a confident `new`.
570
- *
571
- * **Confirm.** The pooled candidates are filtered down to those that actually
572
- * carry the finding's fingerprint footer — or, when `semanticKeyConfirm` is
573
- * on, its location-based semantic-key footer — then resolved:
574
- * - An open match → `update-existing` (or `duplicate` when more than one
575
- * open issue carries the fingerprint).
576
- * - A closed match (no open match) → `regression-of-closed`.
577
- * - No confirmed match → `new`.
578
- *
579
- * The decision enum is identical however the candidates were gathered.
369
+ * Route a finding against existing Issues. Every wired port runs and pools
370
+ * union: the semantic search must widen, never replace, the exact sha lookup
371
+ * (a bag-of-words query alone re-files duplicates). A rejecting port
372
+ * propagates — a partial pool is unknown, not a confident `new`.
580
373
  *
581
374
  * @param {object} finding
582
375
  * @param {object} ports
583
376
  * @param {(sha: string) => Promise<Array<{ number: number, state: string, body?: string }>>} [ports.searchIssues]
584
- * Fingerprint-keyed lookup over open+closed issues. Runs whenever it is
585
- * supplied. Required when `searchCandidates` is not.
586
377
  * @param {(finding: object) => Promise<Array<{ number: number, state: string, title?: string, body?: string }>>} [ports.searchCandidates]
587
- * Meaning-first candidate search over open+closed issues (and Epic
588
- * sub-issues). Runs whenever it is supplied, alongside `searchIssues` rather
589
- * than instead of it; the union is then confirmed by footer.
590
378
  * @param {object} [options]
591
- * @param {boolean} [options.semanticKeyConfirm=false] — also confirm a
592
- * candidate by the location-based semantic-key footer, not the fingerprint
593
- * alone. Opt-in so the audit dedup path catches a reworded finding at an
594
- * unchanged location while the qa-explore path (which does not stamp
595
- * semantic-key footers) stays fingerprint-exact and byte-identical.
379
+ * @param {boolean} [options.semanticKeyConfirm=false] — opt-in; qa-explore
380
+ * stamps no semantic keys.
596
381
  * @returns {Promise<{ decision: 'new'|'update-existing'|'duplicate'|'regression-of-closed', matchedIssue: object|null, fingerprint: string }>}
597
382
  */
598
383
  export async function routeFinding(
@@ -612,14 +397,11 @@ export async function routeFinding(
612
397
  const { full: sha } = fingerprintFinding(finding);
613
398
  const semanticKey = options.semanticKeyConfirm ? semanticKeyFor(finding) : '';
614
399
 
615
- // Gather: every wired port runs, and their pools union (Story #5079).
616
400
  const hits = await gatherCandidates(finding, sha, {
617
401
  searchIssues,
618
402
  searchCandidates,
619
403
  });
620
404
 
621
- // Confirm identity by fingerprint footer (and, when opted in, the
622
- // location-based semantic-key footer) over the pooled candidates.
623
405
  const confirmed = confirmCandidates(hits, { sha, semanticKey });
624
406
 
625
407
  return decideFromConfirmed(confirmed, sha);