mandrel 2.59.0 → 2.61.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (678) hide show
  1. package/.agents/README.md +21 -19
  2. package/.agents/agents/acceptance-critic.md +24 -43
  3. package/.agents/agents/story-worker.md +20 -21
  4. package/.agents/docs/agentrc-reference.json +5 -84
  5. package/.agents/docs/configuration.md +48 -132
  6. package/.agents/docs/workflows.md +2 -2
  7. package/.agents/instructions.md +5 -8
  8. package/.agents/rules/ci-remediation.md +41 -8
  9. package/.agents/rules/gherkin-standards.md +4 -0
  10. package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
  11. package/.agents/schemas/agentrc.schema.json +16 -496
  12. package/.agents/schemas/story-deliver-terminal.schema.json +13 -3
  13. package/.agents/schemas/validation-evidence.schema.json +2 -1
  14. package/.agents/scripts/README.md +23 -13
  15. package/.agents/scripts/acceptance-eval.js +35 -169
  16. package/.agents/scripts/agents-bootstrap-github.js +27 -129
  17. package/.agents/scripts/apply-quality-bootstrap.js +4 -40
  18. package/.agents/scripts/audit-baselines.js +6 -27
  19. package/.agents/scripts/audit-labels-bootstrap.js +5 -29
  20. package/.agents/scripts/audit-to-stories.js +91 -361
  21. package/.agents/scripts/boot-sweep.js +19 -72
  22. package/.agents/scripts/bootstrap.js +74 -395
  23. package/.agents/scripts/ceremony-derive.js +10 -41
  24. package/.agents/scripts/check-arch-cycles.js +14 -64
  25. package/.agents/scripts/check-baselines.js +8 -48
  26. package/.agents/scripts/check-context-budget.js +105 -311
  27. package/.agents/scripts/check-cyclomatic.js +12 -44
  28. package/.agents/scripts/check-dead-exports.js +13 -64
  29. package/.agents/scripts/check-doc-links.js +38 -186
  30. package/.agents/scripts/check-gherkin-corpus.js +24 -127
  31. package/.agents/scripts/check-test-temp-hygiene.js +28 -169
  32. package/.agents/scripts/coverage-capture.js +34 -98
  33. package/.agents/scripts/deliver-light.js +25 -171
  34. package/.agents/scripts/deliver-recover.js +6 -42
  35. package/.agents/scripts/deliver-run.js +534 -0
  36. package/.agents/scripts/diagnose-friction.js +24 -116
  37. package/.agents/scripts/drain-pending-cleanup.js +1 -1
  38. package/.agents/scripts/evidence-gate.js +23 -85
  39. package/.agents/scripts/file-ci-gap.js +57 -49
  40. package/.agents/scripts/generate-config-docs.js +30 -170
  41. package/.agents/scripts/generate-lens-checklists.js +8 -52
  42. package/.agents/scripts/generate-skills-index.js +14 -112
  43. package/.agents/scripts/generate-workflows-doc.js +10 -70
  44. package/.agents/scripts/git-cleanup.js +2 -34
  45. package/.agents/scripts/lib/Graph.js +24 -81
  46. package/.agents/scripts/lib/ITicketingProvider.js +47 -143
  47. package/.agents/scripts/lib/Logger.js +14 -76
  48. package/.agents/scripts/lib/audit-baselines/engine.js +11 -31
  49. package/.agents/scripts/lib/audit-baselines/gate-surface.js +3 -17
  50. package/.agents/scripts/lib/audit-baselines/headroom.js +4 -20
  51. package/.agents/scripts/lib/audit-baselines/hotspots.js +3 -15
  52. package/.agents/scripts/lib/audit-baselines/kinds.js +23 -89
  53. package/.agents/scripts/lib/audit-baselines/outliers.js +6 -23
  54. package/.agents/scripts/lib/audit-baselines/read.js +3 -16
  55. package/.agents/scripts/lib/audit-baselines/staleness.js +7 -26
  56. package/.agents/scripts/lib/audit-baselines/surface-entry.js +7 -28
  57. package/.agents/scripts/lib/audit-baselines/trend.js +7 -20
  58. package/.agents/scripts/lib/audit-baselines/weights.js +9 -37
  59. package/.agents/scripts/lib/audit-suite/audit-rules-reader.js +3 -18
  60. package/.agents/scripts/lib/audit-suite/checklist-threading.js +26 -124
  61. package/.agents/scripts/lib/audit-suite/dispatch-checklist.js +14 -45
  62. package/.agents/scripts/lib/audit-suite/findings.js +12 -52
  63. package/.agents/scripts/lib/audit-suite/frontmatter.js +5 -29
  64. package/.agents/scripts/lib/audit-suite/index.js +1 -15
  65. package/.agents/scripts/lib/audit-suite/lens-checklist.js +10 -45
  66. package/.agents/scripts/lib/audit-suite/lens-diff-floor.js +11 -76
  67. package/.agents/scripts/lib/audit-suite/runner.js +13 -43
  68. package/.agents/scripts/lib/audit-suite/selector.js +49 -349
  69. package/.agents/scripts/lib/audit-suite/substitutions.js +12 -40
  70. package/.agents/scripts/lib/audit-suite/workflow-loader.js +3 -15
  71. package/.agents/scripts/lib/audit-to-stories/audit-label-taxonomy.js +11 -73
  72. package/.agents/scripts/lib/audit-to-stories/audit-lenses.js +8 -37
  73. package/.agents/scripts/lib/audit-to-stories/build-story-body.js +25 -143
  74. package/.agents/scripts/lib/audit-to-stories/dedupe-against-github.js +14 -80
  75. package/.agents/scripts/lib/audit-to-stories/epic-grouping-directive.js +4 -18
  76. package/.agents/scripts/lib/audit-to-stories/finding-adapter.js +7 -40
  77. package/.agents/scripts/lib/audit-to-stories/group-findings.js +9 -39
  78. package/.agents/scripts/lib/audit-to-stories/issue-corpus.js +10 -66
  79. package/.agents/scripts/lib/audit-to-stories/issue-index.js +6 -30
  80. package/.agents/scripts/lib/audit-to-stories/issues-file.js +6 -36
  81. package/.agents/scripts/lib/audit-to-stories/ledger-commit.js +17 -69
  82. package/.agents/scripts/lib/audit-to-stories/ledger-pr.js +17 -85
  83. package/.agents/scripts/lib/audit-to-stories/ledger-record.js +10 -48
  84. package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +38 -146
  85. package/.agents/scripts/lib/audit-to-stories/seed-from-findings.js +7 -42
  86. package/.agents/scripts/lib/audit-to-stories/wire-dependencies.js +10 -57
  87. package/.agents/scripts/lib/baseline-loader.js +12 -51
  88. package/.agents/scripts/lib/baseline-schema-registry.js +5 -22
  89. package/.agents/scripts/lib/baselines/component-matcher.js +3 -12
  90. package/.agents/scripts/lib/baselines/components.js +10 -61
  91. package/.agents/scripts/lib/baselines/coverage-updater-cli.js +7 -36
  92. package/.agents/scripts/lib/baselines/crap-preview-incremental.js +7 -19
  93. package/.agents/scripts/lib/baselines/crap-preview-scan.js +19 -45
  94. package/.agents/scripts/lib/baselines/crap-updater-cli.js +16 -65
  95. package/.agents/scripts/lib/baselines/diff-scope-cli.js +5 -33
  96. package/.agents/scripts/lib/baselines/duplication-scanner.js +11 -60
  97. package/.agents/scripts/lib/baselines/env-overrides.js +12 -67
  98. package/.agents/scripts/lib/baselines/envelope.js +13 -129
  99. package/.agents/scripts/lib/baselines/exit-codes.js +6 -49
  100. package/.agents/scripts/lib/baselines/git-base.js +23 -142
  101. package/.agents/scripts/lib/baselines/kernel.js +11 -111
  102. package/.agents/scripts/lib/baselines/kinds/_crap-new-method-gate.js +9 -47
  103. package/.agents/scripts/lib/baselines/kinds/_crap-read.js +8 -51
  104. package/.agents/scripts/lib/baselines/kinds/_shared-metric.js +7 -62
  105. package/.agents/scripts/lib/baselines/kinds/bundle-size.js +8 -29
  106. package/.agents/scripts/lib/baselines/kinds/coverage.js +3 -15
  107. package/.agents/scripts/lib/baselines/kinds/crap.js +94 -415
  108. package/.agents/scripts/lib/baselines/kinds/duplication.js +4 -30
  109. package/.agents/scripts/lib/baselines/kinds/kind-factory.js +7 -53
  110. package/.agents/scripts/lib/baselines/kinds/maintainability.js +15 -80
  111. package/.agents/scripts/lib/baselines/kinds/mutation.js +12 -72
  112. package/.agents/scripts/lib/baselines/maintainability-baseline-io.js +4 -11
  113. package/.agents/scripts/lib/baselines/merge-envelopes.js +30 -146
  114. package/.agents/scripts/lib/baselines/path-canon.js +19 -128
  115. package/.agents/scripts/lib/baselines/preview-gates.js +8 -37
  116. package/.agents/scripts/lib/baselines/reader.js +14 -107
  117. package/.agents/scripts/lib/baselines/refresh-service.js +35 -252
  118. package/.agents/scripts/lib/baselines/scope.js +11 -135
  119. package/.agents/scripts/lib/baselines/writer.js +16 -149
  120. package/.agents/scripts/lib/bdd-runner-detect.js +18 -113
  121. package/.agents/scripts/lib/bdd-scenario-budget.js +9 -36
  122. package/.agents/scripts/lib/bdd-scenario-scanner.js +11 -73
  123. package/.agents/scripts/lib/bdd-step-index.js +26 -100
  124. package/.agents/scripts/lib/bootstrap/baseline-merge-driver.js +23 -103
  125. package/.agents/scripts/lib/bootstrap/branch-protection.js +2 -5
  126. package/.agents/scripts/lib/bootstrap/commit-push.js +12 -50
  127. package/.agents/scripts/lib/bootstrap/gh-preflight.js +14 -101
  128. package/.agents/scripts/lib/bootstrap/hitl-confirm.js +5 -30
  129. package/.agents/scripts/lib/bootstrap/install-ledger.js +17 -73
  130. package/.agents/scripts/lib/bootstrap/issue-forms-template.js +17 -121
  131. package/.agents/scripts/lib/bootstrap/manifest.js +15 -86
  132. package/.agents/scripts/lib/bootstrap/merge-methods.js +4 -33
  133. package/.agents/scripts/lib/bootstrap/preflight.js +12 -61
  134. package/.agents/scripts/lib/bootstrap/project-bootstrap.js +34 -235
  135. package/.agents/scripts/lib/bootstrap/prompt.js +21 -129
  136. package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +27 -141
  137. package/.agents/scripts/lib/bootstrap/summary.js +1 -8
  138. package/.agents/scripts/lib/bootstrap/workflow-audit.js +11 -84
  139. package/.agents/scripts/lib/branch-name-guard.js +4 -23
  140. package/.agents/scripts/lib/changed-files.js +39 -121
  141. package/.agents/scripts/lib/checks/core-bare-clean.js +4 -24
  142. package/.agents/scripts/lib/checks/index.js +18 -101
  143. package/.agents/scripts/lib/checks/loop-health.js +11 -53
  144. package/.agents/scripts/lib/checks/state.js +16 -91
  145. package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +10 -61
  146. package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +14 -83
  147. package/.agents/scripts/lib/child-exec.js +39 -108
  148. package/.agents/scripts/lib/cli/standard-args.js +9 -116
  149. package/.agents/scripts/lib/cli-args.js +31 -146
  150. package/.agents/scripts/lib/cli-usage.js +5 -27
  151. package/.agents/scripts/lib/cli-utils.js +2 -12
  152. package/.agents/scripts/lib/close-validation/commands.js +13 -76
  153. package/.agents/scripts/lib/close-validation/gates.js +92 -331
  154. package/.agents/scripts/lib/close-validation/process.js +121 -151
  155. package/.agents/scripts/lib/close-validation/projections/advisories.js +5 -31
  156. package/.agents/scripts/lib/close-validation/projections/crap.js +19 -67
  157. package/.agents/scripts/lib/close-validation/projections/head-sha.js +1 -17
  158. package/.agents/scripts/lib/close-validation/projections/inputs.js +4 -34
  159. package/.agents/scripts/lib/close-validation/projections/maintainability.js +11 -58
  160. package/.agents/scripts/lib/close-validation/runner.js +53 -110
  161. package/.agents/scripts/lib/command-header.js +6 -28
  162. package/.agents/scripts/lib/config/acceptance-eval.js +4 -30
  163. package/.agents/scripts/lib/config/baselines.js +3 -14
  164. package/.agents/scripts/lib/config/ci.js +8 -38
  165. package/.agents/scripts/lib/config/commands.js +1 -15
  166. package/.agents/scripts/lib/config/defaults.js +4 -33
  167. package/.agents/scripts/lib/config/delivery-routing.js +6 -34
  168. package/.agents/scripts/lib/config/explain.js +10 -83
  169. package/.agents/scripts/lib/config/gates/coverage.schema.js +0 -12
  170. package/.agents/scripts/lib/config/gates/crap-incremental-coverage.schema.js +3 -31
  171. package/.agents/scripts/lib/config/gates/crap.schema.js +1 -34
  172. package/.agents/scripts/lib/config/gates/duplication.schema.js +1 -8
  173. package/.agents/scripts/lib/config/gates/index.js +2 -17
  174. package/.agents/scripts/lib/config/gates/maintainability.schema.js +1 -20
  175. package/.agents/scripts/lib/config/gates/mutation.schema.js +1 -7
  176. package/.agents/scripts/lib/config/gates/shared.js +4 -64
  177. package/.agents/scripts/lib/config/github.js +4 -22
  178. package/.agents/scripts/lib/config/limits.js +4 -57
  179. package/.agents/scripts/lib/config/paths.js +2 -21
  180. package/.agents/scripts/lib/config/qa.js +4 -38
  181. package/.agents/scripts/lib/config/quality.js +76 -432
  182. package/.agents/scripts/lib/config/runners.js +12 -56
  183. package/.agents/scripts/lib/config/runtime.js +13 -57
  184. package/.agents/scripts/lib/config/shared.js +2 -16
  185. package/.agents/scripts/lib/config/sync-agentrc.js +9 -50
  186. package/.agents/scripts/lib/config/temp-paths.js +40 -280
  187. package/.agents/scripts/lib/config/validate-orchestration.js +5 -17
  188. package/.agents/scripts/lib/config/worktree-isolation.js +9 -28
  189. package/.agents/scripts/lib/config-resolver.js +11 -52
  190. package/.agents/scripts/lib/config-schema-shared.js +1 -4
  191. package/.agents/scripts/lib/config-settings-schema-delivery.js +16 -291
  192. package/.agents/scripts/lib/config-settings-schema-quality.js +7 -219
  193. package/.agents/scripts/lib/config-settings-schema.js +37 -274
  194. package/.agents/scripts/lib/coverage-baseline.js +20 -110
  195. package/.agents/scripts/lib/coverage-capture-fullscope.js +18 -35
  196. package/.agents/scripts/lib/coverage-capture-incremental.js +15 -45
  197. package/.agents/scripts/lib/coverage-capture-usage.js +8 -25
  198. package/.agents/scripts/lib/coverage-capture.js +99 -224
  199. package/.agents/scripts/lib/coverage-utils.js +14 -79
  200. package/.agents/scripts/lib/cpu-pool.js +17 -123
  201. package/.agents/scripts/lib/crap-baseline-join.js +16 -88
  202. package/.agents/scripts/lib/crap-coordinates.js +6 -25
  203. package/.agents/scripts/lib/crap-engine.js +40 -153
  204. package/.agents/scripts/lib/crap-method-identity.js +16 -78
  205. package/.agents/scripts/lib/crap-utils.js +31 -155
  206. package/.agents/scripts/lib/cyclomatic-ceiling.js +14 -87
  207. package/.agents/scripts/lib/cyclomatic-scope.js +10 -50
  208. package/.agents/scripts/lib/dead-exports-knip.js +18 -56
  209. package/.agents/scripts/lib/dead-exports-mode.js +5 -24
  210. package/.agents/scripts/lib/degraded-mode.js +3 -26
  211. package/.agents/scripts/lib/dependency-parser.js +8 -40
  212. package/.agents/scripts/lib/dependency-version.js +13 -35
  213. package/.agents/scripts/lib/detect-package-manager.js +6 -36
  214. package/.agents/scripts/lib/doc-tiers.js +22 -124
  215. package/.agents/scripts/lib/duplicate-search.js +8 -72
  216. package/.agents/scripts/lib/env-loader.js +5 -27
  217. package/.agents/scripts/lib/error-redactor.js +6 -31
  218. package/.agents/scripts/lib/errors/index.js +2 -22
  219. package/.agents/scripts/lib/escomplex-ast-compat.js +22 -163
  220. package/.agents/scripts/lib/escomplex-kernel.js +21 -123
  221. package/.agents/scripts/lib/feedback-loop/graduator-core.js +94 -419
  222. package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +20 -98
  223. package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +27 -149
  224. package/.agents/scripts/lib/findings/audit-ledger.js +23 -97
  225. package/.agents/scripts/lib/findings/classify-finding.js +14 -69
  226. package/.agents/scripts/lib/findings/promote-finding.js +14 -112
  227. package/.agents/scripts/lib/findings/provenance-field.js +11 -52
  228. package/.agents/scripts/lib/findings/route-finding.js +37 -255
  229. package/.agents/scripts/lib/findings/semantic-issue-search.js +14 -59
  230. package/.agents/scripts/lib/findings/severity.js +18 -104
  231. package/.agents/scripts/lib/format-generated-json.js +12 -44
  232. package/.agents/scripts/lib/full-suite-lock.js +160 -429
  233. package/.agents/scripts/lib/full-suite-queue.js +213 -0
  234. package/.agents/scripts/lib/gates/baseline-store.js +5 -9
  235. package/.agents/scripts/lib/gates/friction.js +1 -3
  236. package/.agents/scripts/lib/generated/agentrc-validator.js +2 -2
  237. package/.agents/scripts/lib/gh-exec.js +123 -191
  238. package/.agents/scripts/lib/git/cached-fetch.js +9 -52
  239. package/.agents/scripts/lib/git/sync-from-base.js +15 -107
  240. package/.agents/scripts/lib/git-branch-cleanup.js +14 -61
  241. package/.agents/scripts/lib/git-branch-lifecycle.js +16 -87
  242. package/.agents/scripts/lib/git-utils.js +37 -161
  243. package/.agents/scripts/lib/github/framework-repo.js +8 -71
  244. package/.agents/scripts/lib/github-url.js +2 -17
  245. package/.agents/scripts/lib/import-graph.js +11 -38
  246. package/.agents/scripts/lib/install-cmd-parser.js +4 -13
  247. package/.agents/scripts/lib/json-utils.js +3 -18
  248. package/.agents/scripts/lib/label-constants.js +16 -111
  249. package/.agents/scripts/lib/label-taxonomy.js +4 -30
  250. package/.agents/scripts/lib/maintainability-engine.js +12 -80
  251. package/.agents/scripts/lib/maintainability-unscorable.js +5 -25
  252. package/.agents/scripts/lib/maintainability-utils.js +16 -92
  253. package/.agents/scripts/lib/mandrel-catalog.js +12 -70
  254. package/.agents/scripts/lib/notifications/notifier.js +13 -38
  255. package/.agents/scripts/lib/npm-scripts.js +4 -23
  256. package/.agents/scripts/lib/observability/metrics-ledger.js +16 -76
  257. package/.agents/scripts/lib/observability/runtime-friction.js +44 -286
  258. package/.agents/scripts/lib/observability/signal-validator.js +5 -37
  259. package/.agents/scripts/lib/observability/signals-writer.js +11 -121
  260. package/.agents/scripts/lib/observability/source-classifier.js +22 -203
  261. package/.agents/scripts/lib/observability/terse-result.js +14 -47
  262. package/.agents/scripts/lib/onboard/init-tail.js +13 -74
  263. package/.agents/scripts/lib/onboard/scaffold-docs.js +11 -34
  264. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +25 -139
  265. package/.agents/scripts/lib/orchestration/auto-merge-cwd.js +11 -66
  266. package/.agents/scripts/lib/orchestration/behind-recovery.js +10 -55
  267. package/.agents/scripts/lib/orchestration/ceremony-routing.js +28 -156
  268. package/.agents/scripts/lib/orchestration/change-set.js +7 -36
  269. package/.agents/scripts/lib/orchestration/check-baselines/phases/compare.js +9 -46
  270. package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +11 -44
  271. package/.agents/scripts/lib/orchestration/check-baselines/phases/floors.js +5 -24
  272. package/.agents/scripts/lib/orchestration/check-baselines/phases/friction.js +3 -12
  273. package/.agents/scripts/lib/orchestration/check-baselines/phases/parse-args.js +5 -38
  274. package/.agents/scripts/lib/orchestration/check-baselines/phases/pipeline.js +3 -8
  275. package/.agents/scripts/lib/orchestration/check-baselines/phases/refresh-ack.js +28 -136
  276. package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +3 -13
  277. package/.agents/scripts/lib/orchestration/check-state.js +92 -0
  278. package/.agents/scripts/lib/orchestration/ci-gap-intake.js +37 -144
  279. package/.agents/scripts/lib/orchestration/ci-rerun-guard.js +121 -157
  280. package/.agents/scripts/lib/orchestration/code-review.js +24 -128
  281. package/.agents/scripts/lib/orchestration/column-sync.js +23 -111
  282. package/.agents/scripts/lib/orchestration/complexity-gate.js +118 -462
  283. package/.agents/scripts/lib/orchestration/deliver-recover.js +36 -168
  284. package/.agents/scripts/lib/orchestration/dependency-analyzer.js +4 -35
  285. package/.agents/scripts/lib/orchestration/dependency-candidates.js +9 -41
  286. package/.agents/scripts/lib/orchestration/diff-magnitude.js +25 -115
  287. package/.agents/scripts/lib/orchestration/doc-reader.js +2 -6
  288. package/.agents/scripts/lib/orchestration/docs-digest.js +13 -51
  289. package/.agents/scripts/lib/orchestration/epic-candidates.js +13 -53
  290. package/.agents/scripts/lib/orchestration/epic-checklist.js +9 -33
  291. package/.agents/scripts/lib/orchestration/epic-container.js +41 -167
  292. package/.agents/scripts/lib/orchestration/epic-expansion.js +10 -40
  293. package/.agents/scripts/lib/orchestration/epic-rollup.js +55 -207
  294. package/.agents/scripts/lib/orchestration/file-assumption-enum.js +2 -22
  295. package/.agents/scripts/lib/orchestration/file-assumptions.js +45 -253
  296. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-detect.js +9 -46
  297. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-reap.js +7 -57
  298. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches.js +21 -126
  299. package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +2 -6
  300. package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +1 -4
  301. package/.agents/scripts/lib/orchestration/git-cleanup/phases/filters.js +1 -5
  302. package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes-ff.js +9 -34
  303. package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes.js +41 -190
  304. package/.agents/scripts/lib/orchestration/git-cleanup/phases/merged-tip.js +9 -45
  305. package/.agents/scripts/lib/orchestration/git-cleanup/phases/parse-args.js +1 -4
  306. package/.agents/scripts/lib/orchestration/git-cleanup/phases/phase-drivers.js +19 -85
  307. package/.agents/scripts/lib/orchestration/git-cleanup/phases/prompts.js +3 -17
  308. package/.agents/scripts/lib/orchestration/git-cleanup/phases/prune.js +1 -5
  309. package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +16 -100
  310. package/.agents/scripts/lib/orchestration/git-cleanup/phases/stashes.js +1 -4
  311. package/.agents/scripts/lib/orchestration/lease-guard-shared.js +16 -67
  312. package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +9 -33
  313. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +8 -29
  314. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +15 -68
  315. package/.agents/scripts/lib/orchestration/light-backstop.js +11 -49
  316. package/.agents/scripts/lib/orchestration/light-escalation.js +21 -89
  317. package/.agents/scripts/lib/orchestration/light-suitability.js +37 -307
  318. package/.agents/scripts/lib/orchestration/merge-block-class.js +39 -216
  319. package/.agents/scripts/lib/orchestration/merge-poll.js +104 -377
  320. package/.agents/scripts/lib/orchestration/pinned-identifier-lint.js +17 -57
  321. package/.agents/scripts/lib/orchestration/plan-context.js +55 -318
  322. package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +22 -79
  323. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +5 -31
  324. package/.agents/scripts/lib/orchestration/plan-metrics.js +29 -108
  325. package/.agents/scripts/lib/orchestration/plan-navigation.js +8 -27
  326. package/.agents/scripts/lib/orchestration/plan-persist/acceptance-handle-repair.js +12 -49
  327. package/.agents/scripts/lib/orchestration/plan-persist/audit-provenance.js +18 -73
  328. package/.agents/scripts/lib/orchestration/plan-persist/changes-repair.js +16 -78
  329. package/.agents/scripts/lib/orchestration/plan-persist/cross-plan-links.js +6 -30
  330. package/.agents/scripts/lib/orchestration/plan-persist/epic-adoption.js +14 -65
  331. package/.agents/scripts/lib/orchestration/plan-persist/epic-ops.js +21 -76
  332. package/.agents/scripts/lib/orchestration/plan-persist/external-deps.js +6 -43
  333. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +14 -68
  334. package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +9 -41
  335. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +71 -289
  336. package/.agents/scripts/lib/orchestration/plan-persist/soft-findings.js +2 -12
  337. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +96 -362
  338. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +9 -39
  339. package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +60 -186
  340. package/.agents/scripts/lib/orchestration/plan-persist/wave-collision-gate.js +9 -49
  341. package/.agents/scripts/lib/orchestration/plan-persist/wave-serialisation.js +7 -28
  342. package/.agents/scripts/lib/orchestration/plan-reachability.js +13 -42
  343. package/.agents/scripts/lib/orchestration/plan-run-labels/reap.js +16 -91
  344. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +16 -54
  345. package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +10 -52
  346. package/.agents/scripts/lib/orchestration/planning/authoring-context.js +14 -109
  347. package/.agents/scripts/lib/orchestration/planning/memory-pool-advisory.js +11 -83
  348. package/.agents/scripts/lib/orchestration/pr-watch.js +48 -306
  349. package/.agents/scripts/lib/orchestration/project-meta-cache.js +15 -80
  350. package/.agents/scripts/lib/orchestration/project-meta-resolver.js +10 -51
  351. package/.agents/scripts/lib/orchestration/reassert-status-column.js +12 -76
  352. package/.agents/scripts/lib/orchestration/remote-verifier.js +12 -36
  353. package/.agents/scripts/lib/orchestration/resolve-stories.js +33 -164
  354. package/.agents/scripts/lib/orchestration/retro-proposals.js +66 -361
  355. package/.agents/scripts/lib/orchestration/review-base-ref.js +9 -43
  356. package/.agents/scripts/lib/orchestration/review-depth.js +12 -91
  357. package/.agents/scripts/lib/orchestration/review-providers/codex.js +10 -111
  358. package/.agents/scripts/lib/orchestration/review-providers/degraded-gates.js +13 -71
  359. package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +7 -51
  360. package/.agents/scripts/lib/orchestration/review-providers/mi-exemptions.js +8 -53
  361. package/.agents/scripts/lib/orchestration/review-providers/native.js +30 -214
  362. package/.agents/scripts/lib/orchestration/review-providers/parse-findings.js +7 -52
  363. package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +4 -33
  364. package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +11 -71
  365. package/.agents/scripts/lib/orchestration/review-providers/scoped-lint.js +19 -131
  366. package/.agents/scripts/lib/orchestration/review-providers/security-review.js +6 -89
  367. package/.agents/scripts/lib/orchestration/review-providers/types.js +26 -56
  368. package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +3 -46
  369. package/.agents/scripts/lib/orchestration/run-epilogue.js +245 -326
  370. package/.agents/scripts/lib/orchestration/run-scoped-config.js +55 -159
  371. package/.agents/scripts/lib/orchestration/single-story-close/close-note.js +7 -34
  372. package/.agents/scripts/lib/orchestration/single-story-close/failed-terminal.js +16 -89
  373. package/.agents/scripts/lib/orchestration/single-story-close/gate-log.js +18 -109
  374. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +83 -239
  375. package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +20 -82
  376. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +103 -97
  377. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +8 -64
  378. package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +136 -486
  379. package/.agents/scripts/lib/orchestration/single-story-close/phases/conventional-subject.js +30 -134
  380. package/.agents/scripts/lib/orchestration/single-story-close/phases/graphql-preflight.js +96 -0
  381. package/.agents/scripts/lib/orchestration/single-story-close/phases/lock-wait-pending.js +49 -0
  382. package/.agents/scripts/lib/orchestration/single-story-close/phases/normalize-pr-title.js +13 -86
  383. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +20 -95
  384. package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +46 -203
  385. package/.agents/scripts/lib/orchestration/single-story-close/phases/pre-gate-steps.js +8 -50
  386. package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +12 -83
  387. package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +6 -39
  388. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +1 -6
  389. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-outcome.js +4 -28
  390. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-override.js +6 -51
  391. package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +6 -34
  392. package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +23 -121
  393. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +180 -273
  394. package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +15 -69
  395. package/.agents/scripts/lib/orchestration/story-body-gate.js +4 -23
  396. package/.agents/scripts/lib/orchestration/story-close/baseline-upward-writeback.js +50 -179
  397. package/.agents/scripts/lib/orchestration/story-close/context-budget-writeback.js +11 -41
  398. package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +23 -311
  399. package/.agents/scripts/lib/orchestration/story-close/phases/local-lens-review.js +22 -147
  400. package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +16 -67
  401. package/.agents/scripts/lib/orchestration/story-deliver-terminal-schema.js +12 -68
  402. package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +42 -200
  403. package/.agents/scripts/lib/orchestration/story-follow-ups.js +167 -252
  404. package/.agents/scripts/lib/orchestration/story-init-envelope.js +52 -0
  405. package/.agents/scripts/lib/orchestration/story-init-remote.js +2 -6
  406. package/.agents/scripts/lib/orchestration/story-reachability.js +3 -23
  407. package/.agents/scripts/lib/orchestration/task-body-validator.js +12 -135
  408. package/.agents/scripts/lib/orchestration/ticket-lease.js +28 -131
  409. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +15 -149
  410. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +5 -33
  411. package/.agents/scripts/lib/orchestration/ticket-validator.js +63 -344
  412. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +51 -244
  413. package/.agents/scripts/lib/orchestration/ticketing/reads.js +39 -261
  414. package/.agents/scripts/lib/orchestration/ticketing/state.js +14 -68
  415. package/.agents/scripts/lib/orchestration/ticketing/transition.js +46 -263
  416. package/.agents/scripts/lib/orchestration/ticketing.js +2 -26
  417. package/.agents/scripts/lib/orchestration/verify-credit.js +18 -79
  418. package/.agents/scripts/lib/orchestration/worktree-dirty.js +5 -30
  419. package/.agents/scripts/lib/path-security.js +3 -6
  420. package/.agents/scripts/lib/plan-phase-cleanup.js +9 -49
  421. package/.agents/scripts/lib/preflight-runner.js +13 -69
  422. package/.agents/scripts/lib/process-group.js +143 -0
  423. package/.agents/scripts/lib/project-root.js +2 -8
  424. package/.agents/scripts/lib/provider-factory.js +2 -25
  425. package/.agents/scripts/lib/qa/console-allowlist.js +10 -59
  426. package/.agents/scripts/lib/qa/qa-session.js +15 -69
  427. package/.agents/scripts/lib/qa/redact-evidence.js +18 -129
  428. package/.agents/scripts/lib/qa/resolve-qa-contract.js +26 -135
  429. package/.agents/scripts/lib/qa/resolve-selection.js +16 -84
  430. package/.agents/scripts/lib/reserved-test-ids.js +9 -47
  431. package/.agents/scripts/lib/runtime-deps/dep-resolution.js +13 -53
  432. package/.agents/scripts/lib/runtime-deps/ensure-installed.js +10 -44
  433. package/.agents/scripts/lib/runtime-deps/manifest.js +10 -30
  434. package/.agents/scripts/lib/runtime-deps/parser-major.js +15 -51
  435. package/.agents/scripts/lib/runtime-deps/preflight.js +4 -22
  436. package/.agents/scripts/lib/runtime-deps/scan-imports.js +11 -55
  437. package/.agents/scripts/lib/signals/detectors/common.js +12 -38
  438. package/.agents/scripts/lib/signals/index.js +2 -19
  439. package/.agents/scripts/lib/signals/schema.js +14 -109
  440. package/.agents/scripts/lib/signals/write.js +2 -11
  441. package/.agents/scripts/lib/single-story/confirm-merge.js +31 -72
  442. package/.agents/scripts/lib/single-story/story-merged-notify.js +8 -49
  443. package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +4 -26
  444. package/.agents/scripts/lib/single-story-sweep/protection.js +13 -100
  445. package/.agents/scripts/lib/single-story-sweep/sweep-lock.js +60 -258
  446. package/.agents/scripts/lib/single-story-sweep.js +14 -97
  447. package/.agents/scripts/lib/skills/parse-skill.js +13 -59
  448. package/.agents/scripts/lib/skills/skills-index.js +8 -29
  449. package/.agents/scripts/lib/skills/walk-skill-files.js +17 -78
  450. package/.agents/scripts/lib/source-extensions.js +11 -42
  451. package/.agents/scripts/lib/source-text/strip-js-comments.js +8 -41
  452. package/.agents/scripts/lib/stdio-flush.js +9 -36
  453. package/.agents/scripts/lib/story-adjacency.js +8 -40
  454. package/.agents/scripts/lib/story-body/body-format-lints.js +51 -66
  455. package/.agents/scripts/lib/story-body/footer-block.js +11 -44
  456. package/.agents/scripts/lib/story-body/story-body.js +123 -344
  457. package/.agents/scripts/lib/temp-retention.js +42 -143
  458. package/.agents/scripts/lib/templates/decomposer-prompts.js +18 -80
  459. package/.agents/scripts/lib/test-env.js +12 -65
  460. package/.agents/scripts/lib/test-run-credit.js +10 -65
  461. package/.agents/scripts/lib/test-runner-contract.js +19 -74
  462. package/.agents/scripts/lib/test-temp.js +38 -184
  463. package/.agents/scripts/lib/test-tiers.js +12 -96
  464. package/.agents/scripts/lib/ticket-body-sections.js +21 -96
  465. package/.agents/scripts/lib/transpile.js +15 -74
  466. package/.agents/scripts/lib/util/concurrent-map.js +6 -25
  467. package/.agents/scripts/lib/util/parse-id-list.js +8 -34
  468. package/.agents/scripts/lib/util/poll-loop.js +8 -28
  469. package/.agents/scripts/lib/util/with-timeout.js +2 -11
  470. package/.agents/scripts/lib/validation-evidence.js +21 -96
  471. package/.agents/scripts/lib/wave-runner/footprint.js +17 -70
  472. package/.agents/scripts/lib/wave-runner/live-probe.js +67 -209
  473. package/.agents/scripts/lib/wave-runner/ready-set.js +72 -301
  474. package/.agents/scripts/lib/workers/crap-worker.js +11 -64
  475. package/.agents/scripts/lib/workers/maintainability-report-worker.js +8 -45
  476. package/.agents/scripts/lib/workers/maintainability-worker.js +5 -21
  477. package/.agents/scripts/lib/workers/serve-worker-messages.js +2 -18
  478. package/.agents/scripts/lib/workflow-closure.js +22 -105
  479. package/.agents/scripts/lib/workspace-provisioner.js +16 -54
  480. package/.agents/scripts/lib/worktree/git-hooks.js +15 -60
  481. package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +20 -60
  482. package/.agents/scripts/lib/worktree/lifecycle/merge-reachability.js +10 -62
  483. package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +22 -86
  484. package/.agents/scripts/lib/worktree/lifecycle/reap.js +24 -126
  485. package/.agents/scripts/lib/worktree/lifecycle-manager.js +2 -20
  486. package/.agents/scripts/lib/worktree/node-modules-strategy.js +46 -180
  487. package/.agents/scripts/lib/worktree-manager.js +15 -40
  488. package/.agents/scripts/lint-issue-body.js +12 -68
  489. package/.agents/scripts/mandrel-update-preflight.js +10 -70
  490. package/.agents/scripts/merge-baseline.js +30 -105
  491. package/.agents/scripts/nav-registry-diff.js +22 -108
  492. package/.agents/scripts/notify.js +12 -69
  493. package/.agents/scripts/plan-context.js +97 -92
  494. package/.agents/scripts/plan-critics.js +12 -66
  495. package/.agents/scripts/plan-persist.js +71 -137
  496. package/.agents/scripts/plan-run-epilogue.js +20 -43
  497. package/.agents/scripts/pr-watch-with-update.js +79 -263
  498. package/.agents/scripts/providers/github/auth.js +3 -8
  499. package/.agents/scripts/providers/github/blocked-by-add.js +14 -61
  500. package/.agents/scripts/providers/github/board-add.js +5 -21
  501. package/.agents/scripts/providers/github/branch-protection.js +11 -43
  502. package/.agents/scripts/providers/github/cache.js +2 -14
  503. package/.agents/scripts/providers/github/comments.js +7 -40
  504. package/.agents/scripts/providers/github/compose.js +3 -19
  505. package/.agents/scripts/providers/github/errors.js +22 -125
  506. package/.agents/scripts/providers/github/issues.js +31 -123
  507. package/.agents/scripts/providers/github/labels.js +24 -124
  508. package/.agents/scripts/providers/github/mappers.js +5 -27
  509. package/.agents/scripts/providers/github/merge-methods.js +3 -22
  510. package/.agents/scripts/providers/github/project-board.js +2 -17
  511. package/.agents/scripts/providers/github/projects-v2-graphql.js +3 -6
  512. package/.agents/scripts/providers/github/request-helpers.js +5 -32
  513. package/.agents/scripts/providers/github/search-budget.js +9 -39
  514. package/.agents/scripts/providers/github/search-query.js +5 -26
  515. package/.agents/scripts/providers/github/sub-issue-add.js +15 -65
  516. package/.agents/scripts/providers/github/sub-issues.js +7 -36
  517. package/.agents/scripts/providers/github/tickets.js +32 -134
  518. package/.agents/scripts/providers/github.js +18 -59
  519. package/.agents/scripts/prune-plan-run-labels.js +12 -46
  520. package/.agents/scripts/quality-preview.js +35 -220
  521. package/.agents/scripts/resolve-doc-tiers.js +3 -26
  522. package/.agents/scripts/resolve-stories.js +16 -67
  523. package/.agents/scripts/resync-status-column.js +6 -25
  524. package/.agents/scripts/run-tests.js +29 -104
  525. package/.agents/scripts/single-story-close.js +23 -135
  526. package/.agents/scripts/single-story-confirm-merge.js +32 -139
  527. package/.agents/scripts/single-story-init.js +47 -259
  528. package/.agents/scripts/stories-wave-tick.js +179 -415
  529. package/.agents/scripts/sync-agentrc.js +3 -21
  530. package/.agents/scripts/sync-claude-agents.js +9 -55
  531. package/.agents/scripts/sync-claude-commands.js +20 -110
  532. package/.agents/scripts/test-wrapper.js +6 -43
  533. package/.agents/scripts/update-coverage-baseline.js +5 -22
  534. package/.agents/scripts/update-crap-baseline.js +7 -30
  535. package/.agents/scripts/update-duplication-baseline.js +16 -92
  536. package/.agents/scripts/update-maintainability-baseline.js +8 -62
  537. package/.agents/scripts/update-ticket-state.js +1 -7
  538. package/.agents/scripts/validate-skills.js +6 -26
  539. package/.agents/skills/core/gates-and-baselines/reference.md +0 -1
  540. package/.agents/skills/skills.index.json +2 -2
  541. package/.agents/skills/stack/qa/playwright/SKILL.md +26 -0
  542. package/.agents/templates/agent-protocol.md +2 -2
  543. package/.agents/templates/docs/audit-sweep-runbook.md +3 -4
  544. package/.agents/workflows/audit-accessibility.md +4 -7
  545. package/.agents/workflows/audit-adrs.md +3 -6
  546. package/.agents/workflows/audit-architecture.md +3 -11
  547. package/.agents/workflows/audit-baselines.md +6 -9
  548. package/.agents/workflows/audit-clean-code.md +8 -12
  549. package/.agents/workflows/audit-data-model.md +3 -7
  550. package/.agents/workflows/audit-dependencies.md +4 -7
  551. package/.agents/workflows/audit-devops.md +4 -8
  552. package/.agents/workflows/audit-documentation.md +1 -4
  553. package/.agents/workflows/audit-mobile.md +4 -7
  554. package/.agents/workflows/audit-navigability.md +3 -6
  555. package/.agents/workflows/audit-performance.md +2 -4
  556. package/.agents/workflows/audit-privacy.md +4 -7
  557. package/.agents/workflows/audit-quality.md +4 -7
  558. package/.agents/workflows/audit-security.md +4 -7
  559. package/.agents/workflows/audit-seo.md +4 -7
  560. package/.agents/workflows/audit-sre.md +4 -7
  561. package/.agents/workflows/audit-to-stories.md +17 -30
  562. package/.agents/workflows/audit-ux-ui.md +4 -7
  563. package/.agents/workflows/helpers/acceptance-self-eval.md +84 -157
  564. package/.agents/workflows/helpers/audit-lens-core.md +1 -1
  565. package/.agents/workflows/helpers/code-quality-guardrails.md +12 -15
  566. package/.agents/workflows/helpers/code-review.md +4 -2
  567. package/.agents/workflows/helpers/deliver-digest.md +37 -28
  568. package/.agents/workflows/helpers/deliver-light.md +92 -101
  569. package/.agents/workflows/helpers/deliver-reference.md +162 -220
  570. package/.agents/workflows/helpers/deliver-story-reference.md +197 -607
  571. package/.agents/workflows/helpers/deliver-story.md +17 -18
  572. package/.agents/workflows/helpers/plan-reference.md +125 -167
  573. package/.agents/workflows/helpers/qa-core.md +12 -0
  574. package/.agents/workflows/mandrel-deliver.md +47 -31
  575. package/.agents/workflows/mandrel-plan.md +22 -21
  576. package/.agents/workflows/mandrel-update.md +36 -21
  577. package/.agents/workflows/memory-consolidate.md +1 -1
  578. package/.agents/workflows/qa-assist.md +27 -71
  579. package/.agents/workflows/qa-explore.md +19 -59
  580. package/.agents/workflows/qa-run.md +11 -33
  581. package/README.md +1 -1
  582. package/bin/mandrel.js +5 -46
  583. package/bin/postinstall.js +18 -107
  584. package/docs/CHANGELOG.md +60 -0
  585. package/lib/cli/doctor.js +11 -71
  586. package/lib/cli/init.js +26 -165
  587. package/lib/cli/migrate.js +5 -64
  588. package/lib/cli/registry.js +84 -467
  589. package/lib/cli/sync-agents.js +4 -64
  590. package/lib/cli/sync-commands.js +11 -64
  591. package/lib/cli/sync.js +34 -213
  592. package/lib/cli/uninstall.js +40 -219
  593. package/lib/cli/update.js +326 -523
  594. package/lib/cli/version-check.js +8 -72
  595. package/lib/cli/version-helpers.js +14 -87
  596. package/lib/migrations/helpers/retire-agentrc-key.js +11 -52
  597. package/lib/migrations/index.js +17 -92
  598. package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +2 -15
  599. package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +1 -13
  600. package/lib/migrations/steps/2.11.0-retire-max-seed-words.js +2 -15
  601. package/lib/migrations/steps/2.2.0-retire-epic-ac-tags.js +9 -38
  602. package/lib/migrations/steps/2.20.0-retire-codebase-snapshot.js +1 -13
  603. package/lib/migrations/steps/2.32.0-retire-lint-baseline-command.js +2 -27
  604. package/lib/migrations/steps/2.57.0-retire-delivery-limit-knobs.js +2 -23
  605. package/lib/migrations/steps/2.57.0-retire-planning-limit-knobs.js +2 -27
  606. package/lib/migrations/steps/2.60.0-retire-audit-results-autofile.js +21 -0
  607. package/lib/migrations/steps/strip-removed-agentrc-keys.js +333 -0
  608. package/package.json +17 -14
  609. package/.agents/docs/SDLC.md +0 -590
  610. package/.agents/docs/quality-gates.md +0 -1179
  611. package/.agents/rules/known-tooling-behavior.md +0 -150
  612. package/.agents/rules/orchestration-error-handling.md +0 -61
  613. package/.agents/rules/test-seams.md +0 -59
  614. package/.agents/schemas/baselines/lighthouse.schema.json +0 -59
  615. package/.agents/schemas/baselines/lint.schema.json +0 -47
  616. package/.agents/schemas/model-attribution.schema.json +0 -53
  617. package/.agents/scripts/check-action-pinning.js +0 -260
  618. package/.agents/scripts/check-audit-attribution.js +0 -302
  619. package/.agents/scripts/check-baseline-drift.js +0 -211
  620. package/.agents/scripts/check-baseline-scope.js +0 -362
  621. package/.agents/scripts/check-generated-validator.js +0 -202
  622. package/.agents/scripts/check-knip-entries.js +0 -159
  623. package/.agents/scripts/check-lifecycle-lint.js +0 -294
  624. package/.agents/scripts/check-pinned-override-notes.js +0 -102
  625. package/.agents/scripts/check-schema-references.js +0 -366
  626. package/.agents/scripts/check-test-portability.js +0 -512
  627. package/.agents/scripts/check-workflow-citations.js +0 -332
  628. package/.agents/scripts/check-workflow-cli-lint.js +0 -299
  629. package/.agents/scripts/check-workflow-timeouts.js +0 -291
  630. package/.agents/scripts/install-matrix-assert.js +0 -326
  631. package/.agents/scripts/lib/audit-advisories.js +0 -195
  632. package/.agents/scripts/lib/audit-attribution.js +0 -134
  633. package/.agents/scripts/lib/baselines/drift-detector.js +0 -351
  634. package/.agents/scripts/lib/baselines/kinds/lighthouse.js +0 -87
  635. package/.agents/scripts/lib/baselines/kinds/lint.js +0 -184
  636. package/.agents/scripts/lib/baselines/orphan-pruner.js +0 -233
  637. package/.agents/scripts/lib/baselines/scope-assert.js +0 -223
  638. package/.agents/scripts/lib/baselines/scope-inventory.js +0 -314
  639. package/.agents/scripts/lib/c8-cli-path.js +0 -21
  640. package/.agents/scripts/lib/config/gates/lighthouse.schema.js +0 -51
  641. package/.agents/scripts/lib/config/gates/lint.schema.js +0 -18
  642. package/.agents/scripts/lib/dynamic-workflow/architecture-report-contract.js +0 -70
  643. package/.agents/scripts/lib/dynamic-workflow/audit-orchestrator.js +0 -284
  644. package/.agents/scripts/lib/dynamic-workflow/clean-code-report-contract.js +0 -80
  645. package/.agents/scripts/lib/dynamic-workflow/degraded-coverage.js +0 -81
  646. package/.agents/scripts/lib/dynamic-workflow/documentation-report-contract.js +0 -87
  647. package/.agents/scripts/lib/dynamic-workflow/performance-report-contract.js +0 -74
  648. package/.agents/scripts/lib/dynamic-workflow/quality-report-contract.js +0 -90
  649. package/.agents/scripts/lib/dynamic-workflow/report-contract-core.js +0 -43
  650. package/.agents/scripts/lib/dynamic-workflow/security-report-contract.js +0 -83
  651. package/.agents/scripts/lib/fs-walk.js +0 -52
  652. package/.agents/scripts/lib/knip-config-resolver.js +0 -181
  653. package/.agents/scripts/lib/knip-entry-sync.js +0 -452
  654. package/.agents/scripts/lib/orchestration/model-attribution.js +0 -418
  655. package/.agents/scripts/lib/orchestration/story-plan-state.js +0 -33
  656. package/.agents/scripts/lib/orchestration/structured-comment-parser.js +0 -67
  657. package/.agents/scripts/lib/pinned-override-notes.js +0 -88
  658. package/.agents/scripts/lib/pinned-override-resolve.js +0 -212
  659. package/.agents/scripts/lib/test-isolate/cli-options.js +0 -93
  660. package/.agents/scripts/lib/test-isolate/env-snapshot-loader.js +0 -52
  661. package/.agents/scripts/lib/test-isolate/list-files.js +0 -90
  662. package/.agents/scripts/lib/test-isolate/parse-tap.js +0 -75
  663. package/.agents/scripts/lib/test-isolate/progress-log.js +0 -45
  664. package/.agents/scripts/lib/test-isolate/render-report.js +0 -97
  665. package/.agents/scripts/lib/test-isolate/run-isolate.js +0 -87
  666. package/.agents/scripts/lib/test-isolate/runner.js +0 -483
  667. package/.agents/scripts/lib/test-profile/parse-tap.js +0 -136
  668. package/.agents/scripts/lib/test-profile/render-report.js +0 -45
  669. package/.agents/scripts/lint-label-vocabulary.js +0 -214
  670. package/.agents/scripts/post-structured-comment.js +0 -127
  671. package/.agents/scripts/provision-git-hooks.js +0 -85
  672. package/.agents/scripts/prune-baseline-orphans.js +0 -181
  673. package/.agents/scripts/run-coverage.js +0 -197
  674. package/.agents/scripts/run-lint.js +0 -133
  675. package/.agents/scripts/run-test-profile.js +0 -129
  676. package/.agents/scripts/run-verify.js +0 -118
  677. package/.agents/scripts/test-isolate.js +0 -55
  678. package/.agents/scripts/update-dead-exports-baseline.js +0 -321
@@ -1,80 +1,16 @@
1
1
  /**
2
- * CLI: ratchet-down gate for the always-loaded documentation context budget
3
- * (Story #4438, Epic #4430 — Context Economy).
2
+ * CLI: ratchet gate for documentation context bytes against
3
+ * `baselines/context-budget.json`. Measures `alwaysLoaded` (the `CLAUDE.md`
4
+ * `@`-import closure), `mandatoryRead` (`project.docsContextFiles`) and
5
+ * `workflow` (entry points + `mandatoryReads:` closure).
4
6
  *
5
- * Follows the standalone `check-arch-cycles.js` / `check-dead-exports.js`
6
- * precedent — a pure-Node, baseline-aware, sub-second checker wired into the
7
- * CI `baselines` job — rather than a `baselines/kinds/` metric. It measures the
8
- * live byte total of two documentation read-tiers and compares each against a
9
- * single committed budget in `baselines/context-budget.json`:
7
+ * Only `alwaysLoaded` gates — every session and subagent spawn pays it. Exit 1
8
+ * when it grows past `totalBytes + toleranceBytes` or a recorded row names a
9
+ * path it no longer contains; every other drift, and all shrinkage, is
10
+ * reported with exit 0 (the close writes a lower total back). An empty tier or
11
+ * a missing baseline is a no-op. Tolerance lives only in the baseline JSON.
10
12
  *
11
- * - `alwaysLoaded` — the `CLAUDE.md` `@`-import closure re-paid on every
12
- * session and every subagent spawn (instructions.md § 4).
13
- * - `mandatoryRead` — the resolved `project.docsContextFiles` set.
14
- * - `workflow` — the workflow **mandatory closure** (Story #4752): every
15
- * `.agents/workflows/**` entry point plus the transitive
16
- * closure of its `mandatoryReads:` frontmatter edges. The
17
- * companion **reachable** closure (per entry point) is
18
- * recorded under the top-level `workflowClosure` key as a
19
- * drift signal and never gates — growth there is a
20
- * reading-cost signal, not a contract violation.
21
- *
22
- * It additionally enforces a **per-file** ceiling on the role-scoped agent-boot
23
- * tier (`.agents/agents/*.md`, #4478): no single boot context may exceed
24
- * `agentBoot.ceilingBytes` (default 8192). This is a per-agent cap, not a sum
25
- * ratchet — each role def is a standalone system prompt a converted spawn boots
26
- * on, and adding another role def is legitimate.
27
- *
28
- * The recorded `agentBoot` rows are additionally held **in sync with the tree**
29
- * (Story #4830), because those rows are what an author sizes an edit against.
30
- * The two drift directions are deliberately asymmetric:
31
- *
32
- * - **permissive** (the row understates the file, or no row exists) — the row
33
- * promises headroom that does not exist, the gate stays green, and the
34
- * shortfall only lands as a ceiling failure once the edit is written. This
35
- * fails the gate.
36
- * - **restrictive** (the row overstates the file) — an author under-spends
37
- * and the ceiling is never surprised, so it is self-correcting. Reported as
38
- * a `-` line; exit stays 0.
39
- *
40
- * Each row also records its `headroomBytes` under the ceiling, so the budget an
41
- * author reads is stated rather than re-derived.
42
- *
43
- * A read-tier that resolves **empty** is skipped silently (the `docsContextFiles`
44
- * half skips when unconfigured / its files are absent), so a repo with no
45
- * `CLAUDE.md` and no context docs is a clean no-op.
46
- *
47
- * Ratchet semantics (mirroring the sibling ratchets):
48
- * - A gated tier grows beyond `baseline.tiers.<tier>.totalBytes +
49
- * baseline.toleranceBytes` → exit 1, naming the tier and its delta.
50
- * - A gated tier shrinks below its baseline total → **exit 0**, reported as
51
- * an informational `-` line (Story #5313). This deliberately reverses
52
- * Story #4872's "shrink fails" rule: that rule made every trim a red gate
53
- * whose only remedy was a hand-run `--update`, so the gain was paid for
54
- * twice. The concern it answered — a stale total silently absorbing the
55
- * next growth — is now met by the close's write-back seam
56
- * (`story-close/context-budget-writeback.js`), which rewrites the lower
57
- * total into `baselines/context-budget.json` on the Story branch so the
58
- * gain locks in without a failing gate. Shrinkage stays zero-tolerance
59
- * in the *report* (every byte under the total is listed) so a sub-
60
- * tolerance gain is never discarded by the write-back either.
61
- * - A recorded row naming a path the measured tier no longer contains →
62
- * exit 1. The row describes a file that has been deleted or de-listed, so
63
- * the bytes it contributes to the recorded total are fiction.
64
- * - Within tolerance / clean → exit 0.
65
- * - Baseline file absent → warn + exit 0 (no-op; nothing to ratchet against).
66
- *
67
- * Tolerance lives in the baseline JSON (`toleranceBytes`) — there is **no**
68
- * `.agentrc.json` config key; this is a framework-internal dogfooding ratchet,
69
- * like arch-cycles.
70
- *
71
- * Flags:
72
- * --baseline <path> override the budget path (default
73
- * `baselines/context-budget.json`, resolved from cwd).
74
- * --root <path> resolve tiers against an explicit repo root (default cwd).
75
- * --update reseed the baseline from the current measurement (keeps
76
- * the existing `toleranceBytes`, or defaults it) and exit 0.
77
- * --json write the structured envelope to stdout.
13
+ * Flags: --baseline <path>, --root <path>, --update (keeps tolerance), --json.
78
14
  */
79
15
 
80
16
  import fs from 'node:fs';
@@ -85,143 +21,24 @@ import { resolveConfig } from './lib/config-resolver.js';
85
21
  import { resolveDocTiers, tierTotalBytes } from './lib/doc-tiers.js';
86
22
 
87
23
  /**
88
- * The tiers this ratchet gates (in report order). `digestVisible`, `onDemand`
89
- * and `workflowOnDemand` are resolved by the tier map for the lens, but the
90
- * byte budget intentionally gates only the tiers a session is *forced* to read.
24
+ * Measured tiers, in report order — only those a session is forced to read.
91
25
  * @type {Array<'alwaysLoaded' | 'mandatoryRead' | 'workflow'>}
92
26
  */
93
- export const GATED_TIERS = ['alwaysLoaded', 'mandatoryRead', 'workflow'];
27
+ export const MEASURED_TIERS = ['alwaysLoaded', 'mandatoryRead', 'workflow'];
94
28
 
95
29
  /**
96
- * Default tolerance (bytes) seeded into a fresh baseline by `--update` when the
97
- * existing baseline carries none.
98
- * @type {number}
30
+ * Tiers whose drift fails the command; the rest are report-only.
31
+ * @type {Array<'alwaysLoaded'>}
99
32
  */
100
- export const DEFAULT_TOLERANCE_BYTES = 2048;
33
+ export const ENFORCED_TIERS = ['alwaysLoaded'];
101
34
 
102
35
  /**
103
- * Per-file ceiling (bytes) for the role-scoped agent-boot tier (#4478). Unlike
104
- * the read-tiers (gated by a total-byte ratchet), each `.agents/agents/*.md`
105
- * boot context is a **standalone** system prompt a converted spawn boots on, so
106
- * the meaningful budget is per-agent, not the sum: no single role def may
107
- * exceed this ceiling. Adding another role def is legitimate — a per-file gate
108
- * (rather than a sum ratchet) does not false-positive on that.
36
+ * Seeded by `--update` when the baseline carries none.
109
37
  * @type {number}
110
38
  */
111
- export const AGENT_BOOT_CEILING_BYTES = 8192;
112
-
113
- /**
114
- * Return the agent-boot files that exceed the per-file ceiling.
115
- *
116
- * @param {{ tiers: Record<string, Array<{ path: string, bytes: number }>> }} tierMap
117
- * @param {number} ceiling
118
- * @returns {Array<{ path: string, bytes: number, ceiling: number }>}
119
- */
120
- export function agentBootOverflow(tierMap, ceiling = AGENT_BOOT_CEILING_BYTES) {
121
- const files = tierMap?.tiers?.agentBoot ?? [];
122
- return files
123
- .filter((f) => Number.isFinite(f?.bytes) && f.bytes > ceiling)
124
- .map((f) => ({ path: f.path, bytes: f.bytes, ceiling }));
125
- }
126
-
127
- /**
128
- * Classify one agent-boot file against its recorded baseline row (#4830).
129
- * Returns `null` when the row already agrees with the tree.
130
- *
131
- * `permissive` drift is the failure class this gate exists for: the row
132
- * understates the file (or is missing entirely), so the headroom an author
133
- * computes from it is larger than the headroom that exists, and the shortfall
134
- * only surfaces as a ceiling failure *after* the edit is written.
135
- * `restrictive` drift is the benign mirror — the row overstates the file, so an
136
- * author under-spends and the ceiling gate is never surprised.
137
- *
138
- * @param {{ path: string, bytes: number }} file live file measurement
139
- * @param {{ bytes?: number, headroomBytes?: number } | undefined} row recorded row
140
- * @param {number} ceiling
141
- * @returns {{ path: string, recorded: number|null, actual: number, delta: number,
142
- * direction: 'permissive'|'restrictive', recordedHeadroom: number|null,
143
- * headroomBytes: number } | null}
144
- */
145
- function classifyBootRow(file, row, ceiling) {
146
- const actual = file.bytes;
147
- const headroomBytes = ceiling - actual;
148
- const recorded = Number.isFinite(row?.bytes) ? row.bytes : null;
149
- const recordedHeadroom = Number.isFinite(row?.headroomBytes)
150
- ? row.headroomBytes
151
- : recorded === null
152
- ? null
153
- : ceiling - recorded;
154
- // A row is in sync only when both the byte count and the headroom it
155
- // advertises match the tree — a stale headroom misleads on its own.
156
- if (recorded === actual && recordedHeadroom === headroomBytes) return null;
157
- const permissive =
158
- recorded === null ||
159
- recorded < actual ||
160
- (recordedHeadroom !== null && recordedHeadroom > headroomBytes);
161
- return {
162
- path: file.path,
163
- recorded,
164
- actual,
165
- delta: recorded === null ? actual : actual - recorded,
166
- direction: permissive ? 'permissive' : 'restrictive',
167
- recordedHeadroom,
168
- headroomBytes,
169
- };
170
- }
171
-
172
- /**
173
- * Compare every recorded `agentBoot` row against the tree it describes.
174
- *
175
- * @param {{ tiers: Record<string, Array<{ path: string, bytes: number }>> }} tierMap
176
- * @param {{ agentBoot?: { ceilingBytes?: number, files?: Array<{ path: string, bytes: number, headroomBytes?: number }> } } | null} baseline
177
- * @param {number} [ceiling]
178
- * @returns {Array<ReturnType<typeof classifyBootRow>>} drift rows (empty = in sync)
179
- */
180
- export function agentBootDrift(tierMap, baseline, ceiling) {
181
- const recordedCeiling = Number.isFinite(baseline?.agentBoot?.ceilingBytes)
182
- ? baseline.agentBoot.ceilingBytes
183
- : AGENT_BOOT_CEILING_BYTES;
184
- const effective = Number.isFinite(ceiling) ? ceiling : recordedCeiling;
185
- const rows = new Map(
186
- (baseline?.agentBoot?.files ?? []).map((f) => [f.path, f]),
187
- );
188
- const drift = [];
189
- for (const file of tierMap?.tiers?.agentBoot ?? []) {
190
- if (!Number.isFinite(file?.bytes)) continue;
191
- const row = classifyBootRow(file, rows.get(file.path), effective);
192
- if (row) drift.push(row);
193
- }
194
- return drift;
195
- }
196
-
197
- /**
198
- * Render the agent-boot drift lines. `+` lines are permissive drift (gate
199
- * fail); `-` lines are restrictive drift (informational). Each line states the
200
- * **real** remaining headroom, so the author sizing the next edit reads the
201
- * true number rather than re-deriving it from a row that just proved stale.
202
- *
203
- * @param {Array<ReturnType<typeof classifyBootRow>>} drift
204
- * @returns {string[]}
205
- */
206
- export function renderBootDrift(drift) {
207
- return drift.map((d) => {
208
- const marker = d.direction === 'permissive' ? '+' : '-';
209
- const recorded =
210
- d.recorded === null
211
- ? 'has no recorded row'
212
- : `records ${d.recorded} bytes but the file is ${d.actual}`;
213
- const note =
214
- d.direction === 'permissive'
215
- ? 'the row overstates the headroom an author would size an edit against'
216
- : 'the row is conservative — refresh at leisure';
217
- return `${marker} agentBoot drift: ${d.path} ${recorded} — ${note} (real headroom ${d.headroomBytes})`;
218
- });
219
- }
39
+ export const DEFAULT_TOLERANCE_BYTES = 2048;
220
40
 
221
41
  /**
222
- * Parse argv for `--baseline <path>`, `--root <path>`, `--update`, `--json`.
223
- * Exported so unit tests can pin the parser.
224
- *
225
42
  * @param {string[]} argv
226
43
  * @returns {{ baselinePath: string|null, rootPath: string|null, update: boolean, json: boolean }}
227
44
  */
@@ -254,8 +71,7 @@ export function parseArgv(argv = []) {
254
71
  }
255
72
 
256
73
  /**
257
- * Read the committed budget envelope from disk. Returns the parsed object or
258
- * `null` when the file is missing or unparseable.
74
+ * `null` when missing or unparseable.
259
75
  *
260
76
  * @param {string} baselinePath
261
77
  * @returns {{ toleranceBytes?: number, tiers?: Record<string, { totalBytes: number, files?: Array<{ path: string, bytes: number }> }> } | null}
@@ -272,29 +88,20 @@ export function loadBaseline(baselinePath) {
272
88
  }
273
89
 
274
90
  /**
275
- * Build the committed-baseline envelope from a resolved tier map. Only the
276
- * gated tiers are recorded (each as `{ totalBytes, files }`).
277
- *
278
91
  * @param {{ tiers: Record<string, Array<{ path: string, bytes: number }>> }} tierMap
279
92
  * @param {number} toleranceBytes
280
93
  * @returns {object}
281
94
  */
282
95
  export function buildBaseline(tierMap, toleranceBytes) {
283
96
  const tiers = {};
284
- for (const name of GATED_TIERS) {
97
+ for (const name of MEASURED_TIERS) {
285
98
  const files = tierMap.tiers[name] ?? [];
286
99
  tiers[name] = { totalBytes: tierTotalBytes(files), files };
287
100
  }
288
- // The agent-boot tier is recorded top-level (not under `tiers`) because it is
289
- // gated by a per-file ceiling, not the total-byte ratchet the `tiers` entries
290
- // use — keeping it out of `tiers` keeps the ratchet diff loop unambiguous.
291
- // Each row carries the headroom it leaves under the ceiling, so an author
292
- // sizing an edit reads the remaining budget straight off the row (#4830)
293
- // instead of re-deriving it — and `agentBootDrift` keeps both numbers honest.
101
+ // Top-level, not under `tiers`: a per-file size record with no total to diff.
294
102
  const agentBootFiles = (tierMap.tiers.agentBoot ?? []).map((f) => ({
295
103
  path: f.path,
296
104
  bytes: f.bytes,
297
- headroomBytes: AGENT_BOOT_CEILING_BYTES - f.bytes,
298
105
  }));
299
106
  return {
300
107
  $schema: 'https://mandrel.dev/baselines/context-budget.schema.json',
@@ -302,11 +109,9 @@ export function buildBaseline(tierMap, toleranceBytes) {
302
109
  toleranceBytes,
303
110
  tiers,
304
111
  agentBoot: {
305
- ceilingBytes: AGENT_BOOT_CEILING_BYTES,
306
112
  files: agentBootFiles,
307
113
  },
308
- // Recorded, never gated (#4752): the total reachable closure per workflow
309
- // entry point. It is a drift signal — the gate is `tiers.workflow`.
114
+ // Recorded, never gated.
310
115
  workflowClosure: {
311
116
  reachableTotalBytes: tierMap.workflowClosure?.reachableTotalBytes ?? 0,
312
117
  entryPoints: tierMap.workflowClosure?.entryPoints ?? [],
@@ -315,11 +120,8 @@ export function buildBaseline(tierMap, toleranceBytes) {
315
120
  }
316
121
 
317
122
  /**
318
- * Collect the recorded rows of one gated tier that name a path the measured
319
- * tier no longer contains (Story #4872). A deleted file drops out of the
320
- * resolved tier, and so does one that has been de-listed from the read set —
321
- * either way the row's bytes are counted into a recorded total that no live
322
- * file backs, so the row is drift and not a detail.
123
+ * Recorded rows naming a path the tier no longer contains (deleted or
124
+ * de-listed) — their bytes inflate the total against nothing.
323
125
  *
324
126
  * @param {string} tier
325
127
  * @param {Array<{ path: string, bytes: number }>} files live tier measurement
@@ -341,11 +143,7 @@ function absentRows(tier, files, baseTier) {
341
143
  }
342
144
 
343
145
  /**
344
- * Pure diff: compare the current tier map against the committed baseline. A
345
- * gated tier with no current files is skipped; a tier absent from the baseline
346
- * is skipped. `grown` and `absent` entries fail the gate; `shrunk` entries are
347
- * reported and written back by the close (Story #5313) — see the ratchet
348
- * semantics in the module header.
146
+ * Pure diff against the baseline; empty or unrecorded tiers are skipped.
349
147
  *
350
148
  * @param {{ tiers: Record<string, Array<{ path: string, bytes: number }>> }} tierMap
351
149
  * @param {{ toleranceBytes?: number, tiers?: Record<string, { totalBytes: number }> }} baseline
@@ -364,7 +162,7 @@ export function diffBudget(tierMap, baseline) {
364
162
  const shrunk = [];
365
163
  const absent = [];
366
164
  const skipped = [];
367
- for (const tier of GATED_TIERS) {
165
+ for (const tier of MEASURED_TIERS) {
368
166
  const files = tierMap.tiers[tier] ?? [];
369
167
  const current = tierTotalBytes(files);
370
168
  const baseTier = baseline?.tiers?.[tier];
@@ -386,9 +184,7 @@ export function diffBudget(tierMap, baseline) {
386
184
  delta: current - baselineBytes,
387
185
  });
388
186
  } else if (current < baselineBytes) {
389
- // Deliberately zero-tolerance in the report: `tolerance` guards against
390
- // churn from a trivial *addition*; mirroring it downward would hide a
391
- // gain from the write-back that locks it in (Story #5313).
187
+ // Zero-tolerance downward, so the write-back never misses a small gain.
392
188
  shrunk.push({
393
189
  tier,
394
190
  current,
@@ -402,33 +198,51 @@ export function diffBudget(tierMap, baseline) {
402
198
  }
403
199
 
404
200
  /**
405
- * Count the drift entries that fail the gate: growth past tolerance and a
406
- * recorded row the tree no longer backs. Shrinkage is not in the set (Story
407
- * #5313 — the close writes it back instead). This is the one place the
408
- * failure set is defined and both the summary tag and the exit code read it.
201
+ * @param {{ tier?: string }} entry
202
+ * @returns {boolean}
203
+ */
204
+ function isEnforced(entry) {
205
+ return ENFORCED_TIERS.includes(entry?.tier);
206
+ }
207
+
208
+ /**
209
+ * The single definition of the failure set: enforced-tier `grown` + `absent`.
409
210
  *
410
211
  * @param {ReturnType<typeof diffBudget>} diff
411
212
  * @returns {number}
412
213
  */
413
214
  export function budgetFailureCount(diff) {
414
- return (diff?.grown?.length ?? 0) + (diff?.absent?.length ?? 0);
215
+ const grown = (diff?.grown ?? []).filter(isEnforced).length;
216
+ const absent = (diff?.absent ?? []).filter(isEnforced).length;
217
+ return grown + absent;
415
218
  }
416
219
 
220
+ const REPORT_ONLY_NOTE = ' — reported, never gated';
221
+
417
222
  /**
418
- * Render the human-readable diff. `+` lines are tiers that grew beyond
419
- * tolerance; `-` lines are tiers that shrank below their recorded total
420
- * (informational — the close writes the lower total back) or rows naming a
421
- * path the tree no longer carries (a gate failure). A one-line summary
422
- * always follows.
223
+ * A report-only row is marked `~` with an inline note, so the line itself
224
+ * says whether it broke the build.
423
225
  *
226
+ * @param {{ tier: string }} row
227
+ * @param {string} enforcedPrefix
228
+ * @returns {{ prefix: string, note: string }}
229
+ */
230
+ function gateMarks(row, enforcedPrefix) {
231
+ return isEnforced(row)
232
+ ? { prefix: enforcedPrefix, note: '' }
233
+ : { prefix: '~', note: REPORT_ONLY_NOTE };
234
+ }
235
+
236
+ /**
424
237
  * @param {ReturnType<typeof diffBudget>} diff
425
238
  * @returns {string}
426
239
  */
427
240
  export function renderDiff(diff) {
428
241
  const lines = [];
429
242
  for (const g of diff.grown) {
243
+ const { prefix, note } = gateMarks(g, '+');
430
244
  lines.push(
431
- `+ ${g.tier}: ${g.current} bytes exceeds budget ${g.baseline} + tolerance ${g.tolerance} (delta +${g.delta})`,
245
+ `${prefix} ${g.tier}: ${g.current} bytes exceeds budget ${g.baseline} + tolerance ${g.tolerance} (delta +${g.delta})${note}`,
432
246
  );
433
247
  }
434
248
  for (const s of diff.shrunk) {
@@ -437,8 +251,9 @@ export function renderDiff(diff) {
437
251
  );
438
252
  }
439
253
  for (const a of diff.absent ?? []) {
254
+ const { prefix, note } = gateMarks(a, '-');
440
255
  lines.push(
441
- `- ${a.tier}: recorded row ${a.path} names a path the measured tier no longer contains — refresh baselines/context-budget.json`,
256
+ `${prefix} ${a.tier}: recorded row ${a.path} names a path the measured tier no longer contains — refresh baselines/context-budget.json${note}`,
442
257
  );
443
258
  }
444
259
  const tag = budgetFailureCount(diff) > 0 ? '(gate fail)' : '(ok)';
@@ -449,9 +264,7 @@ export function renderDiff(diff) {
449
264
  }
450
265
 
451
266
  /**
452
- * Render the workflow **reachable** closure line — recorded, never gated
453
- * (Story #4752). Returns `''` when there is no workflow tier to report, so the
454
- * caller can stay a one-liner.
267
+ * The workflow reachable-closure line, or `''`.
455
268
  *
456
269
  * @param {{ workflowClosure?: { reachableTotalBytes?: number, entryPoints?: unknown[] } }} tierMap
457
270
  * @param {{ workflowClosure?: { reachableTotalBytes?: number } } | null} [baseline]
@@ -468,22 +281,20 @@ export function renderReachable(tierMap, baseline) {
468
281
  }
469
282
 
470
283
  /**
471
- * Top-level CLI entry. Exported so tests can drive the full pipeline against a
472
- * tmpdir fixture with an injected config and sinks.
284
+ * The agent-boot size line (total and largest role def), or `''`.
473
285
  *
474
- * @param {{
475
- * argv?: string[],
476
- * cwd?: string,
477
- * config?: object,
478
- * stdout?: { write: (s: string) => void },
479
- * stderr?: { write: (s: string) => void },
480
- * }} [opts]
481
- * @returns {Promise<number>} 0 = clean / within tolerance / shrink-only / no-op;
482
- * 1 = a gated tier grew beyond tolerance or a recorded row is unbacked
286
+ * @param {{ tiers?: { agentBoot?: Array<{ path: string, bytes: number }> } }} tierMap
287
+ * @returns {string}
483
288
  */
289
+ function renderAgentBoot(tierMap) {
290
+ const files = tierMap?.tiers?.agentBoot ?? [];
291
+ if (files.length === 0) return '';
292
+ const largest = files.reduce((a, b) => (b.bytes > a.bytes ? b : a));
293
+ return ` agentBoot: ${tierTotalBytes(files)} bytes across ${files.length} role defs, largest ${largest.path} at ${largest.bytes} — reported, never gated`;
294
+ }
295
+
484
296
  /**
485
- * Write a fresh budget, preserving the recorded tolerance so `--update` never
486
- * silently widens the gate it is refreshing.
297
+ * Preserves the recorded tolerance so `--update` never widens the gate.
487
298
  *
488
299
  * @param {object} params
489
300
  * @returns {0}
@@ -512,9 +323,6 @@ function writeUpdatedBaseline({ tierMap, resolvedBaselinePath, json, stdout }) {
512
323
  }
513
324
 
514
325
  /**
515
- * An absent budget is a no-op, not a failure: a consumer that has never
516
- * recorded one has nothing to regress against.
517
- *
518
326
  * @param {object} params
519
327
  * @returns {0}
520
328
  */
@@ -527,7 +335,7 @@ function reportMissingBaseline({
527
335
  }) {
528
336
  if (json) {
529
337
  stdout.write(
530
- `${JSON.stringify({ kind: 'context-budget-report', baselinePath: resolvedBaselinePath, tiers: tierMap.tiers, grown: [], shrunk: [], absent: [], skipped: GATED_TIERS, exitCode: 0, noBaseline: true }, null, 2)}\n`,
338
+ `${JSON.stringify({ kind: 'context-budget-report', baselinePath: resolvedBaselinePath, tiers: tierMap.tiers, grown: [], shrunk: [], absent: [], skipped: MEASURED_TIERS, exitCode: 0, noBaseline: true }, null, 2)}\n`,
531
339
  );
532
340
  } else {
533
341
  stderr.write(
@@ -538,28 +346,14 @@ function reportMissingBaseline({
538
346
  }
539
347
 
540
348
  /**
541
- * Score the tree against the recorded budget. Pure — every verdict the two
542
- * renderers below present is decided here, so they cannot disagree about what
543
- * failed or drift apart in which fields they surface.
349
+ * Every verdict is decided here, so the two renderers cannot disagree.
544
350
  *
545
351
  * @param {{ tierMap: object, baseline: object }} params
546
- * @returns {{ diff: object, ceiling: number, bootOverflow: object[], bootDrift: object[], permissiveDrift: object[], exitCode: 0 | 1 }}
352
+ * @returns {{ diff: object, exitCode: 0 | 1 }}
547
353
  */
548
354
  function evaluateBudget({ tierMap, baseline }) {
549
355
  const diff = diffBudget(tierMap, baseline);
550
- const ceiling = Number.isFinite(baseline?.agentBoot?.ceilingBytes)
551
- ? baseline.agentBoot.ceilingBytes
552
- : AGENT_BOOT_CEILING_BYTES;
553
- const bootOverflow = agentBootOverflow(tierMap, ceiling);
554
- const bootDrift = agentBootDrift(tierMap, baseline, ceiling);
555
- const permissiveDrift = bootDrift.filter((d) => d.direction === 'permissive');
556
- const exitCode =
557
- budgetFailureCount(diff) > 0 ||
558
- bootOverflow.length > 0 ||
559
- permissiveDrift.length > 0
560
- ? 1
561
- : 0;
562
- return { diff, ceiling, bootOverflow, bootDrift, permissiveDrift, exitCode };
356
+ return { diff, exitCode: budgetFailureCount(diff) > 0 ? 1 : 0 };
563
357
  }
564
358
 
565
359
  /**
@@ -573,7 +367,7 @@ function renderJsonReport({
573
367
  report,
574
368
  stdout,
575
369
  }) {
576
- const { diff, ceiling, bootOverflow, bootDrift, exitCode } = report;
370
+ const { diff, exitCode } = report;
577
371
  const envelope = {
578
372
  kind: 'context-budget-report',
579
373
  baselinePath: resolvedBaselinePath,
@@ -581,15 +375,14 @@ function renderJsonReport({
581
375
  ? baseline.toleranceBytes
582
376
  : 0,
583
377
  current: Object.fromEntries(
584
- GATED_TIERS.map((t) => [t, tierTotalBytes(tierMap.tiers[t] ?? [])]),
378
+ MEASURED_TIERS.map((t) => [t, tierTotalBytes(tierMap.tiers[t] ?? [])]),
585
379
  ),
586
380
  grown: diff.grown,
587
381
  shrunk: diff.shrunk,
588
382
  absent: diff.absent,
589
383
  skipped: diff.skipped,
590
- agentBootCeilingBytes: ceiling,
591
- agentBootOverflow: bootOverflow,
592
- agentBootDrift: bootDrift,
384
+ enforcedTiers: ENFORCED_TIERS,
385
+ agentBoot: tierMap.tiers?.agentBoot ?? [],
593
386
  workflowReachableBytes: tierMap.workflowClosure?.reachableTotalBytes ?? 0,
594
387
  exitCode,
595
388
  };
@@ -597,58 +390,59 @@ function renderJsonReport({
597
390
  }
598
391
 
599
392
  /**
600
- * Each failing condition gets its own remediation line: they are fixed
601
- * differently (trim a role def vs refresh the budget), so a single generic
602
- * message would leave the author guessing which applies.
393
+ * One remediation line per failing condition (each is fixed differently).
603
394
  *
604
395
  * @param {object} params
605
396
  * @returns {void}
606
397
  */
607
398
  function renderFailureDiagnostics({ report, stderr }) {
608
- const { diff, ceiling, bootOverflow, permissiveDrift } = report;
609
- if (permissiveDrift.length > 0) {
610
- stderr.write(
611
- `[context-budget] ❌ a recorded agentBoot row understates the file it describes, so it overstates the headroom an author would size an edit against — refresh it with \`node .agents/scripts/check-context-budget.js --update\` (the ceiling is unchanged)\n`,
612
- );
613
- }
614
- if (bootOverflow.length > 0) {
399
+ const { diff } = report;
400
+ if (diff.grown.some(isEnforced)) {
615
401
  stderr.write(
616
- `[context-budget] ❌ a role-agent boot context exceeds the ${ceiling}-byte per-agent ceiling — trim the role def (the ceiling is a hard cap, not a starve target)\n`,
402
+ `[context-budget] ❌ the always-loaded documentation tier grew beyond tolerance — every session and every subagent spawn re-pays it. Refresh the budget consciously with \`node .agents/scripts/check-context-budget.js --update\` once the growth is intentional\n`,
617
403
  );
618
404
  }
619
- if (diff.grown.length > 0) {
405
+ if (diff.absent.some(isEnforced)) {
620
406
  stderr.write(
621
- `[context-budget] ❌ a documentation tier grew beyond tolerance — refresh the budget consciously with \`node .agents/scripts/check-context-budget.js --update\` once the growth is intentional\n`,
622
- );
623
- }
624
- if (diff.absent.length > 0) {
625
- stderr.write(
626
- `[context-budget] ❌ a recorded row names a path the measured tier no longer contains — its bytes inflate the recorded total against nothing. Refresh with \`node .agents/scripts/check-context-budget.js --update\`\n`,
407
+ `[context-budget] ❌ a recorded always-loaded row names a path the measured tier no longer contains — its bytes inflate the recorded total against nothing. Refresh with \`node .agents/scripts/check-context-budget.js --update\`\n`,
627
408
  );
628
409
  }
629
410
  }
630
411
 
412
+ /**
413
+ * @param {{ tierMap: object, baseline: object | null }} params
414
+ * @returns {string[]}
415
+ */
416
+ function optionalReportLines({ tierMap, baseline }) {
417
+ return [renderReachable(tierMap, baseline), renderAgentBoot(tierMap)].filter(
418
+ Boolean,
419
+ );
420
+ }
421
+
631
422
  /**
632
423
  * @param {object} params
633
424
  * @returns {void}
634
425
  */
635
426
  function renderTextReport({ tierMap, baseline, report, stdout, stderr }) {
636
- const { diff, bootOverflow, bootDrift, exitCode } = report;
427
+ const { diff, exitCode } = report;
637
428
  stdout.write(`\n--- context-budget preview ---\n`);
638
429
  stdout.write(`${renderDiff(diff)}\n`);
639
- const reachable = renderReachable(tierMap, baseline);
640
- if (reachable) stdout.write(`${reachable}\n`);
641
- for (const o of bootOverflow) {
642
- stdout.write(
643
- `+ agentBoot: ${o.path} is ${o.bytes} bytes, over the ${o.ceiling}-byte per-agent ceiling\n`,
644
- );
645
- }
646
- for (const line of renderBootDrift(bootDrift)) {
430
+ for (const line of optionalReportLines({ tierMap, baseline })) {
647
431
  stdout.write(`${line}\n`);
648
432
  }
649
433
  if (exitCode === 1) renderFailureDiagnostics({ report, stderr });
650
434
  }
651
435
 
436
+ /**
437
+ * @param {{
438
+ * argv?: string[],
439
+ * cwd?: string,
440
+ * config?: object,
441
+ * stdout?: { write: (s: string) => void },
442
+ * stderr?: { write: (s: string) => void },
443
+ * }} [opts]
444
+ * @returns {Promise<number>} 1 only for enforced-tier drift.
445
+ */
652
446
  export async function runCli({
653
447
  argv = process.argv.slice(2),
654
448
  cwd = process.cwd(),