@event4u/agent-config 16.2.0 → 16.4.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 (651) hide show
  1. package/.augment-plugin/marketplace.json +3 -3
  2. package/.augment-plugin/plugin.json +1 -1
  3. package/.claude-plugin/marketplace.json +1 -1
  4. package/CHANGELOG.md +337 -234
  5. package/README.md +15 -13
  6. package/agents/templates/.ai-council.yml.example +26 -8
  7. package/dist/agent-src/commands/analyze/inbox.md +11 -8
  8. package/dist/agent-src/commands/analyze/roadmap-repos.md +1 -1
  9. package/dist/agent-src/commands/bug/fix.md +17 -2
  10. package/dist/agent-src/commands/bug/investigate.md +1 -1
  11. package/dist/agent-src/commands/commit/in-chunks.md +40 -31
  12. package/dist/agent-src/commands/commit.md +72 -33
  13. package/dist/agent-src/commands/condense.md +2 -8
  14. package/dist/agent-src/commands/council/debate.md +11 -7
  15. package/dist/agent-src/commands/council/default.md +10 -9
  16. package/dist/agent-src/commands/council.md +1 -1
  17. package/dist/agent-src/commands/estimate-ticket.md +1 -1
  18. package/dist/agent-src/commands/feature/explore.md +3 -3
  19. package/dist/agent-src/commands/feature/plan.md +2 -2
  20. package/dist/agent-src/commands/feature/roadmap.md +1 -1
  21. package/dist/agent-src/commands/fix/ci.md +18 -4
  22. package/dist/agent-src/commands/fix/commit-messages.md +48 -23
  23. package/dist/agent-src/commands/fix/pr-comments.md +3 -6
  24. package/dist/agent-src/commands/implement-ticket.md +4 -4
  25. package/dist/agent-src/commands/jira-ticket.md +1 -1
  26. package/dist/agent-src/commands/memory/add.md +4 -16
  27. package/dist/agent-src/commands/memory/load.md +5 -6
  28. package/dist/agent-src/commands/memory/promote.md +3 -16
  29. package/dist/agent-src/commands/mission/upgrade.md +3 -2
  30. package/dist/agent-src/commands/optimize/agents-dir.md +2 -2
  31. package/dist/agent-src/commands/optimize/deep.md +4 -2
  32. package/dist/agent-src/commands/optimize/rtk.md +4 -26
  33. package/dist/agent-src/commands/pr/create/description-only.md +18 -15
  34. package/dist/agent-src/commands/pr/create.md +42 -34
  35. package/dist/agent-src/commands/pr/merge.md +136 -9
  36. package/dist/agent-src/commands/prepare-for-review.md +13 -11
  37. package/dist/agent-src/commands/project/analyze.md +7 -35
  38. package/dist/agent-src/commands/refine-ticket.md +1 -1
  39. package/dist/agent-src/commands/review/changes.md +14 -19
  40. package/dist/agent-src/commands/roadmap/create.md +1 -1
  41. package/dist/agent-src/commands/roadmap/materialize.md +1 -1
  42. package/dist/agent-src/commands/roadmap/next.md +10 -1
  43. package/dist/agent-src/commands/roadmap/process-full.md +56 -42
  44. package/dist/agent-src/commands/roadmap/resolve-blockers.md +411 -0
  45. package/dist/agent-src/commands/roadmap/triage-parked.md +325 -0
  46. package/dist/agent-src/commands/roadmap.md +18 -4
  47. package/dist/agent-src/commands/tests/create.md +17 -3
  48. package/dist/agent-src/commands/tests/execute.md +22 -5
  49. package/dist/agent-src/commands/worktree/create.md +7 -3
  50. package/dist/agent-src/commands/worktree/verify.md +2 -1
  51. package/dist/agent-src/contexts/authority/decision-revisit-gate-enforcement.md +43 -0
  52. package/dist/agent-src/contexts/communication/rules-auto/design-fidelity-enforcement.md +24 -0
  53. package/dist/agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +5 -3
  54. package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +7 -9
  55. package/dist/agent-src/contexts/contracts/command-suggestion-flow.md +8 -6
  56. package/dist/agent-src/contexts/contracts/frugality-charter.md +8 -5
  57. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +7 -7
  58. package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +0 -1
  59. package/dist/agent-src/contexts/execution/evidence-discipline.md +2 -2
  60. package/dist/agent-src/contexts/execution/non-interactive-contract.md +5 -8
  61. package/dist/agent-src/contexts/execution/rdp-gate.md +4 -4
  62. package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +9 -8
  63. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +99 -54
  64. package/dist/agent-src/contexts/execution/session-canary-enforcement-history.md +67 -0
  65. package/dist/agent-src/contexts/execution/subagent-routing.md +8 -8
  66. package/dist/agent-src/contexts/execution/subagent-steering.md +6 -4
  67. package/dist/agent-src/contexts/execution/terminal-states.md +2 -2
  68. package/dist/agent-src/contexts/execution/toolchain-resolver.md +95 -7
  69. package/dist/agent-src/contexts/subagent-configuration.md +1 -1
  70. package/dist/agent-src/guidelines/agent-infra/active-remediation-mechanics.md +39 -0
  71. package/dist/agent-src/guidelines/agent-infra/context-hygiene-mechanics.md +1 -1
  72. package/dist/agent-src/guidelines/agent-infra/cross-source-consistency-mechanics.md +8 -10
  73. package/dist/agent-src/guidelines/agent-infra/frontier-reasoning-operating-profile.md +3 -2
  74. package/dist/agent-src/guidelines/agent-infra/layered-settings.md +13 -1
  75. package/dist/agent-src/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
  76. package/dist/agent-src/guidelines/agent-infra/self-improvement-pipeline.md +10 -3
  77. package/dist/agent-src/guidelines/agent-infra/size-and-scope.md +36 -0
  78. package/dist/agent-src/guidelines/php/git.md +15 -2
  79. package/dist/agent-src/rules/active-remediation.md +1 -2
  80. package/dist/agent-src/rules/analysis-skill-routing.md +0 -1
  81. package/dist/agent-src/rules/architecture.md +0 -1
  82. package/dist/agent-src/rules/artifact-drafting-protocol.md +0 -1
  83. package/dist/agent-src/rules/artifact-engagement-recording.md +0 -1
  84. package/dist/agent-src/rules/augment-edit-discipline.md +0 -1
  85. package/dist/agent-src/rules/autonomous-execution.md +1 -1
  86. package/dist/agent-src/rules/brand-consistency.md +0 -1
  87. package/dist/agent-src/rules/brand-source-of-truth.md +0 -1
  88. package/dist/agent-src/rules/broken-access-control.md +1 -1
  89. package/dist/agent-src/rules/cli-output-handling.md +0 -1
  90. package/dist/agent-src/rules/code-comment-discipline.md +0 -1
  91. package/dist/agent-src/rules/code-provenance.md +0 -1
  92. package/dist/agent-src/rules/command-suggestion-policy.md +1 -1
  93. package/dist/agent-src/rules/commit-conventions.md +1 -2
  94. package/dist/agent-src/rules/communication-through-line.md +1 -2
  95. package/dist/agent-src/rules/content-quoting-floor.md +1 -2
  96. package/dist/agent-src/rules/context-hygiene.md +6 -6
  97. package/dist/agent-src/rules/copilot-routing.md +1 -2
  98. package/dist/agent-src/rules/council-availability.md +4 -4
  99. package/dist/agent-src/rules/cross-source-consistency.md +4 -6
  100. package/dist/agent-src/rules/decision-revisit-gate.md +17 -35
  101. package/dist/agent-src/rules/delegation-policy.md +2 -3
  102. package/dist/agent-src/rules/design-fidelity.md +12 -16
  103. package/dist/agent-src/rules/design-review-after-ui-write.md +3 -3
  104. package/dist/agent-src/rules/devcontainer-routing.md +1 -2
  105. package/dist/agent-src/rules/doc-screenshot-hygiene.md +1 -1
  106. package/dist/agent-src/rules/docker-commands.md +0 -1
  107. package/dist/agent-src/rules/domain-adoption-policy.md +0 -1
  108. package/dist/agent-src/rules/domain-safety-disclaimer.md +1 -1
  109. package/dist/agent-src/rules/domain-safety-pii.md +1 -1
  110. package/dist/agent-src/rules/domain-safety-retention.md +1 -1
  111. package/dist/agent-src/rules/downstream-changes.md +0 -1
  112. package/dist/agent-src/rules/engineering-safety-floor.md +1 -1
  113. package/dist/agent-src/rules/evaluator-independence.md +3 -2
  114. package/dist/agent-src/rules/external-code-graph-interop.md +0 -1
  115. package/dist/agent-src/rules/external-reference-deep-dive.md +0 -1
  116. package/dist/agent-src/rules/fast-path-marker-visibility.md +2 -2
  117. package/dist/agent-src/rules/finance-safety-floor.md +1 -1
  118. package/dist/agent-src/rules/fix-what-you-see.md +6 -32
  119. package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +0 -1
  120. package/dist/agent-src/rules/git-history-discipline.md +2 -2
  121. package/dist/agent-src/rules/guidelines.md +0 -1
  122. package/dist/agent-src/rules/history-discipline.md +0 -1
  123. package/dist/agent-src/rules/icon-consistency.md +0 -1
  124. package/dist/agent-src/rules/image-likeness-and-rights.md +1 -1
  125. package/dist/agent-src/rules/improve-before-implement.md +0 -1
  126. package/dist/agent-src/rules/invite-challenge.md +0 -1
  127. package/dist/agent-src/rules/laravel-routing.md +1 -2
  128. package/dist/agent-src/rules/laravel-translations.md +0 -1
  129. package/dist/agent-src/rules/legal-safety-floor.md +3 -3
  130. package/dist/agent-src/rules/lethal-trifecta-guard.md +1 -1
  131. package/dist/agent-src/rules/linked-projects-onboarding-gate.md +0 -1
  132. package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +1 -1
  133. package/dist/agent-src/rules/markdown-safe-codeblocks.md +0 -1
  134. package/dist/agent-src/rules/media-governance-routing.md +13 -17
  135. package/dist/agent-src/rules/media-sync-ground-truth.md +0 -1
  136. package/dist/agent-src/rules/minimal-safe-diff.md +0 -1
  137. package/dist/agent-src/rules/missing-skill-recovery.md +0 -1
  138. package/dist/agent-src/rules/missing-tool-handling.md +0 -1
  139. package/dist/agent-src/rules/model-recommendation.md +0 -1
  140. package/dist/agent-src/rules/neighbour-precedence.md +64 -0
  141. package/dist/agent-src/rules/no-attribution-footers.md +0 -1
  142. package/dist/agent-src/rules/no-decorative-emojis-in-git-surfaces.md +0 -1
  143. package/dist/agent-src/rules/no-pr-progress-comments.md +0 -1
  144. package/dist/agent-src/rules/no-roadmap-references.md +0 -1
  145. package/dist/agent-src/rules/notes-first-reasoning.md +0 -1
  146. package/dist/agent-src/rules/onboarding-gate.md +0 -1
  147. package/dist/agent-src/rules/output-discipline.md +0 -1
  148. package/dist/agent-src/rules/package-ci-checks.md +0 -1
  149. package/dist/agent-src/rules/persona-governance.md +4 -5
  150. package/dist/agent-src/rules/php-coding.md +0 -1
  151. package/dist/agent-src/rules/prefer-enums-over-literals.md +0 -1
  152. package/dist/agent-src/rules/preservation-guard.md +0 -1
  153. package/dist/agent-src/rules/provider-lifecycle-discipline.md +3 -4
  154. package/dist/agent-src/rules/question-not-instruction.md +1 -1
  155. package/dist/agent-src/rules/reviewer-awareness.md +0 -1
  156. package/dist/agent-src/rules/roadmap-ci-steps-policy.md +0 -1
  157. package/dist/agent-src/rules/roadmap-progress-sync.md +4 -7
  158. package/dist/agent-src/rules/role-mode-adherence.md +0 -1
  159. package/dist/agent-src/rules/rule-type-governance.md +0 -1
  160. package/dist/agent-src/rules/runtime-safety.md +1 -1
  161. package/dist/agent-src/rules/scale-discipline.md +0 -1
  162. package/dist/agent-src/rules/secret-vcs-guard.md +1 -1
  163. package/dist/agent-src/rules/security-sensitive-stop.md +3 -3
  164. package/dist/agent-src/rules/self-repair-loop.md +0 -1
  165. package/dist/agent-src/rules/senior-engineering-discipline.md +0 -1
  166. package/dist/agent-src/rules/session-canary.md +7 -62
  167. package/dist/agent-src/rules/settings-ask-protocol.md +6 -6
  168. package/dist/agent-src/rules/size-enforcement.md +0 -1
  169. package/dist/agent-src/rules/skill-improvement-trigger.md +2 -3
  170. package/dist/agent-src/rules/skill-quality.md +0 -1
  171. package/dist/agent-src/rules/slash-command-routing-policy.md +0 -1
  172. package/dist/agent-src/rules/source-confidentiality.md +1 -1
  173. package/dist/agent-src/rules/source-discovery-gate.md +0 -1
  174. package/dist/agent-src/rules/source-of-truth.md +0 -1
  175. package/dist/agent-src/rules/spreadsheet-source-quality.md +1 -2
  176. package/dist/agent-src/rules/strategy-safety-floor.md +1 -1
  177. package/dist/agent-src/rules/symfony-routing.md +1 -2
  178. package/dist/agent-src/rules/think-before-action.md +0 -1
  179. package/dist/agent-src/rules/token-budget-discipline.md +12 -46
  180. package/dist/agent-src/rules/token-efficiency.md +0 -1
  181. package/dist/agent-src/rules/token-optimizer-maintenance.md +0 -1
  182. package/dist/agent-src/rules/tool-safety.md +1 -1
  183. package/dist/agent-src/rules/ui-audit-gate.md +1 -2
  184. package/dist/agent-src/rules/untrusted-input-defense.md +1 -1
  185. package/dist/agent-src/rules/upstream-proposal.md +0 -1
  186. package/dist/agent-src/rules/user-interaction.md +0 -1
  187. package/dist/agent-src/rules/user-interrupt-priority.md +1 -1
  188. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
  189. package/dist/agent-src/scripts/deferral_carry.ts +339 -0
  190. package/dist/agent-src/scripts/gate_budget.ts +47 -23
  191. package/dist/agent-src/scripts/gate_execute.ts +12 -4
  192. package/dist/agent-src/scripts/update_roadmap_progress.ts +4 -1
  193. package/dist/agent-src/skills/ai-council/SKILL.md +7 -4
  194. package/dist/agent-src/skills/ai-council/references/cost-and-redaction.md +21 -11
  195. package/dist/agent-src/skills/ai-council/references/procedure.md +12 -6
  196. package/dist/agent-src/skills/analysis-autonomous-mode/SKILL.md +1 -1
  197. package/dist/agent-src/skills/api-design/data/manifest.json +2 -2
  198. package/dist/agent-src/skills/api-testing/SKILL.md +17 -0
  199. package/dist/agent-src/skills/bug-analyzer/SKILL.md +1 -1
  200. package/dist/agent-src/skills/code-intelligence/SKILL.md +14 -2
  201. package/dist/agent-src/skills/command-routing/SKILL.md +3 -4
  202. package/dist/agent-src/skills/conventional-commits-writing/SKILL.md +127 -139
  203. package/dist/agent-src/skills/corpus-grounding/ATTRIBUTION.md +39 -0
  204. package/dist/agent-src/skills/corpus-grounding/SKILL.md +8 -2
  205. package/dist/agent-src/skills/database/data/manifest.json +2 -2
  206. package/dist/agent-src/skills/database/data/query-tuning.csv +13 -13
  207. package/dist/agent-src/skills/design-system-capture/SKILL.md +0 -3
  208. package/dist/agent-src/skills/design-system-capture/references/import-procedure.md +1 -1
  209. package/dist/agent-src/skills/estimate-ticket/SKILL.md +1 -1
  210. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +2 -2
  211. package/dist/agent-src/skills/fe-design/SKILL.md +1 -1
  212. package/dist/agent-src/skills/feature-planning/SKILL.md +1 -1
  213. package/dist/agent-src/skills/git-workflow/SKILL.md +44 -44
  214. package/dist/agent-src/skills/git-workflow/references/branch-update.md +312 -0
  215. package/dist/agent-src/skills/git-workflow/references/commit-subject.md +205 -0
  216. package/dist/agent-src/skills/iconography/SKILL.md +1 -1
  217. package/dist/agent-src/skills/jira-integration/SKILL.md +3 -3
  218. package/dist/agent-src/skills/js-library-packaging/SKILL.md +2 -2
  219. package/dist/agent-src/skills/merge-conflicts/SKILL.md +10 -4
  220. package/dist/agent-src/skills/monorepo-workspace/SKILL.md +1 -1
  221. package/dist/agent-src/skills/po-discovery/SKILL.md +1 -1
  222. package/dist/agent-src/skills/quality-tools/SKILL.md +11 -1
  223. package/dist/agent-src/skills/quality-tools/references/go-tools.md +76 -0
  224. package/dist/agent-src/skills/quality-tools/references/python-tools.md +104 -0
  225. package/dist/agent-src/skills/refine-ticket/SKILL.md +4 -4
  226. package/dist/agent-src/skills/review-routing/SKILL.md +2 -2
  227. package/dist/agent-src/skills/roadmap-writing/SKILL.md +2 -2
  228. package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +5 -3
  229. package/dist/agent-src/skills/source-discovery/SKILL.md +1 -1
  230. package/dist/agent-src/skills/storybook-workshop/SKILL.md +3 -3
  231. package/dist/agent-src/skills/tailwind-engineer/SKILL.md +4 -2
  232. package/dist/agent-src/skills/test-case-discovery/SKILL.md +7 -0
  233. package/dist/agent-src/skills/test-driven-development/SKILL.md +17 -0
  234. package/dist/agent-src/skills/test-performance/SKILL.md +19 -1
  235. package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
  236. package/dist/agent-src/skills/ui-component-architect/SKILL.md +2 -2
  237. package/dist/agent-src/skills/using-git-worktrees/SKILL.md +1 -1
  238. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +2 -2
  239. package/dist/agent-src/templates/AGENTS.md +1 -1
  240. package/dist/agent-src/templates/agent-settings.md +46 -129
  241. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +3 -3
  242. package/dist/agent-src/templates/command.md +2 -2
  243. package/dist/agent-src/templates/roadmaps.md +6 -1
  244. package/dist/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +0 -6
  245. package/dist/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +11 -7
  246. package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +48 -6
  247. package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.ts +3 -2
  248. package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.ts +2 -1
  249. package/dist/agent-src/templates/scripts/work_engine/hooks/settings.ts +0 -6
  250. package/dist/agent-src/templates/scripts/work_engine/scoring/decision_engine.ts +9 -12
  251. package/dist/agent-src/templates/scripts/work_engine/scoring/memory_visibility.ts +2 -1
  252. package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
  253. package/dist/agent-src/templates/skill.md +1 -1
  254. package/dist/cli/registry.js +2 -1
  255. package/dist/cli-delegate/archive_completed_roadmaps.js +92 -12
  256. package/dist/cli-delegate/check_update_banner.js +207 -120
  257. package/dist/cli-delegate/chunk-523HCFYO.js +90 -0
  258. package/dist/cli-delegate/{chunk-FP36SWJD.js → chunk-5GPULQBE.js} +2797 -338
  259. package/dist/cli-delegate/{chunk-IGD6ERX6.js → chunk-6SRJTYJS.js} +42 -176
  260. package/dist/cli-delegate/chunk-6V5FMA3P.js +186 -0
  261. package/dist/cli-delegate/{chunk-M2DPGFZ4.js → chunk-6V6TA25H.js} +22 -152
  262. package/dist/cli-delegate/chunk-6YQC2HLF.js +415 -0
  263. package/dist/cli-delegate/{chunk-E4XIZDIB.js → chunk-7HKRE54K.js} +1 -64
  264. package/dist/cli-delegate/chunk-7IQE3D5S.js +191 -0
  265. package/dist/cli-delegate/{chunk-YJ72UIAK.js → chunk-AED2VQGM.js} +1245 -249
  266. package/dist/cli-delegate/{chunk-7HQ52DHU.js → chunk-AL3RZ22D.js} +1 -1
  267. package/dist/cli-delegate/chunk-DEIV7XP7.js +108 -0
  268. package/dist/cli-delegate/{chunk-DBH4AHDK.js → chunk-ED7KCMLB.js} +9 -11
  269. package/dist/cli-delegate/chunk-F3QDG2GT.js +2569 -0
  270. package/dist/cli-delegate/{chunk-6KFEC3G7.js → chunk-G5VVIZRC.js} +3 -3
  271. package/dist/cli-delegate/{chunk-FC75PGJE.js → chunk-H76PHZBI.js} +149 -61
  272. package/dist/cli-delegate/chunk-IAYTIIQW.js +67 -0
  273. package/dist/cli-delegate/chunk-JQOM7TTM.js +1201 -0
  274. package/dist/cli-delegate/chunk-KB5FZ655.js +208 -0
  275. package/dist/cli-delegate/{chunk-7RQP4UDH.js → chunk-KR6EM23A.js} +235 -1455
  276. package/dist/cli-delegate/{chunk-LTYVIY76.js → chunk-KXXWJTDO.js} +6 -11
  277. package/dist/cli-delegate/{chunk-T7L2QK3K.js → chunk-LQOCRFWT.js} +1 -1
  278. package/dist/cli-delegate/{chunk-6KM6ORRY.js → chunk-MDPPKQCQ.js} +58 -9
  279. package/dist/cli-delegate/{chunk-4XFP2Y3E.js → chunk-MSUL5NYP.js} +5 -5
  280. package/dist/cli-delegate/chunk-OAFSJBHH.js +272 -0
  281. package/dist/cli-delegate/{chunk-4E2W63DA.js → chunk-OKJUIAPS.js} +62 -1
  282. package/dist/cli-delegate/{chunk-QAJS5YWY.js → chunk-PHD7OOLE.js} +2 -1
  283. package/dist/cli-delegate/{chunk-P6ZHP5W2.js → chunk-PWX7CKMD.js} +4 -4
  284. package/dist/cli-delegate/{chunk-NDJLNC6Q.js → chunk-T6BP34WI.js} +1 -0
  285. package/dist/cli-delegate/{chunk-7XGBX6ZH.js → chunk-T7XSJSUQ.js} +1144 -589
  286. package/dist/cli-delegate/chunk-ULQRUR23.js +208 -0
  287. package/dist/cli-delegate/chunk-WQWXGIWB.js +1779 -0
  288. package/dist/cli-delegate/{chunk-RGNIWTEA.js → chunk-XQTPXKFA.js} +1 -1
  289. package/dist/cli-delegate/{chunk-NUHLI2RX.js → chunk-YCU3TIXH.js} +2 -0
  290. package/dist/cli-delegate/chunk-ZBZV2G5R.js +210 -0
  291. package/dist/cli-delegate/{chunk-WGXTVKCQ.js → chunk-ZUZKZYCN.js} +5 -3
  292. package/dist/cli-delegate/cmd_analyze_session.js +223 -43
  293. package/dist/cli-delegate/cmd_brand_status.js +3 -2
  294. package/dist/cli-delegate/cmd_conformance.js +1252 -249
  295. package/dist/cli-delegate/cmd_converge.js +3 -3
  296. package/dist/cli-delegate/cmd_doctor.js +19 -9
  297. package/dist/cli-delegate/cmd_doctor_neighbours.js +30 -0
  298. package/dist/cli-delegate/cmd_explain.js +45 -21
  299. package/dist/cli-delegate/cmd_export.js +13 -10
  300. package/dist/cli-delegate/cmd_fleet.js +3 -3
  301. package/dist/cli-delegate/cmd_git_convention.js +1851 -0
  302. package/dist/cli-delegate/cmd_handoff.js +44 -22
  303. package/dist/cli-delegate/cmd_mcp_available.js +3 -2
  304. package/dist/cli-delegate/cmd_memory_get.js +3 -1
  305. package/dist/cli-delegate/cmd_migrate.js +3 -3
  306. package/dist/cli-delegate/cmd_packs_active.js +5 -4
  307. package/dist/cli-delegate/cmd_preflight.js +6 -6
  308. package/dist/cli-delegate/cmd_prune.js +14 -11
  309. package/dist/cli-delegate/cmd_refresh.js +2 -1
  310. package/dist/cli-delegate/cmd_route_audit.js +10 -8
  311. package/dist/cli-delegate/cmd_route_explain.js +4 -4
  312. package/dist/cli-delegate/cmd_session_recycle.js +10 -7
  313. package/dist/cli-delegate/cmd_settings_check.js +54 -7
  314. package/dist/cli-delegate/cmd_settings_get.js +18 -8
  315. package/dist/cli-delegate/cmd_settings_migrate.js +13 -10
  316. package/dist/cli-delegate/cmd_settings_set.js +4 -4
  317. package/dist/cli-delegate/cmd_sync.js +14 -11
  318. package/dist/cli-delegate/cmd_uninstall.js +15 -12
  319. package/dist/cli-delegate/cmd_update.js +7 -7
  320. package/dist/cli-delegate/cmd_upgrade.js +9 -8
  321. package/dist/cli-delegate/cmd_validate.js +15 -12
  322. package/dist/cli-delegate/cmd_versions.js +5 -5
  323. package/dist/cli-delegate/deferral_carry.js +16 -0
  324. package/dist/cli-delegate/gate_budget.js +1 -1
  325. package/dist/cli-delegate/gate_execute.js +3 -3
  326. package/dist/cli-delegate/roadmap_gates.js +6 -6
  327. package/dist/cli-delegate/update_roadmap_progress.js +1 -1
  328. package/dist/discovery/deprecation-report.md +1 -1
  329. package/dist/discovery/discovery-manifest.json +232 -141
  330. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  331. package/dist/discovery/discovery-manifest.summary.md +3 -3
  332. package/dist/discovery/dormancy-report.md +1 -1
  333. package/dist/discovery/orphan-report.md +1 -1
  334. package/dist/discovery/packs.json +26 -9
  335. package/dist/discovery/trust-report.md +3 -3
  336. package/dist/discovery/workspaces.json +7 -4
  337. package/dist/hooks/dispatch.js +5655 -6623
  338. package/dist/hooks/dispatch.sha256 +1 -1
  339. package/dist/install/claudePathsPlan.js +47 -6
  340. package/dist/install/claudeRuleRewrite.js +7 -0
  341. package/dist/install/emit_host_rules_cli.js +39 -36
  342. package/dist/install/globalRuleScope.js +87 -0
  343. package/dist/install/host_rule_ownership.js +160 -0
  344. package/dist/install/install.mjs +2336 -1249
  345. package/dist/install/installThinLayer.js +289 -0
  346. package/dist/install/installedRuleLinks.js +262 -0
  347. package/dist/install/wizard-plan.js +24 -0
  348. package/dist/mcp/awesome-mcp-servers.row.md +1 -1
  349. package/dist/mcp/mcp-cloudflare-catalogue.json +2 -2
  350. package/dist/mcp/registry-manifest.json +5 -5
  351. package/dist/mcp/server.json +2 -2
  352. package/dist/mcp/server.mjs +36504 -30986
  353. package/dist/router.json +1 -1
  354. package/dist/scripts/_lib/agent_settings.js +26 -120
  355. package/dist/scripts/_lib/claude_settings_hooks.js +10 -8
  356. package/dist/scripts/_lib/compile_time_toggles.js +12 -21
  357. package/dist/scripts/_lib/git_convention.js +232 -0
  358. package/dist/scripts/_lib/global_deploy_inventory.js +730 -0
  359. package/dist/scripts/_lib/installed_layer.js +704 -0
  360. package/dist/scripts/_lib/lean_projection_mode.js +218 -15
  361. package/dist/scripts/_lib/package_root.js +68 -0
  362. package/dist/scripts/_lib/rule_consequence_class.js +45 -0
  363. package/dist/scripts/_lib/rule_injection.js +67 -10
  364. package/dist/scripts/_lib/rule_law_section.js +122 -0
  365. package/dist/scripts/_lib/settings_removed_keys.js +168 -0
  366. package/dist/scripts/_lib/thin_rules.js +535 -0
  367. package/dist/scripts/_lib/windsurf_render.js +60 -0
  368. package/dist/scripts/condense.js +14 -26
  369. package/dist/scripts/project_thin_rules.js +14 -294
  370. package/dist/server/app.js +2 -1
  371. package/dist/server/gitKeysGate.js +105 -0
  372. package/dist/server/routes/settings.js +67 -8
  373. package/dist/server/routes/wizard.js +4 -0
  374. package/dist/server/schemas/settings.js +29 -81
  375. package/dist/shared/skillRanking.js +103 -16
  376. package/dist/ui/assets/{index-Cwq4d0hX.js → index-C3djEJah.js} +2 -2
  377. package/dist/ui/index.html +1 -1
  378. package/docs/MIGRATION.md +72 -1
  379. package/docs/contracts/settings-classes.md +39 -67
  380. package/docs/guidelines/agent-infra/active-remediation-mechanics.md +39 -0
  381. package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +1 -1
  382. package/docs/guidelines/agent-infra/cross-source-consistency-mechanics.md +8 -10
  383. package/docs/guidelines/agent-infra/frontier-reasoning-operating-profile.md +3 -2
  384. package/docs/guidelines/agent-infra/layered-settings.md +13 -1
  385. package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
  386. package/docs/guidelines/agent-infra/self-improvement-pipeline.md +10 -3
  387. package/docs/guidelines/agent-infra/size-and-scope.md +36 -0
  388. package/docs/guidelines/php/git.md +15 -2
  389. package/package.json +1 -1
  390. package/src/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
  391. package/src/agent-src/scripts/deferral_carry.ts +339 -0
  392. package/src/agent-src/scripts/gate_budget.ts +47 -23
  393. package/src/agent-src/scripts/gate_execute.ts +12 -4
  394. package/src/agent-src/scripts/update_roadmap_progress.ts +4 -1
  395. package/src/agent-src/templates/AGENTS.md +1 -1
  396. package/src/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +0 -6
  397. package/src/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +11 -7
  398. package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +48 -6
  399. package/src/agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.ts +3 -2
  400. package/src/agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.ts +2 -1
  401. package/src/agent-src/templates/scripts/work_engine/hooks/settings.ts +0 -6
  402. package/src/agent-src/templates/scripts/work_engine/scoring/decision_engine.ts +9 -12
  403. package/src/agent-src/templates/scripts/work_engine/scoring/memory_visibility.ts +2 -1
  404. package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
  405. package/src/config/agent-settings.template.yml +141 -334
  406. package/src/config/agents-paths.yml +16 -0
  407. package/src/config/assurance-capability-registry.json +7 -3
  408. package/src/config/ci-local-parity.yml +3 -0
  409. package/src/config/continuity-surface.json +10 -3
  410. package/src/config/discovery/packs.yml +17 -1
  411. package/src/config/evaluator-budgets.json +23 -10
  412. package/src/config/gate-coverage.yml +138 -3
  413. package/src/config/gate-violation-baselines.json +64 -16
  414. package/src/config/gitignore-block.txt +19 -0
  415. package/src/config/hook-bundle-budget.json +25 -0
  416. package/src/config/hook-token-budget.json +6 -1
  417. package/src/config/host-instruction-limits.json +33 -0
  418. package/src/config/release-gate-locality.yml +2 -1
  419. package/src/config/routing-coverage-seed.json +67 -4
  420. package/src/config/rule-activation-census.json +7 -3
  421. package/src/config/rule-consequence-class.json +161 -0
  422. package/src/config/rule-law-ceilings.json +105 -0
  423. package/src/config/rule-obligations.json +833 -0
  424. package/src/install/claudePathsPlan.ts +46 -4
  425. package/src/install/claudeRuleRewrite.ts +10 -1
  426. package/src/install/emit_host_rules_cli.ts +43 -34
  427. package/src/install/globalRuleScope.ts +109 -0
  428. package/src/install/host_rule_ownership.ts +170 -0
  429. package/src/install/installThinLayer.ts +378 -0
  430. package/src/install/installedRuleLinks.ts +308 -0
  431. package/src/install/wizard-plan.ts +24 -0
  432. package/src/scripts/_cli/cmd_analyze_session.ts +9 -15
  433. package/src/scripts/_cli/cmd_conformance.ts +13 -2
  434. package/src/scripts/_cli/cmd_doctor.ts +33 -81
  435. package/src/scripts/_cli/cmd_doctor_neighbours.ts +426 -0
  436. package/src/scripts/_cli/cmd_explain.ts +72 -14
  437. package/src/scripts/_cli/cmd_git_convention.ts +637 -0
  438. package/src/scripts/_cli/cmd_settings_check.ts +66 -8
  439. package/src/scripts/_cli/cmd_settings_get.ts +18 -3
  440. package/src/scripts/_cli/doctor_execution.ts +72 -1
  441. package/src/scripts/_dispatch.bash +53 -4
  442. package/src/scripts/_lib/agent_settings.ts +26 -124
  443. package/src/scripts/_lib/blocked_by_marker.ts +1 -1
  444. package/src/scripts/_lib/claude_settings_hooks.ts +10 -8
  445. package/src/scripts/_lib/compile_time_toggles.ts +12 -21
  446. package/src/scripts/_lib/dispatch_import_closure.ts +163 -0
  447. package/src/scripts/_lib/estate_offsets.ts +241 -0
  448. package/src/scripts/_lib/exemption_shape.ts +143 -0
  449. package/src/scripts/_lib/fnv.ts +23 -0
  450. package/src/scripts/_lib/foreign_scan.ts +106 -0
  451. package/src/scripts/_lib/git_base_ref.ts +92 -0
  452. package/src/scripts/_lib/git_convention.ts +291 -0
  453. package/src/scripts/_lib/git_convention_carrier.ts +389 -0
  454. package/src/scripts/_lib/git_convention_grammar.ts +246 -0
  455. package/src/scripts/_lib/git_convention_measure.ts +344 -0
  456. package/src/scripts/_lib/gitignore_block.ts +314 -0
  457. package/src/scripts/_lib/global_deploy_inventory.ts +106 -0
  458. package/src/scripts/_lib/graph_feeder_record.ts +437 -0
  459. package/src/scripts/_lib/hook_settings.ts +73 -0
  460. package/src/scripts/_lib/host_capability.ts +40 -19
  461. package/src/scripts/_lib/host_hook_merge.ts +165 -0
  462. package/src/scripts/_lib/installed_layer.ts +963 -0
  463. package/src/scripts/_lib/json_merge.ts +82 -0
  464. package/src/scripts/_lib/json_pointers.ts +93 -11
  465. package/src/scripts/_lib/knowledge_global.ts +14 -1
  466. package/src/scripts/_lib/lean_projection_mode.ts +275 -15
  467. package/src/scripts/_lib/machine_wake.ts +16 -3
  468. package/src/scripts/_lib/module_reach.ts +456 -0
  469. package/src/scripts/_lib/neighbour_census.ts +760 -0
  470. package/src/scripts/_lib/neighbour_contradictions.ts +236 -0
  471. package/src/scripts/_lib/neighbour_scan.ts +122 -0
  472. package/src/scripts/_lib/neighbour_tool_use.ts +187 -0
  473. package/src/scripts/_lib/prompt_shape.ts +46 -0
  474. package/src/scripts/_lib/ratification_artifact.ts +220 -1
  475. package/src/scripts/_lib/ratification_subject.ts +92 -0
  476. package/src/scripts/_lib/release_findings_ingest.ts +15 -7
  477. package/src/scripts/_lib/release_highlights.ts +5 -0
  478. package/src/scripts/_lib/release_migration_gate.ts +19 -3
  479. package/src/scripts/_lib/reserved_name_sweep.ts +73 -0
  480. package/src/scripts/_lib/review_coverage.ts +134 -0
  481. package/src/scripts/_lib/rule_consequence_class.ts +71 -0
  482. package/src/scripts/_lib/rule_injection.ts +130 -10
  483. package/src/scripts/_lib/rule_law_section.ts +147 -0
  484. package/src/scripts/_lib/rule_layer_overlap.ts +58 -0
  485. package/src/scripts/_lib/rule_obligations.ts +205 -0
  486. package/src/scripts/_lib/self_repair.ts +1 -1
  487. package/src/scripts/_lib/settings_removed_keys.ts +173 -0
  488. package/src/scripts/_lib/skill_origin.ts +254 -0
  489. package/src/scripts/_lib/structured_ask.ts +64 -21
  490. package/src/scripts/_lib/test_red_state.ts +5 -0
  491. package/src/scripts/_lib/thin_rules.ts +620 -0
  492. package/src/scripts/_lib/touched_file_quality.ts +570 -0
  493. package/src/scripts/_lib/turn_end_refusals.ts +77 -2
  494. package/src/scripts/_lib/windsurf_render.ts +63 -0
  495. package/src/scripts/_lib/worker_budget.ts +1 -1
  496. package/src/scripts/adr/regenerate_index.ts +16 -1
  497. package/src/scripts/ai_council/cli_call_budget.ts +13 -5
  498. package/src/scripts/ai_council/clients.ts +26 -57
  499. package/src/scripts/ai_council/config.ts +8 -8
  500. package/src/scripts/ai_council/modification_review.ts +100 -0
  501. package/src/scripts/ai_council/modification_review_questions.ts +90 -0
  502. package/src/scripts/ai_council/orchestrator.ts +5 -5
  503. package/src/scripts/ai_council/spend_gate.ts +18 -7
  504. package/src/scripts/ai_council/vendor_defaults.ts +45 -0
  505. package/src/scripts/ai_team/config.ts +11 -16
  506. package/src/scripts/audit_skill_overlap.ts +261 -0
  507. package/src/scripts/audit_user_type_axis.ts +20 -8
  508. package/src/scripts/before_complete_hook.ts +243 -12
  509. package/src/scripts/bench_ab_clone.ts +1 -2
  510. package/src/scripts/bench_concern_spawn_path.ts +129 -0
  511. package/src/scripts/bench_graph_feeder_latency.ts +584 -0
  512. package/src/scripts/bench_touched_file_quality.ts +238 -0
  513. package/src/scripts/check_agent_artifact_location.ts +36 -0
  514. package/src/scripts/check_branch_freshness.ts +147 -24
  515. package/src/scripts/check_enforcement_coverage.ts +130 -0
  516. package/src/scripts/check_enforcement_matrix.ts +377 -20
  517. package/src/scripts/check_estate_count.ts +130 -153
  518. package/src/scripts/check_evaluator_budgets.ts +4 -0
  519. package/src/scripts/check_finding_dispositions.ts +196 -21
  520. package/src/scripts/check_gate_coverage.ts +4 -3
  521. package/src/scripts/check_gate_reachability.ts +48 -1
  522. package/src/scripts/check_generator_sync.ts +48 -0
  523. package/src/scripts/check_hook_bundle_composition.ts +477 -0
  524. package/src/scripts/check_kernel_edit_ratified.ts +132 -14
  525. package/src/scripts/check_memory.ts +7 -1
  526. package/src/scripts/check_pack_size.ts +1 -1
  527. package/src/scripts/check_release_highlights.ts +10 -0
  528. package/src/scripts/check_release_manifest_content.ts +189 -0
  529. package/src/scripts/check_release_pr_shape.ts +38 -15
  530. package/src/scripts/check_standing_rule_delivery.ts +129 -13
  531. package/src/scripts/check_suppression_hygiene.ts +2 -5
  532. package/src/scripts/check_verify_expectation_delta.ts +521 -0
  533. package/src/scripts/ci_settle.ts +42 -5
  534. package/src/scripts/classify_merge_risk.ts +320 -0
  535. package/src/scripts/closure_scan.ts +91 -1
  536. package/src/scripts/code_graph/detect.ts +127 -7
  537. package/src/scripts/code_graph/foreign.ts +194 -0
  538. package/src/scripts/code_graph/query.ts +217 -4
  539. package/src/scripts/code_graph/types.ts +26 -2
  540. package/src/scripts/code_graph/validate.ts +3 -1
  541. package/src/scripts/code_graph/verbs.ts +103 -0
  542. package/src/scripts/command_suggester/settings.ts +8 -108
  543. package/src/scripts/command_suggester/types.ts +4 -5
  544. package/src/scripts/compile_hook_manifest.ts +33 -1
  545. package/src/scripts/condense.ts +14 -27
  546. package/src/scripts/consumer_matrix.ts +102 -0
  547. package/src/scripts/context_hygiene_hook.ts +13 -23
  548. package/src/scripts/cost/preflight.mjs +12 -1
  549. package/src/scripts/council_cli.ts +7 -7
  550. package/src/scripts/dispatch_r2_reviewer.ts +24 -11
  551. package/src/scripts/estate_exemption_shape.ts +202 -0
  552. package/src/scripts/explain_run.ts +8 -13
  553. package/src/scripts/generate_git_convention_grammar.ts +127 -0
  554. package/src/scripts/generate_host_cost_table.ts +21 -4
  555. package/src/scripts/handoff_context_hook.ts +86 -37
  556. package/src/scripts/hook_manifest.json +1 -1
  557. package/src/scripts/hook_manifest.yaml +175 -15
  558. package/src/scripts/hooks/block_config_weakening.ts +115 -7
  559. package/src/scripts/hooks/block_plumbing_writes.ts +37 -5
  560. package/src/scripts/hooks/code_graph_context_hook.ts +252 -23
  561. package/src/scripts/hooks/concern_failure_policy.ts +280 -0
  562. package/src/scripts/hooks/concern_registry.ts +2 -0
  563. package/src/scripts/hooks/delegation_nudge_hook.ts +2 -3
  564. package/src/scripts/hooks/dispatch_hook.ts +52 -52
  565. package/src/scripts/hooks/evidence_independence.ts +12 -4
  566. package/src/scripts/hooks/exit_codes.ts +2 -1
  567. package/src/scripts/hooks/host_lowering.json +1 -1
  568. package/src/scripts/hooks/host_lowering.ts +19 -1
  569. package/src/scripts/hooks/mcp_usage_observation_hook.ts +121 -0
  570. package/src/scripts/hooks/one_question_per_ask_hook.ts +41 -25
  571. package/src/scripts/hooks/payload_stub.ts +10 -1
  572. package/src/scripts/hooks/push_settle_hook.ts +4 -3
  573. package/src/scripts/hooks/rule_inject_hook.ts +795 -60
  574. package/src/scripts/hooks/state_io.ts +8 -4
  575. package/src/scripts/hooks/table_fingerprint.ts +21 -0
  576. package/src/scripts/hooks/telemetry_usage_hook.ts +24 -7
  577. package/src/scripts/hooks/turn_end_gate_hook.ts +85 -0
  578. package/src/scripts/hooks_status.ts +112 -0
  579. package/src/scripts/injection_scan_hook.ts +7 -0
  580. package/src/scripts/install-hooks.sh +42 -14
  581. package/src/scripts/install.ts +78 -215
  582. package/src/scripts/installed_layer_report.ts +103 -0
  583. package/src/scripts/language_mirror_hook.ts +15 -6
  584. package/src/scripts/learning_sidecar.ts +119 -8
  585. package/src/scripts/lint_blocker_citations.ts +198 -0
  586. package/src/scripts/lint_evidence_artifacts.ts +9 -0
  587. package/src/scripts/lint_hook_concern_budget.ts +10 -21
  588. package/src/scripts/lint_hook_manifest.ts +53 -0
  589. package/src/scripts/lint_major_migration_sections.ts +156 -26
  590. package/src/scripts/lint_pack_boundaries.ts +465 -29
  591. package/src/scripts/lint_roadmap_blockers.ts +282 -29
  592. package/src/scripts/lint_roadmap_complexity.ts +4 -2
  593. package/src/scripts/lint_rule_law_section.ts +647 -0
  594. package/src/scripts/lint_rule_skill_pack_reach.ts +17 -0
  595. package/src/scripts/lint_settings_classes.ts +1 -1
  596. package/src/scripts/lint_ticked_unmet_criteria.ts +165 -0
  597. package/src/scripts/lint_workflow_security.ts +173 -6
  598. package/src/scripts/mcp_server/consumer_tool_catalog.json +53 -0
  599. package/src/scripts/mcp_server/graph_tools.ts +72 -3
  600. package/src/scripts/measure_routing_signal.ts +54 -16
  601. package/src/scripts/measure_skill_ranker_baseline.ts +221 -8
  602. package/src/scripts/memory_learn_hook.ts +91 -6
  603. package/src/scripts/model_rule_injection.ts +55 -8
  604. package/src/scripts/onboarding_gate_hook.ts +7 -6
  605. package/src/scripts/print_required_checks.ts +15 -3
  606. package/src/scripts/probe_host_compliance.ts +33 -5
  607. package/src/scripts/probe_turnaround.ts +183 -3
  608. package/src/scripts/project_thin_rules.ts +34 -327
  609. package/src/scripts/ratification_header.ts +77 -0
  610. package/src/scripts/refusal_envelope.ts +138 -0
  611. package/src/scripts/release_publication.ts +29 -3
  612. package/src/scripts/report_dispatch_import_closure.ts +76 -0
  613. package/src/scripts/report_evidence_temperature.ts +657 -0
  614. package/src/scripts/report_installed_rule_links.ts +274 -0
  615. package/src/scripts/report_label_agreement.ts +233 -0
  616. package/src/scripts/report_module_reach.ts +212 -0
  617. package/src/scripts/report_obligation_mechanism.ts +228 -0
  618. package/src/scripts/report_parked_blockers.ts +222 -0
  619. package/src/scripts/report_required_checks_drift.ts +196 -0
  620. package/src/scripts/report_single_token_triggers.ts +277 -0
  621. package/src/scripts/report_skill_ranker_confusion.ts +543 -0
  622. package/src/scripts/report_standing_payload_by_host.ts +188 -15
  623. package/src/scripts/report_verification_record_coverage.ts +306 -0
  624. package/src/scripts/routing_doctor.ts +2 -2
  625. package/src/scripts/rule_activation_census.ts +5 -2
  626. package/src/scripts/rule_trigger_eval.ts +9 -9
  627. package/src/scripts/schemas/agent-settings.schema.json +17 -31
  628. package/src/scripts/schemas/command.schema.json +1 -1
  629. package/src/scripts/schemas/review-findings.schema.json +3 -2
  630. package/src/scripts/schemas/rule.schema.json +5 -0
  631. package/src/scripts/schemas/skill.schema.json +1 -1
  632. package/src/scripts/self_review_gate.ts +101 -9
  633. package/src/scripts/skill_tools/score_skill_relevance.ts +314 -40
  634. package/src/scripts/sweep_skill_ranker_signals.ts +129 -0
  635. package/src/scripts/sync_gitignore.ts +29 -235
  636. package/src/scripts/sync_pr_branch.ts +403 -132
  637. package/src/scripts/trigger_eval_grandfather.json +0 -21
  638. package/src/server/schemas/settings.ts +42 -176
  639. package/src/shared/skillRanking.ts +169 -14
  640. package/dist/cli-delegate/chunk-5R7HOLAF.js +0 -99
  641. package/dist/cli-delegate/chunk-JNMVLWLR.js +0 -4457
  642. package/dist/cli-delegate/chunk-YDPILCOL.js +0 -152
  643. package/src/scripts/_lib/config_chain.ts +0 -477
  644. package/src/scripts/_lib/conformance_report.ts +0 -403
  645. package/src/scripts/_lib/eval_discrimination.ts +0 -95
  646. package/src/scripts/_lib/evaluator_promotion.ts +0 -225
  647. package/src/scripts/_lib/file_slicer.ts +0 -117
  648. package/src/scripts/_lib/legacy_boundary_map.ts +0 -228
  649. package/src/scripts/_lib/minimality_tiebreak.ts +0 -168
  650. package/src/scripts/_lib/overbuild_lens_contract.ts +0 -196
  651. package/src/scripts/_lib/role_split.ts +0 -338
@@ -0,0 +1,477 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * Composition gate for the self-hosted hook bundle: ONE YAML reader, and a
4
+ * byte ceiling.
5
+ *
6
+ * WHY THIS EXISTS — measured, not hypothetical.
7
+ *
8
+ * Every concern is inlined into one `dist/hooks/dispatch.js` that every hook
9
+ * event loads, so a dependency added for ONE concern is paid by all of them on
10
+ * every dispatch. On 2026-10-01 the bundle carried two YAML parsers: `yaml`,
11
+ * pulled by six modules including the dispatcher itself, and `js-yaml`, pulled
12
+ * by one call site in `block_config_weakening.ts` — 95,846 bytes, 6.13 % of a
13
+ * 1,564,211-byte bundle. Beside it, `host_lowering.ts`'s own header said the
14
+ * `yaml` reader was "the ONLY remaining YAML reader on that path".
15
+ *
16
+ * Nothing in this tree could see either fact. The freshness gate compares
17
+ * mtimes, the content gate compares digests, and neither has an opinion about
18
+ * what is INSIDE the bundle. So the second parser reached a release and was
19
+ * found by an external rescore counting bytes — a review finding where it
20
+ * should have been a red check. This gate is that red check.
21
+ *
22
+ * WHAT IT CHECKS
23
+ *
24
+ * 1. At most `max_yaml_packages` YAML packages contribute bytes to the
25
+ * bundle. The package set is {@link YAML_PACKAGES} — a closed list, so a
26
+ * third parser arriving under a name nobody listed is NOT caught here, and
27
+ * that limit is stated rather than implied.
28
+ * 2. The bundle's byte count is at or under `max_bytes`.
29
+ *
30
+ * Both bounds live in `src/config/hook-bundle-budget.json`, never in this file:
31
+ * a number a reviewer has to read a script to find is a number nobody reviews.
32
+ *
33
+ * WHY IT BUILDS RATHER THAN READS. `dist/hooks/` is untracked, so a gate that
34
+ * read the bundle on disk would be local-only like `check_hook_bundle_content`
35
+ * — and the thing being bounded is what the SOURCE produces, which is a
36
+ * property of the commit rather than of a machine. So this builds its own
37
+ * bundle with `--metafile` and measures that. It runs identically in CI and
38
+ * locally, and it never touches the live bundle.
39
+ *
40
+ * The esbuild invocation is NOT duplicated here: it is read from
41
+ * `package.json`'s `build:hooks` script with only `--outfile=` rewritten, via
42
+ * the same `rewriteOutfile` helper `rebuild_hook_bundle` and
43
+ * `check_hook_bundle_content` use, so the flag set has exactly one home. The
44
+ * trailing `&& node src/scripts/write_bundle_digest.mjs` is stripped — this
45
+ * gate must not write a sidecar for a probe bundle nobody executes.
46
+ *
47
+ * WHAT IT DOES NOT DO. It says nothing about LATENCY. A smaller bundle is not
48
+ * a measured speed-up; `src/config/hook-latency-budget.json` owns that axis and
49
+ * no number here is derived from it. It says nothing about the install or MCP
50
+ * bundles, which carry their own module graphs.
51
+ *
52
+ * Usage:
53
+ * ./scripts-run src/scripts/check_hook_bundle_composition
54
+ * ./scripts-run src/scripts/check_hook_bundle_composition --metafile <path>
55
+ * ./scripts-run src/scripts/check_hook_bundle_composition --self-test
56
+ *
57
+ * Exit codes: 0 = within budget · 1 = over the ceiling or a second reader ·
58
+ * 2 = the build or the budget file failed.
59
+ */
60
+ // ledger-exempt: single-artefact transaction — one bundle build yielding one
61
+ // aggregate verdict. The per-source accounting lives in
62
+ // check_hook_bundle_freshness, which carries the ledger.
63
+ import { spawnSync } from 'node:child_process';
64
+ import * as fs from 'node:fs';
65
+ import * as os from 'node:os';
66
+ import * as path from 'node:path';
67
+ import { fileURLToPath, pathToFileURL } from 'node:url';
68
+
69
+ import { runGateCli, runSelfTest } from './_lib/gate_self_test.js';
70
+ import { reportScanned } from './_lib/scan_scope.js';
71
+ import { buildScript } from './check_hook_bundle_content.js';
72
+ import { rewriteOutfile } from './rebuild_hook_bundle.js';
73
+
74
+ const _HERE = path.dirname(fileURLToPath(import.meta.url));
75
+ export const REPO_ROOT = path.resolve(_HERE, '..', '..');
76
+ export const SELF_REL = path.join('src', 'scripts', 'check_hook_bundle_composition.ts');
77
+ export const BUDGET_REL = path.join('src', 'config', 'hook-bundle-budget.json');
78
+ const LIVE_REL = path.join('dist', 'hooks', 'dispatch.js');
79
+
80
+ /**
81
+ * The YAML readers this tree has ever carried, by package name.
82
+ *
83
+ * A CLOSED LIST, and the consequence is worth stating: a fourth parser arriving
84
+ * under a name not listed here contributes bytes the ceiling catches and the
85
+ * parser cap does not. The alternative — treating any package whose name
86
+ * contains "yaml" as a reader — would match a YAML-adjacent utility that is not
87
+ * a parser, and a cap that fires on the wrong package is worse than one that
88
+ * misses an unlisted one, because the first teaches people to raise the cap.
89
+ */
90
+ export const YAML_PACKAGES: readonly string[] = ['yaml', 'js-yaml', 'yaml-js', 'yamljs'];
91
+
92
+ export interface Budget {
93
+ readonly maxBytes: number;
94
+ readonly maxYamlPackages: number;
95
+ }
96
+
97
+ export interface Analysis {
98
+ /** Bytes of the bundle esbuild produced. */
99
+ readonly bytes: number;
100
+ /** Modules that contributed to it — the unit `scanned:` reports. */
101
+ readonly modules: number;
102
+ /** Bytes in the output, summed per owning npm package. */
103
+ readonly packageBytes: ReadonlyMap<string, number>;
104
+ /** Listed YAML packages contributing more than zero bytes, sorted. */
105
+ readonly yamlPackages: readonly string[];
106
+ }
107
+
108
+ /**
109
+ * The npm package a bundled module path belongs to, or `null` for this tree's
110
+ * own sources.
111
+ *
112
+ * Reads the INNERMOST `node_modules/` segment: a transitively nested copy
113
+ * (`node_modules/a/node_modules/yaml/…`) is still `yaml`'s bytes, and
114
+ * attributing it to `a` would let a second parser hide one level down.
115
+ */
116
+ export function owningPackage(modulePath: string): string | null {
117
+ const marker = 'node_modules/';
118
+ const at = modulePath.lastIndexOf(marker);
119
+ if (at < 0) return null;
120
+ const parts = modulePath.slice(at + marker.length).split('/');
121
+ const head = parts[0] ?? '';
122
+ if (head === '') return null;
123
+ return head.startsWith('@') ? `${head}/${parts[1] ?? ''}` : head;
124
+ }
125
+
126
+ /** Parse an esbuild metafile and attribute its one entry-point output. */
127
+ export function analyzeMetafile(json: string): Analysis {
128
+ const meta = JSON.parse(json) as {
129
+ outputs?: Record<string, { entryPoint?: string; bytes?: number; inputs?: Record<string, { bytesInOutput?: number }> }>;
130
+ };
131
+ const outputs = Object.values(meta.outputs ?? {});
132
+ const out = outputs.find((o) => typeof o.entryPoint === 'string');
133
+ if (out === undefined) {
134
+ throw new Error(
135
+ 'metafile carries no entry-point output — refusing to report a composition for a build that produced nothing',
136
+ );
137
+ }
138
+ const packageBytes = new Map<string, number>();
139
+ const inputs = out.inputs ?? {};
140
+ for (const [p, v] of Object.entries(inputs)) {
141
+ const pkg = owningPackage(p);
142
+ if (pkg === null) continue;
143
+ packageBytes.set(pkg, (packageBytes.get(pkg) ?? 0) + (v.bytesInOutput ?? 0));
144
+ }
145
+ const yamlPackages = YAML_PACKAGES.filter((p) => (packageBytes.get(p) ?? 0) > 0).sort();
146
+ return {
147
+ bytes: out.bytes ?? 0,
148
+ modules: Object.keys(inputs).length,
149
+ packageBytes,
150
+ yamlPackages,
151
+ };
152
+ }
153
+
154
+ /** Read the committed budget. Throws rather than defaulting — a guessed ceiling bounds nothing. */
155
+ export function readBudget(root: string): Budget {
156
+ const abs = path.join(root, BUDGET_REL);
157
+ const raw = JSON.parse(fs.readFileSync(abs, 'utf-8')) as Record<string, unknown>;
158
+ const maxBytes = raw['max_bytes'];
159
+ const maxYaml = raw['max_yaml_packages'];
160
+ if (typeof maxBytes !== 'number' || !Number.isInteger(maxBytes) || maxBytes <= 0) {
161
+ throw new Error(`${BUDGET_REL}: max_bytes must be a positive integer, got ${JSON.stringify(maxBytes)}`);
162
+ }
163
+ if (typeof maxYaml !== 'number' || !Number.isInteger(maxYaml) || maxYaml < 1) {
164
+ throw new Error(
165
+ `${BUDGET_REL}: max_yaml_packages must be an integer >= 1, got ${JSON.stringify(maxYaml)}`,
166
+ );
167
+ }
168
+ return { maxBytes, maxYamlPackages: maxYaml };
169
+ }
170
+
171
+ /** Findings, one line each. Empty means within budget. */
172
+ export function verdict(a: Analysis, budget: Budget): string[] {
173
+ const findings: string[] = [];
174
+ if (a.yamlPackages.length > budget.maxYamlPackages) {
175
+ const detail = a.yamlPackages
176
+ .map((p) => `${p} (${String(a.packageBytes.get(p) ?? 0)} B)`)
177
+ .join(', ');
178
+ findings.push(
179
+ `${String(a.yamlPackages.length)} YAML readers in the bundle, cap is ` +
180
+ `${String(budget.maxYamlPackages)}: ${detail}. Every dispatch loads all of them. ` +
181
+ 'Move the odd caller onto the reader the dispatcher already uses.',
182
+ );
183
+ }
184
+ if (a.bytes > budget.maxBytes) {
185
+ findings.push(
186
+ `bundle is ${String(a.bytes)} bytes, ceiling is ${String(budget.maxBytes)} ` +
187
+ `(over by ${String(a.bytes - budget.maxBytes)}). Shrink the bundle, or raise ` +
188
+ `max_bytes in ${BUDGET_REL} WITH an entry in its raise_log naming what was added.`,
189
+ );
190
+ }
191
+ return findings;
192
+ }
193
+
194
+ /**
195
+ * The raise rule, enforced against the base revision.
196
+ *
197
+ * `road-to-a-ratification-fence-that-follows-its-imports` 3.2. The budget's
198
+ * `shrink_only_note` used to say a raise needs a `raise_log` entry and that
199
+ * "the gate prints the rule but cannot enforce it, because a raise and a
200
+ * lowering are the same edit to a number". Against the base revision they are
201
+ * not: a working `max_bytes` above the base's is a raise, and it passes only if
202
+ * `raise_log` gained an entry — one absent from the base's log — whose `to`
203
+ * equals the new ceiling. A lowering needs nothing. The comparison is the
204
+ * merged value against the base, because that is what ships; a ceiling raised
205
+ * and lowered inside one branch is judged by where it ends.
206
+ *
207
+ * `baseRaw` is the base revision's budget file, or `null` when it has none
208
+ * (the registration diff), which is not a raise.
209
+ */
210
+ export function raiseFindings(baseRaw: string | null, workingRaw: string): string[] {
211
+ if (baseRaw === null) {
212
+ return [];
213
+ }
214
+ const base = JSON.parse(baseRaw) as Record<string, unknown>;
215
+ const working = JSON.parse(workingRaw) as Record<string, unknown>;
216
+ const baseMax = base['max_bytes'];
217
+ const workingMax = working['max_bytes'];
218
+ if (typeof baseMax !== 'number' || typeof workingMax !== 'number' || workingMax <= baseMax) {
219
+ return [];
220
+ }
221
+ const baseLog = Array.isArray(base['raise_log']) ? (base['raise_log'] as unknown[]) : [];
222
+ const workingLog = Array.isArray(working['raise_log']) ? (working['raise_log'] as unknown[]) : [];
223
+ const seen = new Set(baseLog.map((e) => JSON.stringify(e)));
224
+ const gained = workingLog.filter((e) => !seen.has(JSON.stringify(e)));
225
+ const matching = gained.find((e) => isRecord(e) && e['to'] === workingMax);
226
+ if (matching === undefined) {
227
+ return [
228
+ `max_bytes raised from ${String(baseMax)} to ${String(workingMax)} against the base revision ` +
229
+ `with no new raise_log entry whose \`to\` is ${String(workingMax)}. A raise needs a recorded ` +
230
+ `reason in ${BUDGET_REL}'s raise_log naming what was added and why it could not be avoided.`,
231
+ ];
232
+ }
233
+ const problems = raiseEntryProblems(matching as Record<string, unknown>, baseMax);
234
+ return problems.length === 0
235
+ ? []
236
+ : [`the raise_log entry for ${String(workingMax)} is incomplete: ${problems.join('; ')}.`];
237
+ }
238
+
239
+ function isRecord(v: unknown): v is Record<string, unknown> {
240
+ return typeof v === 'object' && v !== null && !Array.isArray(v);
241
+ }
242
+
243
+ /** The prose fields an entry must carry, matching the entry the log already holds. */
244
+ const RAISE_REASON_FIELDS = ['what_was_added', 'why_it_could_not_be_avoided'] as const;
245
+
246
+ /**
247
+ * What a raise entry must say. A bare `{ "to": N }` matched the first version
248
+ * of this rule, which a ratification reviewer refused on: a log entry with no
249
+ * reason is the empty log the rule exists to refuse, wearing a key.
250
+ */
251
+ export function raiseEntryProblems(entry: Record<string, unknown>, baseMax: number): string[] {
252
+ const problems: string[] = [];
253
+ if (entry['from'] !== baseMax) {
254
+ problems.push(`\`from\` must be the base ceiling ${String(baseMax)}`);
255
+ }
256
+ if (typeof entry['date'] !== 'string' || !/^\d{4}-\d{2}-\d{2}$/.test(entry['date'])) {
257
+ problems.push('`date` must be YYYY-MM-DD');
258
+ }
259
+ for (const field of RAISE_REASON_FIELDS) {
260
+ const v = entry[field];
261
+ if (typeof v !== 'string' || v.trim().length < 20) {
262
+ problems.push(`\`${field}\` must say what happened, in at least a sentence`);
263
+ }
264
+ }
265
+ return problems;
266
+ }
267
+
268
+ /** The base revision's budget file, `null` when absent there, `undefined` when no base resolves. */
269
+ function readBaseBudget(root: string, explicit: string | undefined): string | null | undefined {
270
+ const candidates = explicit !== undefined ? [explicit] : ['origin/main', 'main'];
271
+ for (const ref of candidates) {
272
+ const ok = spawnSync('git', ['rev-parse', '--verify', '--quiet', ref], {
273
+ cwd: root,
274
+ stdio: ['ignore', 'ignore', 'ignore'],
275
+ });
276
+ if (ok.status !== 0) continue;
277
+ const shown = spawnSync('git', ['show', `${ref}:${BUDGET_REL}`], { cwd: root, encoding: 'utf-8' });
278
+ return shown.status === 0 ? shown.stdout : null;
279
+ }
280
+ return undefined;
281
+ }
282
+
283
+ /**
284
+ * Build the hook bundle to a throwaway path and return its metafile JSON.
285
+ *
286
+ * Throws on any failure rather than returning a sentinel: a composition read off
287
+ * a build that did not happen is the silent-green this gate exists to replace.
288
+ */
289
+ export function buildMetafile(root: string): string {
290
+ const script = buildScript(root);
291
+ if (script === null) {
292
+ throw new Error('package.json has no `build:hooks` script — refusing to guess the flag set');
293
+ }
294
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'hook-bundle-composition-'));
295
+ const outFile = path.join(dir, 'dispatch.js');
296
+ const metaFile = path.join(dir, 'meta.json');
297
+ try {
298
+ const rewritten = rewriteOutfile(script, outFile);
299
+ if (rewritten === null) {
300
+ throw new Error(`\`build:hooks\` no longer writes ${LIVE_REL} — refusing to build to a guessed path`);
301
+ }
302
+ // Strip the digest sidecar step: it would write `dispatch.sha256` beside
303
+ // a probe bundle nobody executes, and on failure it would mask the build
304
+ // error with a file-not-found.
305
+ const esbuildOnly = rewritten.split('&& node ')[0] ?? rewritten;
306
+ const built = spawnSync('sh', ['-c', `${esbuildOnly.trim()} --metafile=${metaFile}`], {
307
+ cwd: root,
308
+ encoding: 'utf-8',
309
+ maxBuffer: 64 * 1024 * 1024,
310
+ env: {
311
+ ...process.env,
312
+ PATH: `${path.join(root, 'node_modules', '.bin')}:${process.env['PATH'] ?? ''}`,
313
+ },
314
+ });
315
+ if (built.status !== 0 || !fs.existsSync(metaFile)) {
316
+ throw new Error(`esbuild failed (exit ${String(built.status)})\n${built.stderr ?? ''}`);
317
+ }
318
+ return fs.readFileSync(metaFile, 'utf-8');
319
+ } finally {
320
+ fs.rmSync(dir, { recursive: true, force: true });
321
+ }
322
+ }
323
+
324
+ function selfTest(): number {
325
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'hook-bundle-composition-selftest-'));
326
+ const write = (name: string, body: unknown): string => {
327
+ const p = path.join(dir, name);
328
+ fs.writeFileSync(p, JSON.stringify(body));
329
+ return p;
330
+ };
331
+ const meta = (bytes: number, inputs: Record<string, number>): unknown => ({
332
+ inputs: {},
333
+ outputs: {
334
+ 'dist/hooks/dispatch.js': {
335
+ entryPoint: 'src/scripts/hooks/dispatch_entry.ts',
336
+ bytes,
337
+ inputs: Object.fromEntries(
338
+ Object.entries(inputs).map(([k, v]) => [k, { bytesInOutput: v }]),
339
+ ),
340
+ },
341
+ },
342
+ });
343
+ const budget = readBudget(REPO_ROOT);
344
+ const clean = write('clean.json', meta(budget.maxBytes, { 'node_modules/yaml/dist/index.js': 10 }));
345
+ const twoReaders = write(
346
+ 'two-readers.json',
347
+ meta(1000, {
348
+ 'node_modules/yaml/dist/index.js': 600,
349
+ 'node_modules/js-yaml/dist/js-yaml.mjs': 400,
350
+ }),
351
+ );
352
+ const oneOver = write('one-over.json', meta(budget.maxBytes + 1, { 'src/x.ts': 1 }));
353
+ const empty = write('empty.json', { inputs: {}, outputs: {} });
354
+
355
+ const drive = (fixture: string): number =>
356
+ runGateCli(REPO_ROOT, SELF_REL, ['--metafile', fixture], REPO_ROOT);
357
+
358
+ try {
359
+ return runSelfTest({
360
+ gate: 'check_hook_bundle_composition',
361
+ minCases: 4,
362
+ minRejectCases: 3,
363
+ cases: [
364
+ {
365
+ name: 'one YAML reader, exactly at the ceiling → accepted',
366
+ expect: 'accept',
367
+ run: () => drive(clean),
368
+ },
369
+ {
370
+ name: 'a second YAML reader → rejected',
371
+ expect: 'reject',
372
+ run: () => drive(twoReaders),
373
+ },
374
+ {
375
+ name: 'one byte over the ceiling → rejected',
376
+ expect: 'reject',
377
+ run: () => drive(oneOver),
378
+ },
379
+ {
380
+ name: 'a metafile with no entry-point output → rejected, never reported as 0 bytes',
381
+ expect: 'reject',
382
+ run: () => drive(empty),
383
+ },
384
+ ],
385
+ });
386
+ } finally {
387
+ fs.rmSync(dir, { recursive: true, force: true });
388
+ }
389
+ }
390
+
391
+ export function main(argv: readonly string[] = process.argv.slice(2), root: string = REPO_ROOT): number {
392
+ if (argv.includes('--self-test')) {
393
+ return selfTest();
394
+ }
395
+ const at = argv.indexOf('--metafile');
396
+ const fixture = at >= 0 ? argv[at + 1] : undefined;
397
+
398
+ let budget: Budget;
399
+ try {
400
+ budget = readBudget(root);
401
+ } catch (e) {
402
+ process.stderr.write(`check_hook_bundle_composition: ${String(e instanceof Error ? e.message : e)}\n`);
403
+ return 2;
404
+ }
405
+
406
+ let json: string;
407
+ try {
408
+ json = fixture === undefined ? buildMetafile(root) : fs.readFileSync(fixture, 'utf-8');
409
+ } catch (e) {
410
+ process.stderr.write(`check_hook_bundle_composition: ${String(e instanceof Error ? e.message : e)}\n`);
411
+ return 2;
412
+ }
413
+
414
+ let analysis: Analysis;
415
+ try {
416
+ analysis = analyzeMetafile(json);
417
+ } catch (e) {
418
+ process.stderr.write(`check_hook_bundle_composition: ${String(e instanceof Error ? e.message : e)}\n`);
419
+ return 1;
420
+ }
421
+
422
+ const findings = verdict(analysis, budget);
423
+ const baseAt = argv.indexOf('--base-ref');
424
+ const baseBudget = readBaseBudget(root, baseAt >= 0 ? argv[baseAt + 1] : undefined);
425
+ if (baseBudget === undefined) {
426
+ // In CI an unresolvable base is a broken checkout, not a registration
427
+ // diff: refusing there is the difference between a rule and a notice.
428
+ // Locally a missing base is ordinary (a fresh clone without origin), so
429
+ // it is said rather than failed.
430
+ if (process.env['GITHUB_ACTIONS'] === 'true') {
431
+ process.stderr.write(
432
+ 'check_hook_bundle_composition: no base revision resolved in CI — the max_bytes raise ' +
433
+ 'rule cannot be evaluated, and this gate fails closed rather than skip it\n',
434
+ );
435
+ return 2;
436
+ }
437
+ process.stdout.write('raise rule: no base revision resolved — the max_bytes raise check was not evaluated\n');
438
+ } else {
439
+ findings.push(...raiseFindings(baseBudget, fs.readFileSync(path.join(root, BUDGET_REL), 'utf-8')));
440
+ }
441
+ // Reported on BOTH paths, red included: a census that goes quiet exactly
442
+ // when the gate fires is the shape `reportScanned` exists to prevent.
443
+ reportScanned({
444
+ gate: 'check_hook_bundle_composition',
445
+ scanned: analysis.modules,
446
+ units: 'bundled module(s)',
447
+ roots: [LIVE_REL],
448
+ });
449
+
450
+ if (findings.length === 0) {
451
+ process.stdout.write(
452
+ `✅ hook bundle: ${String(analysis.bytes)} B / ${String(budget.maxBytes)} B ceiling, ` +
453
+ `${String(analysis.yamlPackages.length)} YAML reader(s) ` +
454
+ `[${analysis.yamlPackages.join(', ')}], ${String(analysis.modules)} modules\n`,
455
+ );
456
+ return 0;
457
+ }
458
+ process.stderr.write('❌ hook bundle composition is out of budget\n');
459
+ for (const f of findings) process.stderr.write(` - ${f}\n`);
460
+ process.stderr.write(` Budget: ${BUDGET_REL}\n`);
461
+ return 1;
462
+ }
463
+
464
+ function _isCliEntry(): boolean {
465
+ const argv1 = process.argv[1];
466
+ if (argv1 === undefined) return false;
467
+ if (import.meta.url === pathToFileURL(path.resolve(argv1)).href) return true;
468
+ try {
469
+ return fs.realpathSync(fileURLToPath(import.meta.url)) === fs.realpathSync(path.resolve(argv1));
470
+ } catch {
471
+ return false;
472
+ }
473
+ }
474
+
475
+ if (_isCliEntry()) {
476
+ process.exit(main());
477
+ }
@@ -30,12 +30,16 @@
30
30
  *
31
31
  * Gated: a diff touching a kernel rule under `src/rules/` (the nine of
32
32
  * `_lib/kernel_rules.ts`), a governance hook (`src/scripts/hooks/block_*.ts`),
33
- * a hook-plumbing SOURCE (`hook_manifest.yaml`, `host_lowering.yaml`, a
34
- * `*-dispatcher.sh`, either hook budget file — see `PLUMBING_SOURCE_RE`),
35
- * or this gate itself — so it cannot be weakened without its own record. Such
36
- * a diff must carry a ratification artifact under
37
- * the ratifications directory with `verdict: ratified`, valid per the
38
- * ratification-artifact contract.
33
+ * hook plumbing — the YAML sources `hook_manifest.yaml` and
34
+ * `host_lowering.yaml`, their compiled siblings `hook_manifest.json` and
35
+ * `host_lowering.json`, the dispatcher `hooks/dispatch_hook.ts`, the
36
+ * kernel-rule list `_lib/kernel_rules.ts`, a `*-dispatcher.sh`, the token,
37
+ * latency and bundle budget files (see `PLUMBING_SOURCE_RE`), and every module
38
+ * the dispatcher imports that decides an exit code (derived at run time, see
39
+ * `derivedPlumbing`) — or this gate itself, so it cannot
40
+ * be weakened without its own record. Such a diff must carry a ratification
41
+ * artifact under the ratifications directory with `verdict: ratified`, valid
42
+ * per the ratification-artifact contract.
39
43
  *
40
44
  * Every kernel diff is gated, not only the authority-EXPANDING ones.
41
45
  * ADR-268 § 4 makes the artifact required for authority-expanding edits. Which
@@ -71,6 +75,7 @@ import * as path from 'node:path';
71
75
  import { fileURLToPath, pathToFileURL } from 'node:url';
72
76
 
73
77
  import { GateLedger } from './_lib/gate_ledger.js';
78
+ import { dispatchImportClosure, verdictModules } from './_lib/dispatch_import_closure.js';
74
79
  import { is_kernel_rule } from './_lib/kernel_rules.js';
75
80
  import { reportScanned } from './_lib/scan_scope.js';
76
81
  import {
@@ -90,6 +95,13 @@ export const SELF_PATH = 'src/scripts/check_kernel_edit_ratified.ts';
90
95
  /** The reader this gate shares with the artifact contract, also self-watched. */
91
96
  export const READER_PATH = 'src/scripts/_lib/ratification_artifact.ts';
92
97
 
98
+ /**
99
+ * The reader that derives the dispatcher's verdict-deciding imports. It decides
100
+ * part of this gate's reach, so narrowing it is narrowing the gate — watched as
101
+ * part of the mechanism for the reason `READER_PATH` is.
102
+ */
103
+ export const CLOSURE_READER_PATH = 'src/scripts/_lib/dispatch_import_closure.ts';
104
+
93
105
  /** The in-repo quorum policy. Present on every runner; absent means refuse. */
94
106
  export const POLICY_PATH = 'src/config/ratification-policy.json';
95
107
 
@@ -141,13 +153,109 @@ const GOVERNANCE_HOOK_RE = /^src\/scripts\/hooks\/block_[a-z0-9_]+\.ts$/;
141
153
  * and every property the gate already had — base-revision code, in-repo quorum
142
154
  * policy, the whole diff as its unit — carries over unchanged.
143
155
  *
144
- * Sources only. `dist/hooks/dispatch.js` and `hooks/hooks.json` are BUILD
145
- * OUTPUTS with no legitimate hand edit at all, so they are refused at tool-call
146
- * time by `block_plumbing_writes.ts` rather than ratified here — a record for a
147
- * file whose every hand edit is illegitimate would be a record of a mistake.
156
+ * `dist/hooks/dispatch.js` and `hooks/hooks.json` are BUILD OUTPUTS that no
157
+ * reader in this repository opens — they exist only inside an installed
158
+ * consumer tree — and they have no legitimate hand edit at all, so they are
159
+ * refused at tool-call time by `block_plumbing_writes.ts` rather than ratified
160
+ * here: a record for a file whose every hand edit is illegitimate would be a
161
+ * record of a mistake.
162
+ *
163
+ * road-to-blocking-severities 2.1 WIDENS this from "sources only" to
164
+ * "everything the dispatcher serves at runtime", and the distinction above is
165
+ * why the two compiled tables land here while the two build outputs do not.
166
+ * `src/scripts/hook_manifest.json` and `src/scripts/hooks/host_lowering.json`
167
+ * are committed in THIS tree and are READ IN PREFERENCE to the YAML they were
168
+ * compiled from — `dispatch_hook._load_yaml` and `host_lowering.resolveTable`
169
+ * both serve the compiled body whenever its fingerprint matches. A diff that
170
+ * edits only the JSON therefore changes what every host is told about which
171
+ * concern runs and which slot can refuse, while the gated YAML beside it is
172
+ * untouched. That is the same authority change as editing the source, reached
173
+ * one file later, and before this step it carried no record.
174
+ *
175
+ * Two further files join for the same reason rather than by analogy:
176
+ *
177
+ * - `src/scripts/hooks/dispatch_hook.ts` is the dispatcher itself. Every
178
+ * concern's verdict passes through it, so an edit here can suppress a
179
+ * refusal without touching the manifest that declares it.
180
+ * - `src/scripts/_lib/kernel_rules.ts` is the list of the nine kernel rules.
181
+ * THIS GATE resolves `is_kernel_rule` through it, so a diff removing a name
182
+ * from that list removes a rule from this gate's own reach — the one edit
183
+ * that could quietly narrow the gate while every other path kept working.
184
+ *
185
+ * Both are also denied at tool-call time, `dispatch_hook.ts` through the
186
+ * plumbing guard's source set and `kernel_rules.ts` through the kernel-rule
187
+ * write guard, so the pairing of deny-plus-record matches what the YAML sources
188
+ * already had.
189
+ *
190
+ * The compiled tables are REGENERATED, not hand-edited, by
191
+ * `./scripts-run src/scripts/compile_hook_manifest --table manifest|host-lowering`,
192
+ * which runs as a script rather than as an edit tool call and so is not what
193
+ * either mechanism refuses. A regeneration lands in the same diff as the YAML
194
+ * change that caused it, which already requires a record; the case this closes
195
+ * is the diff where only the JSON moves.
148
196
  */
149
197
  const PLUMBING_SOURCE_RE =
150
- /^(?:src\/scripts\/hook_manifest\.yaml|src\/scripts\/hooks\/host_lowering\.yaml|src\/scripts\/hooks\/[a-z0-9-]+-dispatcher\.sh|src\/config\/hook-(?:token|latency)-budget\.json)$/;
198
+ /^(?:src\/scripts\/hook_manifest\.(?:yaml|json)|src\/scripts\/hooks\/host_lowering\.(?:yaml|json)|src\/scripts\/hooks\/dispatch_hook\.ts|src\/scripts\/_lib\/kernel_rules\.ts|src\/scripts\/hooks\/[a-z0-9-]+-dispatcher\.sh|src\/config\/hook-(?:token|latency|bundle)-budget\.json)$/;
199
+
200
+ /**
201
+ * The derived half of the plumbing set: every module in the static import
202
+ * closure of `dispatch_hook.ts` that decides an exit code or a refusal, read by
203
+ * `_lib/dispatch_import_closure.ts`.
204
+ *
205
+ * `road-to-a-ratification-fence-that-follows-its-imports` 2.2. The pattern
206
+ * above stayed correct until `_resolve_execution_failure` moved from the
207
+ * dispatcher into `concern_failure_policy.ts` — release finding `21900086c1a0`:
208
+ * a diff deciding whether a crashed blocking concern refuses then carried no
209
+ * record. A hand list fails the same way the next time a function moves, so
210
+ * this half is computed from the import graph at run time, and a module the
211
+ * dispatcher newly imports that names an exit code joins it with no edit here.
212
+ * Concerns stay outside: the walk stops at the concern table, and a governance
213
+ * concern is already gated by `GOVERNANCE_HOOK_RE`.
214
+ *
215
+ * `hook-bundle-budget.json` joins the pattern for D3: its ceiling was raised on
216
+ * its own registration day, and a raised ceiling is a looser budget reached one
217
+ * file earlier than the bundle it bounds.
218
+ */
219
+ let _repoDerived: readonly string[] | null = null;
220
+ export function derivedPlumbing(root: string = REPO): readonly string[] {
221
+ if (root === REPO) {
222
+ _repoDerived ??= verdictModules(REPO);
223
+ return _repoDerived;
224
+ }
225
+ return verdictModules(root);
226
+ }
227
+
228
+ /**
229
+ * Modules that ARRIVE in the dispatcher's closure: non-concern modules present
230
+ * in the closure under `root` and absent from the closure under `baseRoot`.
231
+ *
232
+ * The classifier reads names, so a verdict-deciding module with neutral names
233
+ * (`acceptsExecution(): boolean`, no exit constant) reads as `payload` or
234
+ * `neither` — the gap the first ratification round of this change refused it
235
+ * on. A name-based classifier cannot close that gap; what can is watching the
236
+ * one moment such a module becomes reachable. So any module newly reachable
237
+ * from the dispatcher is gated on the diff that makes it reachable, whatever
238
+ * its class, and a reviewer reads it once. Modules already in the base closure
239
+ * are judged by class, so routine edits to a payload helper stay record-free.
240
+ *
241
+ * The other direction needs no extra rule: a module the base classes as
242
+ * `verdict` stays watched through the union in `evaluate` even when the head
243
+ * strips the names that classed it, so declassifying one is itself a gated
244
+ * edit of it.
245
+ *
246
+ * Meaningful only where the two trees differ — in CI, where the gate's code is
247
+ * the base revision's and `root` is the head. A local run with `root` equal to
248
+ * the gate's own tree sees no arrivals, and says nothing it cannot measure.
249
+ */
250
+ export function closureArrivals(root: string, baseRoot: string = REPO): string[] {
251
+ if (path.resolve(root) === path.resolve(baseRoot)) {
252
+ return [];
253
+ }
254
+ const base = new Set(dispatchImportClosure(baseRoot).map((e) => e.path));
255
+ return dispatchImportClosure(root)
256
+ .filter((e) => e.class !== 'concern' && !base.has(e.path))
257
+ .map((e) => e.path);
258
+ }
151
259
 
152
260
  /**
153
261
  * A kernel rule, in the source tree or in any projection.
@@ -174,7 +282,11 @@ export interface GatedPaths {
174
282
  }
175
283
 
176
284
  /** Partition a changed-file list into the surfaces this gate watches. */
177
- export function classifyPaths(files: readonly string[]): GatedPaths {
285
+ export function classifyPaths(
286
+ files: readonly string[],
287
+ derived: readonly string[] = derivedPlumbing(),
288
+ ): GatedPaths {
289
+ const derivedSet = new Set(derived);
178
290
  const kernelRules: string[] = [];
179
291
  const governanceHooks: string[] = [];
180
292
  const plumbing: string[] = [];
@@ -187,6 +299,7 @@ export function classifyPaths(files: readonly string[]): GatedPaths {
187
299
  if (
188
300
  p === SELF_PATH ||
189
301
  p === READER_PATH ||
302
+ p === CLOSURE_READER_PATH ||
190
303
  p === POLICY_PATH ||
191
304
  p === WORKFLOW_PATH ||
192
305
  ANCHOR_PATHS.includes(p)
@@ -203,7 +316,7 @@ export function classifyPaths(files: readonly string[]): GatedPaths {
203
316
  governanceHooks.push(p);
204
317
  continue;
205
318
  }
206
- if (PLUMBING_SOURCE_RE.test(p)) {
319
+ if (PLUMBING_SOURCE_RE.test(p) || derivedSet.has(p)) {
207
320
  plumbing.push(p);
208
321
  }
209
322
  }
@@ -281,7 +394,12 @@ export function evaluate(
281
394
  providerCount: number | null,
282
395
  ): GateResult {
283
396
  const lines: string[] = [];
284
- const gated = classifyPaths(files);
397
+ // The union of the closure read from the tree under review and from this
398
+ // script's own tree: under CI the gate code is the base revision's and
399
+ // `root` is the head, so a module present on either side is watched.
400
+ const gated = classifyPaths(files, [
401
+ ...new Set([...derivedPlumbing(), ...derivedPlumbing(root), ...closureArrivals(root)]),
402
+ ]);
285
403
  const scanned = files.length;
286
404
 
287
405
  // Every changed path is a planned target: the gate's denominator is the