mandrel 2.59.0 → 2.61.0

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