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,30 +1,7 @@
1
1
  /**
2
- * audit-to-stories.js — Convert audit-* report findings into actionable
3
- * GitHub Story proposals.
4
- *
5
- * The CLI exposes three deterministic sub-commands the host workflow
6
- * (`/audit-to-stories`) invokes between HITL gates:
7
- *
8
- * --scan [--glob <pattern>] [--severity <threshold>]
9
- * Parse every audit-*-results.md under the glob, normalise findings,
10
- * stamp fingerprints, group cross-audit, and (when a provider is
11
- * available) classify each group as create / skip-open / skip-reoccurring.
12
- * Emits a single `audit-to-stories-plan.json` envelope to --out (or
13
- * stdout when --json is set).
14
- *
15
- * --emit-plan-seed --plan <plan.json> --out <path>
16
- * Read the plan envelope from disk, render the `/mandrel-plan --seed`
17
- * seed markdown, persist to --out.
18
- *
19
- * --emit-stories --plan <plan.json>
20
- * Read the plan envelope from disk, render the per-group `{ title,
21
- * body, labels }` objects. The host LLM consumes the JSON and calls
22
- * the GitHub provider (gh / mcp__github__issue_write) to open one
23
- * Issue per group.
24
- *
25
- * Per .agents/rules/orchestration-error-handling.md, this CLI throws on
26
- * unrecoverable failure rather than calling Logger.fatal so runAsCli's
27
- * exit-code boundary stays robust under mocked process.exit.
2
+ * audit-to-stories.js — turn audit-* report findings into a dedup-checked
3
+ * plan, a `/mandrel-plan` seed, or standalone Story drafts. Throws rather than
4
+ * calling Logger.fatal so runAsCli owns the exit code.
28
5
  */
29
6
 
30
7
  import fs from 'node:fs';
@@ -76,17 +53,8 @@ const DEFAULT_GLOB = 'temp/audits/audit-*-results.md';
76
53
  const FAN_OUT_REPORT = 'audit-fan-out-results.md';
77
54
 
78
55
  /**
79
- * Does `finding` clear the `threshold` severity floor?
80
- *
81
- * `SEVERITY_RANK` is imported from the canonical scale rather than declared
82
- * here (Story #4877). The local copy this replaces ranked only four levels
83
- * (`critical|high|medium|low`), so `info` — the canonical floor — ranked `0`,
84
- * below even `--severity low`, and every informational finding was silently
85
- * dropped from every filtered run. Sourcing the ranking from the SSOT means a
86
- * level cannot exist in the vocabulary and be invisible to the filter.
87
- *
88
- * An unrecognised or absent severity still ranks below every real floor: it
89
- * failed to parse, so it is not evidence that a threshold was met.
56
+ * Does `finding` clear the `threshold` floor? An unparsed severity ranks below
57
+ * every real floor.
90
58
  *
91
59
  * @param {{ severity?: string }} finding
92
60
  * @param {string} [threshold] — a canonical level, `'all'`, or falsy for no floor.
@@ -116,11 +84,8 @@ function readReports(paths) {
116
84
  }
117
85
 
118
86
  /**
119
- * Count findings per severity bucket. The buckets are the canonical levels plus
120
- * `unknown` for a finding whose severity did not parse — kept as a visible
121
- * bucket so an unparseable severity is reported rather than absorbed into a
122
- * real level. Derived from `SEVERITIES` so a new level appears in the tally
123
- * automatically instead of falling into `unknown` (Story #4877).
87
+ * Count findings per canonical level, plus a visible `unknown` bucket for an
88
+ * unparsed severity.
124
89
  *
125
90
  * @param {Array<{ severity?: string }>} findings
126
91
  * @returns {Record<string, number>}
@@ -137,18 +102,10 @@ function tallyBySeverity(findings) {
137
102
  return t;
138
103
  }
139
104
 
140
- /**
141
- * The four levels a report's `Severity tally:` line declares. `Info` is
142
- * deliberately absent — the severity scale already excludes it from scheduled
143
- * work — and `unknown` is not a level a lens can declare, so neither is
144
- * comparable against the line.
145
- */
105
+ /** The levels a `Severity tally:` line declares; `info` and `unknown` are not comparable. */
146
106
  const TALLY_LEVELS = Object.freeze(['critical', 'high', 'medium', 'low']);
147
107
 
148
108
  /**
149
- * Project a findings list onto the four comparable levels, so a report's
150
- * declared tally and the parsed one are compared over the same axes.
151
- *
152
109
  * @param {Array<{ severity?: string }>} findings
153
110
  * @returns {{ critical: number, high: number, medium: number, low: number }}
154
111
  */
@@ -167,14 +124,9 @@ function formatTally(tally) {
167
124
  }
168
125
 
169
126
  /**
170
- * Run the cross-check, route its messages to stderr, and enforce the
171
- * fail-closed arm — the whole report-verification step as one call, so
172
- * `buildPlan` reads as a pipeline rather than absorbing the branching.
173
- *
174
- * `--auto` files unattended, so a report it cannot trust must stop the run
175
- * BEFORE the ledger reconcile and before any Story payload is built: no GitHub
176
- * write, no ledger write, non-zero exit. `--scan` reports and carries on — the
177
- * failures ride the plan envelope for the operator to act on.
127
+ * Cross-check the reports, warn on stderr, and throw under
128
+ * `failOnReportFailures` (`--auto`) BEFORE any ledger or GitHub write; `--scan`
129
+ * carries the failures on the plan envelope instead.
178
130
  *
179
131
  * @param {object} params
180
132
  * @param {Array<{ sourceReport: string, markdown: string }>} params.reports
@@ -209,28 +161,12 @@ function auditReportFailures({
209
161
  }
210
162
 
211
163
  /**
212
- * Cross-check every report's declared `Severity tally:` line against the
213
- * findings the parser actually extracted from it (Story #5144).
214
- *
215
- * A parser that silently drops findings is indistinguishable from a clean
216
- * report: the empty plan looks exactly like "nothing to file". The lens
217
- * contract therefore mandates one machine-readable tally line per report, and
218
- * this is where the two numbers meet. Three failure kinds are named:
219
- *
220
- * - `missing-tally` — the report declares no tally at all (an older or
221
- * hand-written report). `allowMissingTally` downgrades ONLY this kind to a
222
- * warning, for an interactive `--scan` over legacy reports.
223
- * - `tally-mismatch` — the report says one thing and the parse says another.
224
- * - `duplicate-tally` — the report declares the tally more than once, so there
225
- * is no single number to check against. Adopting whichever line the scan
226
- * reached first would compare the parse against an arbitrary one of two
227
- * declarations, which is a cross-check in name only. `allowMissingTally`
228
- * does NOT downgrade it: the report is contradictory, not merely old.
229
- * - `unresolved-severity` — a finding parsed with no resolvable severity. It
230
- * is a report defect, never an `unknown` group.
231
- *
232
- * Pure: returns the messages and lets the caller own the single `Logger.warn`
233
- * (stderr) sink, so `--scan` JSON on stdout stays clean.
164
+ * Cross-check each report's declared `Severity tally:` line against what the
165
+ * parser extracted — a parser that silently drops findings otherwise looks
166
+ * like a clean report. Failure kinds: `missing-tally` (the only kind
167
+ * `allowMissingTally` downgrades to a warning), `tally-mismatch`,
168
+ * `duplicate-tally` (no single number to check; contradictory, never
169
+ * downgraded), and `unresolved-severity`. Pure; the caller owns stderr.
234
170
  *
235
171
  * @param {object} params
236
172
  * @param {Array<{ sourceReport: string, markdown: string }>} params.reports
@@ -295,10 +231,6 @@ function crossCheckReports({ reports, findings, allowMissingTally }) {
295
231
  }
296
232
 
297
233
  /**
298
- * The `--allow-missing-tally` downgrade message. It still names the report and
299
- * says plainly that `--auto` ignores the flag, so an operator never reads the
300
- * warning as "this report is fine".
301
- *
302
234
  * @param {{ sourceReport: string, parsed: object }} failure
303
235
  * @returns {string}
304
236
  */
@@ -307,11 +239,8 @@ function missingTallyWarning(failure) {
307
239
  }
308
240
 
309
241
  /**
310
- * Render the report-failure block: one line per failure naming the report path
311
- * and BOTH tallies, so the operator can see which side is wrong without
312
- * re-reading the report.
313
- *
314
- * Pure: returns the message string so the caller owns the single `Logger.warn`.
242
+ * One line per failure naming the report and BOTH tallies, so the operator
243
+ * sees which side is wrong.
315
244
  *
316
245
  * @param {Array<{ sourceReport: string, kind: string, reported: object|null, parsed: object, titles?: string[], tallyLines?: string[] }>} failures
317
246
  * @returns {string}
@@ -321,9 +250,7 @@ function reportFailureWarning(failures) {
321
250
  const titles = f.titles?.length
322
251
  ? ` findings=${f.titles.map((t) => `"${t}"`).join(', ')}`
323
252
  : '';
324
- // A duplicate names the competing lines rather than a tally: there is no
325
- // single `reported` number to print, and "which two lines" is the whole
326
- // remedy.
253
+ // A duplicate has no single `reported` number; name the competing lines.
327
254
  const declared = f.tallyLines?.length
328
255
  ? ` declared=${f.tallyLines.map((t) => `"${t}"`).join(' | ')}`
329
256
  : '';
@@ -337,11 +264,9 @@ function reportFailureWarning(failures) {
337
264
  }
338
265
 
339
266
  /**
340
- * Test-only seam: when `AUDIT_TO_STORIES_PROVIDER_FIXTURE` names a module, load
341
- * its default export as the dedup provider (ports) instead of the live GitHub
342
- * provider. This lets the soft-fail contract be exercised end-to-end through
343
- * the real `--scan` CLI with a search port that fails for a subset of groups
344
- * (Story #4678, AC-8), with no network. Returns null when the env var is unset.
267
+ * Test-only seam: `AUDIT_TO_STORIES_PROVIDER_FIXTURE` names a module whose
268
+ * default export replaces the whole provider adapter, so the real CLI runs
269
+ * with no network.
345
270
  *
346
271
  * @returns {Promise<object|null>}
347
272
  */
@@ -353,14 +278,8 @@ async function loadFixtureProvider() {
353
278
  }
354
279
 
355
280
  /**
356
- * Why the live provider could not be adapted, as a typed refusal.
357
- *
358
- * `loadProvider` used to collapse every one of these onto a bare `null`, which
359
- * was survivable for the dedup path (it degrades to a create-only plan and
360
- * warns) but not for `--wire-edges`, which cannot degrade and could therefore
361
- * only blame "configuration" for what was just as likely an auth failure.
362
- * Throwing a reason keeps the soft-fail (`loadProviderOrNull`) and lets the
363
- * write path name the missing precondition (Story #5143).
281
+ * Why the live provider could not be adapted. A typed reason lets
282
+ * `--wire-edges`, which cannot degrade, name the missing precondition.
364
283
  */
365
284
  class ProviderUnavailableError extends Error {
366
285
  /**
@@ -375,13 +294,9 @@ class ProviderUnavailableError extends Error {
375
294
  }
376
295
 
377
296
  /**
378
- * Walk the list endpoint once per label and merge the pages into one
379
- * deduplicated, normalised issue list.
380
- *
381
- * `labels` is an OR across the run's lenses, which the REST list endpoint
382
- * cannot express in one query (its `labels` parameter is an AND), so one call
383
- * per label is the narrowest honest read. Each is a paginated **list**, not a
384
- * search — a different, far larger rate-limit budget.
297
+ * List issues once per label (the REST `labels` filter is an AND, we need an
298
+ * OR) and merge them deduplicated. The list endpoint has a far larger
299
+ * rate-limit budget than search.
385
300
  *
386
301
  * @param {object} provider
387
302
  * @param {string[]} labels
@@ -403,11 +318,8 @@ async function listIssuesForLabels(provider, labels) {
403
318
  }
404
319
 
405
320
  /**
406
- * The two read ports the dedupe module consumes, adapted off the provider's
407
- * one full-text `searchIssues` call: `findIssuesByFingerprint(sha)` for the
408
- * exact-fingerprint pass and — since Story #4626 — `searchCandidates(finding)`
409
- * for the meaning-first Stage-1 pass. Adapted here so no provider-shape
410
- * knowledge is baked into the dedupe module.
321
+ * The dedupe module's read ports, adapted here so it holds no provider-shape
322
+ * knowledge.
411
323
  *
412
324
  * @param {object} provider
413
325
  * @param {{ owner: string, repo: string }} coords
@@ -421,12 +333,8 @@ function buildDedupPorts(provider, { owner, repo }) {
421
333
  return (hits ?? []).map(normaliseIssueHit);
422
334
  },
423
335
  /**
424
- * List every Issue carrying one of the run's `audit::*` labels, once, off
425
- * the REST list endpoint. The dedup module indexes the result and answers
426
- * every exact-fingerprint lookup from it, so the rate-limited search API is
427
- * spent only on findings it has never seen. A provider without the list
428
- * port yields `null`, which returns dedup to the per-finding search path
429
- * rather than silently skipping it.
336
+ * Every Issue carrying one of the run's `audit::*` labels, for the
337
+ * fingerprint index. `null` (no list port) falls back to per-finding search.
430
338
  *
431
339
  * @param {string[]} labels
432
340
  * @returns {Promise<Array<object>|null>}
@@ -436,8 +344,6 @@ function buildDedupPorts(provider, { owner, repo }) {
436
344
  return listIssuesForLabels(provider, labels);
437
345
  },
438
346
  async searchCandidates(finding) {
439
- // Wire the shared semantic search onto the provider's full-text
440
- // issue search (open + closed) so route-finding's Stage-1 pass runs.
441
347
  const search = async (query) => {
442
348
  if (!query || query.trim().length === 0) return [];
443
349
  const hits = await provider.searchIssues({ query, owner, repo });
@@ -449,15 +355,9 @@ function buildDedupPorts(provider, { owner, repo }) {
449
355
  }
450
356
 
451
357
  /**
452
- * The provider's write ports, carried through the adapter **bound** to their
453
- * provider so `this` survives the hand-off — `GitHubProvider` delegates each
454
- * of these to a composed gateway off `this`, so an unbound reference throws on
455
- * first call. Narrowing the adapter to the dedup read ports is what made
456
- * `--wire-edges` fail closed against a correctly configured repo (Story #5143).
457
- *
458
- * A port the provider does not implement is omitted rather than stubbed: the
459
- * wire step already degrades per port (footer-only when the native dependency
460
- * ports are absent), and a stub would defeat that check.
358
+ * The provider's write ports, **bound** — `GitHubProvider` delegates off
359
+ * `this`, so an unbound reference throws. A missing port is omitted, not
360
+ * stubbed, so the wire step's per-port degradation still sees it.
461
361
  *
462
362
  * @param {object} provider
463
363
  * @returns {Record<string, Function>}
@@ -480,9 +380,6 @@ const PROVIDER_WRITE_PORTS = [
480
380
  ];
481
381
 
482
382
  /**
483
- * Resolve the config and construct the live provider, converting each way that
484
- * can fail into a typed refusal.
485
- *
486
383
  * @param {{ createProviderImpl?: Function, resolveConfigImpl?: Function }} seams
487
384
  * @returns {Promise<{ config: object, provider: object }>}
488
385
  * @throws {ProviderUnavailableError}
@@ -520,14 +417,7 @@ async function constructProvider({ createProviderImpl, resolveConfigImpl }) {
520
417
  }
521
418
 
522
419
  /**
523
- * Adapt the configured provider for this CLI: the dedup read ports plus the
524
- * provider's own write ports, bound.
525
- *
526
- * The `createProviderImpl` / `resolveConfigImpl` seams let a contract test
527
- * drive this exact adapter with an in-memory issue store instead of the live
528
- * GitHub provider. The `AUDIT_TO_STORIES_PROVIDER_FIXTURE` fixture is returned
529
- * verbatim — it stands in for the whole adapter, not for the provider behind
530
- * it.
420
+ * Adapt the configured provider: dedup read ports plus bound write ports.
531
421
  *
532
422
  * @param {{ createProviderImpl?: Function, resolveConfigImpl?: Function }} [seams]
533
423
  * @returns {Promise<object>} the adapter (never null).
@@ -556,9 +446,7 @@ async function loadProvider({ createProviderImpl, resolveConfigImpl } = {}) {
556
446
  }
557
447
 
558
448
  /**
559
- * The dedup path's soft-fail view of `loadProvider`: the provider is optional
560
- * there — when it cannot be adapted the dedupe step emits a create-only
561
- * classification and warns the operator loudly rather than aborting the scan.
449
+ * Soft-fail `loadProvider` for dedup, which degrades to create-only and warns.
562
450
  *
563
451
  * @param {{ createProviderImpl?: Function, resolveConfigImpl?: Function }} [seams]
564
452
  * @returns {Promise<object|null>}
@@ -572,21 +460,8 @@ async function loadProviderOrNull(seams = {}) {
572
460
  }
573
461
 
574
462
  /**
575
- * Render the loud, operator-visible warning emitted when the Phase 6 dedup
576
- * does NOT run against real GitHub issues. Two distinct reasons:
577
- *
578
- * - `'no-provider-port'` — the configured provider resolved but exposes no
579
- * `searchIssues` port (or `loadProviderOrNull()` swallowed a typed
580
- * refusal — bad config, failed construction). This is the
581
- * silent-no-op the workflow's "Never open a duplicate Issue" contract
582
- * was failing on: every group classifies `create` and the operator gets
583
- * zero automated dedup signal. Surfacing it loudly is the whole point.
584
- * - `'disabled'` — the operator passed `--no-provider`, intentionally
585
- * skipping dedup. Still warned (so a re-run that opens duplicates is
586
- * never a surprise), but framed as a deliberate choice.
587
- *
588
- * Pure: returns the message string so `buildPlan` owns the single
589
- * `Logger.warn` write site and the text stays unit-testable.
463
+ * Warning for a dedup that did not run: `no-provider-port` (no usable provider
464
+ * — otherwise a silent all-`create` plan) or `disabled` (`--no-provider`).
590
465
  *
591
466
  * @param {'no-provider-port'|'disabled'} reason
592
467
  * @returns {string}
@@ -611,16 +486,8 @@ function dedupSkippedWarning(reason) {
611
486
  }
612
487
 
613
488
  /**
614
- * Render the loud, operator-visible warning emitted when Phase 6 dedup ran but
615
- * one or more groups' lookups could not complete (an HTTP 422, or a rate limit
616
- * still exhausted after the endpoint budget's cooldown). Those groups degrade
617
- * to `create` rather than aborting the whole scan (Story #4678); this warning
618
- * names each affected group so the operator knows exactly which to check by
619
- * hand. Mirrors the `dedupSkippedWarning` shape so a partially-checked plan
620
- * reads as clearly as a wholly-unchecked one.
621
- *
622
- * Pure: returns the message string so `buildPlan` owns the single `Logger.warn`
623
- * write site (stderr) and the text stays unit-testable.
489
+ * Warning naming each group whose lookup could not complete (422, exhausted
490
+ * rate limit) and so degraded to `create` unchecked.
624
491
  *
625
492
  * @param {Array<{ group: string, reason: string }>} entries
626
493
  * @returns {string}
@@ -636,15 +503,9 @@ function dedupDegradedWarning(entries) {
636
503
  }
637
504
 
638
505
  /**
639
- * Render the operator-visible line naming a host-supplied index and its size.
640
- *
641
- * Always emitted for a `--issues-file` run, because "how many issues did you
642
- * actually check against" is the one number that separates a real dedup from a
643
- * plan that merely looks checked. At zero it is the load-bearing case: an empty
644
- * corpus is a legitimate first sweep AND exactly what a broken fetch writes, so
645
- * the operator — not the run — decides which this was. Deliberately distinct in
646
- * wording from both `dedupSkippedWarning` and `dedupDegradedWarning` so the
647
- * three are never confused in a scrollback.
506
+ * Always emitted for `--issues-file`: the corpus size separates a real dedup
507
+ * from one that merely looks checked. Zero is ambiguous (first sweep or broken
508
+ * fetch), so the operator decides.
648
509
  *
649
510
  * @param {{ source?: string, size?: number }} dedupIndex
650
511
  * @returns {string}
@@ -662,11 +523,7 @@ function dedupIndexWarning({ size = 0 } = {}) {
662
523
  }
663
524
 
664
525
  /**
665
- * Render the warning for a pre-fetch of the issue index that could not
666
- * complete. The run still dedups — it falls back to a per-finding search — but
667
- * it loses the one-list saving, and until Story #5301 this failure was
668
- * swallowed whole: the operator saw only the downstream per-group degradation
669
- * and could not tell that the pre-fetch itself was the cause.
526
+ * Warning for a failed index pre-fetch; dedup falls back to per-finding search.
670
527
  *
671
528
  * @param {string} reason
672
529
  * @returns {string}
@@ -680,23 +537,10 @@ function dedupIndexDegradedWarning(reason) {
680
537
  }
681
538
 
682
539
  /**
683
- * Phase 6: classify every group against GitHub, and say loudly whichever way
684
- * it went.
685
- *
686
- * Extracted from `buildPlan` because the gate has three outcomes, not two, and
687
- * inlining them pushed the caller past its complexity ceiling. The three:
688
- *
689
- * - **deduped** — a provider resolved, or the host supplied a corpus, or
690
- * both. A host-supplied corpus is a dedup source in its own right, which is
691
- * the whole point: the gate asks "can we dedup at all", not "did a provider
692
- * resolve". While it asked the latter, `--no-provider --issues-file` — the
693
- * one invocation a `gh`-less host can run — short-circuited to the seeded
694
- * all-`create` classifications however well the dedupe module worked.
695
- * - **skipped, no port** — a provider was wanted but could not be adapted.
696
- * - **skipped, disabled** — `--no-provider` with no corpus to fall back on.
697
- *
698
- * Every outcome warns on stderr, so the `--scan` JSON on stdout stays clean and
699
- * a create-only plan is never read as "checked, found nothing".
540
+ * Classify every group against GitHub and warn on stderr whichever way it
541
+ * went. A host-supplied corpus is a dedup source on its own, so
542
+ * `--no-provider --issues-file` (the `gh`-less host) still dedups; only with
543
+ * neither a provider nor a corpus is every group `create`.
700
544
  *
701
545
  * @param {{ groups: Array<object>, useProvider?: boolean,
702
546
  * issues?: Array<object>|null }} params
@@ -740,25 +584,17 @@ async function runDedupPhase(
740
584
  }
741
585
 
742
586
  /**
743
- * Every warning a completed dedup pass owes the operator, in order. Pure, so
744
- * the wording stays unit-testable and `runDedupPhase` keeps one write site.
745
- *
746
587
  * @param {{ issues?: Array<object>|null, summary: object }} params
747
588
  * @returns {string[]}
748
589
  */
749
590
  function dedupPhaseWarnings({ issues, summary }) {
750
591
  const warnings = [];
751
592
  if (issues) warnings.push(dedupIndexWarning(summary.dedupIndex));
752
- // The pre-fetch failing is a distinct fact from any group's lookup failing,
753
- // and used to be invisible: the operator saw only the downstream per-group
754
- // degradation and could not tell what had caused it.
755
593
  if (summary.dedupDegraded?.indexPrefetch) {
756
594
  warnings.push(
757
595
  dedupIndexDegradedWarning(summary.dedupDegraded.indexPrefetch),
758
596
  );
759
597
  }
760
- // A partially-checked plan is a useful result — name the groups that degraded
761
- // to create because their lookup could not complete (Story #4678).
762
598
  if (summary.dedupDegraded?.count > 0) {
763
599
  warnings.push(dedupDegradedWarning(summary.dedupDegraded.groups));
764
600
  }
@@ -766,12 +602,7 @@ function dedupPhaseWarnings({ issues, summary }) {
766
602
  }
767
603
 
768
604
  /**
769
- * Scan → group → dedup → (optionally) reconcile the cross-run ledger, and
770
- * return the plan envelope.
771
- *
772
- * Every seam on the optional final `deps` parameter defaults to the real
773
- * implementation (`.agents/rules/test-seams.md` rules 1-2, 4), so `main`,
774
- * `runAuto`, and every production caller are unchanged.
605
+ * Scan → group → dedup → (optionally) reconcile the cross-run ledger.
775
606
  *
776
607
  * @param {{ glob?: string, severity?: string, useProvider?: boolean,
777
608
  * issuesFile?: string, ledger?: object }} params
@@ -807,9 +638,7 @@ async function buildPlan(
807
638
  reconcileScanLedgerImpl = reconcileScanLedger,
808
639
  logger = Logger,
809
640
  } = deps;
810
- // Deliberately BEFORE the reports are read: an unusable corpus is a usage
811
- // error, and failing fast costs the operator nothing, where failing late
812
- // would tempt a fallback that silently dedups nothing.
641
+ // Before reading reports: an unusable corpus is a usage error, not a fallback.
813
642
  const issues = issuesFile ? loadIssuesFileImpl(issuesFile) : null;
814
643
  const reportPaths = await collectReportPathsImpl(pattern ?? DEFAULT_GLOB);
815
644
  if (reportPaths.length === 0) {
@@ -842,9 +671,7 @@ async function buildPlan(
842
671
  logger,
843
672
  });
844
673
  const filtered = allFindings.filter((f) => meetsSeverity(f, severity));
845
- // A finding whose severity did not resolve is a report defect, not a Story.
846
- // It stays visible in `summary.tally.unknown` and in `reportFailures`, but
847
- // it never reaches grouping — an `unknown` group is not a thing to file.
674
+ // An unresolved severity is a report defect (tallied, never grouped).
848
675
  const stamped = withFingerprints(filtered.filter((f) => Boolean(f.severity)));
849
676
  const { groups, edges } = groupFindings(stamped);
850
677
 
@@ -853,10 +680,7 @@ async function buildPlan(
853
680
  { loadProviderImpl, classifyGroupsImpl, logger },
854
681
  );
855
682
 
856
- // Cross-run ledger (Story #4626): fold this scan onto the committed memory,
857
- // suppress findings a prior run recorded as accepted-risk, and (unless the
858
- // caller asked not to write) persist the updated ledger. Opt-in — the plain
859
- // --scan path leaves it untouched so it never mutates a committed file.
683
+ // Opt-in: plain --scan never mutates the committed ledger.
860
684
  let ledgerSummary;
861
685
  if (ledger) {
862
686
  const suppressed = reconcileScanLedgerImpl({
@@ -903,9 +727,8 @@ async function buildPlan(
903
727
  }
904
728
 
905
729
  /**
906
- * Fold the current scan onto the committed cross-run ledger and persist it.
907
- * Returns the set of finding fingerprints the ledger says are accepted-risk
908
- * (deliberately rejected) so the caller can suppress them.
730
+ * Fold the scan onto the ledger, persist it, and return the accepted-risk
731
+ * fingerprints to suppress.
909
732
  *
910
733
  * @param {object} params
911
734
  * @param {string} params.ledgerPath
@@ -921,8 +744,7 @@ function reconcileScanLedger({ ledgerPath, findings, classifications, write }) {
921
744
  ledger: prior,
922
745
  findings,
923
746
  issueStates,
924
- // The ledger lives in the shared findings layer and cannot import the
925
- // audit adapter without closing a cycle, so the projection is ours to pass.
747
+ // Passed in: the ledger importing the audit adapter would close a cycle.
926
748
  toCanonical: toCanonicalFinding,
927
749
  });
928
750
  if (write !== false) writeLedger(ledgerPath, next);
@@ -934,8 +756,6 @@ function reconcileScanLedger({ ledgerPath, findings, classifications, write }) {
934
756
  }
935
757
 
936
758
  /**
937
- * Derive a `{ fingerprint → issueState }` map from dedupe classifications so
938
- * the ledger reconcile sees the live open/closed state of matched Issues.
939
759
  * @param {Array<object>} classifications
940
760
  * @returns {Record<string, { state: string, number: number|null }>}
941
761
  */
@@ -961,36 +781,21 @@ function loadPlan(planPath) {
961
781
  return JSON.parse(fs.readFileSync(planPath, 'utf8'));
962
782
  }
963
783
 
784
+ /** The `--auto` severity floor when `--severity` names none. */
964
785
  const DEFAULT_SEVERITY_FLOOR = 'high';
965
786
 
966
787
  /**
967
- * Resolve the unattended-sweep severity floor: an explicit `--severity` wins,
968
- * else `delivery.auditToStories.severityFloor` from config, else the built-in
969
- * default (`high`). Reads config defensively so a missing/failed resolve never
970
- * breaks the run.
971
- *
972
788
  * @param {string|undefined} explicit
973
- * @returns {Promise<string>}
789
+ * @returns {string}
974
790
  */
975
- async function resolveSeverityFloor(explicit) {
976
- if (explicit) return explicit;
977
- try {
978
- const { resolveConfig } = await import('./lib/config-resolver.js');
979
- const config = resolveConfig();
980
- const floor = config?.delivery?.auditToStories?.severityFloor;
981
- if (typeof floor === 'string' && floor.length > 0) return floor;
982
- } catch (_) {
983
- // fall through to default
984
- }
985
- return DEFAULT_SEVERITY_FLOOR;
791
+ function severityFloorOf(explicit) {
792
+ return explicit || DEFAULT_SEVERITY_FLOOR;
986
793
  }
987
794
 
988
795
  /**
989
- * Unattended `--auto` sweep. No interactive gates: it resolves the severity
990
- * floor from config, builds the plan (with cross-run ledger reconciliation),
991
- * and reports a run summary. Under `--dry-run` it performs zero GitHub writes
992
- * and emits the summary only; otherwise it returns the create-eligible Story
993
- * payloads for the caller to open. Always resolves — never prompts.
796
+ * Unattended `--auto` sweep: build the plan with ledger reconciliation and
797
+ * return a summary plus the create-eligible Story payloads (none under
798
+ * `--dry-run`, which writes nothing). Never prompts.
994
799
  *
995
800
  * @param {object} params
996
801
  * @param {string} [params.glob]
@@ -1017,7 +822,7 @@ async function runAuto({
1017
822
  cwd,
1018
823
  logger = Logger,
1019
824
  }) {
1020
- const floor = await resolveSeverityFloor(severity);
825
+ const floor = severityFloorOf(severity);
1021
826
  const resolvedLedgerPath = ledgerPath ?? DEFAULT_LEDGER_PATH;
1022
827
  const plan = await buildPlan({
1023
828
  glob,
@@ -1025,8 +830,7 @@ async function runAuto({
1025
830
  useProvider,
1026
831
  issuesFile,
1027
832
  ledger: { path: resolvedLedgerPath, write: !dryRun },
1028
- // `--auto` never accepts `--allow-missing-tally`: an unattended sweep has
1029
- // no operator to read a warning, so every report failure is fatal here.
833
+ // No operator reads warnings unattended, so every report failure is fatal.
1030
834
  allowMissingTally: false,
1031
835
  failOnReportFailures: true,
1032
836
  });
@@ -1061,20 +865,14 @@ async function runAuto({
1061
865
  skipReoccurring: byAction.skipReoccurring.length,
1062
866
  suppressedByLedger: byAction.suppressed.length,
1063
867
  },
1064
- // `--auto` opens no Issues itself — the caller does, from the `--emit-stories`
1065
- // drafts — so these keys are the only thing standing between its summary and
1066
- // the `--wire-edges --ids` map. Without them an unattended sweep cannot
1067
- // record what it filed, and the ledger stays empty however well it works.
868
+ // The caller opens the Issues; these keys feed its `--wire-edges --ids`
869
+ // map, without which the ledger never records what was filed.
1068
870
  createGroupKeys: eligible.map((g) => g?.groupKey).filter(Boolean),
1069
- // Re-detected open Issues the operator may want a "re-detected" comment on.
1070
871
  reDetected: byAction.skipOpen
1071
872
  .flatMap((c) => c.matchedIssues ?? [])
1072
873
  .map((i) => i.number)
1073
874
  .filter((n) => typeof n === 'number'),
1074
- // The sweep may have just written memory this checkout cannot keep — an
1075
- // ephemeral scheduled clone is exactly where that bites (Story #5145).
1076
- // The whole decision lives in `resolveLedgerSummary` so this assembly
1077
- // stays branch-free.
875
+ // An ephemeral clone may not be able to keep the ledger it just wrote.
1078
876
  ledger: await resolveLedgerSummary({
1079
877
  ledger: plan.summary?.ledger ?? null,
1080
878
  ledgerPath: resolvedLedgerPath,
@@ -1090,16 +888,9 @@ async function runAuto({
1090
888
  }
1091
889
 
1092
890
  /**
1093
- * Build every eligible group into a `{ title, body, labels }` Story object and
1094
- * gate the batch against the inline-contract bar BEFORE any issue is opened.
1095
- *
1096
- * The `--emit-stories` path opens GitHub issues directly (no decomposer
1097
- * round-trip), so `assertEveryStoryHasInlineContract` never runs against these
1098
- * bodies. This gate restores that guarantee at the standalone seam: each
1099
- * emitted body is re-parsed through the canonical `story-body` parser and must
1100
- * carry a non-empty `acceptance[]` AND a non-empty `verify[]`. A body that
1101
- * fails throws, surfacing the gap instead of opening an ungated Story
1102
- * (Story #4270).
891
+ * Build each eligible group into a Story and throw BEFORE any issue is opened
892
+ * unless every body re-parses with non-empty `acceptance[]` and `verify[]` —
893
+ * this path skips the decomposer's inline-contract assertion.
1103
894
  *
1104
895
  * @param {Array<{ group: object }>} eligible — classifications eligible to create.
1105
896
  * @param {Array<{ fromGroupKey: string, toGroupKey: string }>} edges — sequencing edges.
@@ -1130,14 +921,8 @@ function buildAndGateStories(eligible, edges) {
1130
921
  }
1131
922
 
1132
923
  /**
1133
- * Which precondition is missing, keyed by the reason `loadProvider` refused.
1134
- *
1135
- * `--wire-edges` cannot degrade — the `blocked by #N` footers are the only
1136
- * thing `/mandrel-deliver`'s resolver reads — so the one thing its failure owes the
1137
- * operator is which of the preconditions is actually unmet. The message it
1138
- * replaced ("Configure github.owner/repo (and auth), or wire the edges by
1139
- * hand") blamed configuration for an auth failure and pointed at a manual
1140
- * fallback for what is a wiring bug (Story #5143).
924
+ * The unmet precondition, keyed by `loadProvider`'s refusal reason.
925
+ * `--wire-edges` cannot degrade, so its error must name which one.
1141
926
  */
1142
927
  const WIRE_EDGES_PRECONDITIONS = {
1143
928
  'no-config': 'github.owner and github.repo are not both set in .agentrc.json',
@@ -1166,18 +951,9 @@ function wireEdgesPreconditionError(reason, detail) {
1166
951
  }
1167
952
 
1168
953
  /**
1169
- * The `--wire-edges` pass: hand the opened issue numbers back so the cohort's
1170
- * detected group edges become declared ordering (Story #5044).
1171
- *
1172
- * This is the second half of the two-pass crossing `--emit-stories` starts. The
1173
- * host opens one Issue per group from the emitted drafts, then replays the
1174
- * `groupKey → issueNumber` map here; each Story whose blockers now exist is
1175
- * re-rendered with a canonical `blocked by #N` footer and the same edges are
1176
- * mirrored as native `blocked_by` relations.
1177
- *
1178
- * The same map is what the cross-run ledger needs to record what this run
1179
- * filed, so the record rides along here rather than arriving as a second
1180
- * command an operator must remember (Story #5305).
954
+ * Second pass after `--emit-stories`: given the opened `groupKey →
955
+ * issueNumber` map, re-render each Story with `blocked by #N` footers, mirror
956
+ * them as native `blocked_by`, and record the filed issues in the ledger.
1181
957
  *
1182
958
  * @param {object} params
1183
959
  * @param {object} params.plan A `--scan` plan envelope.
@@ -1206,12 +982,8 @@ async function wireEdges(
1206
982
  .filter((c) => c.action === 'create')
1207
983
  .map((c) => c.group);
1208
984
 
1209
- // Record BEFORE the provider is loaded. The record is pure local filesystem
1210
- // work, while the wiring below needs a provider exposing `updateTicket` — and
1211
- // the host most likely to lack one is the `gh`-less host where the ledger is
1212
- // the only duplicate protection there is. Recording first means such a run
1213
- // still remembers what it filed, and the precondition error below still
1214
- // surfaces unchanged afterwards.
985
+ // Record before loading the provider: a `gh`-less host, whose only duplicate
986
+ // protection is the ledger, must still remember what it filed.
1215
987
  const ledger = recordFiledIssuesImpl({
1216
988
  ledgerPath,
1217
989
  groups,
@@ -1240,8 +1012,7 @@ async function wireEdges(
1240
1012
  }
1241
1013
 
1242
1014
  /**
1243
- * Parse the `--ids` argument: a JSON object mapping group key → issue number,
1244
- * or a path to a file containing one.
1015
+ * `--ids`: inline JSON `{ groupKey: issueNumber }` or a path to one.
1245
1016
  *
1246
1017
  * @param {string|undefined} raw
1247
1018
  * @returns {Record<string, number>}
@@ -1295,7 +1066,6 @@ export const __testing = {
1295
1066
  dedupIndexDegradedWarning,
1296
1067
  buildAndGateStories,
1297
1068
  runAuto,
1298
- resolveSeverityFloor,
1299
1069
  reconcileScanLedger,
1300
1070
  issueStatesFromClassifications,
1301
1071
  wireEdges,
@@ -1303,13 +1073,7 @@ export const __testing = {
1303
1073
  };
1304
1074
 
1305
1075
  /**
1306
- * The CLI core: dispatch one of the four sub-commands and persist its output.
1307
- * Extracted from the `main` shell so the whole sub-command table (including
1308
- * the no-sub-command usage throw) is reachable without spawning the CLI.
1309
- *
1310
- * Every seam on the optional final `deps` parameter defaults to the real
1311
- * implementation (`.agents/rules/test-seams.md` rules 1-2, 4), so `main` and
1312
- * every production invocation are unchanged.
1076
+ * The CLI core: dispatch one sub-command and persist its output.
1313
1077
  *
1314
1078
  * @param {string[]} [argv]
1315
1079
  * @param {{
@@ -1324,12 +1088,7 @@ export const __testing = {
1324
1088
  * @returns {Promise<void>}
1325
1089
  */
1326
1090
  /**
1327
- * The one-line `--ledger-commit` outcome, for stderr.
1328
- *
1329
- * Names the branch and the PR on success — the two things an operator needs to
1330
- * go look at it — and the skip reason otherwise, because "nothing happened" and
1331
- * "the ledger was already clean" are different facts and only one of them is
1332
- * fine.
1091
+ * The one-line `--ledger-commit` outcome: branch and PR, or the skip reason.
1333
1092
  *
1334
1093
  * @param {{ committed?: boolean, reason?: string, branch?: string,
1335
1094
  * prUrl?: string|null, resumed?: boolean, ledgerPath?: string }} [result]
@@ -1342,8 +1101,6 @@ function describeLedgerCommit(result) {
1342
1101
  }
1343
1102
 
1344
1103
  /**
1345
- * The success half: the branch, whether it resumed a half-finished one, and
1346
- * the PR to go look at.
1347
1104
  * @param {object} result
1348
1105
  * @returns {string}
1349
1106
  */
@@ -1354,8 +1111,7 @@ function ledgerCommittedLine(result) {
1354
1111
  }
1355
1112
 
1356
1113
  /**
1357
- * The skip half. It names the ledger file, because the fact that matters is
1358
- * which state is still only in the working tree.
1114
+ * Names the ledger file: its state is still only in the working tree.
1359
1115
  * @param {object} [result]
1360
1116
  * @returns {string}
1361
1117
  */
@@ -1366,14 +1122,8 @@ function ledgerSkippedLine(result) {
1366
1122
  }
1367
1123
 
1368
1124
  /**
1369
- * Validate `--severity` against the canonical scale, failing on a value the
1370
- * filter would silently ignore.
1371
- *
1372
- * `meetsSeverity` reads an unknown threshold as rank `0`, so a typo — the
1373
- * classic being `--severity Hgh` — quietly widened the run to every finding
1374
- * instead of narrowing it. On an unattended sweep that is the difference
1375
- * between filing a batch and filing the backlog, with nothing on stderr to say
1376
- * so. An absent flag stays absent: the floor then resolves from config.
1125
+ * Reject an unknown `--severity`: `meetsSeverity` would read a typo as rank 0
1126
+ * and silently widen the run to every finding. Absent stays absent.
1377
1127
  *
1378
1128
  * @param {string|undefined} raw
1379
1129
  * @returns {string|undefined} the canonical level.
@@ -1447,15 +1197,10 @@ export async function runAuditToStories(
1447
1197
  })
1448
1198
  ).summary;
1449
1199
 
1450
- // Deliberately AFTER the summary is persisted (see the subcommand table's
1451
- // `after` slot): a broken remote must not cost the operator the sweep's
1452
- // findings, so the PR attempt is the last thing the run does (Story #5145).
1200
+ // Runs after the summary is persisted: a broken remote must not cost the
1201
+ // sweep's findings.
1453
1202
  const commitLedger = async () => {
1454
1203
  if (!values['ledger-commit'] || values['dry-run']) return;
1455
- // Say what happened. The tail used to run silently, so an operator could
1456
- // not tell a ledger PR from a skip without going to look for the branch —
1457
- // and a skip is the outcome that matters, because it means the sweep's
1458
- // memory is still only in the working tree.
1459
1204
  Logger.warn(
1460
1205
  describeLedgerCommit(
1461
1206
  await runLedgerCommitImpl({ ledgerPath: values.ledger }),
@@ -1495,18 +1240,11 @@ export async function runAuditToStories(
1495
1240
  plan: loadPlanImpl(values.plan),
1496
1241
  issueByGroupKey: parseIssueMapImpl(values.ids),
1497
1242
  ledgerPath: values.ledger,
1498
- // `--scan` still never writes the ledger; `--wire-edges` runs only after
1499
- // the Issues were really opened, where recording is never wrong — so the
1500
- // record is on by default here and `--dry-run` is what suppresses it.
1243
+ // The Issues really exist here, so recording defaults on.
1501
1244
  write: !values['dry-run'],
1502
1245
  });
1503
1246
 
1504
- // One table, not a chain of `if (values.X) { …; return; }`. Each entry
1505
- // renders its sub-command's output; persisting it — and the stdout newline a
1506
- // piped run needs — happens once, below. The chain restated that tail in
1507
- // every arm, so each new sub-command paid for it twice: once in the branch
1508
- // and once in the complexity budget. The optional fourth slot is an
1509
- // after-persist tail for work that must not pre-empt the report.
1247
+ // [flag, render, newlineOnStdout, afterPersist?]
1510
1248
  const subcommands = [
1511
1249
  ['auto', async () => json(await runAutoSummary()), true, commitLedger],
1512
1250
  ['scan', async () => json(await scanPlan()), true],
@@ -1528,17 +1266,9 @@ export async function runAuditToStories(
1528
1266
  }
1529
1267
 
1530
1268
  /**
1531
- * Render the Story drafts as the human-readable `--emit-stories` transcript
1532
- * (the `--json` form is the machine one). `dependsOn` is surfaced because the
1533
- * group edges no longer ride the body at emit time — the blockers have no issue
1534
- * numbers yet — so this is where a human driving the create pass by hand sees
1535
- * the ordering they will replay through `--wire-edges` (Story #5044).
1536
- *
1537
- * The trailing `--- grouping ---` block carries the container-Epic default
1538
- * (Story #5139), so the standalone path states it where it is actually read.
1539
- * The `--json` form stays a bare array on purpose: it is a documented output
1540
- * shape with a test asserting it, and the Epic is an operator decision the
1541
- * workflow's Phase 4 stop owns, not a field a machine consumer acts on.
1269
+ * Human-readable `--emit-stories` transcript. `dependsOn` is shown because the
1270
+ * blockers have no issue numbers yet (they are replayed via `--wire-edges`).
1271
+ * The Epic grouping block is text-only; `--json` stays a bare array.
1542
1272
  *
1543
1273
  * @param {Array<{ title: string, labels: string[], body: string, groupKey?: string, dependsOn?: string[] }>} built
1544
1274
  * @returns {string}