mandrel 2.60.0 → 2.62.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 (662) 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/merge-queue.js +158 -0
  318. package/.agents/scripts/lib/orchestration/pinned-identifier-lint.js +17 -57
  319. package/.agents/scripts/lib/orchestration/plan-context.js +52 -303
  320. package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +22 -79
  321. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +5 -31
  322. package/.agents/scripts/lib/orchestration/plan-metrics.js +29 -108
  323. package/.agents/scripts/lib/orchestration/plan-navigation.js +8 -27
  324. package/.agents/scripts/lib/orchestration/plan-persist/acceptance-handle-repair.js +12 -49
  325. package/.agents/scripts/lib/orchestration/plan-persist/audit-provenance.js +18 -73
  326. package/.agents/scripts/lib/orchestration/plan-persist/changes-repair.js +14 -78
  327. package/.agents/scripts/lib/orchestration/plan-persist/cross-plan-links.js +6 -30
  328. package/.agents/scripts/lib/orchestration/plan-persist/epic-adoption.js +14 -65
  329. package/.agents/scripts/lib/orchestration/plan-persist/epic-ops.js +21 -76
  330. package/.agents/scripts/lib/orchestration/plan-persist/external-deps.js +6 -43
  331. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +14 -68
  332. package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +9 -41
  333. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +49 -248
  334. package/.agents/scripts/lib/orchestration/plan-persist/soft-findings.js +2 -12
  335. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +85 -368
  336. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +8 -38
  337. package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +30 -190
  338. package/.agents/scripts/lib/orchestration/plan-persist/wave-collision-gate.js +9 -49
  339. package/.agents/scripts/lib/orchestration/plan-persist/wave-serialisation.js +7 -28
  340. package/.agents/scripts/lib/orchestration/plan-reachability.js +13 -42
  341. package/.agents/scripts/lib/orchestration/plan-run-labels/reap.js +16 -91
  342. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +16 -54
  343. package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +10 -52
  344. package/.agents/scripts/lib/orchestration/planning/authoring-context.js +14 -109
  345. package/.agents/scripts/lib/orchestration/planning/memory-pool-advisory.js +11 -83
  346. package/.agents/scripts/lib/orchestration/pr-watch.js +48 -306
  347. package/.agents/scripts/lib/orchestration/project-meta-cache.js +15 -80
  348. package/.agents/scripts/lib/orchestration/project-meta-resolver.js +10 -51
  349. package/.agents/scripts/lib/orchestration/reassert-status-column.js +12 -76
  350. package/.agents/scripts/lib/orchestration/remote-verifier.js +12 -36
  351. package/.agents/scripts/lib/orchestration/resolve-stories.js +33 -164
  352. package/.agents/scripts/lib/orchestration/retro-proposals.js +66 -361
  353. package/.agents/scripts/lib/orchestration/review-base-ref.js +9 -43
  354. package/.agents/scripts/lib/orchestration/review-depth.js +12 -94
  355. package/.agents/scripts/lib/orchestration/review-providers/codex.js +10 -111
  356. package/.agents/scripts/lib/orchestration/review-providers/degraded-gates.js +13 -71
  357. package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +7 -51
  358. package/.agents/scripts/lib/orchestration/review-providers/mi-exemptions.js +8 -53
  359. package/.agents/scripts/lib/orchestration/review-providers/native.js +30 -214
  360. package/.agents/scripts/lib/orchestration/review-providers/parse-findings.js +7 -52
  361. package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +4 -33
  362. package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +11 -71
  363. package/.agents/scripts/lib/orchestration/review-providers/scoped-lint.js +19 -131
  364. package/.agents/scripts/lib/orchestration/review-providers/security-review.js +6 -89
  365. package/.agents/scripts/lib/orchestration/review-providers/types.js +26 -56
  366. package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +3 -46
  367. package/.agents/scripts/lib/orchestration/run-epilogue.js +40 -199
  368. package/.agents/scripts/lib/orchestration/run-scoped-config.js +13 -81
  369. package/.agents/scripts/lib/orchestration/single-story-close/close-note.js +7 -34
  370. package/.agents/scripts/lib/orchestration/single-story-close/failed-terminal.js +16 -89
  371. package/.agents/scripts/lib/orchestration/single-story-close/gate-log.js +18 -109
  372. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +190 -280
  373. package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +18 -80
  374. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +103 -97
  375. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +8 -64
  376. package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +183 -485
  377. package/.agents/scripts/lib/orchestration/single-story-close/phases/conventional-subject.js +30 -134
  378. package/.agents/scripts/lib/orchestration/single-story-close/phases/graphql-preflight.js +9 -50
  379. package/.agents/scripts/lib/orchestration/single-story-close/phases/lock-wait-pending.js +49 -0
  380. package/.agents/scripts/lib/orchestration/single-story-close/phases/normalize-pr-title.js +13 -86
  381. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +20 -95
  382. package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +46 -203
  383. package/.agents/scripts/lib/orchestration/single-story-close/phases/pre-gate-steps.js +8 -50
  384. package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +12 -83
  385. package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +6 -39
  386. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +1 -6
  387. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-outcome.js +4 -28
  388. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-override.js +6 -51
  389. package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +6 -34
  390. package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +23 -121
  391. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +110 -290
  392. package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +15 -69
  393. package/.agents/scripts/lib/orchestration/story-body-gate.js +4 -23
  394. package/.agents/scripts/lib/orchestration/story-close/baseline-upward-writeback.js +50 -179
  395. package/.agents/scripts/lib/orchestration/story-close/context-budget-writeback.js +11 -41
  396. package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +23 -311
  397. package/.agents/scripts/lib/orchestration/story-close/phases/local-lens-review.js +22 -147
  398. package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +16 -67
  399. package/.agents/scripts/lib/orchestration/story-deliver-terminal-schema.js +12 -68
  400. package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +42 -201
  401. package/.agents/scripts/lib/orchestration/story-follow-ups.js +43 -245
  402. package/.agents/scripts/lib/orchestration/story-init-envelope.js +4 -23
  403. package/.agents/scripts/lib/orchestration/story-init-remote.js +2 -6
  404. package/.agents/scripts/lib/orchestration/story-reachability.js +3 -23
  405. package/.agents/scripts/lib/orchestration/task-body-validator.js +12 -126
  406. package/.agents/scripts/lib/orchestration/ticket-lease.js +28 -131
  407. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +15 -149
  408. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +5 -33
  409. package/.agents/scripts/lib/orchestration/ticket-validator.js +39 -181
  410. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +51 -244
  411. package/.agents/scripts/lib/orchestration/ticketing/reads.js +39 -250
  412. package/.agents/scripts/lib/orchestration/ticketing/state.js +14 -68
  413. package/.agents/scripts/lib/orchestration/ticketing/transition.js +46 -263
  414. package/.agents/scripts/lib/orchestration/ticketing.js +2 -26
  415. package/.agents/scripts/lib/orchestration/verify-credit.js +18 -79
  416. package/.agents/scripts/lib/orchestration/worktree-dirty.js +5 -30
  417. package/.agents/scripts/lib/path-security.js +3 -6
  418. package/.agents/scripts/lib/plan-phase-cleanup.js +9 -49
  419. package/.agents/scripts/lib/preflight-runner.js +13 -69
  420. package/.agents/scripts/lib/process-group.js +143 -0
  421. package/.agents/scripts/lib/project-root.js +2 -8
  422. package/.agents/scripts/lib/provider-factory.js +2 -25
  423. package/.agents/scripts/lib/qa/console-allowlist.js +10 -59
  424. package/.agents/scripts/lib/qa/qa-session.js +15 -69
  425. package/.agents/scripts/lib/qa/redact-evidence.js +18 -129
  426. package/.agents/scripts/lib/qa/resolve-qa-contract.js +26 -135
  427. package/.agents/scripts/lib/qa/resolve-selection.js +16 -84
  428. package/.agents/scripts/lib/reserved-test-ids.js +9 -47
  429. package/.agents/scripts/lib/runtime-deps/dep-resolution.js +13 -53
  430. package/.agents/scripts/lib/runtime-deps/ensure-installed.js +10 -44
  431. package/.agents/scripts/lib/runtime-deps/manifest.js +10 -30
  432. package/.agents/scripts/lib/runtime-deps/parser-major.js +15 -51
  433. package/.agents/scripts/lib/runtime-deps/preflight.js +4 -22
  434. package/.agents/scripts/lib/runtime-deps/scan-imports.js +11 -55
  435. package/.agents/scripts/lib/signals/detectors/common.js +12 -38
  436. package/.agents/scripts/lib/signals/index.js +2 -19
  437. package/.agents/scripts/lib/signals/schema.js +14 -109
  438. package/.agents/scripts/lib/signals/write.js +2 -11
  439. package/.agents/scripts/lib/single-story/confirm-merge.js +31 -72
  440. package/.agents/scripts/lib/single-story/story-merged-notify.js +8 -49
  441. package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +4 -26
  442. package/.agents/scripts/lib/single-story-sweep/protection.js +13 -100
  443. package/.agents/scripts/lib/single-story-sweep/sweep-lock.js +60 -258
  444. package/.agents/scripts/lib/single-story-sweep.js +14 -97
  445. package/.agents/scripts/lib/skills/parse-skill.js +13 -59
  446. package/.agents/scripts/lib/skills/skills-index.js +8 -29
  447. package/.agents/scripts/lib/skills/walk-skill-files.js +17 -78
  448. package/.agents/scripts/lib/source-extensions.js +11 -42
  449. package/.agents/scripts/lib/source-text/strip-js-comments.js +8 -41
  450. package/.agents/scripts/lib/stdio-flush.js +9 -36
  451. package/.agents/scripts/lib/story-adjacency.js +8 -40
  452. package/.agents/scripts/lib/story-body/body-format-lints.js +22 -83
  453. package/.agents/scripts/lib/story-body/footer-block.js +11 -44
  454. package/.agents/scripts/lib/story-body/story-body.js +83 -358
  455. package/.agents/scripts/lib/temp-retention.js +42 -143
  456. package/.agents/scripts/lib/templates/decomposer-prompts.js +11 -65
  457. package/.agents/scripts/lib/test-env.js +12 -65
  458. package/.agents/scripts/lib/test-run-credit.js +10 -65
  459. package/.agents/scripts/lib/test-runner-contract.js +19 -74
  460. package/.agents/scripts/lib/test-temp.js +38 -184
  461. package/.agents/scripts/lib/test-tiers.js +12 -96
  462. package/.agents/scripts/lib/ticket-body-sections.js +21 -96
  463. package/.agents/scripts/lib/transpile.js +15 -74
  464. package/.agents/scripts/lib/util/concurrent-map.js +6 -25
  465. package/.agents/scripts/lib/util/parse-id-list.js +8 -34
  466. package/.agents/scripts/lib/util/poll-loop.js +8 -28
  467. package/.agents/scripts/lib/util/with-timeout.js +2 -11
  468. package/.agents/scripts/lib/validation-evidence.js +21 -96
  469. package/.agents/scripts/lib/wave-runner/footprint.js +17 -70
  470. package/.agents/scripts/lib/wave-runner/live-probe.js +53 -221
  471. package/.agents/scripts/lib/wave-runner/ready-set.js +72 -301
  472. package/.agents/scripts/lib/workers/crap-worker.js +11 -64
  473. package/.agents/scripts/lib/workers/maintainability-report-worker.js +8 -45
  474. package/.agents/scripts/lib/workers/maintainability-worker.js +5 -21
  475. package/.agents/scripts/lib/workers/serve-worker-messages.js +2 -18
  476. package/.agents/scripts/lib/workflow-closure.js +22 -105
  477. package/.agents/scripts/lib/workspace-provisioner.js +16 -54
  478. package/.agents/scripts/lib/worktree/git-hooks.js +15 -60
  479. package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +20 -60
  480. package/.agents/scripts/lib/worktree/lifecycle/merge-reachability.js +10 -62
  481. package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +22 -86
  482. package/.agents/scripts/lib/worktree/lifecycle/reap.js +24 -126
  483. package/.agents/scripts/lib/worktree/lifecycle-manager.js +2 -20
  484. package/.agents/scripts/lib/worktree/node-modules-strategy.js +46 -180
  485. package/.agents/scripts/lib/worktree-manager.js +15 -40
  486. package/.agents/scripts/lint-issue-body.js +12 -68
  487. package/.agents/scripts/mandrel-update-preflight.js +10 -70
  488. package/.agents/scripts/merge-baseline.js +30 -104
  489. package/.agents/scripts/nav-registry-diff.js +22 -108
  490. package/.agents/scripts/notify.js +12 -69
  491. package/.agents/scripts/plan-context.js +27 -111
  492. package/.agents/scripts/plan-critics.js +12 -66
  493. package/.agents/scripts/plan-persist.js +31 -148
  494. package/.agents/scripts/plan-run-epilogue.js +11 -37
  495. package/.agents/scripts/pr-watch-with-update.js +76 -267
  496. package/.agents/scripts/providers/github/auth.js +3 -8
  497. package/.agents/scripts/providers/github/blocked-by-add.js +14 -61
  498. package/.agents/scripts/providers/github/board-add.js +5 -21
  499. package/.agents/scripts/providers/github/branch-protection.js +11 -43
  500. package/.agents/scripts/providers/github/cache.js +2 -14
  501. package/.agents/scripts/providers/github/comments.js +7 -40
  502. package/.agents/scripts/providers/github/compose.js +3 -19
  503. package/.agents/scripts/providers/github/errors.js +22 -125
  504. package/.agents/scripts/providers/github/issues.js +31 -123
  505. package/.agents/scripts/providers/github/labels.js +24 -124
  506. package/.agents/scripts/providers/github/mappers.js +5 -27
  507. package/.agents/scripts/providers/github/merge-methods.js +3 -22
  508. package/.agents/scripts/providers/github/project-board.js +2 -17
  509. package/.agents/scripts/providers/github/projects-v2-graphql.js +3 -6
  510. package/.agents/scripts/providers/github/request-helpers.js +5 -32
  511. package/.agents/scripts/providers/github/search-budget.js +9 -39
  512. package/.agents/scripts/providers/github/search-query.js +5 -26
  513. package/.agents/scripts/providers/github/sub-issue-add.js +15 -65
  514. package/.agents/scripts/providers/github/sub-issues.js +7 -36
  515. package/.agents/scripts/providers/github/tickets.js +32 -134
  516. package/.agents/scripts/providers/github.js +18 -59
  517. package/.agents/scripts/prune-plan-run-labels.js +12 -46
  518. package/.agents/scripts/quality-preview.js +35 -220
  519. package/.agents/scripts/resolve-doc-tiers.js +3 -26
  520. package/.agents/scripts/resolve-stories.js +16 -67
  521. package/.agents/scripts/resync-status-column.js +6 -25
  522. package/.agents/scripts/run-tests.js +29 -104
  523. package/.agents/scripts/single-story-close.js +23 -135
  524. package/.agents/scripts/single-story-confirm-merge.js +32 -139
  525. package/.agents/scripts/single-story-init.js +47 -209
  526. package/.agents/scripts/stories-wave-tick.js +102 -472
  527. package/.agents/scripts/sync-agentrc.js +3 -21
  528. package/.agents/scripts/sync-claude-agents.js +9 -55
  529. package/.agents/scripts/sync-claude-commands.js +20 -110
  530. package/.agents/scripts/test-wrapper.js +6 -43
  531. package/.agents/scripts/update-coverage-baseline.js +5 -22
  532. package/.agents/scripts/update-crap-baseline.js +7 -30
  533. package/.agents/scripts/update-duplication-baseline.js +16 -92
  534. package/.agents/scripts/update-maintainability-baseline.js +8 -62
  535. package/.agents/scripts/update-ticket-state.js +1 -7
  536. package/.agents/scripts/validate-skills.js +6 -26
  537. package/.agents/templates/agent-protocol.md +2 -2
  538. package/.agents/templates/docs/audit-sweep-runbook.md +3 -4
  539. package/.agents/workflows/audit-accessibility.md +4 -7
  540. package/.agents/workflows/audit-adrs.md +3 -6
  541. package/.agents/workflows/audit-architecture.md +3 -11
  542. package/.agents/workflows/audit-baselines.md +6 -9
  543. package/.agents/workflows/audit-clean-code.md +8 -12
  544. package/.agents/workflows/audit-data-model.md +3 -7
  545. package/.agents/workflows/audit-dependencies.md +4 -7
  546. package/.agents/workflows/audit-devops.md +4 -8
  547. package/.agents/workflows/audit-documentation.md +1 -4
  548. package/.agents/workflows/audit-mobile.md +4 -7
  549. package/.agents/workflows/audit-navigability.md +3 -6
  550. package/.agents/workflows/audit-performance.md +2 -4
  551. package/.agents/workflows/audit-privacy.md +4 -7
  552. package/.agents/workflows/audit-quality.md +4 -7
  553. package/.agents/workflows/audit-security.md +4 -7
  554. package/.agents/workflows/audit-seo.md +4 -7
  555. package/.agents/workflows/audit-sre.md +4 -7
  556. package/.agents/workflows/audit-to-stories.md +17 -30
  557. package/.agents/workflows/audit-ux-ui.md +4 -7
  558. package/.agents/workflows/helpers/audit-lens-core.md +1 -1
  559. package/.agents/workflows/helpers/code-quality-guardrails.md +12 -15
  560. package/.agents/workflows/helpers/deliver-digest.md +6 -4
  561. package/.agents/workflows/helpers/deliver-reference.md +114 -188
  562. package/.agents/workflows/helpers/deliver-story-reference.md +189 -533
  563. package/.agents/workflows/helpers/plan-reference.md +86 -139
  564. package/.agents/workflows/helpers/qa-core.md +12 -0
  565. package/.agents/workflows/memory-consolidate.md +1 -1
  566. package/.agents/workflows/qa-assist.md +27 -71
  567. package/.agents/workflows/qa-explore.md +19 -59
  568. package/.agents/workflows/qa-run.md +11 -33
  569. package/README.md +1 -1
  570. package/bin/mandrel.js +5 -46
  571. package/bin/postinstall.js +18 -107
  572. package/docs/CHANGELOG.md +32 -0
  573. package/lib/cli/doctor.js +11 -71
  574. package/lib/cli/init.js +26 -165
  575. package/lib/cli/migrate.js +5 -64
  576. package/lib/cli/registry.js +84 -467
  577. package/lib/cli/sync-agents.js +4 -64
  578. package/lib/cli/sync-commands.js +11 -64
  579. package/lib/cli/sync.js +34 -213
  580. package/lib/cli/uninstall.js +40 -219
  581. package/lib/cli/update.js +105 -661
  582. package/lib/cli/version-check.js +8 -72
  583. package/lib/cli/version-helpers.js +14 -87
  584. package/lib/migrations/helpers/retire-agentrc-key.js +11 -52
  585. package/lib/migrations/index.js +15 -92
  586. package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +2 -15
  587. package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +1 -13
  588. package/lib/migrations/steps/2.11.0-retire-max-seed-words.js +2 -15
  589. package/lib/migrations/steps/2.2.0-retire-epic-ac-tags.js +9 -38
  590. package/lib/migrations/steps/2.20.0-retire-codebase-snapshot.js +1 -13
  591. package/lib/migrations/steps/2.32.0-retire-lint-baseline-command.js +2 -27
  592. package/lib/migrations/steps/2.57.0-retire-delivery-limit-knobs.js +2 -23
  593. package/lib/migrations/steps/2.57.0-retire-planning-limit-knobs.js +2 -27
  594. package/lib/migrations/steps/2.60.0-retire-audit-results-autofile.js +2 -21
  595. package/lib/migrations/steps/strip-removed-agentrc-keys.js +333 -0
  596. package/package.json +16 -14
  597. package/.agents/docs/SDLC.md +0 -590
  598. package/.agents/docs/quality-gates.md +0 -1183
  599. package/.agents/rules/known-tooling-behavior.md +0 -200
  600. package/.agents/rules/orchestration-error-handling.md +0 -61
  601. package/.agents/rules/test-seams.md +0 -59
  602. package/.agents/schemas/baselines/lighthouse.schema.json +0 -59
  603. package/.agents/schemas/baselines/lint.schema.json +0 -47
  604. package/.agents/scripts/check-action-pinning.js +0 -260
  605. package/.agents/scripts/check-audit-attribution.js +0 -302
  606. package/.agents/scripts/check-baseline-drift.js +0 -211
  607. package/.agents/scripts/check-baseline-scope.js +0 -362
  608. package/.agents/scripts/check-generated-validator.js +0 -202
  609. package/.agents/scripts/check-knip-entries.js +0 -159
  610. package/.agents/scripts/check-lifecycle-lint.js +0 -294
  611. package/.agents/scripts/check-pinned-override-notes.js +0 -102
  612. package/.agents/scripts/check-schema-references.js +0 -368
  613. package/.agents/scripts/check-test-portability.js +0 -512
  614. package/.agents/scripts/check-workflow-citations.js +0 -218
  615. package/.agents/scripts/check-workflow-cli-lint.js +0 -299
  616. package/.agents/scripts/check-workflow-timeouts.js +0 -291
  617. package/.agents/scripts/install-matrix-assert.js +0 -326
  618. package/.agents/scripts/lib/audit-advisories.js +0 -195
  619. package/.agents/scripts/lib/audit-attribution.js +0 -134
  620. package/.agents/scripts/lib/baselines/drift-detector.js +0 -351
  621. package/.agents/scripts/lib/baselines/kinds/lighthouse.js +0 -87
  622. package/.agents/scripts/lib/baselines/kinds/lint.js +0 -184
  623. package/.agents/scripts/lib/baselines/orphan-pruner.js +0 -233
  624. package/.agents/scripts/lib/baselines/scope-assert.js +0 -223
  625. package/.agents/scripts/lib/baselines/scope-inventory.js +0 -314
  626. package/.agents/scripts/lib/c8-cli-path.js +0 -21
  627. package/.agents/scripts/lib/config/gates/lighthouse.schema.js +0 -51
  628. package/.agents/scripts/lib/config/gates/lint.schema.js +0 -18
  629. package/.agents/scripts/lib/dynamic-workflow/architecture-report-contract.js +0 -70
  630. package/.agents/scripts/lib/dynamic-workflow/audit-orchestrator.js +0 -284
  631. package/.agents/scripts/lib/dynamic-workflow/clean-code-report-contract.js +0 -80
  632. package/.agents/scripts/lib/dynamic-workflow/degraded-coverage.js +0 -81
  633. package/.agents/scripts/lib/dynamic-workflow/documentation-report-contract.js +0 -87
  634. package/.agents/scripts/lib/dynamic-workflow/performance-report-contract.js +0 -74
  635. package/.agents/scripts/lib/dynamic-workflow/quality-report-contract.js +0 -90
  636. package/.agents/scripts/lib/dynamic-workflow/report-contract-core.js +0 -43
  637. package/.agents/scripts/lib/dynamic-workflow/security-report-contract.js +0 -83
  638. package/.agents/scripts/lib/fs-walk.js +0 -52
  639. package/.agents/scripts/lib/knip-config-resolver.js +0 -181
  640. package/.agents/scripts/lib/knip-entry-sync.js +0 -452
  641. package/.agents/scripts/lib/pinned-override-notes.js +0 -88
  642. package/.agents/scripts/lib/pinned-override-resolve.js +0 -212
  643. package/.agents/scripts/lib/test-isolate/cli-options.js +0 -93
  644. package/.agents/scripts/lib/test-isolate/env-snapshot-loader.js +0 -52
  645. package/.agents/scripts/lib/test-isolate/list-files.js +0 -90
  646. package/.agents/scripts/lib/test-isolate/parse-tap.js +0 -75
  647. package/.agents/scripts/lib/test-isolate/progress-log.js +0 -45
  648. package/.agents/scripts/lib/test-isolate/render-report.js +0 -97
  649. package/.agents/scripts/lib/test-isolate/run-isolate.js +0 -87
  650. package/.agents/scripts/lib/test-isolate/runner.js +0 -483
  651. package/.agents/scripts/lib/test-profile/parse-tap.js +0 -136
  652. package/.agents/scripts/lib/test-profile/render-report.js +0 -45
  653. package/.agents/scripts/lint-label-vocabulary.js +0 -214
  654. package/.agents/scripts/post-structured-comment.js +0 -127
  655. package/.agents/scripts/provision-git-hooks.js +0 -85
  656. package/.agents/scripts/prune-baseline-orphans.js +0 -181
  657. package/.agents/scripts/run-coverage.js +0 -197
  658. package/.agents/scripts/run-lint.js +0 -133
  659. package/.agents/scripts/run-test-profile.js +0 -129
  660. package/.agents/scripts/run-verify.js +0 -125
  661. package/.agents/scripts/test-isolate.js +0 -55
  662. package/.agents/scripts/update-dead-exports-baseline.js +0 -321
@@ -1,31 +1,7 @@
1
1
  /**
2
- * lib/findings/audit-ledger.js — Cross-run audit findings ledger.
3
- *
4
- * Without a committed memory of what a prior sweep already saw, every
5
- * `/audit-to-stories` run re-litigates the whole backlog from zero: it cannot
6
- * tell a brand-new finding from one already filed, an intentionally-rejected
7
- * finding from an unseen one, or a genuine regression from routine churn. The
8
- * ledger is that memory. It is a small committed JSON file
9
- * (`baselines/audit-ledger.json`, the same envelope shape as the arch-cycles
10
- * baseline — `{ $schema, generatedAt, entries: [] }`) keyed by each finding's
11
- * shared-helper fingerprint plus a location-based `semanticKey` that survives a
12
- * reworded title.
13
- *
14
- * Each entry carries a lifecycle `status`:
15
- * - `new` — seen, not yet filed as an Issue.
16
- * - `filed` — an Issue was opened; re-detections are known, not new.
17
- * - `fixed` — the tracking Issue closed as completed.
18
- * - `accepted-risk`— the tracking Issue closed as `not_planned`; the finding
19
- * is deliberately rejected and is SUPPRESSED on re-detect.
20
- * - `regressed` — a `fixed` finding re-appeared (closed-completed Issue,
21
- * finding detected again).
22
- *
23
- * `reconcileLedger` folds a fresh scan and the live Issue states onto the prior
24
- * ledger, returning the next ledger plus a per-finding classification whose
25
- * `action` (`propose` | `known` | `suppress` | `regressed`) tells the caller
26
- * whether to open a Story. Pure: filesystem access is confined to the tiny
27
- * {@link readLedger} / {@link writeLedger} helpers, which take an injectable
28
- * `fs` so tests never touch disk.
2
+ * lib/findings/audit-ledger.js — committed cross-run memory of audit
3
+ * findings, keyed by fingerprint and `semanticKey`. Status: `new` · `filed` ·
4
+ * `fixed` · `accepted-risk` (closed `not_planned`; suppressed) · `regressed`.
29
5
  */
30
6
 
31
7
  import nodeFs from 'node:fs';
@@ -36,11 +12,7 @@ export const DEFAULT_LEDGER_PATH = 'baselines/audit-ledger.json';
36
12
  const LEDGER_SCHEMA_URL =
37
13
  'https://mandrel.dev/baselines/audit-ledger.schema.json';
38
14
 
39
- // Entry lifecycle states — `new | filed | fixed | accepted-risk | regressed`.
40
- // The reconcile policy in `decideStatus` is the single source of truth.
41
-
42
15
  /**
43
- * Build an empty ledger envelope (arch-cycles-baseline shape).
44
16
  * @param {string} [now] — ISO timestamp to stamp.
45
17
  * @returns {{ $schema: string, generatedAt: string, entries: [] }}
46
18
  */
@@ -49,18 +21,9 @@ function createEmptyLedger(now = new Date().toISOString()) {
49
21
  }
50
22
 
51
23
  /**
52
- * Compute a finding's stable identity: its fingerprint (title-sensitive) and
53
- * its location-based semantic key (title-insensitive).
24
+ * `toCanonical` is injected: importing the audit adapter would close a cycle.
54
25
  *
55
- * The projection onto the canonical identity is the **caller's**, injected as
56
- * `toCanonical`. That is what lets this module live beside `route-finding.js`
57
- * in the shared findings layer: the audit pipeline's own adapter
58
- * (`lib/audit-to-stories/finding-adapter.js`) imports *from* here, so importing
59
- * it back would close a `findings → audit-to-stories → findings` cycle that
60
- * `check-arch-cycles` rightly refuses. A caller that already holds canonical
61
- * findings passes nothing.
62
- *
63
- * @param {object} finding — a parsed/stamped audit finding.
26
+ * @param {object} finding
64
27
  * @param {(finding: object) => object} [toCanonical]
65
28
  * @returns {{ fingerprint: string, semanticKey: string }}
66
29
  */
@@ -73,8 +36,7 @@ function findingIdentity(finding, toCanonical) {
73
36
  }
74
37
 
75
38
  /**
76
- * Read the ledger from disk. Returns an empty ledger when the file is absent
77
- * or unparseable — a missing memory is an empty memory, never a hard error.
39
+ * An absent or unparseable file reads as an empty ledger, never an error.
78
40
  * @param {string} filePath
79
41
  * @param {{ fs?: typeof import('node:fs') }} [deps]
80
42
  * @returns {{ $schema?: string, generatedAt?: string, entries: object[] }}
@@ -92,8 +54,6 @@ export function readLedger(filePath, { fs } = {}) {
92
54
  }
93
55
 
94
56
  /**
95
- * Persist the ledger to disk with a stable 2-space indent and a trailing
96
- * newline (so the committed file diffs cleanly).
97
57
  * @param {string} filePath
98
58
  * @param {object} ledger
99
59
  * @param {{ fs?: typeof import('node:fs'), path?: typeof import('node:path') }} [deps]
@@ -107,7 +67,6 @@ export function writeLedger(filePath, ledger, { fs, path } = {}) {
107
67
  }
108
68
 
109
69
  /**
110
- * Index a ledger's entries by fingerprint and by semanticKey for O(1) lookup.
111
70
  * @param {{ entries?: object[] }} ledger
112
71
  */
113
72
  function indexLedger(ledger) {
@@ -121,9 +80,7 @@ function indexLedger(ledger) {
121
80
  }
122
81
 
123
82
  /**
124
- * Resolve the effective Issue state for a finding: an explicit override in
125
- * `issueStates` (keyed by fingerprint then semanticKey) wins over whatever the
126
- * prior ledger entry recorded.
83
+ * An `issueStates` override beats the recorded Issue.
127
84
  * @param {{ fingerprint: string, semanticKey: string }} id
128
85
  * @param {object|null} existing
129
86
  * @param {Record<string, { state?: string, stateReason?: string|null, number?: number }>} issueStates
@@ -141,9 +98,6 @@ function resolveIssueState(id, existing, issueStates) {
141
98
  }
142
99
 
143
100
  /**
144
- * The four verdicts the policy can reach, spelled once. Deduping them keeps
145
- * `decideStatus` readable as the decision table it is, rather than eight
146
- * near-identical object literals.
147
101
  * @type {Record<string, { status: string, action: string }>}
148
102
  */
149
103
  const VERDICT = Object.freeze({
@@ -154,31 +108,20 @@ const VERDICT = Object.freeze({
154
108
  });
155
109
 
156
110
  /**
157
- * Decide the finding's next status + action from its prior ledger state and
158
- * the live Issue state. This is the whole reconciliation policy in one place.
111
+ * The whole reconciliation policy.
159
112
  * @param {object|null} existing — prior ledger entry (or null when unseen).
160
113
  * @param {{ state: string, stateReason: string|null }|null} issue
161
114
  * @returns {{ status: string, action: 'propose'|'known'|'suppress'|'regressed' }}
162
115
  */
163
116
  function decideStatus(existing, issue) {
164
- // A closed Issue is the strongest signal — its close reason drives the
165
- // verdict, and it is read FIRST so a recorded `filed` can never outrank it.
117
+ // A closed Issue outranks any recorded status.
166
118
  if (issue && issue.state === 'closed') {
167
119
  return issue.stateReason === 'not_planned'
168
120
  ? VERDICT.suppress
169
- : // Closed as completed (or unspecified) but the finding is in this scan
170
- // → it came back. That is a regression, not a fresh proposal.
171
- VERDICT.regressed;
121
+ : VERDICT.regressed;
172
122
  }
173
123
 
174
- // An OPEN tracking Issue means the finding has been filed, whatever the prior
175
- // entry said — including when there is no prior entry at all. Until Story
176
- // #5305 nothing in the package ever assigned `filed`, so this fell through to
177
- // `new`/`propose` on every run and the `filed` arm below was unreachable in
178
- // production: the ledger suppressed nothing, and only the GitHub-search dedup
179
- // stopped a sweep re-filing what it had already filed. Reading it before the
180
- // `!existing` guard is what makes a record pass correct on its FIRST run
181
- // rather than its second.
124
+ // An open Issue means filed even with no prior entry.
182
125
  const unseen = issue?.state === 'open' ? VERDICT.filed : VERDICT.propose;
183
126
  if (!existing) return unseen;
184
127
 
@@ -187,9 +130,7 @@ function decideStatus(existing, issue) {
187
130
  return VERDICT.suppress;
188
131
  case 'filed':
189
132
  return VERDICT.filed;
190
- // Recorded fixed, yet detected again with no closed-Issue evidence → treat
191
- // as a regression the operator should look at. An open Issue does not
192
- // soften that: the finding came back either way.
133
+ // Recorded fixed yet detected again: a regression, open Issue or not.
193
134
  case 'fixed':
194
135
  return VERDICT.regressed;
195
136
  case 'regressed':
@@ -200,17 +141,15 @@ function decideStatus(existing, issue) {
200
141
  }
201
142
 
202
143
  /**
203
- * Fold a fresh scan and the live Issue states onto the prior ledger.
144
+ * Fold a scan and live Issue states onto the prior ledger; untouched entries
145
+ * are preserved.
204
146
  *
205
147
  * @param {object} params
206
- * @param {{ entries?: object[] }} [params.ledger] — prior ledger (default empty).
207
- * @param {Array<object>} params.findings — parsed/stamped audit findings from this scan.
148
+ * @param {{ entries?: object[] }} [params.ledger]
149
+ * @param {Array<object>} params.findings
208
150
  * @param {Record<string, { state?: string, stateReason?: string|null, number?: number }>} [params.issueStates]
209
- * Live Issue state keyed by fingerprint (or semanticKey). Optional — when a
210
- * prior entry already records the Issue, that is used.
211
- * @param {string} [params.now] — ISO timestamp for firstSeen/lastSeen stamping.
212
- * @param {(finding: object) => object} [params.toCanonical] — projection onto
213
- * the canonical identity; omit when `findings` are already canonical.
151
+ * @param {string} [params.now]
152
+ * @param {(finding: object) => object} [params.toCanonical]
214
153
  * @returns {{
215
154
  * ledger: { $schema: string, generatedAt: string, entries: object[] },
216
155
  * classifications: Array<{ fingerprint: string, semanticKey: string, status: string, action: string, issue: object|null }>,
@@ -228,7 +167,6 @@ export function reconcileLedger({
228
167
  }
229
168
 
230
169
  const { byFingerprint, bySemanticKey } = indexLedger(ledger);
231
- // Preserve any prior entries NOT touched by this scan (their memory survives).
232
170
  const nextByFingerprint = new Map(byFingerprint);
233
171
  const classifications = [];
234
172
 
@@ -263,8 +201,7 @@ export function reconcileLedger({
263
201
  lastSeen: now,
264
202
  };
265
203
 
266
- // Re-key under the fresh fingerprint; drop the old entry if it was matched
267
- // by semanticKey under a now-drifted fingerprint (reworded finding).
204
+ // Re-key a reworded finding matched by semanticKey.
268
205
  if (existing?.fingerprint && existing.fingerprint !== id.fingerprint) {
269
206
  nextByFingerprint.delete(existing.fingerprint);
270
207
  }
@@ -290,24 +227,13 @@ export function reconcileLedger({
290
227
  }
291
228
 
292
229
  /**
293
- * Record a set of already-known identities as filed against one Issue.
294
- *
295
- * The finding-shaped {@link reconcileLedger} cannot serve this caller:
296
- * `plan-persist` never sees findings. It holds the provenance identities it
297
- * stamped on a Story body — fingerprints and semantic keys, as strings — plus
298
- * the issue number it just created. That is enough to record the filing, and
299
- * demanding a finding it does not have would be the reason the recommended
300
- * planning path never reached this ledger at all.
301
- *
302
- * An identity already carrying a **closed** Issue is left exactly as it is: a
303
- * finding whose tracking Issue was closed `not_planned` is `accepted-risk` and
304
- * must stay suppressed, and one closed as completed is a `regressed` the
305
- * operator still needs to see. A fresh filing never overwrites either verdict.
230
+ * Record identity strings (`plan-persist` has no findings) as filed. An
231
+ * identity whose Issue is closed is skipped, so its verdict survives.
306
232
  *
307
233
  * @param {object} params
308
- * @param {{ entries?: object[] }} [params.ledger] — prior ledger (default empty).
234
+ * @param {{ entries?: object[] }} [params.ledger]
309
235
  * @param {Array<{ fingerprint: string, semanticKey?: string, title?: string, dimension?: string, primaryFile?: string }>} params.identities
310
- * @param {{ number: number }} params.issue — the Issue these identities were filed as.
236
+ * @param {{ number: number }} params.issue
311
237
  * @param {string} [params.now]
312
238
  * @returns {{ ledger: object, recorded: number, skipped: number }}
313
239
  */
@@ -1,32 +1,14 @@
1
1
  /**
2
- * lib/findings/classify-finding.js — Finding classification + label routing.
3
- *
4
- * A "finding" here is an exploratory-QA ledger item (see
5
- * `.agents/schemas/qa-ledger.schema.json`, Epic #3686). Each item carries a
6
- * `class` drawn from a closed enum. `classifyFinding(finding)` resolves that
7
- * class and routes it to the GitHub label set Triage applies when promoting
8
- * the item to a follow-up ticket.
9
- *
10
- * Pure function: no network I/O. The class → label routing table is the
11
- * single source of truth for which labels a given finding class maps to;
12
- * label *names* are pulled from `lib/label-constants.js` so renames land in
13
- * one place rather than as string literals here.
14
- *
15
- * Rejection (not silent defaulting) is the contract: a finding whose class is
16
- * absent, empty, or outside the enum throws rather than falling back to a
17
- * default class. A misclassified finding routed to the wrong labels is worse
18
- * than a loud failure the operator can fix.
2
+ * lib/findings/classify-finding.js — resolve a QA ledger item's `class` and
3
+ * route it to the labels Triage applies on promotion. An absent or unknown
4
+ * class throws rather than defaulting: a mis-routed finding is worse than a
5
+ * loud failure.
19
6
  */
20
7
 
21
8
  import { META_LABELS } from '../label-constants.js';
22
9
  import { normalizeSeverity, SEVERITIES } from './severity.js';
23
10
 
24
- /**
25
- * Focus-axis labels (Story #3721). These scope a finding to the area of the
26
- * framework it concerns. They are not in `label-constants.js` because the
27
- * focus axis is consumer-extensible; the routing table below is the only
28
- * in-tree consumer, so the literals are defined here and referenced by symbol.
29
- */
11
+ /** Not in `label-constants.js`: the focus axis is consumer-extensible. */
30
12
  export const FOCUS_LABELS = {
31
13
  PRODUCT: 'focus::product',
32
14
  ENVIRONMENT: 'focus::environment',
@@ -35,11 +17,7 @@ export const FOCUS_LABELS = {
35
17
  ENHANCEMENT: 'focus::enhancement',
36
18
  };
37
19
 
38
- /**
39
- * The closed set of finding classes, mirroring the `class` enum in
40
- * `.agents/schemas/qa-ledger.schema.json`. Exported so callers can validate
41
- * against the same source of truth.
42
- */
20
+ /** Mirrors the `class` enum in `.agents/schemas/qa-ledger.schema.json`. */
43
21
  export const FINDING_CLASSES = Object.freeze([
44
22
  'product-bug',
45
23
  'environment-setup',
@@ -49,9 +27,8 @@ export const FINDING_CLASSES = Object.freeze([
49
27
  ]);
50
28
 
51
29
  /**
52
- * Class → label-set routing table. Each class maps to exactly one label set.
53
- * `tooling-dx` is the framework-gap path: it carries `meta::framework-gap` so
54
- * the `/mandrel-plan` Phase 0 feedback fetcher surfaces it to the planner.
30
+ * `tooling-dx` carries `meta::framework-gap` so `/mandrel-plan` Phase 0
31
+ * surfaces it.
55
32
  */
56
33
  const CLASS_TO_LABELS = Object.freeze({
57
34
  'product-bug': [FOCUS_LABELS.PRODUCT],
@@ -61,19 +38,11 @@ const CLASS_TO_LABELS = Object.freeze({
61
38
  enhancement: [FOCUS_LABELS.ENHANCEMENT, META_LABELS.CONSUMER_IMPROVEMENT],
62
39
  });
63
40
 
64
- /**
65
- * The closed set of severity values a finding can carry, re-exported from the
66
- * canonical {@link ./severity.js} source of truth (Story #3816) so this module
67
- * does not re-declare its own list. Ordered highest → lowest:
68
- * `critical | high | medium | low | info`.
69
- */
70
41
  export { SEVERITIES };
71
42
 
72
43
  /**
73
- * Tokens that, when present in a finding's `area`, `labels`, or explicit
74
- * `security` flag, mark it as security-relevant. The security signal is
75
- * orthogonal to the class → label mapping: a `product-bug` and a `tooling-dx`
76
- * finding can both be security-relevant, so this never alters the class route.
44
+ * Tokens in `area`/`labels` marking a finding security-relevant. Orthogonal
45
+ * to the class route.
77
46
  */
78
47
  const SECURITY_TOKENS = Object.freeze([
79
48
  'security',
@@ -92,13 +61,6 @@ const SECURITY_TOKENS = Object.freeze([
92
61
  ]);
93
62
 
94
63
  /**
95
- * Resolve a finding's severity to one of {@link SEVERITIES} via the shared
96
- * canonical normaliser. An absent, empty, or unrecognised severity resolves to
97
- * the canonical floor (`info`). Case- and whitespace-insensitive. Delegating to
98
- * {@link normalizeSeverity} keeps this path bit-for-bit identical to the
99
- * `promote-finding` path, so the same finding fingerprints the same regardless
100
- * of which path produced its severity (Story #3816).
101
- *
102
64
  * @param {object} finding
103
65
  * @returns {string} one of {@link SEVERITIES}
104
66
  */
@@ -107,10 +69,6 @@ function resolveSeverity(finding) {
107
69
  }
108
70
 
109
71
  /**
110
- * Detect whether a finding is security-relevant. True when the finding sets an
111
- * explicit truthy `security` flag, OR when any of its `area` / `labels`
112
- * carries a known security token. Pure string inspection — no network I/O.
113
- *
114
72
  * @param {object} finding
115
73
  * @returns {boolean}
116
74
  */
@@ -132,8 +90,6 @@ function resolveSecuritySignal(finding) {
132
90
  }
133
91
 
134
92
  /**
135
- * Resolve the raw `class` field of a finding to a known, non-empty class.
136
- *
137
93
  * @param {object} finding
138
94
  * @returns {string} one of {@link FINDING_CLASSES}
139
95
  * @throws {TypeError} when `finding` is not an object
@@ -159,24 +115,13 @@ function resolveClass(finding) {
159
115
  }
160
116
 
161
117
  /**
162
- * Classify a finding into exactly one class, route it to its label set, and
163
- * carry a severity value plus a security signal alongside.
164
- *
165
- * The class → label routing is unchanged: every class still maps to exactly
166
- * the same label set it always did. `severity` and `security` are additive
167
- * signal fields the caller can act on (e.g. escalate a high-severity security
168
- * finding) — they never alter the label set, so no existing class-to-label
169
- * mapping is dropped.
118
+ * Classify a finding and route it to its label set. `severity` and `security`
119
+ * are additive signals; they never alter the labels.
170
120
  *
171
- * @param {object} finding — a ledger item carrying a `class` field, and
172
- * optionally `severity` and a `security` flag / security-relevant `area` /
173
- * `labels`.
121
+ * @param {object} finding — a ledger item carrying a `class` field.
174
122
  * @returns {{ class: string, labels: string[], severity: string, security: boolean }}
175
- * the resolved class, the ordered GitHub labels Triage should apply, the
176
- * resolved severity (one of {@link SEVERITIES}; `info` when absent), and
177
- * whether the finding is security-relevant.
178
123
  * @throws {TypeError|RangeError} on a non-object finding or an
179
- * unknown/empty class (never silently defaults).
124
+ * unknown/empty class.
180
125
  */
181
126
  export function classifyFinding(finding) {
182
127
  const findingClass = resolveClass(finding);
@@ -1,66 +1,24 @@
1
1
  /**
2
- * lib/findings/promote-finding.js — Promote clustered ledger items to tickets.
3
- *
4
- * The `f1-shared-qa-core` promotion step (Epic #3798, Feature #3803). It is the
5
- * tail of the exploratory-QA Triage path: once an operator has dispositioned a
6
- * session's ledger items (see `.agents/schemas/qa-ledger.schema.json` and
7
- * `lib/qa/qa-session.js`), the still-untriaged backlog is clustered and each
8
- * cluster is promoted to a follow-up ticket — a single Story (via `/mandrel-plan`)
9
- * for a tight, one-deliverable cluster, or a multi-Story plan-seed (via `/mandrel-plan --seed`) for
10
- * a broad cluster that spans multiple coverage surfaces. Each contributing
11
- * ledger item then has the resulting `routedTo` issue link written back onto it
12
- * so a resume run sees the item as filed rather than re-promoting it.
13
- *
14
- * Routing **reuses the shared findings/route logic** — `routeFinding` from
15
- * `route-finding.js`, the single dedup/route implementation `audit-to-stories`
16
- * and `qa-explore` already share. It does NOT call `audit-to-stories`: that
17
- * workflow parses `audit-*-results.md` markdown and is a different intake path.
18
- * Here a cluster is adapted onto the canonical finding identity, routed against
19
- * existing Issues, and only a `new` decision opens a fresh ticket; an
20
- * `update-existing` / `duplicate` / `regression-of-closed` decision links back
21
- * to the matched Issue without creating a duplicate.
22
- *
23
- * Pure orchestration: **no network I/O lives here.** Every GitHub side-effect
24
- * (issue search, ticket creation) flows through INJECTED PORTS so the unit test
25
- * runs with no network. Production wires the ports to the GitHub provider /
26
- * `/mandrel-plan` / `/mandrel-plan` surfaces; tests pass in-memory stubs.
2
+ * lib/findings/promote-finding.js — promote clustered untriaged QA ledger
3
+ * items to a Story or plan-seed via `routeFinding`, stamping `routedTo` on
4
+ * each item so a resume does not re-promote. Ports are injected.
27
5
  */
28
6
 
29
7
  import { fingerprintFinding, routeFinding } from './route-finding.js';
30
8
  import { highestSeverity as highestSeverityOf } from './severity.js';
31
9
 
32
- /** Triaged dispositions, mirrored from the `disposition` enum in the schema. */
33
10
  const TRIAGED_DISPOSITIONS = Object.freeze(['file', 'defer', 'dismiss']);
34
11
 
35
- /**
36
- * The two promotion targets a cluster routes to.
37
- *
38
- * `PLAN_SEED` promotes a broad cluster by seeding a multi-Story `/mandrel-plan`
39
- * run (`/mandrel-plan --seed`). Its persisted wire token is the legacy string
40
- * `'epic'`: archived qa-ledger records (and the distributed
41
- * `qa-ledger.schema.json` `routedTo.kind` enum) still carry `'epic'`, so
42
- * the value is kept read-compatible while the write-side constant name is
43
- * modernised.
44
- */
12
+ /** `PLAN_SEED` stays `'epic'` on the wire: archived ledgers and the schema enum carry it. */
45
13
  export const PROMOTION_TARGETS = Object.freeze({
46
14
  STORY: 'story',
47
15
  PLAN_SEED: 'epic',
48
16
  });
49
17
 
50
- /**
51
- * A cluster of more than this many distinct coverage surfaces is broad enough
52
- * to warrant a plan-seed (`/mandrel-plan --seed`) rather than a single Story
53
- * (`/mandrel-plan`). One or two surfaces is a tight, single-deliverable cluster.
54
- */
18
+ /** More distinct coverage surfaces than this → plan-seed instead of a Story. */
55
19
  const EPIC_COVERAGE_THRESHOLD = 2;
56
20
 
57
21
  /**
58
- * True when a ledger item has NOT yet been promoted — i.e. it is part of the
59
- * rolling backlog. An item is untriaged when its `disposition` is not one of
60
- * the canonical triaged values, OR it is explicitly dispositioned `file` but
61
- * has not yet been routed (`routedTo` absent). A `defer` / `dismiss` item, or
62
- * an already-`routedTo` item, is skipped.
63
- *
64
22
  * @param {{ disposition?: unknown, routedTo?: unknown }} item
65
23
  * @returns {boolean}
66
24
  */
@@ -69,20 +27,12 @@ export function isPromotable(item) {
69
27
  if (item.routedTo) return false;
70
28
  const disposition = item.disposition;
71
29
  if (disposition === 'defer' || disposition === 'dismiss') return false;
72
- // `file` items are promotable; anything not in the triaged set (pending,
73
- // untriaged, null, absent) is the rolling backlog and also promotable.
74
30
  if (disposition === 'file') return true;
75
31
  return !TRIAGED_DISPOSITIONS.includes(disposition);
76
32
  }
77
33
 
78
34
  /**
79
- * Stable cluster key for a ledger item: its `class`. Items sharing a class
80
- * describe the same kind of signal (a product bug, a tooling-DX gap, …) and
81
- * merge into one follow-up ticket. A class whose items span many distinct
82
- * coverage surfaces is broad enough to promote to a plan-seed (see
83
- * {@link targetForCluster}); a class confined to one or two surfaces is a
84
- * single-deliverable Story. Coverage is therefore a *secondary* signal that
85
- * sizes the cluster rather than splitting it.
35
+ * Coverage sizes a cluster; it never splits one.
86
36
  *
87
37
  * @param {{ class?: string }} item
88
38
  * @returns {string}
@@ -94,27 +44,15 @@ function clusterKeyFor(item) {
94
44
  }
95
45
 
96
46
  /**
97
- * The highest severity present across a cluster's items, resolved through the
98
- * shared canonical {@link ./severity.js} vocabulary (Story #3816). This module
99
- * no longer declares its own severity rank table — the ordering lives in one
100
- * place so a cluster severity and a `classify-finding` severity for the same
101
- * input are identical, keeping the `fingerprintFinding` identity stable.
102
- *
103
47
  * @param {Array<{ severity?: string }>} items
104
- * @returns {string} one of the canonical severities.
48
+ * @returns {string}
105
49
  */
106
50
  function highestSeverity(items) {
107
51
  return highestSeverityOf(items.map((item) => item?.severity));
108
52
  }
109
53
 
110
54
  /**
111
- * Cluster the promotable (untriaged / unrouted) ledger items by coverage
112
- * surface + class. Returns one cluster per distinct key, each carrying the
113
- * contributing items, the distinct coverage surfaces it spans, the highest
114
- * severity in the merge, and a synthesized title. Deterministic: clusters and
115
- * their items preserve first-seen order.
116
- *
117
- * @param {Array<object>} items — ledger items (the full session ledger).
55
+ * @param {Array<object>} items
118
56
  * @returns {Array<{
119
57
  * key: string,
120
58
  * class: string,
@@ -166,11 +104,6 @@ export function clusterLedgerItems(items) {
166
104
  }
167
105
 
168
106
  /**
169
- * Decide a cluster's promotion target. A cluster that spans more than
170
- * {@link EPIC_COVERAGE_THRESHOLD} distinct coverage surfaces is broad enough to
171
- * warrant a plan-seed (`/mandrel-plan --seed`); otherwise it is a single-deliverable
172
- * Story (`/mandrel-plan`).
173
- *
174
107
  * @param {{ coverages: string[] }} cluster
175
108
  * @returns {'story'|'epic'}
176
109
  */
@@ -184,10 +117,8 @@ export function targetForCluster(cluster) {
184
117
  }
185
118
 
186
119
  /**
187
- * Adapt a cluster onto the canonical finding identity that `routeFinding`
188
- * fingerprints over (`title`, `area`, `primaryFile`, `severity`, `labels`).
189
- * The coverage surface stands in for `area`; the class becomes a label so two
190
- * clusters with the same title but different classes fingerprint distinctly.
120
+ * The class is a label so same-titled clusters of different classes
121
+ * fingerprint distinctly.
191
122
  *
192
123
  * @param {{ title: string, coverages: string[], class: string, severity: string }} cluster
193
124
  * @returns {{ title: string, area: string, primaryFile: string, severity: string, labels: string[] }}
@@ -203,13 +134,7 @@ function clusterToFinding(cluster) {
203
134
  }
204
135
 
205
136
  /**
206
- * Build the `routedTo` link the schema stamps onto a promoted ledger item.
207
- *
208
- * The `routedTo.url` field is `minLength: 1` in `qa-ledger.schema.json`,
209
- * and the search/create port contract requires a
210
- * routed issue to carry its canonical URL. So rather than silently stamp an
211
- * empty string (which would persist a schema-invalid ledger item), this guards
212
- * the url and throws when it is absent or blank (Story #3816, AC #4).
137
+ * `routedTo.url` is `minLength: 1` in the schema, so an empty url throws.
213
138
  *
214
139
  * @param {{ number: number, url?: string }} issue
215
140
  * @param {'story'|'epic'|'issue'} kind
@@ -233,35 +158,15 @@ function routedToLink(issue, kind) {
233
158
  }
234
159
 
235
160
  /**
236
- * Promote the clustered untriaged ledger items into Stories / plan-seeds via the
237
- * shared findings/route logic, then write the resulting `routedTo` issue link
238
- * back onto each contributing ledger item.
239
- *
240
- * For each cluster:
241
- * 1. Adapt the cluster onto the canonical finding shape and route it with the
242
- * shared `routeFinding` against existing Issues (via the injected search
243
- * port). This dedups against work already filed.
244
- * 2. On a `new` decision, open the follow-up ticket through the injected
245
- * `createStory` (`/mandrel-plan`) or `createPlanSeed` (`/mandrel-plan --seed`) port,
246
- * chosen by {@link targetForCluster}. On any other decision, link back to
247
- * the matched Issue rather than creating a duplicate.
248
- * 3. Stamp the resolved `routedTo` link onto every contributing ledger item
249
- * (mutating the item objects in place, so a `qa-session` append persists
250
- * the link).
251
- *
252
- * All GitHub side-effects flow through the injected ports — there is no network
253
- * I/O in this module, so the unit test runs offline.
161
+ * On `new`, create via the target's port; otherwise link to the matched
162
+ * Issue. Items are mutated in place so a `qa-session` append persists the link.
254
163
  *
255
- * @param {Array<object>} ledgerItems — the full session ledger.
164
+ * @param {Array<object>} ledgerItems
256
165
  * @param {object} ports
257
166
  * @param {(sha: string) => Promise<Array<{ number: number, state: string, body?: string }>>} [ports.searchIssues]
258
- * Fingerprint-keyed lookup over open+closed issues, forwarded to `routeFinding`.
259
167
  * @param {(finding: object) => Promise<Array<{ number: number, state: string, title?: string, body?: string }>>} [ports.searchCandidates]
260
- * Optional semantic candidate search, forwarded to `routeFinding`.
261
168
  * @param {(cluster: object) => Promise<{ number: number, url?: string }>} ports.createStory
262
- * Opens a single Story (`/mandrel-plan`) for a tight cluster.
263
169
  * @param {(cluster: object) => Promise<{ number: number, url?: string }>} ports.createPlanSeed
264
- * Opens a plan-seed (`/mandrel-plan --seed`) run for a broad cluster.
265
170
  * @returns {Promise<{
266
171
  * promotions: Array<{
267
172
  * clusterKey: string,
@@ -312,8 +217,6 @@ export async function promoteFindings(ledgerItems, ports = {}) {
312
217
  issue = await createPort(cluster);
313
218
  created = true;
314
219
  } else {
315
- // Already filed (open match, duplicate, or regression of a closed
316
- // ticket) — link back to the matched Issue instead of duplicating.
317
220
  issue = {
318
221
  number: route.matchedIssue.number,
319
222
  url: route.matchedIssue.url,
@@ -323,7 +226,6 @@ export async function promoteFindings(ledgerItems, ports = {}) {
323
226
  const kind = created ? target : 'issue';
324
227
  const link = routedToLink(issue, kind);
325
228
 
326
- // Write the routedTo link back onto each contributing ledger item.
327
229
  for (const item of cluster.items) {
328
230
  item.routedTo = { ...link };
329
231
  }