@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,71 @@
1
+ /**
2
+ * The high-consequence rule class — one reader for the config, the projector
3
+ * and the test.
4
+ *
5
+ * The criterion itself is prose and lives where an author meets it: the
6
+ * `consequence_class` property of `src/scripts/schemas/rule.schema.json`. This
7
+ * module does not restate it. It reads the list the criterion produced
8
+ * (`src/config/rule-consequence-class.json`), joins it to what each rule file
9
+ * actually declares, and answers the one question `project_thin_rules` asks:
10
+ * may this rule's stub carry its own law, and if not, has that been declared?
11
+ *
12
+ * WHY A DECLARED `no_stub` SUBSET RATHER THAN A SHORTER CLASS. A member whose
13
+ * law section is missing or over the ceiling cannot ship as stub-plus-law —
14
+ * there is nothing short enough to copy. Two ways to handle that: drop it from
15
+ * the class, or keep it in the class and record why it cannot stand. Dropping
16
+ * it makes the class shrinkable by NOT writing a law, which is the incentive a
17
+ * criterion must not create. Keeping it leaves the obligation visible and costs
18
+ * only a full-bodied projection, which is what those rules get today anyway.
19
+ */
20
+ import * as fs from 'node:fs';
21
+ import * as path from 'node:path';
22
+
23
+ export const CLASS_CONFIG_REL = 'src/config/rule-consequence-class.json';
24
+
25
+ export const CLAUSES = ['irreversible-external', 'security-boundary', 'authority-bypass'] as const;
26
+ export type Clause = (typeof CLAUSES)[number];
27
+
28
+ export interface ClassMember {
29
+ clause: Clause;
30
+ /** What this rule's own law obligates, and what violating it costs. */
31
+ why: string;
32
+ }
33
+
34
+ export interface NoStubEntry extends ClassMember {
35
+ /** Why the law cannot stand in a stub today. */
36
+ reason: string;
37
+ }
38
+
39
+ export interface ConsequenceClassConfig {
40
+ criterion_ref: string;
41
+ members: Record<string, ClassMember>;
42
+ /** Subset of `members` that projects full-bodied, each with its reason. */
43
+ no_stub: Record<string, NoStubEntry>;
44
+ /** Near misses the criterion rejected, each with the reason it was rejected. */
45
+ excluded: Record<string, string>;
46
+ }
47
+
48
+ export function readConsequenceClass(repoRoot: string): ConsequenceClassConfig {
49
+ const raw = JSON.parse(fs.readFileSync(path.join(repoRoot, CLASS_CONFIG_REL), 'utf-8')) as Partial<
50
+ ConsequenceClassConfig
51
+ >;
52
+ return {
53
+ criterion_ref: raw.criterion_ref ?? '',
54
+ members: raw.members ?? {},
55
+ no_stub: raw.no_stub ?? {},
56
+ excluded: raw.excluded ?? {},
57
+ };
58
+ }
59
+
60
+ /** Ids whose stub carries their law — members minus the declared `no_stub` set. */
61
+ export function stubLawIds(cfg: ConsequenceClassConfig): Set<string> {
62
+ return new Set(Object.keys(cfg.members).filter((id) => cfg.no_stub[id] === undefined));
63
+ }
64
+
65
+ /** The `consequence_class:` value a rule file declares, or `null`. */
66
+ export function declaredClause(ruleText: string): Clause | null {
67
+ const m = /^consequence_class:\s*"?([a-z-]+)"?\s*$/m.exec(ruleText);
68
+ if (m === null) return null;
69
+ const v = m[1] as string;
70
+ return (CLAUSES as readonly string[]).includes(v) ? (v as Clause) : null;
71
+ }
@@ -72,8 +72,115 @@ export interface TierRuleMatch {
72
72
  /** Kinds of trigger a prompt alone can never fire. */
73
73
  export const PATH_TRIGGER_KINDS = ['path_prefix', 'file_pattern'] as const;
74
74
 
75
+ /**
76
+ * Set by `dispatch_hook` to its own resolved package root. Read here rather
77
+ * than threaded through every caller — see `ruleSourceDirs`.
78
+ */
79
+ export const PACKAGE_ROOT_ENV = 'AGENT_CONFIG_PACKAGE_ROOT';
80
+
81
+ function statKind(p: string): 'dir' | 'file' | null {
82
+ try {
83
+ const s = fs.statSync(p);
84
+ return s.isDirectory() ? 'dir' : s.isFile() ? 'file' : null;
85
+ } catch {
86
+ return null;
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Every tree a rule body may come from, highest precedence first.
92
+ *
93
+ * THE DEFECT THIS CLOSES, reproduced at `main` @ `9bc8cd4f2` and again on
94
+ * 2026-10-01. This module resolved bodies and the router under ONE root, and
95
+ * the carrier passed the envelope's workspace or `process.cwd()`. In this
96
+ * checkout those are the same directory and everything works. In a consumer
97
+ * project they are not: there is no `dist/` under the consumer's tree at all,
98
+ * so `loadRouter` threw, the carrier caught it and returned allow, and the
99
+ * concern delivered NOTHING while reporting no error. Every consumer runs it
100
+ * in someone else's project, so the shipped carrier was silent for every
101
+ * consumer and loud only for its author. `dispatch_hook.ts:722` has passed
102
+ * `AGENT_CONFIG_PACKAGE_ROOT` to every concern since the ADR-020 global-only
103
+ * install landed — the fix was one environment read away and nothing read it.
104
+ *
105
+ * THE ORDER IS THE CONTRACT:
106
+ *
107
+ * 1. `<root>/agents/overrides/<id>.md` — the developer's own layer.
108
+ * `agents_overlay.ts` already makes `overrides/` the one cascade kind
109
+ * that is both project- and user-global-eligible, and a consumer who has
110
+ * overridden a rule means it. It wins, which is what step 1.1's "with
111
+ * `agents/overrides/` keeping precedence" asks for.
112
+ * 2. `<root>/dist/agent-src/rules/<id>.md` — the maintainer checkout. Kept
113
+ * AHEAD of the package root and not behind it, so this repository's own
114
+ * behaviour is byte-identical to what it was before. A change that
115
+ * repairs consumers by moving the maintainer tree is one nobody can
116
+ * review against a known-good reading.
117
+ * 3. `<packageRoot>/dist/agent-src/rules/<id>.md` — the install. The only
118
+ * one of the three that exists in a foreign project.
119
+ *
120
+ * WHY THE ENVIRONMENT IS READ HERE rather than passed in. Nine call sites
121
+ * across the model, the shortlist, the arm experiment and two hooks pass a
122
+ * single `repoRoot`, and none of them has a second tree to offer. Threading a
123
+ * resolved source object through all of them would be a wide diff whose only
124
+ * real consumer is the carrier, and it costs runtime bytes in the composed
125
+ * hook bundle — which every hook event on every slot loads, under a hard
126
+ * ceiling (`src/config/hook-bundle-budget.json`). `roadmap_progress_hook`
127
+ * already reads this same variable this same way; this follows it rather than
128
+ * inventing a second convention. No `~` expansion: the one writer is
129
+ * `dispatch_hook`, which sets it from a `path.resolve` result.
130
+ */
131
+ export interface RuleSources {
132
+ /** Body directories, highest precedence first. */
133
+ readonly dirs: readonly string[];
134
+ /** The resolved package root, or `null` when the variable named nothing. */
135
+ readonly pkg: string | null;
136
+ /** The `dist/router.json` to route against, or `null`. */
137
+ readonly router: string | null;
138
+ /**
139
+ * One line naming why nothing resolved, or `null` when something did.
140
+ *
141
+ * A caller that found nothing must be able to SAY so. An empty delivery is
142
+ * indistinguishable from "no rule matched", which is exactly the silence
143
+ * this chain exists to end; reproducing it one layer up would be the whole
144
+ * defect again. The three wordings are distinguishable because the
145
+ * operator's next action differs: the variable was never set (a host or
146
+ * wrapper problem), it points somewhere that is gone (a move after
147
+ * install), or both resolved and the package carries no built corpus.
148
+ */
149
+ readonly gap: string | null;
150
+ }
151
+
152
+ /** Resolve the body dirs, the router and the gap wording in ONE filesystem pass. */
153
+ export function ruleSources(repoRoot: string): RuleSources {
154
+ const env = (process.env[PACKAGE_ROOT_ENV] ?? '').trim();
155
+ const pkg = env ? path.resolve(env) : null;
156
+ const dirs: string[] = [];
157
+ const add = (d: string): void => {
158
+ if (statKind(d) === 'dir' && !dirs.includes(d)) dirs.push(d);
159
+ };
160
+ add(path.join(repoRoot, 'agents', 'overrides'));
161
+ add(path.join(repoRoot, 'dist', 'agent-src', 'rules'));
162
+ if (pkg !== null) add(path.join(pkg, 'dist', 'agent-src', 'rules'));
163
+
164
+ const local = path.join(repoRoot, 'dist', 'router.json');
165
+ let router: string | null = statKind(local) === 'file' ? local : null;
166
+ if (router === null && pkg !== null) {
167
+ const shipped = path.join(pkg, 'dist', 'router.json');
168
+ if (statKind(shipped) === 'file') router = shipped;
169
+ }
170
+
171
+ let gap: string | null = null;
172
+ if (router === null || dirs.length === 0) {
173
+ const miss =
174
+ pkg === null
175
+ ? `${PACKAGE_ROOT_ENV} unset`
176
+ : `no ${router === null ? 'dist/router.json' : 'dist/agent-src/rules'} under ${repoRoot} or ${pkg}`;
177
+ gap = `rule-inject: no rule source — ${miss}`;
178
+ }
179
+ return { dirs, pkg, router, gap };
180
+ }
181
+
75
182
  export function loadRouter(repoRoot: string): Router {
76
- const p = path.join(repoRoot, 'dist', 'router.json');
183
+ const p = ruleSources(repoRoot).router ?? path.join(repoRoot, 'dist', 'router.json');
77
184
  return JSON.parse(fs.readFileSync(p, 'utf8')) as Router;
78
185
  }
79
186
 
@@ -163,16 +270,29 @@ export function matchTierRules(
163
270
  return out;
164
271
  }
165
272
 
166
- /** Where the projected body of a rule lives. */
167
- export function ruleBodyPath(repoRoot: string, id: string): string {
168
- return path.join(repoRoot, 'dist', 'agent-src', 'rules', `${id}.md`);
169
- }
170
-
171
- /** The projected body, or `null` when the rule has no projected file. */
273
+ /**
274
+ * The projected body from the highest-precedence tree carrying it, or `null`.
275
+ *
276
+ * `ruleBodyPath` used to sit in front of this and is gone: it returned the
277
+ * single-root path unconditionally, this diff changed its contract to "the
278
+ * first tree that has the file", and nothing outside this module ever called
279
+ * it. An exported helper whose last caller disappeared in the same diff is an
280
+ * own-orphan, and the composed hook bundle charges for it on every dispatch
281
+ * (`src/config/hook-bundle-budget.json`), so it is removed rather than left as
282
+ * a wrapper nobody uses.
283
+ */
172
284
  export function loadRuleBody(repoRoot: string, id: string): string | null {
173
- const p = ruleBodyPath(repoRoot, id);
174
- if (!fs.existsSync(p)) return null;
175
- return fs.readFileSync(p, 'utf8');
285
+ for (const dir of ruleSources(repoRoot).dirs) {
286
+ const p = path.join(dir, `${id}.md`);
287
+ if (statKind(p) === 'file') {
288
+ try {
289
+ return fs.readFileSync(p, 'utf8');
290
+ } catch {
291
+ return null;
292
+ }
293
+ }
294
+ }
295
+ return null;
176
296
  }
177
297
 
178
298
  /**
@@ -0,0 +1,147 @@
1
+ /**
2
+ * One spelling of "a rule's law section" — the unit three gates and one
3
+ * projector all price.
4
+ *
5
+ * A **law section** is a heading whose title matches `\biron\s+laws?\b` plus
6
+ * everything under it up to the next heading of the same or a shallower depth.
7
+ * A rule may carry several (`direct-answers` has three, `no-cheap-questions`
8
+ * six); the rule's law is all of them, joined by a blank line, because each one
9
+ * states an obligation and a stub carrying only the first would ship a rule
10
+ * whose other laws silently vanished.
11
+ *
12
+ * WHY A SHARED MODULE RATHER THAN A REGEX PER CALLER. The projector
13
+ * (`project_thin_rules.ts`) byte-copies this text into a stub and digests it;
14
+ * the lint (`lint_rule_law_section.ts`) holds it under a ceiling. If those two
15
+ * disagreed about where a section ends, the lint would certify a length the
16
+ * projection does not carry — the exact drift `THIN_ENTRY_MARKER`'s own comment
17
+ * argues against one file over.
18
+ *
19
+ * The heading regex is deliberately the SAME one `check_iron_law_prominence.ts`
20
+ * uses, so "has a law section" here and "is an Iron Law heading" there cannot
21
+ * diverge. That gate owns prominence (H2, near the top); this module owns
22
+ * extent and size.
23
+ *
24
+ * WHAT THIS DOES NOT CLAIM. Not that the extracted text IS the rule's obligation. A rule can state its
25
+ * law in bold prose or a bare fence under no heading at all — several of the 35
26
+ * routed rules without a heading match do exactly that. A heading match is a
27
+ * STRUCTURAL property, checkable; "this sentence is the obligation" is not, and
28
+ * `report_obligation_carriers` plus the ids in `src/config/rule-obligations.json` is where
29
+ * that question already lives.
30
+ */
31
+ import * as fs from 'node:fs';
32
+
33
+ /** Same literal as `check_iron_law_prominence.ts` — one definition, two readers. */
34
+ export const IRON_LAW_RE = /\biron\s+laws?\b/i;
35
+
36
+ const HEADING_RE = /^(#{1,6})\s+(.+?)\s*$/;
37
+ const FENCE_RE = /^\s*```/;
38
+
39
+ export interface LawSection {
40
+ /** Heading title, verbatim. */
41
+ title: string;
42
+ /** Heading depth (1–6). */
43
+ depth: number;
44
+ /** 1-based line of the heading within the body. */
45
+ line: number;
46
+ /** Heading line plus its section, trimmed. */
47
+ text: string;
48
+ }
49
+
50
+ /** Return `[frontmatter_including_fences, body]`. Empty frontmatter if none. */
51
+ export function splitFrontmatter(text: string): [string, string] {
52
+ if (text.startsWith('---\n')) {
53
+ const end = text.indexOf('\n---\n', 4);
54
+ if (end !== -1) {
55
+ return [text.slice(0, end + 5), text.slice(end + 5)];
56
+ }
57
+ }
58
+ return ['', text];
59
+ }
60
+
61
+ /**
62
+ * The body a runtime delivery carries: frontmatter removed, HTML comments
63
+ * removed, trimmed.
64
+ *
65
+ * Comments are stripped because they are authoring scaffolding
66
+ * (`<!-- risk-review: … -->`, `<!-- harvest:… -->`, `ref-ignore` markers) that
67
+ * no host renders to a model, so charging a rule for them would price the wrong
68
+ * thing. Frontmatter is excluded for the reason `check_rule_stub_ceiling` gives
69
+ * for the same exclusion: it is the routing surface, and a rule that gains a
70
+ * trigger must not trip a ceiling whose message tells the author to move prose.
71
+ */
72
+ export function ruleBody(text: string): string {
73
+ const [, body] = splitFrontmatter(text);
74
+ return body.replace(/<!--[\s\S]*?-->/g, '').trim();
75
+ }
76
+
77
+ /** Every law section in a rule body, in document order. */
78
+ export function lawSections(body: string): LawSection[] {
79
+ const lines = body.split('\n');
80
+ let inFence = false;
81
+ const headings: Array<{ i: number; depth: number; title: string }> = [];
82
+ for (let i = 0; i < lines.length; i += 1) {
83
+ const raw = lines[i] as string;
84
+ if (FENCE_RE.test(raw)) {
85
+ inFence = !inFence;
86
+ continue;
87
+ }
88
+ if (inFence) continue;
89
+ const m = HEADING_RE.exec(raw);
90
+ if (m) headings.push({ i, depth: (m[1] as string).length, title: (m[2] as string).trim() });
91
+ }
92
+ const out: LawSection[] = [];
93
+ for (let k = 0; k < headings.length; k += 1) {
94
+ const h = headings[k] as { i: number; depth: number; title: string };
95
+ if (!IRON_LAW_RE.test(h.title)) continue;
96
+ let end = lines.length;
97
+ for (let j = k + 1; j < headings.length; j += 1) {
98
+ const n = headings[j] as { i: number; depth: number; title: string };
99
+ if (n.depth <= h.depth) {
100
+ end = n.i;
101
+ break;
102
+ }
103
+ }
104
+ out.push({
105
+ title: h.title,
106
+ depth: h.depth,
107
+ line: h.i + 1,
108
+ text: lines.slice(h.i, end).join('\n').trim(),
109
+ });
110
+ }
111
+ return out;
112
+ }
113
+
114
+ /**
115
+ * The rule's law, as one byte string — all sections joined by a blank line.
116
+ * `null` when the rule has none, which is a different answer from `''`.
117
+ */
118
+ export function lawText(body: string): string | null {
119
+ const sections = lawSections(body);
120
+ if (sections.length === 0) return null;
121
+ return sections.map((s) => s.text).join('\n\n');
122
+ }
123
+
124
+ export interface RuleLawMeasure {
125
+ id: string;
126
+ /** Characters of the law text, 0 when there is none. */
127
+ lawChars: number;
128
+ /** Number of law sections found. */
129
+ sections: number;
130
+ /** Characters of the comment-stripped body. */
131
+ bodyChars: number;
132
+ /** The law text itself, `null` when absent. */
133
+ law: string | null;
134
+ }
135
+
136
+ /** Measure one rule file. */
137
+ export function measureRuleFile(id: string, filePath: string): RuleLawMeasure {
138
+ const body = ruleBody(fs.readFileSync(filePath, 'utf-8'));
139
+ const law = lawText(body);
140
+ return {
141
+ id,
142
+ lawChars: law === null ? 0 : law.length,
143
+ sections: lawSections(body).length,
144
+ bodyChars: body.length,
145
+ law,
146
+ };
147
+ }
@@ -25,6 +25,7 @@
25
25
  */
26
26
 
27
27
  import * as fs from 'node:fs';
28
+ import * as os from 'node:os';
28
29
  import * as path from 'node:path';
29
30
 
30
31
  /**
@@ -140,6 +141,63 @@ export function compareLayers(
140
141
  };
141
142
  }
142
143
 
144
+ /**
145
+ * The two directories Claude Code loads rules from, user layer first.
146
+ *
147
+ * ONE SOURCE OF TRUTH FOR SCOPE (`road-to-a-rule-carrier-that-works-outside-the-repo`
148
+ * step 1.3). Two readers need this pair and both used to spell it out inline:
149
+ * the installer's overlap gate, and — once the carrier started resolving bodies
150
+ * from the package rather than from the workspace — the delivery scope itself.
151
+ * A carrier scoping on one list while the installer gates on another would
152
+ * deliver a rule the install never wrote, which is the state step 1.3 exists to
153
+ * end.
154
+ *
155
+ * It is a UNION and not a precedence chain. The host loads both with no dedup —
156
+ * that is the whole reason this module exists — so a rule present in either
157
+ * layer is loaded, and "what the install carries" is the union of the two.
158
+ *
159
+ * `os.homedir()` rather than a settings key: the installer resolves the user
160
+ * layer the same way, and a second spelling of "where is home" is a second
161
+ * thing to disagree about.
162
+ */
163
+ export function hostRuleLayerDirs(projectRoot: string): [string, string] {
164
+ return [
165
+ path.join(os.homedir(), '.claude', 'rules'),
166
+ path.join(projectRoot, '.claude', 'rules'),
167
+ ];
168
+ }
169
+
170
+ /**
171
+ * Rule ids present in either host rule layer, or `null` when NEITHER directory
172
+ * exists.
173
+ *
174
+ * `null` IS A DIFFERENT ANSWER FROM AN EMPTY SET, and the difference is the
175
+ * contract. An empty set means the install wrote a rule layer and it carries
176
+ * nothing, so nothing is in scope. `null` means no rule layer exists to declare
177
+ * a scope at all: a maintainer checkout, or a host this install writes no rules
178
+ * directory for. Scoping to the empty set there would re-create exactly the
179
+ * silence step 1.1 repaired, so the caller applies no filter instead.
180
+ *
181
+ * Names only, never bodies. This runs on the `user_prompt_submit` hot path, and
182
+ * {@link readRuleLayer} beside it reads every file's contents because ITS
183
+ * caller compares them. A scope check never needs a byte of any of them.
184
+ */
185
+ export function hostRuleLayerIds(projectRoot: string): Set<string> | null {
186
+ const ids = new Set<string>();
187
+ let found = false;
188
+ for (const dir of hostRuleLayerDirs(projectRoot)) {
189
+ let names: string[];
190
+ try {
191
+ names = fs.readdirSync(dir);
192
+ } catch {
193
+ continue;
194
+ }
195
+ found = true;
196
+ for (const n of names) if (n.endsWith('.md')) ids.add(n.slice(0, -3));
197
+ }
198
+ return found ? ids : null;
199
+ }
200
+
143
201
  /**
144
202
  * Read every `.md` in `dir` into a {@link RuleLayer}, or `null` when the
145
203
  * directory does not exist.
@@ -0,0 +1,205 @@
1
+ /**
2
+ * Stable obligation ids per rule, and which `enforced_by` entry refuses which.
3
+ *
4
+ * A rule holds several obligations, and `enforced_by` used to credit all of
5
+ * them for whatever one gate refuses: `git-history-discipline` counted as gated
6
+ * because a hook refuses `--no-verify`, while its laws against unsolicited
7
+ * rebase and dropped commits are refused by nothing. The inventory names each
8
+ * obligation `<rule>.<obligation>` so a gate is credited with the ids it
9
+ * actually refuses and nothing else.
10
+ *
11
+ * WHY A SIDECAR AND NOT RULE FRONTMATTER. `check_preamble_payload_budget`
12
+ * measures every byte of every projected rule file, frontmatter included, as
13
+ * per-spawn payload, and holds it at zero net growth. Some 290 ids in
14
+ * frontmatter would have been payload no model needs. The ids are routing and
15
+ * accounting data, so they live with the rest of that data in `src/config/`.
16
+ *
17
+ * WHY THE ID IS NOT DERIVED FROM THE LAW TEXT. A hash or an excerpt changes
18
+ * when the law is reworded, and an id that moves on every reword is not stable.
19
+ * The slug names the clause; the law text is free to change under it. That is
20
+ * also why the `# obligation: line N` frontmatter marker is retired: a line
21
+ * number drifts on every edit above it, and at retirement 34 of the 68 markers
22
+ * on rules with a law section no longer pointed inside that section.
23
+ *
24
+ * BINDINGS. `bindings` maps an `enforced_by` entry, spelled exactly as in the
25
+ * rule's frontmatter, to the ids it refuses. An entry with no key here is
26
+ * UNBOUND: it keeps the rule-level credit it always had and is counted
27
+ * separately, never as obligation-level coverage. An entry bound to `[]` is a
28
+ * recorded finding that it refuses none of this rule's obligations.
29
+ *
30
+ * The nine kernel rules are absent by construction: agents cannot write them,
31
+ * and they stay at rule granularity.
32
+ */
33
+ import * as fs from 'node:fs';
34
+ import * as path from 'node:path';
35
+
36
+ import { parse as parseYaml } from 'yaml';
37
+
38
+ import { KERNEL_RULE_ID_SET } from './kernel_rules.js';
39
+ import { lawSections, ruleBody, splitFrontmatter } from './rule_law_section.js';
40
+
41
+ export const RULE_OBLIGATIONS_PATH = 'src/config/rule-obligations.json';
42
+
43
+ const SLUG = '[a-z0-9]+(?:-[a-z0-9]+)*';
44
+
45
+ /** `<rule>.<obligation>`, both halves kebab-case. */
46
+ export const OBLIGATION_ID_RE = new RegExp(`^(${SLUG})\\.(${SLUG})$`);
47
+
48
+ /** The retired per-rule pointer. Kept only so the lint can refuse its return. */
49
+ export const OBLIGATION_MARKER_RE = /^#\s*obligation:\s*line\s+\d+\s*$/m;
50
+
51
+ export interface RuleObligationEntry {
52
+ obligations: string[];
53
+ bindings?: Record<string, string[]>;
54
+ }
55
+
56
+ export interface RuleObligationInventory {
57
+ rules: Record<string, RuleObligationEntry>;
58
+ }
59
+
60
+ export function loadRuleObligations(root: string): RuleObligationInventory {
61
+ const file = path.join(root, RULE_OBLIGATIONS_PATH);
62
+ const raw = JSON.parse(fs.readFileSync(file, 'utf-8')) as Partial<RuleObligationInventory>;
63
+ return { rules: raw.rules ?? {} };
64
+ }
65
+
66
+ /** What the lint needs to know about one rule file. */
67
+ export interface RuleFacts {
68
+ id: string;
69
+ kernel: boolean;
70
+ hasLawSection: boolean;
71
+ enforcedBy: string[];
72
+ hasMarker: boolean;
73
+ }
74
+
75
+ export function readRuleFacts(id: string, text: string): RuleFacts {
76
+ const [fmBlock] = splitFrontmatter(text);
77
+ let enforcedBy: string[] = [];
78
+ if (fmBlock !== '') {
79
+ const inner = fmBlock.replace(/^---\n/, '').replace(/\n---\n$/, '');
80
+ const fm = (parseYaml(inner) ?? {}) as Record<string, unknown>;
81
+ const raw = fm['enforced_by'];
82
+ if (Array.isArray(raw)) enforcedBy = raw.map(String);
83
+ else if (typeof raw === 'string' && raw !== '') enforcedBy = [raw];
84
+ }
85
+ return {
86
+ id,
87
+ kernel: KERNEL_RULE_ID_SET.has(id),
88
+ hasLawSection: lawSections(ruleBody(text)).length > 0,
89
+ enforcedBy,
90
+ hasMarker: OBLIGATION_MARKER_RE.test(fmBlock),
91
+ };
92
+ }
93
+
94
+ export function collectRuleFacts(rulesDir: string): RuleFacts[] {
95
+ return fs
96
+ .readdirSync(rulesDir)
97
+ .filter((n) => n.endsWith('.md'))
98
+ .sort()
99
+ .map((n) => readRuleFacts(n.slice(0, -3), fs.readFileSync(path.join(rulesDir, n), 'utf-8')));
100
+ }
101
+
102
+ export interface ObligationFinding {
103
+ rule: string;
104
+ code:
105
+ | 'unknown-rule'
106
+ | 'kernel-declared'
107
+ | 'missing'
108
+ | 'empty'
109
+ | 'bad-id'
110
+ | 'wrong-prefix'
111
+ | 'duplicate'
112
+ | 'binding-entry-not-declared'
113
+ | 'binding-id-unknown'
114
+ | 'marker-present';
115
+ message: string;
116
+ }
117
+
118
+ /**
119
+ * Every finding the inventory and the rule tree produce together.
120
+ *
121
+ * Required: every non-kernel rule with a law section has an entry. A rule
122
+ * without one MAY have an entry, and if it does the same checks apply.
123
+ */
124
+ export function lintRuleObligations(
125
+ inventory: RuleObligationInventory,
126
+ facts: readonly RuleFacts[],
127
+ ): ObligationFinding[] {
128
+ const out: ObligationFinding[] = [];
129
+ const byId = new Map(facts.map((f) => [f.id, f]));
130
+ const seen = new Map<string, string>();
131
+
132
+ for (const f of facts) {
133
+ if (f.hasMarker) {
134
+ out.push({
135
+ rule: f.id,
136
+ code: 'marker-present',
137
+ message:
138
+ 'carries a `# obligation: line N` marker; it is retired — the ids in ' +
139
+ `${RULE_OBLIGATIONS_PATH} name the obligation`,
140
+ });
141
+ }
142
+ if (!f.kernel && f.hasLawSection && inventory.rules[f.id] === undefined) {
143
+ out.push({
144
+ rule: f.id,
145
+ code: 'missing',
146
+ message: `has a law section and no entry in ${RULE_OBLIGATIONS_PATH}`,
147
+ });
148
+ }
149
+ }
150
+
151
+ for (const [rule, entry] of Object.entries(inventory.rules)) {
152
+ const fact = byId.get(rule);
153
+ if (fact === undefined) {
154
+ out.push({ rule, code: 'unknown-rule', message: 'no such rule under src/rules/' });
155
+ continue;
156
+ }
157
+ if (fact.kernel) {
158
+ out.push({
159
+ rule,
160
+ code: 'kernel-declared',
161
+ message: 'kernel rules stay at rule granularity and carry no obligation ids',
162
+ });
163
+ }
164
+ const ids = Array.isArray(entry.obligations) ? entry.obligations : [];
165
+ if (ids.length === 0) {
166
+ out.push({ rule, code: 'empty', message: 'declares no obligations' });
167
+ }
168
+ const own = new Set<string>();
169
+ for (const id of ids) {
170
+ const m = OBLIGATION_ID_RE.exec(id);
171
+ if (m === null) {
172
+ out.push({ rule, code: 'bad-id', message: `\`${id}\` is not \`<rule>.<obligation>\` kebab-case` });
173
+ continue;
174
+ }
175
+ if (m[1] !== rule) {
176
+ out.push({ rule, code: 'wrong-prefix', message: `\`${id}\` is not prefixed with \`${rule}.\`` });
177
+ }
178
+ const prior = seen.get(id);
179
+ if (prior !== undefined) {
180
+ out.push({ rule, code: 'duplicate', message: `\`${id}\` is declared twice (also under ${prior})` });
181
+ }
182
+ seen.set(id, rule);
183
+ own.add(id);
184
+ }
185
+ for (const [entryName, bound] of Object.entries(entry.bindings ?? {})) {
186
+ if (!fact.enforcedBy.includes(entryName)) {
187
+ out.push({
188
+ rule,
189
+ code: 'binding-entry-not-declared',
190
+ message: `binds \`${entryName}\`, which is not in the rule's enforced_by`,
191
+ });
192
+ }
193
+ for (const id of bound) {
194
+ if (!own.has(id)) {
195
+ out.push({
196
+ rule,
197
+ code: 'binding-id-unknown',
198
+ message: `\`${entryName}\` binds \`${id}\`, which this rule does not declare`,
199
+ });
200
+ }
201
+ }
202
+ }
203
+ }
204
+ return out;
205
+ }
@@ -322,7 +322,7 @@ function stemOf(token: string): string {
322
322
  return base.replace(/\.md$/, '');
323
323
  }
324
324
 
325
- /** Dotted settings-key shape — `personal.autonomy`, `tokens.rich_skills`, … */
325
+ /** Dotted settings-key shape — `personal.autonomy`, `memory.redact_patterns`, … */
326
326
  const DOTTED_KEY_RE = /^[a-z0-9_]+(\.[a-z0-9_]+)+$/;
327
327
 
328
328
  /**