@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,647 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * lint_rule_law_section — every routed rule states its law in one section short
4
+ * enough to stand on its own.
5
+ *
6
+ * THE DEFECT. Measured 2026-10-01 over `dist/router.json`'s 106 tier rules:
7
+ * 71 carry a heading matching `Iron Law`, 35 do not — among them
8
+ * `runtime-safety` and `tool-safety`, which govern tool grants and execution
9
+ * handlers. Several of the 35 state a law in bold text or a bare fence instead,
10
+ * so 35 is an upper bound on what is genuinely missing, not a count of
11
+ * lawless rules. Nothing asserted either way: law sections were an authoring
12
+ * habit, never a state.
13
+ *
14
+ * That matters now because `project_thin_rules` ships a class of rules as a
15
+ * stub plus their own law section. A rule with no law section cannot be in that
16
+ * class, and a rule whose law section is 5,387 characters defeats the point of
17
+ * a stub. This gate holds three lines so the projector can rely on them.
18
+ *
19
+ * WHAT IT ASSERTS, three axes, each with its own ratchet:
20
+ *
21
+ * 1. PRESENCE (`--axis presence`). Every routed tier rule has a law section, or
22
+ * is named in the `missing` baseline. SHRINK-ONLY: an id may leave that list
23
+ * freely, and a routed rule that is not on it and has no law section fails.
24
+ * A NEW routed rule therefore cannot be born lawless.
25
+ *
26
+ * 2. LAW CEILING (`--axis ceiling`). Target 1,200 characters, REPORTED and
27
+ * never failing; hard 2,000, failing. A rule over the hard ceiling today is
28
+ * named in `law_exceptions` with an owner and a review date, and may only
29
+ * shrink — its recorded size is a ceiling, not a licence.
30
+ *
31
+ * 3. BODY CEILING (`--axis body-ceiling`). 8,000 characters of
32
+ * comment-stripped body, the unit a full runtime delivery carries, so it is
33
+ * priced in the same unit the installed-layer report uses. Today's larger
34
+ * rules are named in `body_exceptions`, shrink-only on the same terms.
35
+ *
36
+ * 4. TRIGGER PRESENCE (`--axis trigger`). Added by step 3.4 of
37
+ * `road-to-an-installed-layer-that-is-thinned`: a stub is a pointer a prompt
38
+ * must be able to pull in, so a routed rule with ZERO triggers in
39
+ * `dist/router.json` cannot be discovered once it ships as a stub — the
40
+ * pointer sits in the installed layer forever and the law behind it never
41
+ * arrives. Four rules read zero today (measured 2026-10-06) and are named in
42
+ * `no_trigger`, SHRINK-ONLY on the same terms as `missing`: each is delivered
43
+ * by a mechanism other than a keyword match — a path collision
44
+ * (`collision_ok`) or an unconditional load with no scoping at all — which is
45
+ * a deliberate routing choice recorded in the rule's own frontmatter, not an
46
+ * oversight this gate should paper over. A NEW routed rule therefore cannot
47
+ * be born with no trigger a prompt can fire, same as it cannot be born
48
+ * lawless.
49
+ *
50
+ * WHY THE TARGET IS REPORTED AND NOT ENFORCED. A rule shortened to fit a number
51
+ * is the failure this roadmap says it will not cause. 1,200 is where the
52
+ * distribution sits (median 511, p90 1,787) and a rule between target and hard
53
+ * ceiling is a rule to look at, not a rule to cut. Only 2,000 — above p90, so
54
+ * no rule is truncated by it — refuses.
55
+ *
56
+ * WHY SCOPED TO TIER RULES. "Routed" means present in `router.json`'s `tier_1`
57
+ * or `tier_2`. The nine kernel rules are excluded and the exclusion is a fact
58
+ * about this repository, not a judgement: kernel rule files are agent-write-
59
+ * denied, and two of them (`agent-authority`, `scope-control`) carry no Iron-Law
60
+ * heading today, so a gate that included them would be a gate no agent could
61
+ * ever make green. They are counted and printed under `kernel (reported)` so
62
+ * the exclusion is visible rather than silent, and `project_thin_rules` keeps
63
+ * the kernel full-bodied anyway — it never ships a kernel stub, so the stub-law
64
+ * question does not arise there.
65
+ *
66
+ * WHAT IT DOES NOT ASSERT. Not that the extracted section is the rule's real
67
+ * obligation — a heading match is structural and checkable, "this sentence is
68
+ * the obligation" is not; the ids in `src/config/rule-obligations.json` and
69
+ * `report_obligation_carriers` own that. Not that a rule at its recorded
70
+ * exception is correct, only that it is not worse. And not a cross-commit
71
+ * ratchet: this gate reads one tree, so "shrink-only" means the tree sits at or
72
+ * under what is committed, and a silently LOWERED baseline is a question the
73
+ * diff answers, not this gate. Saying so is the point.
74
+ *
75
+ * Exit codes: 0 clean, 1 violations, 2 usage error, 3 internal error.
76
+ */
77
+ import * as fs from 'node:fs';
78
+ import * as os from 'node:os';
79
+ import * as path from 'node:path';
80
+ import process from 'node:process';
81
+ import { fileURLToPath, pathToFileURL } from 'node:url';
82
+
83
+ import { asOf } from './_lib/as_of.js';
84
+ import { measureRuleFile, type RuleLawMeasure } from './_lib/rule_law_section.js';
85
+ import { DeadScopeError, reportScanned } from './_lib/scan_scope.js';
86
+
87
+ const _HERE = fileURLToPath(import.meta.url);
88
+ export const REPO_ROOT = path.resolve(path.dirname(_HERE), '..', '..');
89
+
90
+ export const CONFIG_REL = 'src/config/rule-law-ceilings.json';
91
+ export const RULES_REL = 'src/rules';
92
+ export const ROUTER_REL = 'dist/router.json';
93
+
94
+ /** Reported, never failing — a rule above it is a rule to look at. */
95
+ export const LAW_TARGET_CHARS = 1_200;
96
+ /** Refused. Above p90, so no rule in the distribution is truncated by it. */
97
+ export const LAW_HARD_CHARS = 2_000;
98
+ /** Refused. The unit a full runtime delivery carries. */
99
+ export const BODY_HARD_CHARS = 8_000;
100
+
101
+ export interface SizeException {
102
+ /** Recorded size at adoption. The rule may sit at or under it, never above. */
103
+ chars: number;
104
+ /** Who answers for this rule staying oversized. */
105
+ owner: string;
106
+ /** `YYYY-MM-DD` the exception is due for review. */
107
+ review: string;
108
+ /** Why this rule cannot state its law under the ceiling today. */
109
+ reason: string;
110
+ }
111
+
112
+ export interface LawConfig {
113
+ _comment?: string;
114
+ measured_at_commit?: string;
115
+ /** Routed rules with no law section. Shrink-only: ids may leave, never join. */
116
+ missing: string[];
117
+ /** Routed rules with no trigger a prompt can fire. Shrink-only, same terms as `missing`. */
118
+ no_trigger: string[];
119
+ /** Rules whose law exceeds {@link LAW_HARD_CHARS}. */
120
+ law_exceptions: Record<string, SizeException>;
121
+ /** Rules whose body exceeds {@link BODY_HARD_CHARS}. */
122
+ body_exceptions: Record<string, SizeException>;
123
+ }
124
+
125
+ export type Axis = 'presence' | 'ceiling' | 'body-ceiling' | 'trigger' | 'all';
126
+
127
+ export interface Finding {
128
+ id: string;
129
+ axis: Exclude<Axis, 'all'>;
130
+ kind: string;
131
+ detail: string;
132
+ }
133
+
134
+ export interface LintResult {
135
+ findings: Finding[];
136
+ /** Rules at or above the soft target but under the hard ceiling. */
137
+ overTarget: Array<{ id: string; chars: number }>;
138
+ measures: RuleLawMeasure[];
139
+ kernelReported: Array<{ id: string; sections: number }>;
140
+ scanned: number;
141
+ }
142
+
143
+ /** Routed tier rule ids, sorted — `tier_1` + `tier_2`, kernel excluded. */
144
+ export function routedRuleIds(root = REPO_ROOT): string[] {
145
+ const data = JSON.parse(fs.readFileSync(path.join(root, ROUTER_REL), 'utf-8')) as Record<
146
+ string,
147
+ unknown
148
+ >;
149
+ const ids: string[] = [];
150
+ for (const tier of ['tier_1', 'tier_2']) {
151
+ const entries = data[tier];
152
+ if (!Array.isArray(entries)) continue;
153
+ for (const e of entries) ids.push(String((e as Record<string, unknown>).id));
154
+ }
155
+ return [...new Set(ids)].sort();
156
+ }
157
+
158
+ export function kernelRuleIds(root = REPO_ROOT): string[] {
159
+ const data = JSON.parse(fs.readFileSync(path.join(root, ROUTER_REL), 'utf-8')) as Record<
160
+ string,
161
+ unknown
162
+ >;
163
+ const kernel = data.kernel;
164
+ return Array.isArray(kernel) ? kernel.map((x) => String(x)).sort() : [];
165
+ }
166
+
167
+ export function readConfig(root = REPO_ROOT): LawConfig {
168
+ const p = path.join(root, CONFIG_REL);
169
+ const raw = JSON.parse(fs.readFileSync(p, 'utf-8')) as Partial<LawConfig>;
170
+ return {
171
+ missing: Array.isArray(raw.missing) ? raw.missing : [],
172
+ no_trigger: Array.isArray(raw.no_trigger) ? raw.no_trigger : [],
173
+ law_exceptions: raw.law_exceptions ?? {},
174
+ body_exceptions: raw.body_exceptions ?? {},
175
+ measured_at_commit: raw.measured_at_commit ?? '',
176
+ };
177
+ }
178
+
179
+ /** Measure every routed rule that has a file. */
180
+ export function measureRouted(root = REPO_ROOT): RuleLawMeasure[] {
181
+ const out: RuleLawMeasure[] = [];
182
+ for (const id of routedRuleIds(root)) {
183
+ const p = path.join(root, RULES_REL, `${id}.md`);
184
+ if (!fs.existsSync(p)) continue;
185
+ out.push(measureRuleFile(id, p));
186
+ }
187
+ return out;
188
+ }
189
+
190
+ /** Trigger count per routed tier rule id, straight off `dist/router.json`. */
191
+ export function routedRuleTriggerCounts(root = REPO_ROOT): Map<string, number> {
192
+ const data = JSON.parse(fs.readFileSync(path.join(root, ROUTER_REL), 'utf-8')) as Record<
193
+ string,
194
+ unknown
195
+ >;
196
+ const counts = new Map<string, number>();
197
+ for (const tier of ['tier_1', 'tier_2']) {
198
+ const entries = data[tier];
199
+ if (!Array.isArray(entries)) continue;
200
+ for (const e of entries) {
201
+ const rec = e as Record<string, unknown>;
202
+ const triggers = rec['triggers'];
203
+ counts.set(String(rec['id']), Array.isArray(triggers) ? triggers.length : 0);
204
+ }
205
+ }
206
+ return counts;
207
+ }
208
+
209
+ export function lint(root = REPO_ROOT, axis: Axis = 'all'): LintResult {
210
+ const cfg = readConfig(root);
211
+ const measures = measureRouted(root);
212
+ const triggerCounts = routedRuleTriggerCounts(root);
213
+ const findings: Finding[] = [];
214
+ const overTarget: Array<{ id: string; chars: number }> = [];
215
+ const baselined = new Set(cfg.missing);
216
+ const noTriggerBaselined = new Set(cfg.no_trigger);
217
+ const want = (a: Exclude<Axis, 'all'>): boolean => axis === 'all' || axis === a;
218
+
219
+ for (const m of measures) {
220
+ if (want('trigger') && (triggerCounts.get(m.id) ?? 0) === 0 && !noTriggerBaselined.has(m.id)) {
221
+ findings.push({
222
+ id: m.id,
223
+ axis: 'trigger',
224
+ kind: 'no-trigger',
225
+ detail:
226
+ 'routed rule has no trigger in `dist/router.json` — a prompt can never pull it in, ' +
227
+ `so it cannot ship as a stub; add a trigger, or add the id to \`no_trigger\` in ` +
228
+ `${CONFIG_REL} (that list is shrink-only, so a new routed rule may not join it)`,
229
+ });
230
+ }
231
+ if (want('presence') && m.law === null && !baselined.has(m.id)) {
232
+ findings.push({
233
+ id: m.id,
234
+ axis: 'presence',
235
+ kind: 'no-law-section',
236
+ detail:
237
+ 'routed rule has no heading matching `Iron Law` — state the obligation under ' +
238
+ `one, or add the id to \`missing\` in ${CONFIG_REL} (that list is shrink-only, ` +
239
+ 'so a new routed rule may not join it)',
240
+ });
241
+ }
242
+ if (want('ceiling') && m.law !== null) {
243
+ const exc = cfg.law_exceptions[m.id];
244
+ if (exc === undefined) {
245
+ if (m.lawChars > LAW_HARD_CHARS) {
246
+ findings.push({
247
+ id: m.id,
248
+ axis: 'ceiling',
249
+ kind: 'law-over-hard-ceiling',
250
+ detail:
251
+ `law section is ${m.lawChars} chars, over the ${LAW_HARD_CHARS} hard ceiling — ` +
252
+ 'move the discussion under it behind `load_context`, or record a dated ' +
253
+ `exception with an owner in ${CONFIG_REL}`,
254
+ });
255
+ } else if (m.lawChars > LAW_TARGET_CHARS) {
256
+ overTarget.push({ id: m.id, chars: m.lawChars });
257
+ }
258
+ } else if (m.lawChars > exc.chars) {
259
+ findings.push({
260
+ id: m.id,
261
+ axis: 'ceiling',
262
+ kind: 'law-exception-grew',
263
+ detail:
264
+ `law section is ${m.lawChars} chars, above its recorded exception of ` +
265
+ `${exc.chars} (owner ${exc.owner}, review ${exc.review}) — an exception is ` +
266
+ 'a ceiling, not a licence; it may only shrink',
267
+ });
268
+ }
269
+ }
270
+ if (want('body-ceiling')) {
271
+ const exc = cfg.body_exceptions[m.id];
272
+ if (exc === undefined) {
273
+ if (m.bodyChars > BODY_HARD_CHARS) {
274
+ findings.push({
275
+ id: m.id,
276
+ axis: 'body-ceiling',
277
+ kind: 'body-over-hard-ceiling',
278
+ detail:
279
+ `body is ${m.bodyChars} chars, over the ${BODY_HARD_CHARS} hard ceiling — ` +
280
+ 'move history and mechanism discussion into a context file the rule names ' +
281
+ `in \`load_context\`, or record a dated exception in ${CONFIG_REL}`,
282
+ });
283
+ }
284
+ } else if (m.bodyChars > exc.chars) {
285
+ findings.push({
286
+ id: m.id,
287
+ axis: 'body-ceiling',
288
+ kind: 'body-exception-grew',
289
+ detail:
290
+ `body is ${m.bodyChars} chars, above its recorded exception of ${exc.chars} ` +
291
+ `(owner ${exc.owner}, review ${exc.review}) — it may only shrink`,
292
+ });
293
+ }
294
+ }
295
+ }
296
+
297
+ // A baseline entry for a rule that now HAS a law section is debt that was
298
+ // paid and never collected. Reported as a finding, because a stale
299
+ // suppression is how a ratchet hardens into configuration.
300
+ if (want('presence')) {
301
+ const haveLaw = new Set(measures.filter((m) => m.law !== null).map((m) => m.id));
302
+ const routed = new Set(measures.map((m) => m.id));
303
+ for (const id of cfg.missing) {
304
+ if (haveLaw.has(id)) {
305
+ findings.push({
306
+ id,
307
+ axis: 'presence',
308
+ kind: 'stale-baseline-entry',
309
+ detail: `now has a law section — remove it from \`missing\` in ${CONFIG_REL}`,
310
+ });
311
+ } else if (!routed.has(id)) {
312
+ findings.push({
313
+ id,
314
+ axis: 'presence',
315
+ kind: 'stale-baseline-entry',
316
+ detail: `is not a routed rule any more — remove it from \`missing\` in ${CONFIG_REL}`,
317
+ });
318
+ }
319
+ }
320
+ }
321
+
322
+ // Same stale-debt check for the trigger baseline: an id that gained a
323
+ // trigger, or left the routed set, is debt that was paid and never
324
+ // collected.
325
+ if (want('trigger')) {
326
+ const routed = new Set(measures.map((m) => m.id));
327
+ for (const id of cfg.no_trigger) {
328
+ if (!routed.has(id)) {
329
+ findings.push({
330
+ id,
331
+ axis: 'trigger',
332
+ kind: 'stale-baseline-entry',
333
+ detail: `is not a routed rule any more — remove it from \`no_trigger\` in ${CONFIG_REL}`,
334
+ });
335
+ } else if ((triggerCounts.get(id) ?? 0) > 0) {
336
+ findings.push({
337
+ id,
338
+ axis: 'trigger',
339
+ kind: 'stale-baseline-entry',
340
+ detail: `now has a trigger — remove it from \`no_trigger\` in ${CONFIG_REL}`,
341
+ });
342
+ }
343
+ }
344
+ }
345
+
346
+ const kernelReported = kernelRuleIds(root).map((id) => {
347
+ const p = path.join(root, RULES_REL, `${id}.md`);
348
+ return { id, sections: fs.existsSync(p) ? measureRuleFile(id, p).sections : 0 };
349
+ });
350
+
351
+ findings.sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : a.kind < b.kind ? -1 : 1));
352
+ overTarget.sort((a, b) => b.chars - a.chars);
353
+ return { findings, overTarget, measures, kernelReported, scanned: measures.length };
354
+ }
355
+
356
+ /** Rebuild the config from the current tree. Never raises an existing ceiling. */
357
+ export function writeBaseline(root = REPO_ROOT, today: string): string {
358
+ const prev = fs.existsSync(path.join(root, CONFIG_REL))
359
+ ? readConfig(root)
360
+ : { missing: [], no_trigger: [], law_exceptions: {}, body_exceptions: {} };
361
+ const measures = measureRouted(root);
362
+ const triggerCounts = routedRuleTriggerCounts(root);
363
+ const missing = measures.filter((m) => m.law === null).map((m) => m.id).sort();
364
+ const no_trigger = measures
365
+ .filter((m) => (triggerCounts.get(m.id) ?? 0) === 0)
366
+ .map((m) => m.id)
367
+ .sort();
368
+ const law_exceptions: Record<string, SizeException> = {};
369
+ const body_exceptions: Record<string, SizeException> = {};
370
+ for (const m of measures) {
371
+ if (m.law !== null && m.lawChars > LAW_HARD_CHARS) {
372
+ const old = prev.law_exceptions[m.id];
373
+ law_exceptions[m.id] = {
374
+ chars: old === undefined ? m.lawChars : Math.min(old.chars, m.lawChars),
375
+ owner: old?.owner ?? 'agent-config-maintainer',
376
+ review: old?.review ?? today,
377
+ reason: old?.reason ?? 'recorded at adoption; not yet reviewed',
378
+ };
379
+ }
380
+ if (m.bodyChars > BODY_HARD_CHARS) {
381
+ const old = prev.body_exceptions[m.id];
382
+ body_exceptions[m.id] = {
383
+ chars: old === undefined ? m.bodyChars : Math.min(old.chars, m.bodyChars),
384
+ owner: old?.owner ?? 'agent-config-maintainer',
385
+ review: old?.review ?? today,
386
+ reason: old?.reason ?? 'recorded at adoption; not yet reviewed',
387
+ };
388
+ }
389
+ }
390
+ const cfg = {
391
+ _comment:
392
+ 'Per-rule law-section and body ceilings (road-to-rule-laws-that-can-stand Phase 1) plus ' +
393
+ 'the trigger-presence baseline (road-to-an-installed-layer-that-is-thinned step 3.4). Two ' +
394
+ 'different guarantees, not one: `law_exceptions` and `body_exceptions` are numeric ' +
395
+ 'ceilings `--write-baseline` structurally refuses to raise (it re-records the SMALLER of ' +
396
+ 'old and current, never the current alone) — a rule at its exception is not thereby ' +
397
+ 'correct, only not worse. `missing` and `no_trigger` are LIST membership: an id SHOULD ' +
398
+ 'only leave, never join, but that is a review convention the generator does not enforce ' +
399
+ 'by construction — `--write-baseline` re-records every id that currently fails ' +
400
+ 'presence/trigger, full stop, so a newly-broken rule is swept in exactly like a ' +
401
+ 'genuinely-fixed one is swept out. The `stale-baseline-entry` finding makes a fixed id ' +
402
+ 'visible for removal; nothing makes a newly-broken id visible for refusal except a human ' +
403
+ 'reading the diff. Regenerate with `lint_rule_law_section --write-baseline`; never ' +
404
+ 'hand-edit the counts, but DO hand-edit `owner`, `review` and `reason` — those are the ' +
405
+ 'review contract and the generator only seeds them.',
406
+ measured_at_commit: prev.measured_at_commit ?? '',
407
+ no_trigger,
408
+ missing,
409
+ law_exceptions,
410
+ body_exceptions,
411
+ };
412
+ const text = JSON.stringify(cfg, null, 4) + '\n';
413
+ fs.writeFileSync(path.join(root, CONFIG_REL), text, 'utf-8');
414
+ return text;
415
+ }
416
+
417
+ interface Args {
418
+ axis: Axis;
419
+ quiet: boolean;
420
+ writeBaseline: boolean;
421
+ root: string;
422
+ selfTest: boolean;
423
+ }
424
+
425
+ const USAGE =
426
+ 'usage: lint_rule_law_section [--axis presence|ceiling|body-ceiling|trigger|all] [--quiet] ' +
427
+ '[--write-baseline] [--root DIR] [--self-test]\n';
428
+
429
+ function parseArgs(argv: string[]): Args {
430
+ const out: Args = { axis: 'all', quiet: false, writeBaseline: false, root: REPO_ROOT, selfTest: false };
431
+ for (let i = 0; i < argv.length; i += 1) {
432
+ const a = argv[i] as string;
433
+ if (a === '-h' || a === '--help') {
434
+ process.stdout.write(USAGE);
435
+ process.exit(0);
436
+ } else if (a === '--quiet') {
437
+ out.quiet = true;
438
+ } else if (a === '--write-baseline') {
439
+ out.writeBaseline = true;
440
+ } else if (a === '--self-test') {
441
+ out.selfTest = true;
442
+ } else if (a === '--axis') {
443
+ const v = argv[i + 1];
444
+ if (v === undefined) {
445
+ process.stderr.write(USAGE);
446
+ process.exit(2);
447
+ }
448
+ out.axis = v as Axis;
449
+ i += 1;
450
+ } else if (a.startsWith('--axis=')) {
451
+ out.axis = a.slice('--axis='.length) as Axis;
452
+ } else if (a === '--root') {
453
+ const v = argv[i + 1];
454
+ if (v === undefined) {
455
+ process.stderr.write(USAGE);
456
+ process.exit(2);
457
+ }
458
+ out.root = path.resolve(v);
459
+ i += 1;
460
+ } else if (a.startsWith('--root=')) {
461
+ out.root = path.resolve(a.slice('--root='.length));
462
+ } else {
463
+ process.stderr.write(USAGE);
464
+ process.stderr.write(`lint_rule_law_section: error: unrecognized argument: ${a}\n`);
465
+ process.exit(2);
466
+ }
467
+ }
468
+ if (!['presence', 'ceiling', 'body-ceiling', 'trigger', 'all'].includes(out.axis)) {
469
+ process.stderr.write(USAGE);
470
+ process.stderr.write(`lint_rule_law_section: error: unknown axis: ${out.axis}\n`);
471
+ process.exit(2);
472
+ }
473
+ return out;
474
+ }
475
+
476
+ /**
477
+ * Prove the gate's reading changes its verdict, not just that it read
478
+ * something. A `scanned:` floor says a corpus was inspected; only a rejecting
479
+ * case says the inspection decides anything.
480
+ */
481
+ export function selfTest(write: (s: string) => void = (s) => process.stdout.write(s)): number {
482
+ const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'law-selftest-'));
483
+ try {
484
+ fs.mkdirSync(path.join(tmp, 'src', 'rules'), { recursive: true });
485
+ fs.mkdirSync(path.join(tmp, 'src', 'config'), { recursive: true });
486
+ fs.mkdirSync(path.join(tmp, 'dist'), { recursive: true });
487
+ fs.writeFileSync(
488
+ path.join(tmp, ROUTER_REL),
489
+ JSON.stringify({
490
+ kernel: [],
491
+ tier_1: [
492
+ { id: 'lawless', triggers: [{ keyword: 'lawless-word' }] },
493
+ { id: 'lawful', triggers: [{ keyword: 'lawful-word' }] },
494
+ { id: 'mute', triggers: [] },
495
+ { id: 'vocal', triggers: [{ keyword: 'vocal-word' }] },
496
+ ],
497
+ tier_2: [],
498
+ }),
499
+ );
500
+ fs.writeFileSync(
501
+ path.join(tmp, CONFIG_REL),
502
+ JSON.stringify({ missing: [], no_trigger: [], law_exceptions: {}, body_exceptions: {} }),
503
+ );
504
+ fs.writeFileSync(path.join(tmp, 'src/rules/lawless.md'), '---\nx: 1\n---\n\n# Lawless\n\nProse.\n');
505
+ fs.writeFileSync(
506
+ path.join(tmp, 'src/rules/lawful.md'),
507
+ '---\nx: 1\n---\n\n# Lawful\n\n## The Iron Law\n\nNEVER DO THE THING.\n',
508
+ );
509
+ fs.writeFileSync(
510
+ path.join(tmp, 'src/rules/mute.md'),
511
+ '---\nx: 1\n---\n\n# Mute\n\n## The Iron Law\n\nNEVER DO THE THING.\n',
512
+ );
513
+ fs.writeFileSync(
514
+ path.join(tmp, 'src/rules/vocal.md'),
515
+ '---\nx: 1\n---\n\n# Vocal\n\n## The Iron Law\n\nNEVER DO THE THING.\n',
516
+ );
517
+
518
+ const rejecting = lint(tmp, 'presence');
519
+ const accepting = (() => {
520
+ fs.writeFileSync(
521
+ path.join(tmp, CONFIG_REL),
522
+ JSON.stringify({
523
+ missing: ['lawless'],
524
+ no_trigger: [],
525
+ law_exceptions: {},
526
+ body_exceptions: {},
527
+ }),
528
+ );
529
+ return lint(tmp, 'presence');
530
+ })();
531
+ const ok =
532
+ rejecting.findings.length === 1 &&
533
+ rejecting.findings[0]?.kind === 'no-law-section' &&
534
+ accepting.findings.length === 0;
535
+
536
+ // Same rejecting/accepting shape for the trigger axis (step 3.4):
537
+ // `mute` has a law but no trigger and is unbaselined, `vocal` has both.
538
+ const triggerRejecting = lint(tmp, 'trigger');
539
+ const triggerAccepting = (() => {
540
+ fs.writeFileSync(
541
+ path.join(tmp, CONFIG_REL),
542
+ JSON.stringify({
543
+ missing: ['lawless'],
544
+ no_trigger: ['mute'],
545
+ law_exceptions: {},
546
+ body_exceptions: {},
547
+ }),
548
+ );
549
+ return lint(tmp, 'trigger');
550
+ })();
551
+ const triggerOk =
552
+ triggerRejecting.findings.map((f) => f.id).sort().join(',') === 'mute' &&
553
+ triggerRejecting.findings.every((f) => f.kind === 'no-trigger') &&
554
+ triggerAccepting.findings.length === 0;
555
+
556
+ const allOk = ok && triggerOk;
557
+ write(
558
+ allOk
559
+ ? '✅ self-test: presence + trigger axes each have a rejecting and an accepting case\n'
560
+ : `❌ self-test FAILED: presence rejecting=${rejecting.findings.length} ` +
561
+ `accepting=${accepting.findings.length}; trigger rejecting=` +
562
+ `${triggerRejecting.findings.length} accepting=${triggerAccepting.findings.length}\n`,
563
+ );
564
+ return allOk ? 0 : 1;
565
+ } finally {
566
+ fs.rmSync(tmp, { recursive: true, force: true });
567
+ }
568
+ }
569
+
570
+ export function main(argv: string[] | null = null): number {
571
+ const args = parseArgs(argv ?? process.argv.slice(2));
572
+ if (args.selfTest) {
573
+ return selfTest();
574
+ }
575
+ if (args.writeBaseline) {
576
+ const today = asOf().toISOString().slice(0, 10);
577
+ writeBaseline(args.root, today);
578
+ process.stdout.write(`wrote ${CONFIG_REL}\n`);
579
+ return 0;
580
+ }
581
+
582
+ let res: LintResult;
583
+ try {
584
+ res = lint(args.root, args.axis);
585
+ } catch (exc) {
586
+ process.stderr.write(`❌ lint_rule_law_section: ${(exc as Error).message}\n`);
587
+ return 3;
588
+ }
589
+
590
+ // Outside the `--quiet` guard on purpose: CI passes `--quiet`, and a gate
591
+ // whose count disappears under the flag reads as silent to the coverage
592
+ // census.
593
+ try {
594
+ reportScanned({
595
+ gate: 'lint_rule_law_section',
596
+ scanned: res.scanned,
597
+ units: 'routed rule(s)',
598
+ roots: [RULES_REL, ROUTER_REL],
599
+ });
600
+ } catch (exc) {
601
+ if (exc instanceof DeadScopeError) {
602
+ process.stderr.write(`❌ ${exc.message}\n`);
603
+ return 1;
604
+ }
605
+ throw exc;
606
+ }
607
+
608
+ if (!args.quiet) {
609
+ const withLaw = res.measures.filter((m) => m.law !== null).length;
610
+ process.stdout.write(
611
+ `law sections: ${withLaw}/${res.measures.length} routed rules; ` +
612
+ `kernel reported separately (${res.kernelReported.filter((k) => k.sections > 0).length}/` +
613
+ `${res.kernelReported.length} carry one, write-denied so never failed here)\n`,
614
+ );
615
+ for (const t of res.overTarget) {
616
+ process.stdout.write(
617
+ ` over target (${LAW_TARGET_CHARS}), not a failure: ${t.id} — ${t.chars} chars\n`,
618
+ );
619
+ }
620
+ }
621
+
622
+ if (res.findings.length > 0) {
623
+ for (const f of res.findings) {
624
+ process.stderr.write(`❌ ${f.id} [${f.axis}/${f.kind}] ${f.detail}\n`);
625
+ }
626
+ process.stderr.write(`❌ lint_rule_law_section: ${res.findings.length} finding(s)\n`);
627
+ return 1;
628
+ }
629
+ if (!args.quiet) {
630
+ process.stdout.write('✅ lint_rule_law_section clean\n');
631
+ }
632
+ return 0;
633
+ }
634
+
635
+ function isCliEntry(): boolean {
636
+ if (process.argv[1] === undefined) return false;
637
+ if (import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href) return true;
638
+ try {
639
+ return fs.realpathSync(fileURLToPath(import.meta.url)) === fs.realpathSync(path.resolve(process.argv[1]));
640
+ } catch {
641
+ return false;
642
+ }
643
+ }
644
+
645
+ if (isCliEntry()) {
646
+ process.exit(main());
647
+ }
@@ -35,6 +35,23 @@
35
35
  * the wizard may offer it and the user may decline, so an invariant that
36
36
  * counted it would pass on installs that do not exist.
37
37
  *
38
+ * SIBLING GATE, OPPOSITE READING, SAME REASONING (2026-10-09). Since D5 of
39
+ * `road-to-gates-a-pull-request-can-hear`, `lint_pack_boundaries` DOES read
40
+ * `suggests` — as permitting a cross-pack link. That is not a contradiction of
41
+ * the paragraph above, and the discriminator is the direction of the claim
42
+ * each gate makes:
43
+ *
44
+ * - THIS gate asserts a route WILL RESOLVE on the installs it covers.
45
+ * Counting an advisory edge would assert resolution on installs that may
46
+ * not exist — a false negative in the dangerous direction.
47
+ * - The boundary gate reports a link that MAY DANGLE. An advisory edge is
48
+ * the author stating they accept the dangle for a declining consumer, so
49
+ * reading it there downgrades a finding the author has already answered.
50
+ *
51
+ * Practical consequence, stated because it is the mistake the asymmetry
52
+ * invites: adding a `suggests` edge does NOT clear an `unreachable-route`
53
+ * finding here. It never will. Fix the route or accept the finding.
54
+ *
38
55
  * ADVISORY UNTIL ITS FINDING SET IS EMPTY, AND THE FIRST RUN SAYS WHY.
39
56
  * Measured on introduction: 12 `unreachable-route` and 14 `unrouted-skill`
40
57
  * findings across 116 rules. The UI pair is one instance of an estate-wide
@@ -604,7 +604,7 @@ function main(): number {
604
604
  for (const [removedKey, reason] of REMOVED_KEYS) {
605
605
  if (reason.trim() === '') {
606
606
  findings.push(
607
- `src/scripts/_lib/agent_settings.ts \`${removedKey}\` is in REMOVED_KEYS with an empty ` +
607
+ `src/scripts/_lib/settings_removed_keys.ts \`${removedKey}\` is in REMOVED_KEYS with an empty ` +
608
608
  'reason — name what decides instead, not that it is gone.',
609
609
  );
610
610
  }