mandrel 2.60.0 → 2.61.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (661) hide show
  1. package/.agents/README.md +10 -10
  2. package/.agents/agents/story-worker.md +1 -1
  3. package/.agents/docs/agentrc-reference.json +4 -82
  4. package/.agents/docs/configuration.md +20 -87
  5. package/.agents/docs/workflows.md +1 -1
  6. package/.agents/instructions.md +1 -3
  7. package/.agents/rules/gherkin-standards.md +4 -0
  8. package/.agents/schemas/agentrc.schema.json +11 -486
  9. package/.agents/schemas/story-deliver-terminal.schema.json +10 -0
  10. package/.agents/schemas/validation-evidence.schema.json +2 -1
  11. package/.agents/scripts/README.md +14 -14
  12. package/.agents/scripts/acceptance-eval.js +32 -164
  13. package/.agents/scripts/agents-bootstrap-github.js +27 -129
  14. package/.agents/scripts/apply-quality-bootstrap.js +4 -40
  15. package/.agents/scripts/audit-baselines.js +6 -27
  16. package/.agents/scripts/audit-labels-bootstrap.js +5 -29
  17. package/.agents/scripts/audit-to-stories.js +91 -361
  18. package/.agents/scripts/boot-sweep.js +19 -72
  19. package/.agents/scripts/bootstrap.js +74 -395
  20. package/.agents/scripts/ceremony-derive.js +9 -45
  21. package/.agents/scripts/check-arch-cycles.js +14 -64
  22. package/.agents/scripts/check-baselines.js +8 -48
  23. package/.agents/scripts/check-context-budget.js +46 -172
  24. package/.agents/scripts/check-cyclomatic.js +12 -44
  25. package/.agents/scripts/check-dead-exports.js +13 -64
  26. package/.agents/scripts/check-doc-links.js +38 -186
  27. package/.agents/scripts/check-gherkin-corpus.js +24 -127
  28. package/.agents/scripts/check-test-temp-hygiene.js +28 -169
  29. package/.agents/scripts/coverage-capture.js +32 -99
  30. package/.agents/scripts/deliver-light.js +14 -101
  31. package/.agents/scripts/deliver-recover.js +6 -42
  32. package/.agents/scripts/deliver-run.js +36 -133
  33. package/.agents/scripts/diagnose-friction.js +24 -116
  34. package/.agents/scripts/drain-pending-cleanup.js +1 -1
  35. package/.agents/scripts/evidence-gate.js +23 -85
  36. package/.agents/scripts/file-ci-gap.js +10 -50
  37. package/.agents/scripts/generate-config-docs.js +30 -170
  38. package/.agents/scripts/generate-lens-checklists.js +8 -52
  39. package/.agents/scripts/generate-skills-index.js +14 -112
  40. package/.agents/scripts/generate-workflows-doc.js +10 -70
  41. package/.agents/scripts/git-cleanup.js +2 -34
  42. package/.agents/scripts/lib/Graph.js +24 -81
  43. package/.agents/scripts/lib/ITicketingProvider.js +47 -143
  44. package/.agents/scripts/lib/Logger.js +14 -76
  45. package/.agents/scripts/lib/audit-baselines/engine.js +11 -31
  46. package/.agents/scripts/lib/audit-baselines/gate-surface.js +3 -17
  47. package/.agents/scripts/lib/audit-baselines/headroom.js +4 -20
  48. package/.agents/scripts/lib/audit-baselines/hotspots.js +3 -15
  49. package/.agents/scripts/lib/audit-baselines/kinds.js +23 -89
  50. package/.agents/scripts/lib/audit-baselines/outliers.js +6 -23
  51. package/.agents/scripts/lib/audit-baselines/read.js +3 -16
  52. package/.agents/scripts/lib/audit-baselines/staleness.js +7 -26
  53. package/.agents/scripts/lib/audit-baselines/surface-entry.js +7 -28
  54. package/.agents/scripts/lib/audit-baselines/trend.js +7 -20
  55. package/.agents/scripts/lib/audit-baselines/weights.js +9 -37
  56. package/.agents/scripts/lib/audit-suite/audit-rules-reader.js +3 -18
  57. package/.agents/scripts/lib/audit-suite/checklist-threading.js +26 -124
  58. package/.agents/scripts/lib/audit-suite/dispatch-checklist.js +14 -45
  59. package/.agents/scripts/lib/audit-suite/findings.js +12 -52
  60. package/.agents/scripts/lib/audit-suite/frontmatter.js +5 -29
  61. package/.agents/scripts/lib/audit-suite/index.js +1 -15
  62. package/.agents/scripts/lib/audit-suite/lens-checklist.js +10 -45
  63. package/.agents/scripts/lib/audit-suite/lens-diff-floor.js +11 -76
  64. package/.agents/scripts/lib/audit-suite/runner.js +13 -43
  65. package/.agents/scripts/lib/audit-suite/selector.js +49 -349
  66. package/.agents/scripts/lib/audit-suite/substitutions.js +12 -40
  67. package/.agents/scripts/lib/audit-suite/workflow-loader.js +3 -15
  68. package/.agents/scripts/lib/audit-to-stories/audit-label-taxonomy.js +11 -73
  69. package/.agents/scripts/lib/audit-to-stories/audit-lenses.js +8 -37
  70. package/.agents/scripts/lib/audit-to-stories/build-story-body.js +25 -143
  71. package/.agents/scripts/lib/audit-to-stories/dedupe-against-github.js +14 -80
  72. package/.agents/scripts/lib/audit-to-stories/epic-grouping-directive.js +4 -18
  73. package/.agents/scripts/lib/audit-to-stories/finding-adapter.js +7 -40
  74. package/.agents/scripts/lib/audit-to-stories/group-findings.js +9 -39
  75. package/.agents/scripts/lib/audit-to-stories/issue-corpus.js +10 -66
  76. package/.agents/scripts/lib/audit-to-stories/issue-index.js +6 -30
  77. package/.agents/scripts/lib/audit-to-stories/issues-file.js +6 -36
  78. package/.agents/scripts/lib/audit-to-stories/ledger-commit.js +17 -69
  79. package/.agents/scripts/lib/audit-to-stories/ledger-pr.js +17 -85
  80. package/.agents/scripts/lib/audit-to-stories/ledger-record.js +10 -48
  81. package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +38 -146
  82. package/.agents/scripts/lib/audit-to-stories/seed-from-findings.js +7 -42
  83. package/.agents/scripts/lib/audit-to-stories/wire-dependencies.js +10 -57
  84. package/.agents/scripts/lib/baseline-loader.js +12 -51
  85. package/.agents/scripts/lib/baseline-schema-registry.js +5 -22
  86. package/.agents/scripts/lib/baselines/component-matcher.js +3 -12
  87. package/.agents/scripts/lib/baselines/components.js +10 -61
  88. package/.agents/scripts/lib/baselines/coverage-updater-cli.js +7 -36
  89. package/.agents/scripts/lib/baselines/crap-preview-incremental.js +5 -21
  90. package/.agents/scripts/lib/baselines/crap-preview-scan.js +19 -45
  91. package/.agents/scripts/lib/baselines/crap-updater-cli.js +16 -65
  92. package/.agents/scripts/lib/baselines/diff-scope-cli.js +5 -33
  93. package/.agents/scripts/lib/baselines/duplication-scanner.js +11 -60
  94. package/.agents/scripts/lib/baselines/env-overrides.js +12 -67
  95. package/.agents/scripts/lib/baselines/envelope.js +13 -129
  96. package/.agents/scripts/lib/baselines/exit-codes.js +6 -49
  97. package/.agents/scripts/lib/baselines/git-base.js +23 -142
  98. package/.agents/scripts/lib/baselines/kernel.js +11 -111
  99. package/.agents/scripts/lib/baselines/kinds/_crap-new-method-gate.js +9 -47
  100. package/.agents/scripts/lib/baselines/kinds/_crap-read.js +8 -51
  101. package/.agents/scripts/lib/baselines/kinds/_shared-metric.js +7 -62
  102. package/.agents/scripts/lib/baselines/kinds/bundle-size.js +8 -29
  103. package/.agents/scripts/lib/baselines/kinds/coverage.js +3 -15
  104. package/.agents/scripts/lib/baselines/kinds/crap.js +94 -415
  105. package/.agents/scripts/lib/baselines/kinds/duplication.js +4 -30
  106. package/.agents/scripts/lib/baselines/kinds/kind-factory.js +7 -53
  107. package/.agents/scripts/lib/baselines/kinds/maintainability.js +15 -80
  108. package/.agents/scripts/lib/baselines/kinds/mutation.js +12 -72
  109. package/.agents/scripts/lib/baselines/maintainability-baseline-io.js +4 -11
  110. package/.agents/scripts/lib/baselines/merge-envelopes.js +30 -146
  111. package/.agents/scripts/lib/baselines/path-canon.js +19 -128
  112. package/.agents/scripts/lib/baselines/preview-gates.js +8 -37
  113. package/.agents/scripts/lib/baselines/reader.js +14 -107
  114. package/.agents/scripts/lib/baselines/refresh-service.js +35 -252
  115. package/.agents/scripts/lib/baselines/scope.js +11 -135
  116. package/.agents/scripts/lib/baselines/writer.js +16 -149
  117. package/.agents/scripts/lib/bdd-runner-detect.js +18 -113
  118. package/.agents/scripts/lib/bdd-scenario-budget.js +9 -36
  119. package/.agents/scripts/lib/bdd-scenario-scanner.js +11 -73
  120. package/.agents/scripts/lib/bdd-step-index.js +26 -100
  121. package/.agents/scripts/lib/bootstrap/baseline-merge-driver.js +23 -103
  122. package/.agents/scripts/lib/bootstrap/branch-protection.js +2 -5
  123. package/.agents/scripts/lib/bootstrap/commit-push.js +12 -50
  124. package/.agents/scripts/lib/bootstrap/gh-preflight.js +14 -101
  125. package/.agents/scripts/lib/bootstrap/hitl-confirm.js +5 -30
  126. package/.agents/scripts/lib/bootstrap/install-ledger.js +17 -73
  127. package/.agents/scripts/lib/bootstrap/issue-forms-template.js +17 -121
  128. package/.agents/scripts/lib/bootstrap/manifest.js +15 -86
  129. package/.agents/scripts/lib/bootstrap/merge-methods.js +4 -33
  130. package/.agents/scripts/lib/bootstrap/preflight.js +12 -61
  131. package/.agents/scripts/lib/bootstrap/project-bootstrap.js +34 -235
  132. package/.agents/scripts/lib/bootstrap/prompt.js +21 -129
  133. package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +27 -141
  134. package/.agents/scripts/lib/bootstrap/summary.js +1 -8
  135. package/.agents/scripts/lib/bootstrap/workflow-audit.js +11 -84
  136. package/.agents/scripts/lib/branch-name-guard.js +4 -23
  137. package/.agents/scripts/lib/changed-files.js +31 -143
  138. package/.agents/scripts/lib/checks/core-bare-clean.js +4 -24
  139. package/.agents/scripts/lib/checks/index.js +18 -101
  140. package/.agents/scripts/lib/checks/loop-health.js +11 -53
  141. package/.agents/scripts/lib/checks/state.js +16 -91
  142. package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +10 -61
  143. package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +14 -83
  144. package/.agents/scripts/lib/child-exec.js +39 -108
  145. package/.agents/scripts/lib/cli/standard-args.js +9 -116
  146. package/.agents/scripts/lib/cli-args.js +31 -146
  147. package/.agents/scripts/lib/cli-usage.js +5 -27
  148. package/.agents/scripts/lib/cli-utils.js +2 -12
  149. package/.agents/scripts/lib/close-validation/commands.js +13 -76
  150. package/.agents/scripts/lib/close-validation/gates.js +92 -331
  151. package/.agents/scripts/lib/close-validation/process.js +121 -151
  152. package/.agents/scripts/lib/close-validation/projections/advisories.js +5 -31
  153. package/.agents/scripts/lib/close-validation/projections/crap.js +19 -67
  154. package/.agents/scripts/lib/close-validation/projections/head-sha.js +1 -17
  155. package/.agents/scripts/lib/close-validation/projections/inputs.js +4 -34
  156. package/.agents/scripts/lib/close-validation/projections/maintainability.js +11 -58
  157. package/.agents/scripts/lib/close-validation/runner.js +53 -110
  158. package/.agents/scripts/lib/command-header.js +6 -28
  159. package/.agents/scripts/lib/config/acceptance-eval.js +4 -30
  160. package/.agents/scripts/lib/config/baselines.js +3 -14
  161. package/.agents/scripts/lib/config/ci.js +8 -38
  162. package/.agents/scripts/lib/config/commands.js +1 -15
  163. package/.agents/scripts/lib/config/defaults.js +4 -33
  164. package/.agents/scripts/lib/config/delivery-routing.js +6 -35
  165. package/.agents/scripts/lib/config/explain.js +9 -80
  166. package/.agents/scripts/lib/config/gates/coverage.schema.js +0 -12
  167. package/.agents/scripts/lib/config/gates/crap-incremental-coverage.schema.js +2 -30
  168. package/.agents/scripts/lib/config/gates/crap.schema.js +1 -34
  169. package/.agents/scripts/lib/config/gates/duplication.schema.js +1 -8
  170. package/.agents/scripts/lib/config/gates/index.js +2 -17
  171. package/.agents/scripts/lib/config/gates/maintainability.schema.js +1 -20
  172. package/.agents/scripts/lib/config/gates/mutation.schema.js +1 -7
  173. package/.agents/scripts/lib/config/gates/shared.js +4 -64
  174. package/.agents/scripts/lib/config/github.js +4 -22
  175. package/.agents/scripts/lib/config/limits.js +4 -57
  176. package/.agents/scripts/lib/config/paths.js +2 -21
  177. package/.agents/scripts/lib/config/qa.js +4 -38
  178. package/.agents/scripts/lib/config/quality.js +76 -432
  179. package/.agents/scripts/lib/config/runners.js +12 -56
  180. package/.agents/scripts/lib/config/runtime.js +13 -57
  181. package/.agents/scripts/lib/config/shared.js +2 -16
  182. package/.agents/scripts/lib/config/sync-agentrc.js +9 -50
  183. package/.agents/scripts/lib/config/temp-paths.js +40 -280
  184. package/.agents/scripts/lib/config/validate-orchestration.js +5 -17
  185. package/.agents/scripts/lib/config/worktree-isolation.js +9 -28
  186. package/.agents/scripts/lib/config-resolver.js +10 -52
  187. package/.agents/scripts/lib/config-schema-shared.js +1 -4
  188. package/.agents/scripts/lib/config-settings-schema-delivery.js +12 -294
  189. package/.agents/scripts/lib/config-settings-schema-quality.js +7 -219
  190. package/.agents/scripts/lib/config-settings-schema.js +37 -274
  191. package/.agents/scripts/lib/coverage-baseline.js +20 -110
  192. package/.agents/scripts/lib/coverage-capture-fullscope.js +12 -37
  193. package/.agents/scripts/lib/coverage-capture-incremental.js +12 -43
  194. package/.agents/scripts/lib/coverage-capture-usage.js +4 -24
  195. package/.agents/scripts/lib/coverage-capture.js +99 -224
  196. package/.agents/scripts/lib/coverage-utils.js +14 -79
  197. package/.agents/scripts/lib/cpu-pool.js +17 -123
  198. package/.agents/scripts/lib/crap-baseline-join.js +16 -88
  199. package/.agents/scripts/lib/crap-coordinates.js +6 -25
  200. package/.agents/scripts/lib/crap-engine.js +40 -153
  201. package/.agents/scripts/lib/crap-method-identity.js +16 -78
  202. package/.agents/scripts/lib/crap-utils.js +31 -155
  203. package/.agents/scripts/lib/cyclomatic-ceiling.js +14 -87
  204. package/.agents/scripts/lib/cyclomatic-scope.js +10 -50
  205. package/.agents/scripts/lib/dead-exports-knip.js +18 -56
  206. package/.agents/scripts/lib/dead-exports-mode.js +5 -24
  207. package/.agents/scripts/lib/degraded-mode.js +3 -26
  208. package/.agents/scripts/lib/dependency-parser.js +8 -40
  209. package/.agents/scripts/lib/dependency-version.js +13 -35
  210. package/.agents/scripts/lib/detect-package-manager.js +6 -36
  211. package/.agents/scripts/lib/doc-tiers.js +22 -126
  212. package/.agents/scripts/lib/duplicate-search.js +8 -72
  213. package/.agents/scripts/lib/env-loader.js +5 -27
  214. package/.agents/scripts/lib/error-redactor.js +6 -31
  215. package/.agents/scripts/lib/errors/index.js +2 -22
  216. package/.agents/scripts/lib/escomplex-ast-compat.js +22 -163
  217. package/.agents/scripts/lib/escomplex-kernel.js +21 -123
  218. package/.agents/scripts/lib/feedback-loop/graduator-core.js +93 -419
  219. package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +20 -98
  220. package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +27 -151
  221. package/.agents/scripts/lib/findings/audit-ledger.js +23 -97
  222. package/.agents/scripts/lib/findings/classify-finding.js +14 -69
  223. package/.agents/scripts/lib/findings/promote-finding.js +14 -112
  224. package/.agents/scripts/lib/findings/provenance-field.js +11 -52
  225. package/.agents/scripts/lib/findings/route-finding.js +37 -255
  226. package/.agents/scripts/lib/findings/semantic-issue-search.js +14 -59
  227. package/.agents/scripts/lib/findings/severity.js +18 -104
  228. package/.agents/scripts/lib/format-generated-json.js +12 -44
  229. package/.agents/scripts/lib/full-suite-lock.js +160 -429
  230. package/.agents/scripts/lib/full-suite-queue.js +213 -0
  231. package/.agents/scripts/lib/gates/baseline-store.js +5 -9
  232. package/.agents/scripts/lib/gates/friction.js +1 -3
  233. package/.agents/scripts/lib/generated/agentrc-validator.js +2 -2
  234. package/.agents/scripts/lib/gh-exec.js +31 -259
  235. package/.agents/scripts/lib/git/cached-fetch.js +9 -52
  236. package/.agents/scripts/lib/git/sync-from-base.js +15 -107
  237. package/.agents/scripts/lib/git-branch-cleanup.js +14 -61
  238. package/.agents/scripts/lib/git-branch-lifecycle.js +16 -87
  239. package/.agents/scripts/lib/git-utils.js +37 -161
  240. package/.agents/scripts/lib/github/framework-repo.js +8 -71
  241. package/.agents/scripts/lib/github-url.js +2 -17
  242. package/.agents/scripts/lib/import-graph.js +11 -38
  243. package/.agents/scripts/lib/install-cmd-parser.js +4 -13
  244. package/.agents/scripts/lib/json-utils.js +3 -18
  245. package/.agents/scripts/lib/label-constants.js +16 -111
  246. package/.agents/scripts/lib/label-taxonomy.js +4 -30
  247. package/.agents/scripts/lib/maintainability-engine.js +12 -80
  248. package/.agents/scripts/lib/maintainability-unscorable.js +5 -25
  249. package/.agents/scripts/lib/maintainability-utils.js +16 -92
  250. package/.agents/scripts/lib/mandrel-catalog.js +12 -70
  251. package/.agents/scripts/lib/notifications/notifier.js +13 -38
  252. package/.agents/scripts/lib/npm-scripts.js +4 -23
  253. package/.agents/scripts/lib/observability/metrics-ledger.js +16 -76
  254. package/.agents/scripts/lib/observability/runtime-friction.js +44 -286
  255. package/.agents/scripts/lib/observability/signal-validator.js +5 -37
  256. package/.agents/scripts/lib/observability/signals-writer.js +11 -121
  257. package/.agents/scripts/lib/observability/source-classifier.js +21 -203
  258. package/.agents/scripts/lib/observability/terse-result.js +14 -47
  259. package/.agents/scripts/lib/onboard/init-tail.js +13 -74
  260. package/.agents/scripts/lib/onboard/scaffold-docs.js +11 -34
  261. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +25 -139
  262. package/.agents/scripts/lib/orchestration/auto-merge-cwd.js +11 -66
  263. package/.agents/scripts/lib/orchestration/behind-recovery.js +10 -55
  264. package/.agents/scripts/lib/orchestration/ceremony-routing.js +5 -75
  265. package/.agents/scripts/lib/orchestration/change-set.js +7 -36
  266. package/.agents/scripts/lib/orchestration/check-baselines/phases/compare.js +9 -46
  267. package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +11 -44
  268. package/.agents/scripts/lib/orchestration/check-baselines/phases/floors.js +5 -24
  269. package/.agents/scripts/lib/orchestration/check-baselines/phases/friction.js +3 -12
  270. package/.agents/scripts/lib/orchestration/check-baselines/phases/parse-args.js +5 -38
  271. package/.agents/scripts/lib/orchestration/check-baselines/phases/pipeline.js +3 -8
  272. package/.agents/scripts/lib/orchestration/check-baselines/phases/refresh-ack.js +28 -136
  273. package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +3 -13
  274. package/.agents/scripts/lib/orchestration/check-state.js +92 -0
  275. package/.agents/scripts/lib/orchestration/ci-gap-intake.js +37 -144
  276. package/.agents/scripts/lib/orchestration/ci-rerun-guard.js +42 -189
  277. package/.agents/scripts/lib/orchestration/code-review.js +24 -128
  278. package/.agents/scripts/lib/orchestration/column-sync.js +23 -111
  279. package/.agents/scripts/lib/orchestration/complexity-gate.js +42 -214
  280. package/.agents/scripts/lib/orchestration/deliver-recover.js +36 -168
  281. package/.agents/scripts/lib/orchestration/dependency-analyzer.js +4 -35
  282. package/.agents/scripts/lib/orchestration/dependency-candidates.js +9 -41
  283. package/.agents/scripts/lib/orchestration/diff-magnitude.js +25 -115
  284. package/.agents/scripts/lib/orchestration/doc-reader.js +2 -6
  285. package/.agents/scripts/lib/orchestration/docs-digest.js +13 -51
  286. package/.agents/scripts/lib/orchestration/epic-candidates.js +13 -53
  287. package/.agents/scripts/lib/orchestration/epic-checklist.js +9 -33
  288. package/.agents/scripts/lib/orchestration/epic-container.js +41 -167
  289. package/.agents/scripts/lib/orchestration/epic-expansion.js +10 -40
  290. package/.agents/scripts/lib/orchestration/epic-rollup.js +55 -207
  291. package/.agents/scripts/lib/orchestration/file-assumption-enum.js +2 -22
  292. package/.agents/scripts/lib/orchestration/file-assumptions.js +45 -253
  293. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-detect.js +9 -46
  294. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-reap.js +7 -57
  295. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches.js +21 -126
  296. package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +2 -6
  297. package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +1 -4
  298. package/.agents/scripts/lib/orchestration/git-cleanup/phases/filters.js +1 -5
  299. package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes-ff.js +9 -34
  300. package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes.js +41 -190
  301. package/.agents/scripts/lib/orchestration/git-cleanup/phases/merged-tip.js +9 -45
  302. package/.agents/scripts/lib/orchestration/git-cleanup/phases/parse-args.js +1 -4
  303. package/.agents/scripts/lib/orchestration/git-cleanup/phases/phase-drivers.js +19 -85
  304. package/.agents/scripts/lib/orchestration/git-cleanup/phases/prompts.js +3 -17
  305. package/.agents/scripts/lib/orchestration/git-cleanup/phases/prune.js +1 -5
  306. package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +16 -100
  307. package/.agents/scripts/lib/orchestration/git-cleanup/phases/stashes.js +1 -4
  308. package/.agents/scripts/lib/orchestration/lease-guard-shared.js +16 -67
  309. package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +9 -33
  310. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +8 -29
  311. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +15 -68
  312. package/.agents/scripts/lib/orchestration/light-backstop.js +11 -49
  313. package/.agents/scripts/lib/orchestration/light-escalation.js +21 -89
  314. package/.agents/scripts/lib/orchestration/light-suitability.js +26 -231
  315. package/.agents/scripts/lib/orchestration/merge-block-class.js +39 -216
  316. package/.agents/scripts/lib/orchestration/merge-poll.js +104 -377
  317. package/.agents/scripts/lib/orchestration/pinned-identifier-lint.js +17 -57
  318. package/.agents/scripts/lib/orchestration/plan-context.js +52 -303
  319. package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +22 -79
  320. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +5 -31
  321. package/.agents/scripts/lib/orchestration/plan-metrics.js +29 -108
  322. package/.agents/scripts/lib/orchestration/plan-navigation.js +8 -27
  323. package/.agents/scripts/lib/orchestration/plan-persist/acceptance-handle-repair.js +12 -49
  324. package/.agents/scripts/lib/orchestration/plan-persist/audit-provenance.js +18 -73
  325. package/.agents/scripts/lib/orchestration/plan-persist/changes-repair.js +14 -78
  326. package/.agents/scripts/lib/orchestration/plan-persist/cross-plan-links.js +6 -30
  327. package/.agents/scripts/lib/orchestration/plan-persist/epic-adoption.js +14 -65
  328. package/.agents/scripts/lib/orchestration/plan-persist/epic-ops.js +21 -76
  329. package/.agents/scripts/lib/orchestration/plan-persist/external-deps.js +6 -43
  330. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +14 -68
  331. package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +9 -41
  332. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +49 -248
  333. package/.agents/scripts/lib/orchestration/plan-persist/soft-findings.js +2 -12
  334. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +85 -368
  335. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +8 -38
  336. package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +30 -190
  337. package/.agents/scripts/lib/orchestration/plan-persist/wave-collision-gate.js +9 -49
  338. package/.agents/scripts/lib/orchestration/plan-persist/wave-serialisation.js +7 -28
  339. package/.agents/scripts/lib/orchestration/plan-reachability.js +13 -42
  340. package/.agents/scripts/lib/orchestration/plan-run-labels/reap.js +16 -91
  341. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +16 -54
  342. package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +10 -52
  343. package/.agents/scripts/lib/orchestration/planning/authoring-context.js +14 -109
  344. package/.agents/scripts/lib/orchestration/planning/memory-pool-advisory.js +11 -83
  345. package/.agents/scripts/lib/orchestration/pr-watch.js +48 -306
  346. package/.agents/scripts/lib/orchestration/project-meta-cache.js +15 -80
  347. package/.agents/scripts/lib/orchestration/project-meta-resolver.js +10 -51
  348. package/.agents/scripts/lib/orchestration/reassert-status-column.js +12 -76
  349. package/.agents/scripts/lib/orchestration/remote-verifier.js +12 -36
  350. package/.agents/scripts/lib/orchestration/resolve-stories.js +33 -164
  351. package/.agents/scripts/lib/orchestration/retro-proposals.js +66 -361
  352. package/.agents/scripts/lib/orchestration/review-base-ref.js +9 -43
  353. package/.agents/scripts/lib/orchestration/review-depth.js +12 -94
  354. package/.agents/scripts/lib/orchestration/review-providers/codex.js +10 -111
  355. package/.agents/scripts/lib/orchestration/review-providers/degraded-gates.js +13 -71
  356. package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +7 -51
  357. package/.agents/scripts/lib/orchestration/review-providers/mi-exemptions.js +8 -53
  358. package/.agents/scripts/lib/orchestration/review-providers/native.js +30 -214
  359. package/.agents/scripts/lib/orchestration/review-providers/parse-findings.js +7 -52
  360. package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +4 -33
  361. package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +11 -71
  362. package/.agents/scripts/lib/orchestration/review-providers/scoped-lint.js +19 -131
  363. package/.agents/scripts/lib/orchestration/review-providers/security-review.js +6 -89
  364. package/.agents/scripts/lib/orchestration/review-providers/types.js +26 -56
  365. package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +3 -46
  366. package/.agents/scripts/lib/orchestration/run-epilogue.js +40 -199
  367. package/.agents/scripts/lib/orchestration/run-scoped-config.js +13 -81
  368. package/.agents/scripts/lib/orchestration/single-story-close/close-note.js +7 -34
  369. package/.agents/scripts/lib/orchestration/single-story-close/failed-terminal.js +16 -89
  370. package/.agents/scripts/lib/orchestration/single-story-close/gate-log.js +18 -109
  371. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +83 -239
  372. package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +18 -80
  373. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +103 -97
  374. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +8 -64
  375. package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +136 -486
  376. package/.agents/scripts/lib/orchestration/single-story-close/phases/conventional-subject.js +30 -134
  377. package/.agents/scripts/lib/orchestration/single-story-close/phases/graphql-preflight.js +9 -50
  378. package/.agents/scripts/lib/orchestration/single-story-close/phases/lock-wait-pending.js +49 -0
  379. package/.agents/scripts/lib/orchestration/single-story-close/phases/normalize-pr-title.js +13 -86
  380. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +20 -95
  381. package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +46 -203
  382. package/.agents/scripts/lib/orchestration/single-story-close/phases/pre-gate-steps.js +8 -50
  383. package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +12 -83
  384. package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +6 -39
  385. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +1 -6
  386. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-outcome.js +4 -28
  387. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-override.js +6 -51
  388. package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +6 -34
  389. package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +23 -121
  390. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +110 -290
  391. package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +15 -69
  392. package/.agents/scripts/lib/orchestration/story-body-gate.js +4 -23
  393. package/.agents/scripts/lib/orchestration/story-close/baseline-upward-writeback.js +50 -179
  394. package/.agents/scripts/lib/orchestration/story-close/context-budget-writeback.js +11 -41
  395. package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +23 -311
  396. package/.agents/scripts/lib/orchestration/story-close/phases/local-lens-review.js +22 -147
  397. package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +16 -67
  398. package/.agents/scripts/lib/orchestration/story-deliver-terminal-schema.js +12 -68
  399. package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +42 -201
  400. package/.agents/scripts/lib/orchestration/story-follow-ups.js +43 -245
  401. package/.agents/scripts/lib/orchestration/story-init-envelope.js +4 -23
  402. package/.agents/scripts/lib/orchestration/story-init-remote.js +2 -6
  403. package/.agents/scripts/lib/orchestration/story-reachability.js +3 -23
  404. package/.agents/scripts/lib/orchestration/task-body-validator.js +12 -126
  405. package/.agents/scripts/lib/orchestration/ticket-lease.js +28 -131
  406. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +15 -149
  407. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +5 -33
  408. package/.agents/scripts/lib/orchestration/ticket-validator.js +39 -181
  409. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +51 -244
  410. package/.agents/scripts/lib/orchestration/ticketing/reads.js +39 -250
  411. package/.agents/scripts/lib/orchestration/ticketing/state.js +14 -68
  412. package/.agents/scripts/lib/orchestration/ticketing/transition.js +46 -263
  413. package/.agents/scripts/lib/orchestration/ticketing.js +2 -26
  414. package/.agents/scripts/lib/orchestration/verify-credit.js +18 -79
  415. package/.agents/scripts/lib/orchestration/worktree-dirty.js +5 -30
  416. package/.agents/scripts/lib/path-security.js +3 -6
  417. package/.agents/scripts/lib/plan-phase-cleanup.js +9 -49
  418. package/.agents/scripts/lib/preflight-runner.js +13 -69
  419. package/.agents/scripts/lib/process-group.js +143 -0
  420. package/.agents/scripts/lib/project-root.js +2 -8
  421. package/.agents/scripts/lib/provider-factory.js +2 -25
  422. package/.agents/scripts/lib/qa/console-allowlist.js +10 -59
  423. package/.agents/scripts/lib/qa/qa-session.js +15 -69
  424. package/.agents/scripts/lib/qa/redact-evidence.js +18 -129
  425. package/.agents/scripts/lib/qa/resolve-qa-contract.js +26 -135
  426. package/.agents/scripts/lib/qa/resolve-selection.js +16 -84
  427. package/.agents/scripts/lib/reserved-test-ids.js +9 -47
  428. package/.agents/scripts/lib/runtime-deps/dep-resolution.js +13 -53
  429. package/.agents/scripts/lib/runtime-deps/ensure-installed.js +10 -44
  430. package/.agents/scripts/lib/runtime-deps/manifest.js +10 -30
  431. package/.agents/scripts/lib/runtime-deps/parser-major.js +15 -51
  432. package/.agents/scripts/lib/runtime-deps/preflight.js +4 -22
  433. package/.agents/scripts/lib/runtime-deps/scan-imports.js +11 -55
  434. package/.agents/scripts/lib/signals/detectors/common.js +12 -38
  435. package/.agents/scripts/lib/signals/index.js +2 -19
  436. package/.agents/scripts/lib/signals/schema.js +14 -109
  437. package/.agents/scripts/lib/signals/write.js +2 -11
  438. package/.agents/scripts/lib/single-story/confirm-merge.js +31 -72
  439. package/.agents/scripts/lib/single-story/story-merged-notify.js +8 -49
  440. package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +4 -26
  441. package/.agents/scripts/lib/single-story-sweep/protection.js +13 -100
  442. package/.agents/scripts/lib/single-story-sweep/sweep-lock.js +60 -258
  443. package/.agents/scripts/lib/single-story-sweep.js +14 -97
  444. package/.agents/scripts/lib/skills/parse-skill.js +13 -59
  445. package/.agents/scripts/lib/skills/skills-index.js +8 -29
  446. package/.agents/scripts/lib/skills/walk-skill-files.js +17 -78
  447. package/.agents/scripts/lib/source-extensions.js +11 -42
  448. package/.agents/scripts/lib/source-text/strip-js-comments.js +8 -41
  449. package/.agents/scripts/lib/stdio-flush.js +9 -36
  450. package/.agents/scripts/lib/story-adjacency.js +8 -40
  451. package/.agents/scripts/lib/story-body/body-format-lints.js +22 -83
  452. package/.agents/scripts/lib/story-body/footer-block.js +11 -44
  453. package/.agents/scripts/lib/story-body/story-body.js +83 -358
  454. package/.agents/scripts/lib/temp-retention.js +42 -143
  455. package/.agents/scripts/lib/templates/decomposer-prompts.js +11 -65
  456. package/.agents/scripts/lib/test-env.js +12 -65
  457. package/.agents/scripts/lib/test-run-credit.js +10 -65
  458. package/.agents/scripts/lib/test-runner-contract.js +19 -74
  459. package/.agents/scripts/lib/test-temp.js +38 -184
  460. package/.agents/scripts/lib/test-tiers.js +12 -96
  461. package/.agents/scripts/lib/ticket-body-sections.js +21 -96
  462. package/.agents/scripts/lib/transpile.js +15 -74
  463. package/.agents/scripts/lib/util/concurrent-map.js +6 -25
  464. package/.agents/scripts/lib/util/parse-id-list.js +8 -34
  465. package/.agents/scripts/lib/util/poll-loop.js +8 -28
  466. package/.agents/scripts/lib/util/with-timeout.js +2 -11
  467. package/.agents/scripts/lib/validation-evidence.js +21 -96
  468. package/.agents/scripts/lib/wave-runner/footprint.js +17 -70
  469. package/.agents/scripts/lib/wave-runner/live-probe.js +53 -221
  470. package/.agents/scripts/lib/wave-runner/ready-set.js +72 -301
  471. package/.agents/scripts/lib/workers/crap-worker.js +11 -64
  472. package/.agents/scripts/lib/workers/maintainability-report-worker.js +8 -45
  473. package/.agents/scripts/lib/workers/maintainability-worker.js +5 -21
  474. package/.agents/scripts/lib/workers/serve-worker-messages.js +2 -18
  475. package/.agents/scripts/lib/workflow-closure.js +22 -105
  476. package/.agents/scripts/lib/workspace-provisioner.js +16 -54
  477. package/.agents/scripts/lib/worktree/git-hooks.js +15 -60
  478. package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +20 -60
  479. package/.agents/scripts/lib/worktree/lifecycle/merge-reachability.js +10 -62
  480. package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +22 -86
  481. package/.agents/scripts/lib/worktree/lifecycle/reap.js +24 -126
  482. package/.agents/scripts/lib/worktree/lifecycle-manager.js +2 -20
  483. package/.agents/scripts/lib/worktree/node-modules-strategy.js +46 -180
  484. package/.agents/scripts/lib/worktree-manager.js +15 -40
  485. package/.agents/scripts/lint-issue-body.js +12 -68
  486. package/.agents/scripts/mandrel-update-preflight.js +10 -70
  487. package/.agents/scripts/merge-baseline.js +30 -104
  488. package/.agents/scripts/nav-registry-diff.js +22 -108
  489. package/.agents/scripts/notify.js +12 -69
  490. package/.agents/scripts/plan-context.js +27 -111
  491. package/.agents/scripts/plan-critics.js +12 -66
  492. package/.agents/scripts/plan-persist.js +31 -148
  493. package/.agents/scripts/plan-run-epilogue.js +11 -37
  494. package/.agents/scripts/pr-watch-with-update.js +76 -267
  495. package/.agents/scripts/providers/github/auth.js +3 -8
  496. package/.agents/scripts/providers/github/blocked-by-add.js +14 -61
  497. package/.agents/scripts/providers/github/board-add.js +5 -21
  498. package/.agents/scripts/providers/github/branch-protection.js +11 -43
  499. package/.agents/scripts/providers/github/cache.js +2 -14
  500. package/.agents/scripts/providers/github/comments.js +7 -40
  501. package/.agents/scripts/providers/github/compose.js +3 -19
  502. package/.agents/scripts/providers/github/errors.js +22 -125
  503. package/.agents/scripts/providers/github/issues.js +31 -123
  504. package/.agents/scripts/providers/github/labels.js +24 -124
  505. package/.agents/scripts/providers/github/mappers.js +5 -27
  506. package/.agents/scripts/providers/github/merge-methods.js +3 -22
  507. package/.agents/scripts/providers/github/project-board.js +2 -17
  508. package/.agents/scripts/providers/github/projects-v2-graphql.js +3 -6
  509. package/.agents/scripts/providers/github/request-helpers.js +5 -32
  510. package/.agents/scripts/providers/github/search-budget.js +9 -39
  511. package/.agents/scripts/providers/github/search-query.js +5 -26
  512. package/.agents/scripts/providers/github/sub-issue-add.js +15 -65
  513. package/.agents/scripts/providers/github/sub-issues.js +7 -36
  514. package/.agents/scripts/providers/github/tickets.js +32 -134
  515. package/.agents/scripts/providers/github.js +18 -59
  516. package/.agents/scripts/prune-plan-run-labels.js +12 -46
  517. package/.agents/scripts/quality-preview.js +35 -220
  518. package/.agents/scripts/resolve-doc-tiers.js +3 -26
  519. package/.agents/scripts/resolve-stories.js +16 -67
  520. package/.agents/scripts/resync-status-column.js +6 -25
  521. package/.agents/scripts/run-tests.js +29 -104
  522. package/.agents/scripts/single-story-close.js +23 -135
  523. package/.agents/scripts/single-story-confirm-merge.js +32 -139
  524. package/.agents/scripts/single-story-init.js +47 -209
  525. package/.agents/scripts/stories-wave-tick.js +102 -472
  526. package/.agents/scripts/sync-agentrc.js +3 -21
  527. package/.agents/scripts/sync-claude-agents.js +9 -55
  528. package/.agents/scripts/sync-claude-commands.js +20 -110
  529. package/.agents/scripts/test-wrapper.js +6 -43
  530. package/.agents/scripts/update-coverage-baseline.js +5 -22
  531. package/.agents/scripts/update-crap-baseline.js +7 -30
  532. package/.agents/scripts/update-duplication-baseline.js +16 -92
  533. package/.agents/scripts/update-maintainability-baseline.js +8 -62
  534. package/.agents/scripts/update-ticket-state.js +1 -7
  535. package/.agents/scripts/validate-skills.js +6 -26
  536. package/.agents/templates/agent-protocol.md +2 -2
  537. package/.agents/templates/docs/audit-sweep-runbook.md +3 -4
  538. package/.agents/workflows/audit-accessibility.md +4 -7
  539. package/.agents/workflows/audit-adrs.md +3 -6
  540. package/.agents/workflows/audit-architecture.md +3 -11
  541. package/.agents/workflows/audit-baselines.md +6 -9
  542. package/.agents/workflows/audit-clean-code.md +8 -12
  543. package/.agents/workflows/audit-data-model.md +3 -7
  544. package/.agents/workflows/audit-dependencies.md +4 -7
  545. package/.agents/workflows/audit-devops.md +4 -8
  546. package/.agents/workflows/audit-documentation.md +1 -4
  547. package/.agents/workflows/audit-mobile.md +4 -7
  548. package/.agents/workflows/audit-navigability.md +3 -6
  549. package/.agents/workflows/audit-performance.md +2 -4
  550. package/.agents/workflows/audit-privacy.md +4 -7
  551. package/.agents/workflows/audit-quality.md +4 -7
  552. package/.agents/workflows/audit-security.md +4 -7
  553. package/.agents/workflows/audit-seo.md +4 -7
  554. package/.agents/workflows/audit-sre.md +4 -7
  555. package/.agents/workflows/audit-to-stories.md +17 -30
  556. package/.agents/workflows/audit-ux-ui.md +4 -7
  557. package/.agents/workflows/helpers/audit-lens-core.md +1 -1
  558. package/.agents/workflows/helpers/code-quality-guardrails.md +12 -15
  559. package/.agents/workflows/helpers/deliver-digest.md +6 -4
  560. package/.agents/workflows/helpers/deliver-reference.md +114 -188
  561. package/.agents/workflows/helpers/deliver-story-reference.md +189 -533
  562. package/.agents/workflows/helpers/plan-reference.md +86 -139
  563. package/.agents/workflows/helpers/qa-core.md +12 -0
  564. package/.agents/workflows/memory-consolidate.md +1 -1
  565. package/.agents/workflows/qa-assist.md +27 -71
  566. package/.agents/workflows/qa-explore.md +19 -59
  567. package/.agents/workflows/qa-run.md +11 -33
  568. package/README.md +1 -1
  569. package/bin/mandrel.js +5 -46
  570. package/bin/postinstall.js +18 -107
  571. package/docs/CHANGELOG.md +25 -0
  572. package/lib/cli/doctor.js +11 -71
  573. package/lib/cli/init.js +26 -165
  574. package/lib/cli/migrate.js +5 -64
  575. package/lib/cli/registry.js +84 -467
  576. package/lib/cli/sync-agents.js +4 -64
  577. package/lib/cli/sync-commands.js +11 -64
  578. package/lib/cli/sync.js +34 -213
  579. package/lib/cli/uninstall.js +40 -219
  580. package/lib/cli/update.js +105 -661
  581. package/lib/cli/version-check.js +8 -72
  582. package/lib/cli/version-helpers.js +14 -87
  583. package/lib/migrations/helpers/retire-agentrc-key.js +11 -52
  584. package/lib/migrations/index.js +15 -92
  585. package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +2 -15
  586. package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +1 -13
  587. package/lib/migrations/steps/2.11.0-retire-max-seed-words.js +2 -15
  588. package/lib/migrations/steps/2.2.0-retire-epic-ac-tags.js +9 -38
  589. package/lib/migrations/steps/2.20.0-retire-codebase-snapshot.js +1 -13
  590. package/lib/migrations/steps/2.32.0-retire-lint-baseline-command.js +2 -27
  591. package/lib/migrations/steps/2.57.0-retire-delivery-limit-knobs.js +2 -23
  592. package/lib/migrations/steps/2.57.0-retire-planning-limit-knobs.js +2 -27
  593. package/lib/migrations/steps/2.60.0-retire-audit-results-autofile.js +2 -21
  594. package/lib/migrations/steps/strip-removed-agentrc-keys.js +333 -0
  595. package/package.json +16 -14
  596. package/.agents/docs/SDLC.md +0 -590
  597. package/.agents/docs/quality-gates.md +0 -1183
  598. package/.agents/rules/known-tooling-behavior.md +0 -200
  599. package/.agents/rules/orchestration-error-handling.md +0 -61
  600. package/.agents/rules/test-seams.md +0 -59
  601. package/.agents/schemas/baselines/lighthouse.schema.json +0 -59
  602. package/.agents/schemas/baselines/lint.schema.json +0 -47
  603. package/.agents/scripts/check-action-pinning.js +0 -260
  604. package/.agents/scripts/check-audit-attribution.js +0 -302
  605. package/.agents/scripts/check-baseline-drift.js +0 -211
  606. package/.agents/scripts/check-baseline-scope.js +0 -362
  607. package/.agents/scripts/check-generated-validator.js +0 -202
  608. package/.agents/scripts/check-knip-entries.js +0 -159
  609. package/.agents/scripts/check-lifecycle-lint.js +0 -294
  610. package/.agents/scripts/check-pinned-override-notes.js +0 -102
  611. package/.agents/scripts/check-schema-references.js +0 -368
  612. package/.agents/scripts/check-test-portability.js +0 -512
  613. package/.agents/scripts/check-workflow-citations.js +0 -218
  614. package/.agents/scripts/check-workflow-cli-lint.js +0 -299
  615. package/.agents/scripts/check-workflow-timeouts.js +0 -291
  616. package/.agents/scripts/install-matrix-assert.js +0 -326
  617. package/.agents/scripts/lib/audit-advisories.js +0 -195
  618. package/.agents/scripts/lib/audit-attribution.js +0 -134
  619. package/.agents/scripts/lib/baselines/drift-detector.js +0 -351
  620. package/.agents/scripts/lib/baselines/kinds/lighthouse.js +0 -87
  621. package/.agents/scripts/lib/baselines/kinds/lint.js +0 -184
  622. package/.agents/scripts/lib/baselines/orphan-pruner.js +0 -233
  623. package/.agents/scripts/lib/baselines/scope-assert.js +0 -223
  624. package/.agents/scripts/lib/baselines/scope-inventory.js +0 -314
  625. package/.agents/scripts/lib/c8-cli-path.js +0 -21
  626. package/.agents/scripts/lib/config/gates/lighthouse.schema.js +0 -51
  627. package/.agents/scripts/lib/config/gates/lint.schema.js +0 -18
  628. package/.agents/scripts/lib/dynamic-workflow/architecture-report-contract.js +0 -70
  629. package/.agents/scripts/lib/dynamic-workflow/audit-orchestrator.js +0 -284
  630. package/.agents/scripts/lib/dynamic-workflow/clean-code-report-contract.js +0 -80
  631. package/.agents/scripts/lib/dynamic-workflow/degraded-coverage.js +0 -81
  632. package/.agents/scripts/lib/dynamic-workflow/documentation-report-contract.js +0 -87
  633. package/.agents/scripts/lib/dynamic-workflow/performance-report-contract.js +0 -74
  634. package/.agents/scripts/lib/dynamic-workflow/quality-report-contract.js +0 -90
  635. package/.agents/scripts/lib/dynamic-workflow/report-contract-core.js +0 -43
  636. package/.agents/scripts/lib/dynamic-workflow/security-report-contract.js +0 -83
  637. package/.agents/scripts/lib/fs-walk.js +0 -52
  638. package/.agents/scripts/lib/knip-config-resolver.js +0 -181
  639. package/.agents/scripts/lib/knip-entry-sync.js +0 -452
  640. package/.agents/scripts/lib/pinned-override-notes.js +0 -88
  641. package/.agents/scripts/lib/pinned-override-resolve.js +0 -212
  642. package/.agents/scripts/lib/test-isolate/cli-options.js +0 -93
  643. package/.agents/scripts/lib/test-isolate/env-snapshot-loader.js +0 -52
  644. package/.agents/scripts/lib/test-isolate/list-files.js +0 -90
  645. package/.agents/scripts/lib/test-isolate/parse-tap.js +0 -75
  646. package/.agents/scripts/lib/test-isolate/progress-log.js +0 -45
  647. package/.agents/scripts/lib/test-isolate/render-report.js +0 -97
  648. package/.agents/scripts/lib/test-isolate/run-isolate.js +0 -87
  649. package/.agents/scripts/lib/test-isolate/runner.js +0 -483
  650. package/.agents/scripts/lib/test-profile/parse-tap.js +0 -136
  651. package/.agents/scripts/lib/test-profile/render-report.js +0 -45
  652. package/.agents/scripts/lint-label-vocabulary.js +0 -214
  653. package/.agents/scripts/post-structured-comment.js +0 -127
  654. package/.agents/scripts/provision-git-hooks.js +0 -85
  655. package/.agents/scripts/prune-baseline-orphans.js +0 -181
  656. package/.agents/scripts/run-coverage.js +0 -197
  657. package/.agents/scripts/run-lint.js +0 -133
  658. package/.agents/scripts/run-test-profile.js +0 -129
  659. package/.agents/scripts/run-verify.js +0 -125
  660. package/.agents/scripts/test-isolate.js +0 -55
  661. package/.agents/scripts/update-dead-exports-baseline.js +0 -321
@@ -1,90 +1,23 @@
1
1
  /**
2
- * lib/orchestration/retro-proposals.js — pure composer that turns
3
- * aggregated source-tagged friction signals into three routed proposal
4
- * sections (framework, consumer, discarded).
5
- *
6
- * Epic #2547 / Story #2558 / Tech Spec #2550. Consumes per-Story signals
7
- * already source-tagged by `signals-writer.appendSignal` and yields a
8
- * three-way split that the retro composer renders above the
9
- * `<!-- retro-complete: ... -->` marker. The former "memory updates"
10
- * pane was deleted in the Epic #4406 signal-contract cutover (it had no
11
- * producer — no writer ever emitted the record it rendered).
12
- *
13
- * Heuristic (uniform across anchors — Story #4649):
14
- * - **Actionable** (renders as a pre-drafted `gh issue create` shell
15
- * command): a friction `category` with **≥ 2** occurrences under the
16
- * anchor, OR a blocked event whose root cause was never resolved (the
17
- * caller supplies these as `unresolvedBlockedEvents`).
18
- * - **Discarded**: a friction category under the threshold with no
19
- * follow-on signal. Discarded is not silent — the caller still renders
20
- * the bucket, so the event stays *recorded* without opening an issue.
21
- * - **Netted out** before either decision: a category with a recovery
22
- * marker for that Story (see `netOutRecoveredIncidents`) contributes
23
- * nothing at all.
24
- *
25
- * `anchorKind` deliberately does NOT move the threshold. It used to — story
26
- * scope promoted singletons at `≥ 1` — which, since the v2 Epic collapse put
27
- * every close on a per-Story window of population 1, made *every* un-netted
28
- * friction event auto-file. Cleanly-shipped Stories accumulated "recurred 1
29
- * times" issues, which is how a warning channel gets tuned out. The signal
30
- * that carve-out was standing in for is served properly by
31
- * `unresolvedBlockedEvents`: a Story genuinely parked at `agent::blocked`
32
- * forces actionable at count 1, while one that blocked and self-resolved
33
- * nets out. `anchorKind` now only selects title/body wording.
34
- *
35
- * Routing:
36
- * - Each actionable item is routed to `framework` or `consumer` based
37
- * on the dominant `source` tag for that category. "Dominant" means
38
- * the source with the higher count; ties resolve to whichever source
39
- * contributed the first occurrence so the ordering is deterministic.
40
- *
41
- * Corpus vs. trigger (Story #4850):
42
- * - The run-scope gather reduces over the **whole surviving recurrence
43
- * window**, not the triggering run's own Stories — deliberately, because a
44
- * systemic defect fires once per Story and scored 1 under the old per-run
45
- * window (see `gatherRunFrictionSignals`). The composer therefore may NOT
46
- * describe its corpus as "in <the triggering run>": it names the window it
47
- * was reduced over (occurrences, distinct Stories, first-to-last dates) and
48
- * carries the run as a separate labelled fact. When the corpus IS confined
49
- * to the run's own Stories, the plain "in <anchor>" wording is kept — that
50
- * is the common single-run case and it is not a false claim there.
51
- *
52
- * Publishable evidence (Story #4892):
53
- * - A routed item's body is filed verbatim as a real GitHub issue, and its
54
- * contributing-Story line is the recurrence claim a reader triages on. The
55
- * ids used to be rendered with no validation at all, so a synthetic id
56
- * from a test fixture reached a live ticket unchallenged: issue #4870 was
57
- * auto-filed naming `#999999`, an id the framework reserves for fixtures,
58
- * alongside one real Story. Contributing ids are therefore filtered
59
- * through `isPublishableTicketId` before they can be counted or printed,
60
- * and a bucket whose contributing ids are ALL unpublishable is discarded
61
- * rather than routed — a proposal with no resolvable evidence must not
62
- * auto-file at all. The filter is a resolvability bound, never a scope
63
- * narrowing: a real Story from outside the triggering run is published
64
- * exactly as before, which is the cross-run recurrence the window exists
65
- * to produce.
66
- *
67
- * Determinism:
68
- * - Output arrays are sorted by `category` ASC so a given input always
69
- * yields byte-identical markdown (Story #2558 AC).
70
- * - The rendered window is derived from the corpus's own timestamps, never
71
- * from the clock, so the module stays pure and its output reproducible.
72
- *
73
- * The module is pure: no I/O, no provider calls, no time-dependent state.
2
+ * Pure composer: source-tagged friction signals → framework / consumer /
3
+ * discarded proposal sections. No I/O, no clock; output sorted by `category`
4
+ * so a given input renders byte-identically.
5
+ *
6
+ * A category is actionable at ≥ 2 occurrences (any anchor kind — a per-Story
7
+ * window has population 1, so a lower bar files every event) or when an
8
+ * unresolved block forces it; recovered incidents net out first. Actionable
9
+ * items route to the dominant `source` (ties → first seen). The corpus is the
10
+ * whole recurrence window, so bodies name the window, not the triggering run.
11
+ * Unpublishable (fixture) Story ids are never printed, and a bucket whose ids
12
+ * are all unpublishable is discarded rather than filed.
74
13
  *
75
14
  * @typedef {Object} FrictionSignal
76
- * @property {string} category Free-form bucket (e.g. `"lint-loop"`).
15
+ * @property {string} category
77
16
  * @property {"framework"|"consumer"} source
78
- * @property {number} [storyId] Emitting Story id (used to net out recovered
79
- * incidents — Story #4622 / #4649).
80
- * @property {string} [tool] Emitting tool (`emitter.tool`) — descriptive
81
- * roll-up legibility only, never routing.
82
- * @property {string|null} [ts] ISO-8601 emit time (Story #4850), carried by
83
- * `normalizeGatheredSignal`; `null` when the row
84
- * carried none a `Date` could read.
85
- * @property {object} [details] Kind-specific payload; a record with
86
- * `details.recovered === true` is a recovery
87
- * marker for its own category.
17
+ * @property {number} [storyId] Used to net out recovered incidents.
18
+ * @property {string} [tool] Descriptive only, never routing.
19
+ * @property {string|null} [ts] ISO-8601; `null` when unreadable.
20
+ * @property {object} [details] `details.recovered === true` marks a recovery.
88
21
  *
89
22
  * @typedef {Object} BlockedEvent
90
23
  * @property {number} ticketId
@@ -93,17 +26,11 @@
93
26
  * @property {string} [summary]
94
27
  *
95
28
  * @typedef {Object} RoutedProposalsInput
96
- * @property {number} anchorId Story or run/Epic id in titles.
97
- * @property {'story'|'run'} [anchorKind] Wording in titles/bodies (default `story`).
98
- * @property {string} [runToken] The triggering run's own token
99
- * (`plan-run::<id>` / `adhoc-<ids>`) — Story #4850. `run-epilogue.js` used to
100
- * splice this in by regex over the rendered title and body *after* the fact;
101
- * it is an input now, so the composer never emits a token the caller then has
102
- * to rewrite.
103
- * @property {Array<number|string>} [anchorStoryIds] The triggering run's own
104
- * Story ids. Decides whether the corpus is confined to the run (the anchor is
105
- * then a true scope) or spans Stories outside it (the anchor is then only the
106
- * trigger). Defaults to `[anchorId]`.
29
+ * @property {number} anchorId
30
+ * @property {'story'|'run'} [anchorKind] Wording only (default `story`).
31
+ * @property {string} [runToken] `plan-run::<id>` / `adhoc-<ids>`.
32
+ * @property {Array<number|string>} [anchorStoryIds] The run's own Stories;
33
+ * decides whether the corpus is confined to the run. Defaults to `[anchorId]`.
107
34
  * @property {string} frameworkRepo `"<owner>/<repo>"`.
108
35
  * @property {string} consumerRepo `"<owner>/<repo>"`.
109
36
  * @property {FrictionSignal[]} [signals]
@@ -115,16 +42,15 @@
115
42
  * @property {"framework"|"consumer"} source
116
43
  * @property {string} title
117
44
  * @property {string} body
118
- * @property {string} command The pre-drafted `gh issue create` line.
45
+ * @property {string} command Pre-drafted `gh issue create` line.
119
46
  *
120
47
  * @typedef {Object} DiscardedItem
121
48
  * @property {string} category
122
49
  * @property {number} occurrences
123
50
  * @property {"framework"|"consumer"} source
124
- * @property {string[]} tools Emitting tools, sorted (Story #4824).
125
- * @property {string} fingerprint Stable 8-hex shape token (Story #4824).
126
- * @property {number} storyCount Distinct publishable Stories the bucket
127
- * spans — the cross-run recurrence count.
51
+ * @property {string[]} tools
52
+ * @property {string} fingerprint Stable 8-hex shape token.
53
+ * @property {number} storyCount Distinct publishable Stories spanned.
128
54
  *
129
55
  * @typedef {Object} RoutedProposals
130
56
  * @property {RoutedItem[]} framework
@@ -140,19 +66,12 @@ import {
140
66
  } from '../observability/runtime-friction.js';
141
67
  import { isPublishableTicketId } from '../reserved-test-ids.js';
142
68
 
143
- /**
144
- * Empty result helper — returned for zero-input callers so the consumer
145
- * never needs to defensively spread undefineds.
146
- *
147
- * @returns {RoutedProposals}
148
- */
69
+ /** @returns {RoutedProposals} */
149
70
  function emptyResult() {
150
71
  return { framework: [], consumer: [], discarded: [] };
151
72
  }
152
73
 
153
74
  /**
154
- * Normalise a stringy input to a trimmed string, or empty.
155
- *
156
75
  * @param {unknown} value
157
76
  * @returns {string}
158
77
  */
@@ -162,10 +81,6 @@ function asString(value) {
162
81
  }
163
82
 
164
83
  /**
165
- * Epoch milliseconds for a signal's `ts`, or `null` when it carries none a
166
- * `Date` can read. Pure, so the composer stays time-independent: the window it
167
- * renders is a property of the corpus, never of the clock.
168
- *
169
84
  * @param {unknown} ts
170
85
  * @returns {number|null}
171
86
  */
@@ -176,8 +91,6 @@ function tsMillis(ts) {
176
91
  }
177
92
 
178
93
  /**
179
- * Key a signal into its netting bucket: one `(category, storyId)` pair.
180
- *
181
94
  * @param {string} category
182
95
  * @param {number} storyId
183
96
  * @returns {string}
@@ -187,27 +100,11 @@ function incidentKey(category, storyId) {
187
100
  }
188
101
 
189
102
  /**
190
- * Net transient (self-resolved) incidents out of the signal stream before it
191
- * is aggregated (Story #4622, generalized by Story #4649).
192
- *
193
- * A recovery emits a record in the SAME category carrying
194
- * `details.recovered === true` — `agent::blocked → active` for
195
- * `story-blocked`, a confirmed land for `close-failed`. When a Story has such
196
- * a marker, that incident was transient: lease contention or a stale label
197
- * read under concurrent shared-checkout pressure (swarm-os friction #581), a
198
- * close that failed once and succeeded on retry. This drops **every** record
199
- * in that category for that Story (both the original incident and its
200
- * recovery marker), so the retro counts only incidents that never resolved.
201
- *
202
- * The netting is per `(category, storyId)`, not 1:1 pairing: a Story that
203
- * ever recovered from an incident in the run is treated as non-terminal for
204
- * that category for the whole run. That is a deliberate coarsening — the
205
- * aggregate is a routing heuristic, not an incident ledger, and the signal
206
- * stream carries no reliable ordering to reconstruct interleaved
207
- * incident/recover cycles. Keying on the category (rather than netting a
208
- * Story wholesale) is what keeps a recovered close from also cancelling that
209
- * Story's unrelated `story-blocked`. Records for other categories, and
210
- * Stories with no recovery marker, pass through untouched.
103
+ * Drop every record in a `(category, storyId)` pair that carries a recovery
104
+ * marker (`details.recovered === true`), so only never-resolved incidents are
105
+ * counted. Deliberately coarse — the stream has no reliable ordering to pair
106
+ * incident/recover cycles — and keyed per category so a recovered close does
107
+ * not cancel the same Story's unrelated `story-blocked`.
211
108
  *
212
109
  * @param {FrictionSignal[]} signals
213
110
  * @returns {FrictionSignal[]}
@@ -228,20 +125,8 @@ function netOutRecoveredIncidents(signals) {
228
125
  }
229
126
 
230
127
  /**
231
- * Derive the unresolved-block events for a signal stream (Story #4649).
232
- *
233
- * This is what replaces the retired story-scope threshold carve-out. A
234
- * `story-blocked` record whose Story has no companion recovery marker is a
235
- * Story still parked at `agent::blocked` — a human owes it a decision, and
236
- * that is worth filing at a single occurrence. One that recovered is netted
237
- * out by {@link netOutRecoveredIncidents} and produces no event here, so the
238
- * two mechanisms agree by construction.
239
- *
240
- * Callers previously passed a hardcoded `[]`, which left
241
- * `blockedForceActionable` permanently empty and made the carve-out the only
242
- * thing that could file anything at story scope.
243
- *
244
- * Pure. Sorted by `ticketId` so the routed output stays deterministic.
128
+ * A `story-blocked` record with no recovery marker is a Story still parked at
129
+ * `agent::blocked`, worth filing at one occurrence. Sorted by `ticketId`.
245
130
  *
246
131
  * @param {FrictionSignal[]} signals
247
132
  * @returns {BlockedEvent[]}
@@ -280,21 +165,12 @@ export function deriveUnresolvedBlockedEvents(signals) {
280
165
  }
281
166
 
282
167
  /**
283
- * Fingerprint the *shape* of a friction bucket (Story #4824) — the emitting
284
- * tools plus the `details` key set, hashed to a short stable token.
285
- *
286
- * Deliberately over the detail **keys**, never their values: a `reason` names
287
- * the file or command that failed and differs on every occurrence, so
288
- * hashing values would mint a fresh fingerprint per event and identify
289
- * nothing. The keys plus the emitting tool are what make two occurrences "the
290
- * same defect".
291
- *
292
- * Descriptive only. Routing and de-duplication stay keyed on `category`, so a
293
- * fingerprint can never split one filed issue into two.
168
+ * Hash of the emitting tools and `details` KEYS (values vary per event, so
169
+ * would identify nothing). Descriptive only — routing stays keyed on category.
294
170
  *
295
171
  * @param {string} category
296
- * @param {string[]} tools Sorted, de-duplicated emitter tools.
297
- * @param {string[]} detailKeys Sorted, de-duplicated `details` keys.
172
+ * @param {string[]} tools Sorted, de-duplicated.
173
+ * @param {string[]} detailKeys Sorted, de-duplicated.
298
174
  * @returns {string} 8 hex characters.
299
175
  */
300
176
  function fingerprintBucket(category, tools, detailKeys) {
@@ -306,21 +182,9 @@ function fingerprintBucket(category, tools, detailKeys) {
306
182
  }
307
183
 
308
184
  /**
309
- * Every reason text one signal's `details` carries, read from BOTH shapes the
310
- * emitters actually write.
311
- *
312
- * Two keys because two emitter conventions, and the divergence was silent: the
313
- * degradation emitters write a singular `details.reason` string, while the
314
- * light path's refusal emitter (`light-escalation.recordScopeFriction`) writes
315
- * `details.reasons` — an **array**, because one backstop verdict can object on
316
- * sensitivity and magnitude in the same pass. Reading only the singular key is
317
- * why every `light-scope-rejected` follow-up rendered with no `Reason:` line
318
- * at all (issue #5237), which defeated Story #4837's whole intent for that
319
- * emitter: the filed issue named a count and a category, and the refusal text
320
- * that would have told a reader which ceiling fired stayed in the ledger.
321
- *
322
- * Non-string members are skipped rather than coerced — `String(value)` would
323
- * put `[object Object]` in a live issue body.
185
+ * Reason texts from both emitter shapes: singular `details.reason` and the
186
+ * light-path refusal's `details.reasons` array. Non-strings are skipped, not
187
+ * coerced to `[object Object]`.
324
188
  *
325
189
  * @param {object} details
326
190
  * @returns {string[]}
@@ -339,9 +203,7 @@ function collectReasons(details) {
339
203
  }
340
204
 
341
205
  /**
342
- * Widen a bucket's first-to-last window to include one instant. A row with no
343
- * usable `ts` widens nothing — it is counted in `total` but cannot date the
344
- * corpus, so it must not be able to shrink the range either.
206
+ * A row with no usable `ts` is counted but never moves the window.
345
207
  *
346
208
  * @param {{ firstMs: number|null, lastMs: number|null }} entry
347
209
  * @param {number|null} ms
@@ -354,19 +216,9 @@ function widenWindow(entry, ms) {
354
216
  }
355
217
 
356
218
  /**
357
- * Aggregate friction signals by `category`, tracking per-source counts and
358
- * arrival order so we can pick a dominant source deterministically.
359
- *
360
- * Records with a missing/invalid `category` are skipped (no silent
361
- * "" bucket). Records with an unknown `source` default to `"consumer"`
362
- * — that matches the source-classifier's safe default.
363
- *
364
- * `category` is deliberately still the aggregation unit (Story #4824): it is
365
- * what titles a filed issue and what the graduator's idempotency marker
366
- * fingerprints, so splitting the bucket by emitter would file N issues where
367
- * the loop is designed to file one. The emitter tools, `details` key set, and
368
- * the distinct Stories a bucket spans ride **on** the entry instead, purely
369
- * so a roll-up can name what it counted.
219
+ * Aggregate by `category` — the unit the graduator's idempotency marker keys
220
+ * on, so it must not split by emitter. Missing category is skipped; unknown
221
+ * `source` defaults to `"consumer"`.
370
222
  *
371
223
  * @param {FrictionSignal[]} signals
372
224
  * @returns {Map<string, {
@@ -416,22 +268,14 @@ function aggregateByCategory(signals) {
416
268
  if (tool.length > 0) entry.tools.add(tool);
417
269
  if (sig.details !== null && typeof sig.details === 'object') {
418
270
  for (const key of Object.keys(sig.details)) entry.detailKeys.add(key);
419
- // Two detail VALUES are carried through to the rendered body (Story
420
- // #4837): the surface that degraded and the reason text. They are what
421
- // turn "tool-degraded ×6" into "the scoped-lint gate could not execute
422
- // and failed open" — the thing a reader absent from the run needs.
423
- // Values never reach `detailKeys`, so the bucket fingerprint (hashed
424
- // over keys, deliberately) is untouched by them.
271
+ // Surface and reason values reach the body, never the fingerprint.
425
272
  const surface = asString(sig.details.surface);
426
273
  if (surface.length > 0) entry.surfaces.add(surface);
427
274
  for (const reason of collectReasons(sig.details)) {
428
275
  entry.reasons.add(reason);
429
276
  }
430
277
  }
431
- // An id that cannot be resolved to a real issue is tracked separately
432
- // rather than dropped: it must never be counted or printed as recurrence
433
- // evidence, but "this bucket's only contributing ids were synthetic" is
434
- // exactly what stops it auto-filing (see `hasPublishableStoryEvidence`).
278
+ // Unpublishable ids are withheld, not dropped: they gate auto-filing.
435
279
  if (Number.isInteger(sig.storyId) && sig.storyId > 0) {
436
280
  if (isPublishableTicketId(sig.storyId)) entry.storyIds.add(sig.storyId);
437
281
  else entry.withheldStoryIds.add(sig.storyId);
@@ -441,17 +285,8 @@ function aggregateByCategory(signals) {
441
285
  }
442
286
 
443
287
  /**
444
- * Does this bucket carry story evidence a filed issue may cite (Story #4892)?
445
- *
446
- * Three cases, and the middle one is the point:
447
- * - Some publishable id → yes, file it (the withheld ids are simply absent
448
- * from the body).
449
- * - Contributing ids, none publishable → **no**. Every id the bucket could
450
- * cite is synthetic, so a filed issue would assert recurrence evidence
451
- * that resolves to nothing. The bucket is discarded instead.
452
- * - No contributing ids at all → yes. That is a bucket forced actionable by
453
- * an unresolved block with no aggregated signals behind it; it never cited
454
- * a Story, so there is nothing unresolvable about it.
288
+ * False only when every contributing id is unpublishable — a filed issue would
289
+ * then cite evidence that resolves to nothing. No ids at all is fine.
455
290
  *
456
291
  * @param {{ storyIds: Set<number>, withheldStoryIds: Set<number> }} entry
457
292
  * @returns {boolean}
@@ -461,16 +296,6 @@ function hasPublishableStoryEvidence(entry) {
461
296
  }
462
297
 
463
298
  /**
464
- * Project an aggregate entry's descriptive fields onto a `DiscardedItem`
465
- * (Story #4824).
466
- *
467
- * A roll-up that discards every candidate used to render as a bare
468
- * `` `category` ×1 `` per row, which is how a defect recurring once per Story
469
- * across eighteen consecutive Stories stayed invisible. The row now names the
470
- * emitting tools, the bucket fingerprint, and how many distinct Stories it
471
- * spans — the last is the cross-run count the widened recurrence window
472
- * exists to produce.
473
- *
474
299
  * @param {{ category: string, tools: Set<string>, detailKeys: Set<string>, storyIds: Set<number> }} entry
475
300
  * @returns {{ tools: string[], fingerprint: string, storyCount: number }}
476
301
  */
@@ -485,20 +310,8 @@ function describeBucket(entry) {
485
310
  }
486
311
 
487
312
  /**
488
- * The evidence an ACTIONABLE item's rendered body names (Story #4837).
489
- *
490
- * Story #4824 put the emitting tools, the shape fingerprint and the
491
- * distinct-Story span on the aggregate entry, but projected them only onto
492
- * the *discarded* rows — so the one bucket that actually became a GitHub
493
- * issue was rendered from a category and a count alone. Measured on issue
494
- * #4836: a `tool-degraded ×6` body that never named `native-review-lint`,
495
- * never named the `scoped-lint` surface, and never named the reason, so the
496
- * review gate that could not execute and failed open appeared nowhere in the
497
- * ticket opened about it.
498
- *
499
- * Every collection is sorted so the same input renders byte-identically —
500
- * the body is written to a live issue on every recurrence, and an unstable
501
- * ordering would rewrite it with no change of meaning.
313
+ * Evidence an actionable body names. Collections are sorted: the body is
314
+ * rewritten to a live issue on every recurrence.
502
315
  *
503
316
  * @param {{
504
317
  * category: string,
@@ -522,9 +335,7 @@ function describeEvidence(entry) {
522
335
  surfaces: [...entry.surfaces].sort(),
523
336
  reasons: [...entry.reasons].sort(),
524
337
  storyIds: [...entry.storyIds].sort((a, b) => a - b),
525
- // Story #4850 — the corpus's own first-to-last span. Deliberately NOT
526
- // projected onto `describeBucket`: a discarded row is rendered from the
527
- // bucket shape, and the window belongs to the claim a *filed* issue makes.
338
+ // Only a filed issue claims a window; discarded rows omit it.
528
339
  window: { firstMs: entry.firstMs, lastMs: entry.lastMs },
529
340
  };
530
341
  }
@@ -549,9 +360,7 @@ const MAX_RENDERED_REASONS = 3;
549
360
  const MAX_RENDERED_STORIES = 12;
550
361
 
551
362
  /**
552
- * Render a `label: value` evidence line, or `null` when there is nothing to
553
- * say. A missing field is omitted outright rather than rendered as "none":
554
- * an absent emitter is not the finding.
363
+ * `null` (omitted) rather than "none" when there are no values.
555
364
  *
556
365
  * @param {string} label
557
366
  * @param {string[]} values
@@ -562,11 +371,6 @@ function evidenceLine(label, values) {
562
371
  }
563
372
 
564
373
  /**
565
- * Render the contributing-Story line: the distinct Stories that emitted into
566
- * this bucket. This is the cross-run recurrence evidence — the difference
567
- * between "happened six times somewhere" and "happened on these six Stories,
568
- * so it is not one bad afternoon".
569
- *
570
374
  * @param {number[]} storyIds
571
375
  * @param {number} storyCount
572
376
  * @returns {string|null}
@@ -581,9 +385,6 @@ function storiesLine(storyIds, storyCount) {
581
385
  }
582
386
 
583
387
  /**
584
- * Render the reason texts the emitters supplied, capped so one pathological
585
- * bucket cannot produce an unreadable issue body.
586
- *
587
388
  * @param {string[]} reasons
588
389
  * @returns {string|null}
589
390
  */
@@ -596,9 +397,7 @@ function reasonsLine(reasons) {
596
397
  }
597
398
 
598
399
  /**
599
- * Resolve the dominant source for an aggregated category. Ties resolve to
600
- * `firstSource` so byte-identical inputs always produce byte-identical
601
- * routing.
400
+ * Ties resolve to `firstSource` so routing is deterministic.
602
401
  *
603
402
  * @param {{ bySource: { framework: number, consumer: number }, firstSource: "framework"|"consumer" }} entry
604
403
  * @returns {"framework"|"consumer"}
@@ -611,12 +410,6 @@ function dominantSource(entry) {
611
410
  }
612
411
 
613
412
  /**
614
- * Name the triggering anchor. For a run that means its own token when the
615
- * caller supplied one (Story #4850) — `run-epilogue.js` previously let the
616
- * composer print the primary Story's numeric id as if it were the run id and
617
- * then rewrote it by regex, which meant the rendered text and the caller's
618
- * notion of the run could silently disagree.
619
- *
620
413
  * @param {'story'|'run'} kind
621
414
  * @param {number} id
622
415
  * @param {string} runToken
@@ -627,13 +420,6 @@ function formatAnchor(kind, id, runToken) {
627
420
  }
628
421
 
629
422
  /**
630
- * Label the evidence fact that names the triggering anchor.
631
- *
632
- * Tracks `anchorKind` for the same reason {@link formatAnchor} does. Story
633
- * #4850 introduced the fact with a fixed `Triggering run` label, which on the
634
- * story-scope path called a Story a run (`Triggering run: Story #7`) — the one
635
- * place in this file where the wording did not follow the anchor.
636
- *
637
423
  * @param {'story'|'run'} kind
638
424
  * @returns {string}
639
425
  */
@@ -642,11 +428,8 @@ function formatTriggerLabel(kind) {
642
428
  }
643
429
 
644
430
  /**
645
- * The UTC calendar day of an instant, or `''` when there is no instant.
646
- *
647
- * Day granularity on purpose: the window is triage context ("this has been
648
- * recurring for three weeks"), and a full timestamp would rewrite the live
649
- * issue body on every recurrence for no change of meaning.
431
+ * UTC day, deliberately: a full timestamp would rewrite the live issue body on
432
+ * every recurrence.
650
433
  *
651
434
  * @param {number|null} ms
652
435
  * @returns {string}
@@ -656,9 +439,7 @@ function isoDay(ms) {
656
439
  }
657
440
 
658
441
  /**
659
- * Render the corpus window as a prose phrase, or `''` when no row in the
660
- * bucket carried a readable `ts`. Omitting it is the honest degradation: an
661
- * undateable corpus must not be given a made-up range.
442
+ * `''` when the corpus is undateable — never a made-up range.
662
443
  *
663
444
  * @param {{ firstMs: number|null, lastMs: number|null }} window
664
445
  * @returns {string}
@@ -671,8 +452,6 @@ function windowPhrase(window) {
671
452
  }
672
453
 
673
454
  /**
674
- * The same window as the compact span a title carries.
675
- *
676
455
  * @param {{ firstMs: number|null, lastMs: number|null }} window
677
456
  * @returns {string}
678
457
  */
@@ -684,8 +463,6 @@ function windowSpan(window) {
684
463
  }
685
464
 
686
465
  /**
687
- * `across N Stories`, or `''` when no Story could be attributed.
688
- *
689
466
  * @param {number} storyCount
690
467
  * @returns {string}
691
468
  */
@@ -694,29 +471,14 @@ function storySpan(storyCount) {
694
471
  return `across ${storyCount} ${storyCount === 1 ? 'Story' : 'Stories'}`;
695
472
  }
696
473
 
697
- /**
698
- * Occurrences needed before a category routes on its own. Uniform across
699
- * anchors (Story #4649) — see the module header for why story scope no
700
- * longer promotes singletons.
701
- */
702
474
  const ACTIONABLE_THRESHOLD = 2;
703
475
 
704
- /** A category routes when it recurred, or when a block forces it. */
705
476
  function isActionableFriction(total, force) {
706
477
  return total >= ACTIONABLE_THRESHOLD || Boolean(force);
707
478
  }
708
479
 
709
480
  /**
710
- * Render the opening sentence: what the corpus is, sized and dated by its own
711
- * contents (Story #4850).
712
- *
713
- * This line used to read `surfaced N times during <anchor>`, where `<anchor>`
714
- * was the run whose epilogue happened to fire. The corpus is the whole
715
- * surviving recurrence window (deliberately — see `gatherRunFrictionSignals`),
716
- * so on any systemic defect the sentence asserted a scope the evidence block
717
- * three lines below it already contradicted by listing foreign Stories. It now
718
- * describes the window it was actually reduced over; the triggering run is a
719
- * separate labelled fact, because that is what it is.
481
+ * Sized and dated by the corpus itself, never by the triggering run.
720
482
  *
721
483
  * @param {string} category
722
484
  * @param {number} occurrences
@@ -733,22 +495,8 @@ function corpusSentence(category, occurrences, evidence) {
733
495
  }
734
496
 
735
497
  /**
736
- * Render the issue body. Plain text — no markdown headings — so the
737
- * pre-drafted `gh issue create --body-file` heredoc remains a faithful
738
- * representation of what the operator would paste.
739
- *
740
- * The evidence block (Story #4837) is what makes the issue actionable by
741
- * someone who was not in the run: the emitting tool, the surface that
742
- * degraded, the reason the emitter gave, the distinct Stories it spans, and
743
- * the shape fingerprint that ties recurrences together. Absent fields are
744
- * omitted, so a bucket that genuinely carries no evidence renders as it
745
- * always did rather than as a wall of "unknown".
746
- *
747
- * The triggering anchor leads that block (Story #4850): it is what caused this
748
- * issue to be *filed now*, which is worth naming, and is exactly not the same
749
- * claim as its being where the occurrences happened. Its label tracks
750
- * `anchorKind` via {@link formatTriggerLabel}, so the story-scope path says
751
- * `Triggering Story` rather than calling a Story a run.
498
+ * Plain text (no headings) so the heredoc matches what an operator pastes.
499
+ * The trigger is a separate fact from where the occurrences happened.
752
500
  *
753
501
  * @param {{
754
502
  * anchor: { label: string, trigger: string },
@@ -786,11 +534,7 @@ function renderIssueBody({ anchor, category, occurrences, source, evidence }) {
786
534
  }
787
535
 
788
536
  /**
789
- * Compose the pre-drafted `gh issue create` shell command for an actionable
790
- * item. The command is rendered verbatim — operators copy-paste it as-is.
791
- *
792
- * The body is supplied via `--body-file -` and a trailing heredoc so the
793
- * multi-line content survives shell quoting on every platform.
537
+ * Body goes via `--body-file -` heredoc so multi-line content survives quoting.
794
538
  *
795
539
  * @param {{
796
540
  * repo: string,
@@ -803,8 +547,7 @@ function renderIssueBody({ anchor, category, occurrences, source, evidence }) {
803
547
  */
804
548
  function renderIssueCommand({ repo, title, metaLabel, category, body }) {
805
549
  const labels = `meta::${metaLabel},friction::${category}`;
806
- // Heredoc form keeps multi-line bodies safe under POSIX shells; agents
807
- // running on PowerShell convert it to a `--body` flag if needed.
550
+ // PowerShell agents convert the heredoc to `--body`.
808
551
  return [
809
552
  `gh issue create --repo ${repo} --title "${title}" --label "${labels}" --body-file - <<EOF`,
810
553
  body,
@@ -813,23 +556,9 @@ function renderIssueCommand({ repo, title, metaLabel, category, body }) {
813
556
  }
814
557
 
815
558
  /**
816
- * Render the issue title — the one line a human triages on, so it is the one
817
- * line that must not misname its own corpus (Story #4850).
818
- *
819
- * Two forms, selected by whether the corpus is *confined* to the triggering
820
- * run's own Stories:
821
- *
822
- * - **Confined** → `recurred N times in <anchor>`. The anchor genuinely is
823
- * the scope, and this is the common single-run case; hedging it would make
824
- * every ordinary title longer and vaguer for no gain.
825
- * - **Spanning** → `recurred N times across M Stories (<first> → <last>)`.
826
- * The anchor is dropped from the *claim* entirely (it stays in the body as
827
- * the triggering fact), because naming it here is the falsehood: the
828
- * occurrences did not happen in it.
829
- *
830
- * Retitling is de-dupe safe — the graduator's idempotency marker is
831
- * category-fingerprint-only and anchor-free (Story #4837), and the title is
832
- * deliberately excluded from the hash.
559
+ * `in <anchor>` only when the corpus is confined to the run's Stories;
560
+ * otherwise `across M Stories (<first> → <last>)`. Retitling is de-dupe safe:
561
+ * the graduator's marker excludes the title.
833
562
  *
834
563
  * @param {{
835
564
  * category: string,
@@ -855,11 +584,7 @@ function renderIssueTitle({
855
584
  }
856
585
 
857
586
  /**
858
- * Is every contributing Story one of the triggering run's own?
859
- *
860
- * A corpus with no attributable Story at all (a block forced actionable with no
861
- * aggregated signals) counts as confined: there is no foreign evidence to
862
- * contradict the anchor, so the plain wording stays.
587
+ * An empty corpus counts as confined.
863
588
  *
864
589
  * @param {number[]} storyIds
865
590
  * @param {Set<number>} anchorStoryIds
@@ -870,8 +595,6 @@ function isCorpusConfined(storyIds, anchorStoryIds) {
870
595
  }
871
596
 
872
597
  /**
873
- * Build an actionable RoutedItem for a category.
874
- *
875
598
  * @param {{
876
599
  * anchor: { label: string, trigger: string, storyIds: Set<number> },
877
600
  * category: string,
@@ -920,9 +643,6 @@ function buildRoutedItem({
920
643
  }
921
644
 
922
645
  /**
923
- * Validate that the input shape is sane and extract typed arrays. Returns
924
- * `null` when input is unusable (caller short-circuits to `emptyResult`).
925
- *
926
646
  * @param {unknown} input
927
647
  * @returns {{
928
648
  * anchor: { label: string, trigger: string, storyIds: Set<number> },
@@ -937,11 +657,7 @@ function normalizeAnchorKind(kind) {
937
657
  }
938
658
 
939
659
  /**
940
- * The triggering run's own Story ids as a set, defaulting to the anchor itself.
941
- *
942
- * The default is what keeps story-scope capture byte-identical: one Story's
943
- * stream can only carry its own id, so the corpus is confined by construction
944
- * and the wording never hedges.
660
+ * Defaults to the anchor itself, so story scope is confined by construction.
945
661
  *
946
662
  * @param {unknown} raw
947
663
  * @param {number} anchorId
@@ -1051,8 +767,6 @@ function routeCategoryBuckets({
1051
767
  source: info.source,
1052
768
  frameworkRepo,
1053
769
  consumerRepo,
1054
- // Forced actionable by an unresolved block with no aggregated
1055
- // signals behind it — there is no bucket to describe.
1056
770
  evidence: emptyEvidence(),
1057
771
  }),
1058
772
  );
@@ -1064,15 +778,6 @@ function routeCategoryBuckets({
1064
778
  }
1065
779
 
1066
780
  /**
1067
- * Compose the four routed proposal sections from aggregated source-tagged
1068
- * signals.
1069
- *
1070
- * Pure — no I/O, no time-dependent state, no provider calls. Returns an
1071
- * object with three arrays:
1072
- * - `framework`: actionable items routed to the framework repo.
1073
- * - `consumer`: actionable items routed to the consumer repo.
1074
- * - `discarded`: single-occurrence friction with no follow-on signal.
1075
- *
1076
781
  * @param {RoutedProposalsInput} input
1077
782
  * @returns {RoutedProposals}
1078
783
  */