@event4u/agent-config 16.1.0 → 16.3.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 (467) 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 +98 -257
  5. package/README.md +14 -12
  6. package/dist/agent-src/commands/analyze/inbox.md +1 -1
  7. package/dist/agent-src/commands/analyze/roadmap-repos.md +1 -1
  8. package/dist/agent-src/commands/bug/fix.md +17 -2
  9. package/dist/agent-src/commands/feature/plan.md +1 -1
  10. package/dist/agent-src/commands/feature/roadmap.md +1 -1
  11. package/dist/agent-src/commands/fix/ci.md +1 -1
  12. package/dist/agent-src/commands/implement-ticket.md +1 -1
  13. package/dist/agent-src/commands/jira-ticket.md +1 -1
  14. package/dist/agent-src/commands/roadmap/create.md +1 -1
  15. package/dist/agent-src/commands/roadmap/materialize.md +1 -1
  16. package/dist/agent-src/commands/roadmap/process-full.md +5 -5
  17. package/dist/agent-src/commands/roadmap/resolve-blockers.md +361 -0
  18. package/dist/agent-src/commands/roadmap/triage-parked.md +325 -0
  19. package/dist/agent-src/commands/roadmap.md +18 -4
  20. package/dist/agent-src/commands/tests/create.md +17 -3
  21. package/dist/agent-src/commands/tests/execute.md +22 -5
  22. package/dist/agent-src/commands/work.md +4 -0
  23. package/dist/agent-src/contexts/authority/decision-revisit-gate-enforcement.md +43 -0
  24. package/dist/agent-src/contexts/communication/rules-auto/design-fidelity-enforcement.md +24 -0
  25. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +6 -6
  26. package/dist/agent-src/contexts/execution/autonomy-mechanics.md +4 -8
  27. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +32 -2
  28. package/dist/agent-src/contexts/execution/session-canary-enforcement-history.md +67 -0
  29. package/dist/agent-src/contexts/execution/toolchain-resolver.md +101 -7
  30. package/dist/agent-src/rules/active-remediation.md +1 -1
  31. package/dist/agent-src/rules/autonomous-execution.md +1 -0
  32. package/dist/agent-src/rules/broken-access-control.md +1 -0
  33. package/dist/agent-src/rules/command-suggestion-policy.md +1 -0
  34. package/dist/agent-src/rules/context-hygiene.md +1 -1
  35. package/dist/agent-src/rules/decision-revisit-gate.md +16 -33
  36. package/dist/agent-src/rules/design-fidelity.md +13 -16
  37. package/dist/agent-src/rules/doc-screenshot-hygiene.md +1 -0
  38. package/dist/agent-src/rules/domain-safety-disclaimer.md +1 -0
  39. package/dist/agent-src/rules/domain-safety-pii.md +1 -0
  40. package/dist/agent-src/rules/domain-safety-retention.md +1 -0
  41. package/dist/agent-src/rules/engineering-safety-floor.md +1 -0
  42. package/dist/agent-src/rules/evaluator-independence.md +3 -2
  43. package/dist/agent-src/rules/fast-path-marker-visibility.md +1 -0
  44. package/dist/agent-src/rules/finance-safety-floor.md +1 -0
  45. package/dist/agent-src/rules/git-history-discipline.md +1 -0
  46. package/dist/agent-src/rules/image-likeness-and-rights.md +1 -0
  47. package/dist/agent-src/rules/legal-safety-floor.md +3 -2
  48. package/dist/agent-src/rules/lethal-trifecta-guard.md +1 -0
  49. package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +1 -0
  50. package/dist/agent-src/rules/media-governance-routing.md +14 -17
  51. package/dist/agent-src/rules/persona-governance.md +2 -2
  52. package/dist/agent-src/rules/provider-lifecycle-discipline.md +1 -1
  53. package/dist/agent-src/rules/question-not-instruction.md +1 -0
  54. package/dist/agent-src/rules/roadmap-progress-sync.md +1 -1
  55. package/dist/agent-src/rules/runtime-safety.md +1 -0
  56. package/dist/agent-src/rules/secret-vcs-guard.md +1 -0
  57. package/dist/agent-src/rules/security-sensitive-stop.md +3 -2
  58. package/dist/agent-src/rules/session-canary.md +8 -62
  59. package/dist/agent-src/rules/settings-ask-protocol.md +1 -0
  60. package/dist/agent-src/rules/source-confidentiality.md +1 -0
  61. package/dist/agent-src/rules/strategy-safety-floor.md +1 -0
  62. package/dist/agent-src/rules/tool-safety.md +1 -0
  63. package/dist/agent-src/rules/ui-audit-gate.md +1 -2
  64. package/dist/agent-src/rules/untrusted-input-defense.md +1 -0
  65. package/dist/agent-src/rules/user-interrupt-priority.md +1 -0
  66. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
  67. package/dist/agent-src/scripts/deferral_carry.ts +339 -0
  68. package/dist/agent-src/scripts/update_roadmap_progress.ts +4 -1
  69. package/dist/agent-src/skills/accessibility-auditor/data/aria-patterns.csv +1 -1
  70. package/dist/agent-src/skills/accessibility-auditor/data/manifest.json +2 -2
  71. package/dist/agent-src/skills/api-design/data/manifest.json +2 -2
  72. package/dist/agent-src/skills/api-testing/SKILL.md +17 -0
  73. package/dist/agent-src/skills/code-intelligence/SKILL.md +14 -2
  74. package/dist/agent-src/skills/design-review/SKILL.md +30 -4
  75. package/dist/agent-src/skills/design-review/references/verification-automation.md +32 -0
  76. package/dist/agent-src/skills/design-system-capture/references/import-procedure.md +1 -1
  77. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +18 -3
  78. package/dist/agent-src/skills/existing-ui-audit/references/component-taxonomy-detection.md +56 -0
  79. package/dist/agent-src/skills/fe-design/SKILL.md +1 -1
  80. package/dist/agent-src/skills/iconography/SKILL.md +1 -1
  81. package/dist/agent-src/skills/js-library-packaging/SKILL.md +2 -2
  82. package/dist/agent-src/skills/markitdown/SKILL.md +4 -0
  83. package/dist/agent-src/skills/monorepo-workspace/SKILL.md +1 -1
  84. package/dist/agent-src/skills/playwright-testing/SKILL.md +30 -6
  85. package/dist/agent-src/skills/quality-tools/SKILL.md +11 -1
  86. package/dist/agent-src/skills/quality-tools/references/go-tools.md +76 -0
  87. package/dist/agent-src/skills/quality-tools/references/python-tools.md +104 -0
  88. package/dist/agent-src/skills/review-routing/SKILL.md +2 -2
  89. package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +1 -1
  90. package/dist/agent-src/skills/storybook-workshop/SKILL.md +3 -3
  91. package/dist/agent-src/skills/tailwind-engineer/SKILL.md +1 -1
  92. package/dist/agent-src/skills/test-case-discovery/SKILL.md +7 -0
  93. package/dist/agent-src/skills/test-driven-development/SKILL.md +17 -0
  94. package/dist/agent-src/skills/test-performance/SKILL.md +19 -1
  95. package/dist/agent-src/skills/ui-component-architect/SKILL.md +25 -2
  96. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  97. package/dist/agent-src/templates/roadmaps.md +30 -0
  98. package/dist/agent-src/templates/scripts/work_engine/directives/ui/app_spec.ts +10 -4
  99. package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +302 -21
  100. package/dist/agent-src/templates/scripts/work_engine/directives/ui/audit.ts +22 -3
  101. package/dist/agent-src/templates/scripts/work_engine/directives/ui/scaffold.ts +6 -1
  102. package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
  103. package/dist/agent-src/templates/scripts/work_engine/state.ts +57 -7
  104. package/dist/agent-src/templates/scripts/work_engine/taxonomy/detect.ts +500 -0
  105. package/dist/agent-src/templates/scripts/work_engine/taxonomy/place.ts +183 -0
  106. package/dist/cli/python/knowledge_ingest.js +1 -1
  107. package/dist/cli/python/workspace_drive.js +1 -1
  108. package/dist/cli/registry.js +1 -1
  109. package/dist/cli-delegate/archive_completed_roadmaps.js +92 -12
  110. package/dist/cli-delegate/check_update_banner.js +12 -1
  111. package/dist/cli-delegate/chunk-523HCFYO.js +90 -0
  112. package/dist/cli-delegate/{chunk-M2DPGFZ4.js → chunk-6V6TA25H.js} +22 -152
  113. package/dist/cli-delegate/chunk-7IQE3D5S.js +191 -0
  114. package/dist/cli-delegate/{chunk-6KFEC3G7.js → chunk-CQWX336L.js} +1 -1
  115. package/dist/cli-delegate/chunk-DEIV7XP7.js +108 -0
  116. package/dist/cli-delegate/chunk-EEHDXSYD.js +2040 -0
  117. package/dist/cli-delegate/{chunk-P6ZHP5W2.js → chunk-GKE7ZVFA.js} +4 -4
  118. package/dist/cli-delegate/chunk-JQOM7TTM.js +1201 -0
  119. package/dist/cli-delegate/{chunk-UNCRJBT3.js → chunk-JQVYKIZA.js} +41 -0
  120. package/dist/cli-delegate/{chunk-FC75PGJE.js → chunk-JY2I2DXV.js} +12 -1
  121. package/dist/cli-delegate/chunk-KB5FZ655.js +208 -0
  122. package/dist/cli-delegate/{chunk-YUM5KURG.js → chunk-KR6EM23A.js} +235 -1455
  123. package/dist/cli-delegate/{chunk-LTYVIY76.js → chunk-LIYTLH6O.js} +1 -1
  124. package/dist/cli-delegate/chunk-NQ7WT43P.js +2729 -0
  125. package/dist/cli-delegate/chunk-NXEILF2K.js +2160 -0
  126. package/dist/cli-delegate/{chunk-5R7HOLAF.js → chunk-NYX3L2PZ.js} +1 -1
  127. package/dist/cli-delegate/{chunk-4E2W63DA.js → chunk-OKJUIAPS.js} +62 -1
  128. package/dist/cli-delegate/{chunk-QAJS5YWY.js → chunk-PHD7OOLE.js} +2 -1
  129. package/dist/cli-delegate/{chunk-RGNIWTEA.js → chunk-QLDHIPWR.js} +1 -1
  130. package/dist/cli-delegate/{chunk-HDVVGPQW.js → chunk-RQNNW7IF.js} +1405 -567
  131. package/dist/cli-delegate/{chunk-S3VFXMTM.js → chunk-S4UMZNES.js} +1 -1
  132. package/dist/cli-delegate/{chunk-6KM6ORRY.js → chunk-S4YWNRKO.js} +24 -8
  133. package/dist/cli-delegate/{chunk-GJCBB2UG.js → chunk-TRI6DQZ6.js} +3054 -325
  134. package/dist/cli-delegate/chunk-ULQRUR23.js +208 -0
  135. package/dist/cli-delegate/{chunk-NUHLI2RX.js → chunk-YCU3TIXH.js} +2 -0
  136. package/dist/cli-delegate/chunk-ZBZV2G5R.js +210 -0
  137. package/dist/cli-delegate/{chunk-WGXTVKCQ.js → chunk-ZUZKZYCN.js} +5 -3
  138. package/dist/cli-delegate/cmd_analyze_session.js +1 -1
  139. package/dist/cli-delegate/cmd_brand_status.js +1 -1
  140. package/dist/cli-delegate/cmd_conformance.js +1862 -809
  141. package/dist/cli-delegate/cmd_doctor.js +13 -6
  142. package/dist/cli-delegate/cmd_doctor_neighbours.js +23 -0
  143. package/dist/cli-delegate/cmd_explain.js +5 -5
  144. package/dist/cli-delegate/cmd_export.js +11 -8
  145. package/dist/cli-delegate/cmd_fleet.js +3 -3
  146. package/dist/cli-delegate/cmd_handoff.js +10 -7
  147. package/dist/cli-delegate/cmd_mcp_available.js +1 -1
  148. package/dist/cli-delegate/cmd_memory_get.js +3 -1
  149. package/dist/cli-delegate/cmd_migrate.js +2 -2
  150. package/dist/cli-delegate/cmd_packs_active.js +3 -3
  151. package/dist/cli-delegate/cmd_preflight.js +6 -6
  152. package/dist/cli-delegate/cmd_prune.js +11 -8
  153. package/dist/cli-delegate/cmd_refresh.js +2 -1
  154. package/dist/cli-delegate/cmd_route_audit.js +8 -6
  155. package/dist/cli-delegate/cmd_route_explain.js +4 -4
  156. package/dist/cli-delegate/cmd_session_recycle.js +4 -3
  157. package/dist/cli-delegate/cmd_settings_get.js +1 -1
  158. package/dist/cli-delegate/cmd_settings_migrate.js +11 -8
  159. package/dist/cli-delegate/cmd_settings_set.js +4 -4
  160. package/dist/cli-delegate/cmd_sync.js +11 -8
  161. package/dist/cli-delegate/cmd_uninstall.js +11 -8
  162. package/dist/cli-delegate/cmd_update.js +1 -1
  163. package/dist/cli-delegate/cmd_upgrade.js +3 -2
  164. package/dist/cli-delegate/cmd_validate.js +11 -8
  165. package/dist/cli-delegate/cmd_versions.js +1 -1
  166. package/dist/cli-delegate/deferral_carry.js +16 -0
  167. package/dist/cli-delegate/gate_execute.js +2 -2
  168. package/dist/cli-delegate/roadmap_gates.js +5 -5
  169. package/dist/cli-delegate/update_roadmap_progress.js +1 -1
  170. package/dist/discovery/deprecation-report.md +1 -1
  171. package/dist/discovery/discovery-manifest.json +132 -80
  172. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  173. package/dist/discovery/discovery-manifest.summary.md +3 -3
  174. package/dist/discovery/dormancy-report.md +1 -1
  175. package/dist/discovery/orphan-report.md +1 -1
  176. package/dist/discovery/packs.json +7 -5
  177. package/dist/discovery/trust-report.md +2 -2
  178. package/dist/discovery/workspaces.json +6 -4
  179. package/dist/hooks/dispatch.js +7972 -5186
  180. package/dist/hooks/dispatch.sha256 +1 -0
  181. package/dist/install/claudePathsPlan.js +47 -6
  182. package/dist/install/claudeRuleRewrite.js +7 -0
  183. package/dist/install/emit_host_rules_cli.js +39 -36
  184. package/dist/install/globalRuleScope.js +87 -0
  185. package/dist/install/host_rule_ownership.js +160 -0
  186. package/dist/install/install.mjs +2226 -1055
  187. package/dist/install/installThinLayer.js +261 -0
  188. package/dist/install/installedRuleLinks.js +176 -0
  189. package/dist/install/wizard-plan.js +24 -0
  190. package/dist/mcp/registry-manifest.json +3 -3
  191. package/dist/mcp/server.json +2 -2
  192. package/dist/mcp/server.mjs +40913 -34865
  193. package/dist/scripts/_lib/agent_settings.js +11 -0
  194. package/dist/scripts/_lib/claude_settings_hooks.js +10 -8
  195. package/dist/scripts/_lib/installed_layer.js +378 -0
  196. package/dist/scripts/_lib/lean_projection_mode.js +218 -15
  197. package/dist/scripts/_lib/rule_consequence_class.js +45 -0
  198. package/dist/scripts/_lib/rule_injection.js +67 -10
  199. package/dist/scripts/_lib/rule_law_section.js +122 -0
  200. package/dist/scripts/_lib/thin_rules.js +458 -0
  201. package/dist/scripts/_lib/windsurf_render.js +60 -0
  202. package/dist/scripts/condense.js +14 -26
  203. package/dist/scripts/project_thin_rules.js +14 -294
  204. package/dist/server/schemas/settings.js +29 -0
  205. package/dist/shared/skillRanking.js +74 -13
  206. package/dist/ui/assets/index-Cwq4d0hX.js +23 -0
  207. package/dist/ui/assets/index-Cyjy8bWO.css +1 -0
  208. package/dist/ui/index.html +2 -2
  209. package/docs/contracts/settings-classes.md +10 -6
  210. package/package.json +4 -4
  211. package/src/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
  212. package/src/agent-src/scripts/deferral_carry.ts +339 -0
  213. package/src/agent-src/scripts/update_roadmap_progress.ts +4 -1
  214. package/src/agent-src/templates/scripts/work_engine/directives/ui/app_spec.ts +10 -4
  215. package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +302 -21
  216. package/src/agent-src/templates/scripts/work_engine/directives/ui/audit.ts +22 -3
  217. package/src/agent-src/templates/scripts/work_engine/directives/ui/scaffold.ts +6 -1
  218. package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
  219. package/src/agent-src/templates/scripts/work_engine/state.ts +57 -7
  220. package/src/agent-src/templates/scripts/work_engine/taxonomy/detect.ts +500 -0
  221. package/src/agent-src/templates/scripts/work_engine/taxonomy/place.ts +183 -0
  222. package/src/config/agent-settings.template.yml +91 -22
  223. package/src/config/ci-local-parity.yml +18 -0
  224. package/src/config/continuity-surface.json +9 -2
  225. package/src/config/evaluator-budgets.json +4 -4
  226. package/src/config/gate-coverage.yml +327 -3
  227. package/src/config/gate-violation-baselines.json +21 -9
  228. package/src/config/hook-bundle-budget.json +25 -0
  229. package/src/config/hook-latency-budget.json +21 -0
  230. package/src/config/hook-token-budget.json +8 -3
  231. package/src/config/host-instruction-limits.json +33 -0
  232. package/src/config/metric-registry.yml +114 -0
  233. package/src/config/placeholder-drift-budget.json +10 -0
  234. package/src/config/routing-coverage-seed.json +38 -3
  235. package/src/config/rule-activation-census.json +7 -3
  236. package/src/config/rule-consequence-class.json +161 -0
  237. package/src/config/rule-law-ceilings.json +99 -0
  238. package/src/install/claudePathsPlan.ts +46 -4
  239. package/src/install/claudeRuleRewrite.ts +10 -1
  240. package/src/install/emit_host_rules_cli.ts +43 -34
  241. package/src/install/globalRuleScope.ts +109 -0
  242. package/src/install/host_rule_ownership.ts +170 -0
  243. package/src/install/installThinLayer.ts +312 -0
  244. package/src/install/installedRuleLinks.ts +220 -0
  245. package/src/install/wizard-plan.ts +24 -0
  246. package/src/scripts/_cli/cmd_doctor.ts +28 -90
  247. package/src/scripts/_cli/cmd_doctor_neighbours.ts +293 -0
  248. package/src/scripts/_cli/doctor_execution.ts +100 -17
  249. package/src/scripts/_cli/doctor_network_posture.ts +226 -0
  250. package/src/scripts/_dispatch.bash +16 -2
  251. package/src/scripts/_lib/agent_settings.ts +11 -0
  252. package/src/scripts/_lib/body_portable.ts +102 -0
  253. package/src/scripts/_lib/cc_transcript.ts +132 -1
  254. package/src/scripts/_lib/claude_settings_hooks.ts +10 -8
  255. package/src/scripts/_lib/concern_sla_window.ts +200 -0
  256. package/src/scripts/_lib/estate_offsets.ts +241 -0
  257. package/src/scripts/_lib/exemption_shape.ts +143 -0
  258. package/src/scripts/_lib/fnv.ts +23 -0
  259. package/src/scripts/_lib/foreign_scan.ts +106 -0
  260. package/src/scripts/_lib/forge_protection.ts +114 -0
  261. package/src/scripts/_lib/forge_reader.ts +558 -0
  262. package/src/scripts/_lib/gitignore_block.ts +314 -0
  263. package/src/scripts/_lib/global_deploy_inventory.ts +32 -0
  264. package/src/scripts/_lib/graph_feeder_record.ts +214 -0
  265. package/src/scripts/_lib/hook_settings.ts +73 -0
  266. package/src/scripts/_lib/host_capability.ts +40 -19
  267. package/src/scripts/_lib/host_env_write.ts +111 -0
  268. package/src/scripts/_lib/host_hook_merge.ts +165 -0
  269. package/src/scripts/_lib/installed_layer.ts +538 -0
  270. package/src/scripts/_lib/json_merge.ts +82 -0
  271. package/src/scripts/_lib/json_pointers.ts +93 -11
  272. package/src/scripts/_lib/lean_projection_mode.ts +275 -15
  273. package/src/scripts/_lib/llm_proposer_transport.ts +14 -4
  274. package/src/scripts/_lib/machine_wake.ts +16 -3
  275. package/src/scripts/_lib/neighbour_census.ts +760 -0
  276. package/src/scripts/_lib/neighbour_scan.ts +122 -0
  277. package/src/scripts/_lib/neighbour_tool_use.ts +189 -0
  278. package/src/scripts/_lib/obligations.ts +119 -8
  279. package/src/scripts/_lib/probe_inputs.ts +271 -0
  280. package/src/scripts/_lib/prompt_shape.ts +46 -0
  281. package/src/scripts/_lib/read_surface_scan.ts +322 -0
  282. package/src/scripts/_lib/release_highlights.ts +2 -1
  283. package/src/scripts/_lib/release_migration_gate.ts +19 -3
  284. package/src/scripts/_lib/reserved_name_sweep.ts +73 -0
  285. package/src/scripts/_lib/retrieval_sanitize.ts +77 -16
  286. package/src/scripts/_lib/review_coverage.ts +134 -0
  287. package/src/scripts/_lib/rule_consequence_class.ts +71 -0
  288. package/src/scripts/_lib/rule_injection.ts +130 -10
  289. package/src/scripts/_lib/rule_law_section.ts +147 -0
  290. package/src/scripts/_lib/rule_layer_overlap.ts +58 -0
  291. package/src/scripts/_lib/shell_write_shapes.ts +108 -0
  292. package/src/scripts/_lib/skill_origin.ts +254 -0
  293. package/src/scripts/_lib/structural_hiding.ts +622 -0
  294. package/src/scripts/_lib/structured_ask.ts +64 -21
  295. package/src/scripts/_lib/thin_rules.ts +540 -0
  296. package/src/scripts/_lib/touched_file_quality.ts +434 -0
  297. package/src/scripts/_lib/turn_end_refusals.ts +600 -4
  298. package/src/scripts/_lib/turn_end_transcript.ts +216 -0
  299. package/src/scripts/_lib/verification_command.ts +324 -0
  300. package/src/scripts/_lib/verification_evidence.ts +647 -0
  301. package/src/scripts/_lib/verify_clause.ts +280 -0
  302. package/src/scripts/_lib/windsurf_render.ts +63 -0
  303. package/src/scripts/ai_council/cli_call_budget.ts +13 -5
  304. package/src/scripts/ai_council/clients.ts +26 -57
  305. package/src/scripts/ai_council/config.ts +1 -1
  306. package/src/scripts/ai_council/vendor_defaults.ts +45 -0
  307. package/src/scripts/ai_team/team_dispatch.ts +4 -0
  308. package/src/scripts/audit_skill_overlap.ts +261 -0
  309. package/src/scripts/before_complete_hook.ts +573 -25
  310. package/src/scripts/bench_hook_latency.ts +412 -5
  311. package/src/scripts/bench_touched_file_quality.ts +238 -0
  312. package/src/scripts/cache_realization_report.ts +61 -1
  313. package/src/scripts/check_argument_hint.ts +287 -0
  314. package/src/scripts/check_claims.ts +125 -1
  315. package/src/scripts/check_enforcement_coverage.ts +38 -9
  316. package/src/scripts/check_enforcement_matrix.ts +621 -22
  317. package/src/scripts/check_estate_count.ts +130 -153
  318. package/src/scripts/check_finding_dispositions.ts +138 -7
  319. package/src/scripts/check_generator_sync.ts +71 -0
  320. package/src/scripts/check_hook_bundle_composition.ts +370 -0
  321. package/src/scripts/check_host_docs_digest.ts +786 -0
  322. package/src/scripts/check_host_format_column.ts +559 -0
  323. package/src/scripts/check_input_references.ts +228 -0
  324. package/src/scripts/check_inputs_parity.ts +235 -0
  325. package/src/scripts/check_kernel_edit_ratified.ts +89 -9
  326. package/src/scripts/check_kill_switch_table.ts +294 -0
  327. package/src/scripts/check_memory.ts +7 -1
  328. package/src/scripts/check_placeholder_drift.ts +221 -0
  329. package/src/scripts/check_read_surface_coverage.ts +515 -0
  330. package/src/scripts/check_release_highlights.ts +10 -0
  331. package/src/scripts/check_release_holds.ts +2 -1
  332. package/src/scripts/check_release_pr_shape.ts +38 -15
  333. package/src/scripts/check_routing_coverage.ts +378 -11
  334. package/src/scripts/check_standing_rule_delivery.ts +33 -13
  335. package/src/scripts/check_static_parity.ts +17 -0
  336. package/src/scripts/check_verify_expectation_delta.ts +521 -0
  337. package/src/scripts/ci_settle.ts +145 -19
  338. package/src/scripts/closure_scan.ts +115 -1
  339. package/src/scripts/code_graph/detect.ts +127 -7
  340. package/src/scripts/code_graph/foreign.ts +194 -0
  341. package/src/scripts/code_graph/query.ts +217 -4
  342. package/src/scripts/code_graph/types.ts +26 -2
  343. package/src/scripts/code_graph/validate.ts +3 -1
  344. package/src/scripts/code_graph/verbs.ts +103 -0
  345. package/src/scripts/compile_hook_manifest.ts +90 -14
  346. package/src/scripts/condense.ts +14 -27
  347. package/src/scripts/estate_exemption_shape.ts +202 -0
  348. package/src/scripts/external_sources_denylist.json +29 -4
  349. package/src/scripts/generate_host_cost_table.ts +1 -1
  350. package/src/scripts/hook_manifest.json +1 -1
  351. package/src/scripts/hook_manifest.yaml +192 -14
  352. package/src/scripts/hooks/block_config_weakening.ts +294 -4
  353. package/src/scripts/hooks/block_kernel_rule_writes.ts +9 -78
  354. package/src/scripts/hooks/block_plumbing_writes.ts +342 -0
  355. package/src/scripts/hooks/bundle_integrity.ts +291 -0
  356. package/src/scripts/hooks/chain_nudge_hook.ts +1 -2
  357. package/src/scripts/hooks/code_graph_context_hook.ts +253 -25
  358. package/src/scripts/hooks/comment_discipline_hook.ts +1 -3
  359. package/src/scripts/hooks/concern_failure_policy.ts +280 -0
  360. package/src/scripts/hooks/concern_registry.ts +2 -0
  361. package/src/scripts/hooks/concern_timings.ts +94 -0
  362. package/src/scripts/hooks/delegation_nudge_hook.ts +1 -2
  363. package/src/scripts/hooks/design_pass_hook.ts +100 -9
  364. package/src/scripts/hooks/design_slop_hook.ts +1 -2
  365. package/src/scripts/hooks/dispatch_hook.ts +77 -71
  366. package/src/scripts/hooks/edit_shape_hook.ts +1 -2
  367. package/src/scripts/hooks/end_review_nudge_hook.ts +1 -1
  368. package/src/scripts/hooks/evidence_independence.ts +1 -2
  369. package/src/scripts/hooks/exit_codes.ts +129 -0
  370. package/src/scripts/hooks/host_lowering.json +1 -0
  371. package/src/scripts/hooks/host_lowering.ts +146 -3
  372. package/src/scripts/hooks/host_lowering.yaml +262 -46
  373. package/src/scripts/hooks/host_semantics.ts +30 -2
  374. package/src/scripts/hooks/injection_budget.ts +9 -2
  375. package/src/scripts/hooks/interruption_ledger_hook.ts +1 -2
  376. package/src/scripts/hooks/journal_record_hook.ts +1 -2
  377. package/src/scripts/hooks/memory_recall_hook.ts +1 -2
  378. package/src/scripts/hooks/obligation_settle_hook.ts +151 -5
  379. package/src/scripts/hooks/one_question_per_ask_hook.ts +43 -6
  380. package/src/scripts/hooks/orchestration_record_hook.ts +1 -2
  381. package/src/scripts/hooks/payload_stub.ts +10 -1
  382. package/src/scripts/hooks/permission_gate.ts +1 -2
  383. package/src/scripts/hooks/push_settle_hook.ts +1 -3
  384. package/src/scripts/hooks/replay_hook.ts +2 -1
  385. package/src/scripts/hooks/reread_guard_hook.ts +1 -2
  386. package/src/scripts/hooks/review_baseline_hook.ts +1 -2
  387. package/src/scripts/hooks/rtk_wrap_hook.ts +1 -2
  388. package/src/scripts/hooks/rule_inject_hook.ts +765 -68
  389. package/src/scripts/hooks/run_continuation_hook.ts +13 -15
  390. package/src/scripts/hooks/skill_route_hook.ts +1 -2
  391. package/src/scripts/hooks/source_first_gate_hook.ts +1 -2
  392. package/src/scripts/hooks/spawn_guard_shadow_hook.ts +1 -2
  393. package/src/scripts/hooks/subagent_ledger_hook.ts +1 -2
  394. package/src/scripts/hooks/suggestion_capture_hook.ts +1 -1
  395. package/src/scripts/hooks/table_fingerprint.ts +70 -0
  396. package/src/scripts/hooks/telemetry_flush_hook.ts +1 -2
  397. package/src/scripts/hooks/telemetry_usage_hook.ts +65 -10
  398. package/src/scripts/hooks/tool_result_bytes_hook.ts +93 -9
  399. package/src/scripts/hooks/turn_end_gate_hook.ts +421 -324
  400. package/src/scripts/hooks/ui_route_nudge_hook.ts +1 -2
  401. package/src/scripts/hooks_status.ts +112 -0
  402. package/src/scripts/injection_scan_hook.ts +7 -0
  403. package/src/scripts/install.ts +75 -189
  404. package/src/scripts/installed_layer_report.ts +103 -0
  405. package/src/scripts/language_mirror_hook.ts +15 -6
  406. package/src/scripts/learning_sidecar.ts +119 -8
  407. package/src/scripts/lint_deny_text.ts +419 -0
  408. package/src/scripts/lint_exit_codes.ts +262 -0
  409. package/src/scripts/lint_hook_manifest.ts +108 -0
  410. package/src/scripts/lint_major_migration_sections.ts +156 -26
  411. package/src/scripts/lint_pack_boundaries.ts +63 -5
  412. package/src/scripts/lint_roadmap_blockers.ts +78 -12
  413. package/src/scripts/lint_rule_law_section.ts +517 -0
  414. package/src/scripts/lint_skill_descriptions.ts +1 -1
  415. package/src/scripts/lint_skill_scripts_readonly.ts +1 -1
  416. package/src/scripts/lint_workflow_security.ts +161 -5
  417. package/src/scripts/mcp_server/consumer_tool_catalog.json +53 -0
  418. package/src/scripts/mcp_server/graph_tools.ts +72 -3
  419. package/src/scripts/mcp_server/prompts.ts +142 -1
  420. package/src/scripts/measure_routing_signal.ts +54 -16
  421. package/src/scripts/measure_skill_ranker_baseline.ts +515 -53
  422. package/src/scripts/measure_turn_end_gate.ts +193 -0
  423. package/src/scripts/memory_learn_hook.ts +91 -6
  424. package/src/scripts/memory_lookup.ts +1 -1
  425. package/src/scripts/model_rule_injection.ts +52 -5
  426. package/src/scripts/prepack-check.mjs +53 -0
  427. package/src/scripts/project_thin_rules.ts +34 -327
  428. package/src/scripts/release_publication.ts +13 -1
  429. package/src/scripts/report_evidence_temperature.ts +657 -0
  430. package/src/scripts/report_installed_rule_links.ts +157 -0
  431. package/src/scripts/report_invocation_surface.ts +383 -0
  432. package/src/scripts/report_label_agreement.ts +233 -0
  433. package/src/scripts/report_obligation_carriers.ts +699 -0
  434. package/src/scripts/report_obligation_mechanism.ts +230 -0
  435. package/src/scripts/report_obligation_writer_split.ts +236 -0
  436. package/src/scripts/report_single_token_triggers.ts +277 -0
  437. package/src/scripts/report_skill_menu_census.ts +208 -0
  438. package/src/scripts/report_skill_ranker_confusion.ts +442 -0
  439. package/src/scripts/report_standing_payload_by_host.ts +188 -15
  440. package/src/scripts/report_verification_record_coverage.ts +306 -0
  441. package/src/scripts/roadmap_verify_share.ts +213 -0
  442. package/src/scripts/rule_activation_census.ts +5 -2
  443. package/src/scripts/rule_trigger_eval.ts +9 -9
  444. package/src/scripts/schemas/command.schema.json +44 -0
  445. package/src/scripts/schemas/review-findings.schema.json +7 -2
  446. package/src/scripts/schemas/rule.schema.json +5 -0
  447. package/src/scripts/schemas/skill.schema.json +44 -0
  448. package/src/scripts/self_review_gate.ts +421 -17
  449. package/src/scripts/semantic_parity_census.ts +314 -0
  450. package/src/scripts/session_eol_report.ts +54 -1
  451. package/src/scripts/skill_tools/score_skill_relevance.ts +290 -25
  452. package/src/scripts/sweep_dead_scan_roots.ts +1 -1
  453. package/src/scripts/sweep_skill_ranker_signals.ts +129 -0
  454. package/src/scripts/sync_gitignore.ts +29 -235
  455. package/src/scripts/trigger_eval_grandfather.json +0 -7
  456. package/src/scripts/trigger_eval_rotation.ts +122 -27
  457. package/src/scripts/ui_conformance_probe.ts +156 -4
  458. package/src/scripts/update_prices.ts +85 -3
  459. package/src/scripts/write_bundle_digest.mjs +74 -0
  460. package/src/server/schemas/settings.ts +41 -0
  461. package/src/shared/skillRanking.ts +117 -11
  462. package/src/templates/consumer-settings/ONBOARDING.md +1 -0
  463. package/dist/cli-delegate/chunk-FXYUYU4N.js +0 -4416
  464. package/dist/cli-delegate/chunk-QJWAUMJW.js +0 -1072
  465. package/dist/cli-delegate/chunk-YDPILCOL.js +0 -152
  466. package/dist/ui/assets/index-DH1xc62v.js +0 -29
  467. package/dist/ui/assets/index-jSfMW8_t.css +0 -1
@@ -18,11 +18,10 @@
18
18
  * target dir of your choosing — it never overwrites the live `.claude/` /
19
19
  * `.augment/` projections.
20
20
  *
21
- * NOTE (faithful literal): the thin-entry pointer keeps the verbatim
22
- * `Body: [`{rule_id}`](../../dist/agent-src/rules/{rule_id}.md)`
23
- * Markdown link from the retired Python implementation. The same-basename `.py` twin
24
- * carries that literal, so the ADR-051 legacy-path guard exempts this `.ts`
25
- * file by twin-parity.
21
+ * NOTE: the thin-entry pointer literal moved with the mechanism — it is
22
+ * `BODY_LINK_PREFIX` in `_lib/thin_rules.ts` now, so the twin-parity argument
23
+ * that exempted it from the ADR-051 legacy-path guard belongs to THAT file and
24
+ * no longer describes this one, which holds the string nowhere.
26
25
  *
27
26
  * Historical quirks are preserved deliberately — tests and downstream consumers pin the exact behaviour.
28
27
  *
@@ -34,299 +33,20 @@ import * as fs from 'node:fs';
34
33
  import * as path from 'node:path';
35
34
  import process from 'node:process';
36
35
  import { fileURLToPath, pathToFileURL } from 'node:url';
37
- import { pathOnlyRuleIds, triggerlessRuleIds, } from './_lib/rule_injection.js';
38
36
  import * as token_count from './_lib/token_count.js';
39
- const _HERE = fileURLToPath(import.meta.url);
40
- // REPO_ROOT = Path(__file__).resolve().parent.parent.parent — three dirs up
41
- // from src/scripts/<file>.
42
- export const REPO_ROOT = path.resolve(path.dirname(_HERE), '..', '..');
43
- export const RULES_SOURCE = path.join(REPO_ROOT, 'dist/agent-src', 'rules');
44
- export const ROUTER = path.join(REPO_ROOT, 'dist', 'router.json');
45
- /** `sorted(dir.glob("*.md"))` — non-recursive, lexically sorted abs paths. */
46
- function _globSortedMd(dir) {
47
- let names;
48
- try {
49
- names = fs.readdirSync(dir);
50
- }
51
- catch {
52
- return [];
53
- }
54
- const out = names.filter((n) => n.endsWith('.md')).map((n) => path.join(dir, n));
55
- out.sort();
56
- return out;
57
- }
58
- /** The always-full-bodied set — authoritative kernel list from the router. */
59
- export function kernel_ids() {
60
- const data = JSON.parse(fs.readFileSync(ROUTER, 'utf-8'));
61
- const kernel = data.kernel;
62
- if (Array.isArray(kernel)) {
63
- return new Set(kernel.map((x) => String(x)));
64
- }
65
- return new Set();
66
- }
67
- /**
68
- * Tier rules the router gives NO trigger at all.
69
- *
70
- * These cannot be delivered on a match, so thinning them would remove a body
71
- * that nothing can ever put back — a silent hole rather than a saving. They
72
- * project full-bodied, and `measure` reports them by name so the residue is
73
- * visible instead of being absorbed into the pointer count
74
- * (road-to-trigger-delivered-rule-bodies 1.3).
75
- */
76
- /**
77
- * Rules whose ONLY triggers are path-shaped — reachable from `pre_tool_use`
78
- * and from no other slot (road-to-delivery-for-every-host 3.2).
79
- *
80
- * They must never be thinned while the delivery concern is NOT bound on
81
- * `pre_tool_use`, because a stub plus a slot nobody listens on is a rule that
82
- * reaches the model at no scope at all. This is the same failure the
83
- * `no_trigger_ids` exemption prevents, one step out: there the rule has nothing
84
- * to match on, here it has nothing to match ON.
85
- *
86
- * Stated as a PROPERTY rather than a list of ids. If the concern is ever bound
87
- * on `pre_tool_use` again, this exemption is what should be reconsidered — not
88
- * three names someone has to remember.
89
- *
90
- * WHAT THIS EXEMPTION DOES **NOT** COVER — recorded 2026-09-08, R2 finding 1,
91
- * because the silence read as coverage. The predicate is `every` trigger
92
- * path-shaped. A rule with BOTH path and non-path triggers is therefore THINNED,
93
- * and its path-shaped half then has no carrier at all: the stub carries no
94
- * frontmatter (`condense.ts` writes it with `_writeText`, bypassing
95
- * `_emit_claude_rule`'s host-native `paths:` key), `pre_tool_use` lost the
96
- * binding under owner ruling E2, and `user_prompt_submit` never populates
97
- * `openFiles`. Measured over the current `dist/router.json`: **18 such rules**,
98
- * all non-kernel and all thinned — augment-edit-discipline, design-fidelity,
99
- * doc-screenshot-hygiene, domain-adoption-policy,
100
- * framework-neutrality-in-generic-skills, image-likeness-and-rights,
101
- * laravel-translations, lethal-trifecta-guard, linked-projects-onboarding-gate,
102
- * low-impact-corpus-privacy-floor, markdown-safe-codeblocks, onboarding-gate,
103
- * persona-governance, php-coding, provider-lifecycle-discipline,
104
- * roadmap-ci-steps-policy, roadmap-progress-sync, settings-ask-protocol.
105
- *
106
- * They do NOT reach the model at no scope: every non-path route
107
- * (keyword / phrase / command) still delivers the body through the concern, and
108
- * on `claude-code` they never had a separate host-native path route to lose —
109
- * `_claude_paths_plan` emits no `paths:` for a mixed-trigger rule on purpose, so
110
- * under `eager-all` they loaded UNCONDITIONALLY. What is lost is the difference
111
- * between unconditional and prompt-triggered: a session that touches a matching
112
- * file and says nothing that matches gets nothing.
113
- *
114
- * The labelled corpus cannot see this and the endpoint says so rather than
115
- * implying otherwise — `model_rule_injection --endpoints` (b) now publishes the
116
- * shipped `user_prompt_submit` reach beside the pre-registered reading, and
117
- * every one of these 18 has at least one prompt-matching positive, so none
118
- * appears in its "reachable only via a path trigger" column.
119
- *
120
- * WHY THIS IS NOT WIDENED TO `some` HERE. Measured: exempting all 18 moves the
121
- * thin rule layer 23,592 -> 39,921 GPT tok (+16,329, +69 %), which is a budget
122
- * move of a magnitude no agent may take, and it would erase most of the saving
123
- * the flip is licensed on. Restoring a path route needs either that exemption
124
- * under a re-anchored baseline or a `pre_tool_use` binding under a raised slot
125
- * cap — both owner-reserved, so the closure is tracked rather than taken here.
126
- * ADR-267's Consequences section names the receiver.
127
- */
128
- /**
129
- * ONE spelling of the router-derived sets, shared with the injector (R2
130
- * finding 11).
131
- *
132
- * `path_only_ids` and `no_trigger_ids` were each a second, hand-rolled
133
- * implementation of `_lib/rule_injection.ts::pathOnlyRuleIds` /
134
- * `triggerlessRuleIds` — verified identical over the current router at the time
135
- * (symmetric difference empty), so drift risk rather than a live defect. It is
136
- * exactly the hazard `THIN_ENTRY_MARKER`'s own comment argues against one
137
- * screen below ("a gate that re-spelled this string would drift from the writer
138
- * silently"), and the two consumers here are the PROJECTOR's exemption set and
139
- * the INJECTOR's reachability set: they must not be able to disagree about which
140
- * rules the delivery path can reach.
141
- *
142
- * The finding named `path_only_ids`. The defect-pattern sweep found the SECOND
143
- * instance one function down — `no_trigger_ids` against `triggerlessRuleIds` —
144
- * and it is delegated in the same change. Count: 2 of 2 duplicated
145
- * router-derived sets in this file, 0 remaining.
146
- */
147
- function _router() {
148
- return JSON.parse(fs.readFileSync(ROUTER, 'utf-8'));
149
- }
150
- export function path_only_ids() {
151
- return pathOnlyRuleIds(_router());
152
- }
153
- export function no_trigger_ids() {
154
- return new Set(triggerlessRuleIds(_router()));
155
- }
156
- /**
157
- * id → workspaces for every non-kernel router entry (router.json schema v2,
158
- * road-to-request-scoped-rule-load Phase 1). Rules absent from the map (or
159
- * with an empty list) fail safe: they stay in scope.
160
- */
161
- export function rule_workspaces_map() {
162
- const data = JSON.parse(fs.readFileSync(ROUTER, 'utf-8'));
163
- const map = new Map();
164
- for (const tier of ['tier_1', 'tier_2']) {
165
- const entries = data[tier];
166
- if (!Array.isArray(entries))
167
- continue;
168
- for (const e of entries) {
169
- const obj = e;
170
- const ws = Array.isArray(obj.workspaces) ? obj.workspaces.map((w) => String(w)) : [];
171
- map.set(String(obj.id), ws);
172
- }
173
- }
174
- return map;
175
- }
176
- /**
177
- * Whether a rule id survives a workspace scope. Kernel always survives;
178
- * `scope === null` = legacy-all. An out-of-scope non-kernel rule is dropped
179
- * entirely — neither body nor pointer line (the pointer floor shrinks with
180
- * consumer scoping).
181
- */
182
- export function id_in_scope(rule_id, scope, kernel, wsMap, fallback_ws = []) {
183
- if (scope === null || kernel.has(rule_id)) {
184
- return true;
185
- }
186
- // Router map first (schema v2); `type: manual` rules are reference-only
187
- // and never emitted to the router — their frontmatter is the fallback.
188
- const ws = wsMap.get(rule_id) ?? fallback_ws;
189
- if (ws.length === 0) {
190
- return true; // untagged / unknown → fail safe
191
- }
192
- return ws.some((w) => scope.includes(w));
193
- }
194
- /** `workspaces:` list parsed straight from a rule file's frontmatter. */
195
- export function fm_workspaces(text) {
196
- const [fm] = split_frontmatter(text);
197
- // Flow style: `workspaces: [a, b, c]`
198
- const flow = /^workspaces:[ \t]*\[([^\]]*)\]/m.exec(fm);
199
- if (flow) {
200
- return flow[1]
201
- .split(',')
202
- .map((s) => s.trim().replace(/^["']|["']$/g, ''))
203
- .filter((s) => s.length > 0);
204
- }
205
- // Block style; tolerate the list being the LAST frontmatter key.
206
- const m = /^workspaces:[ \t]*\n((?:[ \t]+-[ \t]+.*(?:\n|$))+)/m.exec(fm);
207
- if (!m) {
208
- return [];
209
- }
210
- return [...m[1].matchAll(/-[ \t]+(\S+)/g)].map((x) => x[1]);
211
- }
212
- /** Return [frontmatter_including_fences, body]. Empty fm if none. */
213
- export function split_frontmatter(text) {
214
- if (text.startsWith('---\n')) {
215
- const end = text.indexOf('\n---\n', 4);
216
- if (end !== -1) {
217
- return [text.slice(0, end + 5), text.slice(end + 5)];
218
- }
219
- }
220
- return ['', text];
221
- }
222
- function _description(fm) {
223
- // re.search(r'^description:\s*"?(.+?)"?\s*$', fm, re.MULTILINE)
224
- const m = /^description:\s*"?(.+?)"?\s*$/m.exec(fm);
225
- return m ? m[1].trim() : '';
226
- }
227
- // How many trigger keywords/phrases to surface as the always-on match hint.
228
- const _TRIGGER_HINT_LIMIT = 6;
229
- /** A short, comma-joined sample of the rule's trigger keywords/phrases. */
230
- function _trigger_hint(fm) {
231
- const hits = [];
232
- // re.finditer(r'^\s*-\s*(?:keyword|phrase):\s*"?(.+?)"?\s*$', fm, re.MULTILINE)
233
- const re = /^\s*-\s*(?:keyword|phrase):\s*"?(.+?)"?\s*$/gm;
234
- let m;
235
- while ((m = re.exec(fm)) !== null) {
236
- hits.push(m[1].trim());
237
- if (hits.length >= _TRIGGER_HINT_LIMIT) {
238
- break;
239
- }
240
- }
241
- return hits.join(', ');
242
- }
243
- /** Python `str.title()` — uppercase first alpha of each run, rest lowercase. */
244
- function _title(s) {
245
- return s.replace(/[A-Za-z]+/g, (w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase());
246
- }
247
- /**
248
- * The marker that makes a projected entry recognisable as a stub.
249
- *
250
- * Exported so the WRITER and every DETECTOR share one definition. A gate that
251
- * re-spelled this string would drift from the writer silently, and the failure
252
- * would be invisible in exactly the direction that matters: a stub the gate
253
- * fails to recognise reads as a complete rule body.
254
- */
255
- export const THIN_ENTRY_MARKER = '> Routed rule — load the body on trigger-match.';
256
- /** Is this projected entry a pointer stub rather than a rule body? */
257
- export function is_thin_entry(text) {
258
- return text.includes(THIN_ENTRY_MARKER);
259
- }
260
37
  /**
261
- * Where a stub tells a reader the body actually is.
262
- *
263
- * FIXED 2026-09-07: this pointed into the uncondensed source tree ADR-051
264
- * retired — the literal path is deliberately NOT reproduced here, because
265
- * `check_no_uncondensed_refs` matches the string and cannot tell a repair
266
- * record from a live reference; `git log -S` on this file finds the old value.
267
- * It exists in no checkout, so EVERY stub's fallback pointer
268
- * resolved to nothing — invisible under `delivery`, where the hook loads the
269
- * body from `dist/agent-src/rules` and never follows this link, and total under
270
- * `thin`, where the pointer is the only path to the body there is.
38
+ * The mechanism lives in `_lib/thin_rules.ts`; this file is its CLI.
271
39
  *
272
- * KNOWN LIMIT, stated rather than discovered later: one relative prefix cannot
273
- * be right for every tree, because they sit at different depths — `.claude/rules`
274
- * and `.cursor/rules` are two levels below the repo root and `.clinerules` is
275
- * one. `../../` is correct for the first two, which are the only trees the
276
- * shipped `lean_projection.hosts` default can thin. A stub in `.clinerules`
277
- * needs an operator to have added `cline` to that list, and its pointer is off
278
- * by one level. That is strictly better than the previous state, where the
279
- * pointer was dead in all three, and it is recorded here so the remaining case
280
- * is a known limit rather than a surprise.
40
+ * Re-exported wholesale so every existing importer of
41
+ * `project_thin_rules.{build_thin,thin_entry,is_thin_entry,RULES_SOURCE,…}`
42
+ * keeps working unchanged. The split exists because `src/scripts/install.ts` is
43
+ * a bundle entry and `check_installer_import_purity` forbids it reaching a
44
+ * module-level `process.exit()` — which this file has, at its foot, by design.
281
45
  */
282
- const BODY_LINK_PREFIX = '../../dist/agent-src/rules/';
283
- /** Build the minimal progressive-disclosure pointer for a non-kernel rule. */
284
- export function thin_entry(rule_id, text) {
285
- const [fm] = split_frontmatter(text);
286
- const desc = _description(fm);
287
- const hint = _trigger_hint(fm);
288
- const title = _title(rule_id.replace(/-/g, ' '));
289
- const fires = hint ? ` Fires on: ${hint}.` : '';
290
- return (`## ${title}\n` +
291
- `${THIN_ENTRY_MARKER}${fires} ${desc} ` +
292
- `Body: [\`${rule_id}\`](${BODY_LINK_PREFIX}${rule_id}.md)\n`);
293
- }
294
- /** Map {filename: thin_or_full_text} for every rule. Kernel stays full. */
295
- export function build_thin(rules_dir = RULES_SOURCE, scope = null,
296
- /**
297
- * Optional sink for the D3 diagnostic
298
- * (road-to-delivery-for-every-host 2.2).
299
- *
300
- * An `auto` rule the router gives NO trigger is already kept full-bodied by
301
- * `noTrigger` below, which is the substantive protection and predates this
302
- * roadmap. What did not exist is any way to SEE it happen: the rule is
303
- * silently exempted, so an author who removes a rule's last trigger gets a
304
- * silently eager rule and no signal. The line makes the exemption audible.
305
- */
306
- announce = null) {
307
- const kernel = kernel_ids();
308
- const noTrigger = no_trigger_ids();
309
- const pathOnly = path_only_ids();
310
- const wsMap = scope !== null ? rule_workspaces_map() : new Map();
311
- const out = new Map();
312
- for (const p of _globSortedMd(rules_dir)) {
313
- const text = fs.readFileSync(p, 'utf-8');
314
- const stem = path.basename(p).replace(/\.md$/, '');
315
- if (!id_in_scope(stem, scope, kernel, wsMap, fm_workspaces(text))) {
316
- continue; // out of workspace scope — no body, no pointer line
317
- }
318
- const full = kernel.has(stem) || noTrigger.has(stem) || pathOnly.has(stem);
319
- if (announce !== null && noTrigger.has(stem) && !kernel.has(stem)) {
320
- announce(`D3: trigger-less auto rule ${path.basename(p)} — kept full-bodied, never thinned`);
321
- }
322
- if (announce !== null && pathOnly.has(stem) && !kernel.has(stem) && !noTrigger.has(stem)) {
323
- announce(`E2: path-only auto rule ${path.basename(p)} — kept full-bodied; its only triggers ` +
324
- `are path-shaped and the delivery concern is not bound on pre_tool_use`);
325
- }
326
- out.set(path.basename(p), full ? text : thin_entry(stem, text));
327
- }
328
- return out;
329
- }
46
+ export * from './_lib/thin_rules.js';
47
+ import { _globSortedMd, build_thin, fm_workspaces, id_in_scope, kernel_ids, no_trigger_ids, REPO_ROOT, RULES_SOURCE, rule_workspaces_map, } from './_lib/thin_rules.js';
48
+ void REPO_ROOT;
49
+ const _HERE = fileURLToPath(import.meta.url);
330
50
  /** Python `round(x, 1)` — round-half-to-even at one decimal. */
331
51
  function _python_round1(x) {
332
52
  const scaled = x * 10;
@@ -101,6 +101,29 @@ export const settingsSchema = z.object({
101
101
  wait_for_ci: z.boolean().default(true).describe('Whether the run stays alive until the required checks settle. true (default) = the run drives CI and reports the settled verdict. false = the run ends once the branch is pushed and the PR is open, leaving the checks to be read later. Independent of merge: a run may wait for CI without being allowed to merge.'),
102
102
  pr_topology: prTopology.default('single').describe('How a mission\'s work is shaped into pull requests. single (default) = one branch, one pull request. stacked = a dependent series. stacked is never chosen by the agent and never asked about at roadmap creation — the owner plans it or it does not happen.'),
103
103
  }),
104
+ /**
105
+ * What this package may write into the HOST's own environment.
106
+ *
107
+ * THE GUARANTEE IS THE SHAPE, not a check. Only two keys exist here, and
108
+ * both are request-SIZE caps. Neither traffic variable is expressible —
109
+ * `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` and `DISABLE_AUTOUPDATER` both
110
+ * reach the host's update-disabled resolver (the blanket one as its third
111
+ * rung, measured on Claude Code 2.1.284), so a profile able to write either
112
+ * could disable a consumer's security updates. Owner-decided 2026-09-30:
113
+ * they are not writable through this package at all, and the strongest way
114
+ * to hold that is a schema that cannot say them rather than an exclusion
115
+ * list somebody has to maintain.
116
+ *
117
+ * `null` is the default on both, and it is the off switch: nothing is
118
+ * written. There is no separate enable flag, because a flag plus a value is
119
+ * two ways to say off and one of them would drift.
120
+ */
121
+ host_environment: z.object({
122
+ request_size_caps: z.object({
123
+ bash_max_output_length: z.number().int().positive().max(150_000).nullable().default(null).describe('Character cap on Bash tool output the host places inline into a model request. null (default) = this package writes nothing and the host default of 30000 applies. A number is written into the host env block. Values above 150000 are capped by the host itself, so the schema refuses them here rather than writing a value the host silently changes. Bounds request SIZE, never request COUNT: lowering it suppresses no telemetry, no update check and no download.'),
124
+ max_mcp_output_tokens: z.number().int().positive().nullable().default(null).describe('Token cap on a single MCP tool result the host places into a model request. null (default) = nothing written, host default 25000 applies. Same size-not-count caveat: it does not govern MCP connections, timeouts, or whether a tool runs.'),
125
+ }).default({}).describe('Request-size caps this package may write into the host env block. Both null by default. No traffic or auto-updater variable is expressible here, by construction — see the block comment.'),
126
+ }).default({}).describe('What this package may write into the host environment. ABSENT resolves to the all-null shape, which is the same thing as off — a settings file predating this section must not fail to parse, and "no section" and "both caps null" both mean write nothing.'),
104
127
  augment: z.object({
105
128
  rules_use_symlinks: z.boolean().default(false).describe('When true, .augment/rules/*.md are symlinks into dist/agent-src/rules/ — edits flow back to source on save. When false (default), they are copies — safer on Windows and shared volumes, but rule edits in .augment/ are lost on the next `task sync`.'),
106
129
  }),
@@ -167,6 +190,9 @@ export const settingsSchema = z.object({
167
190
  fidelity_mode: 'strict',
168
191
  approximation: { enabled: false, tolerance: { color: null, length: null } },
169
192
  }),
193
+ code_graph: z.object({
194
+ consumer_index_paths: z.array(z.string()).default([]).describe("Extra project-relative paths where THIS project keeps a code-graph index another tool wrote. The built-in list is deliberately vendor-neutral (graph.json, code-graph.json, .code-graph/graph.json) and names no tool, so a tool that writes its index elsewhere is named here rather than waited for. A graph found this way LOADS and answers query and explain with every edge tagged read-from-elsewhere; the gate verbs (impact, untested, dead) refuse a graph made only of such edges and say so, because an empty answer from a gate must not read as 'nothing found' when it means 'nothing trusted'. Absolute paths and paths escaping the project root are ignored."),
195
+ }).default({}),
170
196
  consistency: z.object({
171
197
  cross_source: crossSourceMode.default('on').describe('Consumed by the cross-source-consistency rule. When the agent works from multiple sources (ticket text, an attached image/mockup, the spec, the codebase) it checks them against each other and asks before proceeding on a discrepancy — instead of silently guessing. on (default) = surface every real cross-source contradiction / silent-scope-expansion as one question; auto = surface only high-confidence contradictions, state low-confidence as an assumption; off = no cross-source checking.'),
172
198
  }).default({ cross_source: 'on' }),
@@ -296,6 +322,9 @@ export const settingsSchema = z.object({
296
322
  tier1_concerns: z.array(z.string()).default([]).describe('Concern IDs (one per line) that are allowed to block the run on failure rather than warn. Reserved for high-confidence guards — leave empty unless you maintain custom hooks.'),
297
323
  hard_fail: z.boolean().default(false).describe('When a hook exceeds hooks.concern_budget.max_per_event, fail the run (true) instead of warning and continuing (false, default). Turn on in CI when you want hook quality to gate merges.'),
298
324
  }),
325
+ verify_before_complete: z.object({
326
+ touched_file_quality: z.enum(['off', 'shadow', 'warn']).default('off').describe("Stop-slot pass that runs the project's OWN quality commands — the ones resolve_toolchain() already reports — over the files this turn edited. Default off. `shadow` records a per-run result and emits nothing; `warn` adds ONE advisory line of at most 200 bytes. Never blocks and never counts as verification: a command recorded here never reaches _lib/verification_command.ts, so a clean eslint run cannot let a turn claim it verified anything. A writing command runs only in its check form (pint --test) or not at all, and a command with no per-file form is skipped rather than run project-wide at every stop."),
327
+ }).default({}),
299
328
  injection_scan: z.object({
300
329
  enabled: z.boolean().default(false).describe('PostToolUse prompt-injection scanner (road-to-security-pillar.md P3.2). Default off. When on, scans tool output (file reads, web fetches, MCP responses) for injection signatures and WARNS in context (never blocks). Runtime backstop on top of the always-on untrusted-input-defense rule; detection is probabilistic.'),
301
330
  }).default({}),
@@ -24,10 +24,13 @@
24
24
  * `score_skill_relevance` CLI's argparse-parity suite is the check that the move
25
25
  * changed nothing.
26
26
  *
27
- * THE ONE ADDITION is `triggerTerms`, off by default. Phase 3.1 of the same
28
- * roadmap indexes `triggers.keyword` / `triggers.phrase` text; it is an opt-in
29
- * parameter rather than a second function so the two rankers can be measured
30
- * against each other on one corpus.
27
+ * THE ADDITIONS ARE ALL OFF BY DEFAULT and live in one {@link RankOptions}
28
+ * object: three that widen the indexed TERM SOURCE (trigger prose, the skill's
29
+ * own `## When to use` section, the body's headings) and one that changes the
30
+ * WEIGHTING (inverse document frequency over the catalogue). They are opt-in
31
+ * parameters rather than separate functions so two configurations can be
32
+ * measured against each other on one corpus without becoming two rankers. With
33
+ * every flag off the arithmetic is the ported one, unchanged.
31
34
  *
32
35
  * Pure — no imports, no I/O, no clock.
33
36
  */
@@ -113,23 +116,78 @@ export function skillTerms(skill, opts = {}) {
113
116
  const parts = [skill.name, skill.description];
114
117
  if (opts.includeTriggers && skill.triggerText)
115
118
  parts.push(...skill.triggerText);
119
+ if (opts.includeWhenToUse && skill.whenToUseText)
120
+ parts.push(skill.whenToUseText);
121
+ if (opts.includeHeadings && skill.headingText)
122
+ parts.push(...skill.headingText);
116
123
  return tokenize(parts.join(' '));
117
124
  }
125
+ /** True when `opts` turns on at least one term source beyond name + description. */
126
+ export function widensTermSource(opts) {
127
+ return Boolean(opts.includeTriggers || opts.includeWhenToUse || opts.includeHeadings);
128
+ }
129
+ /**
130
+ * @param termSets the per-skill term sets, in the same order as `skills`.
131
+ * Required rather than derived, so the catalogue is tokenized ONCE per call
132
+ * instead of once here and again at the scoring loop. Tokenizing ~300 skills
133
+ * twice per prompt is invisible next to re-reading them from disk, which is
134
+ * exactly why it would have stayed invisible.
135
+ */
136
+ export function buildTermStats(skills, termSets) {
137
+ const df = new Map();
138
+ for (const terms of termSets) {
139
+ for (const t of terms)
140
+ df.set(t, (df.get(t) ?? 0) + 1);
141
+ }
142
+ return { df, skills: skills.length };
143
+ }
144
+ /**
145
+ * The weight one matched term carries.
146
+ *
147
+ * `ln(1 + skills / (1 + df))`, the smoothed textbook form: a term on every
148
+ * skill tends to zero, a term on one skill carries the most. Unknown terms are
149
+ * treated as df 0 — a task term no skill indexes cannot be matched anyway, so
150
+ * its weight only affects the denominator, where counting it fully is right:
151
+ * failing to cover a rare term should cost more than failing to cover a common
152
+ * one.
153
+ */
154
+ export function idf(term, stats) {
155
+ return Math.log(1 + stats.skills / (1 + (stats.df.get(term) ?? 0)));
156
+ }
118
157
  /**
119
158
  * The score. `taskTerms` is `tokenize(task)`; `terms` is `skillTerms(skill)`.
120
159
  *
121
160
  * Both are passed in rather than derived here so a caller ranking N skills
122
161
  * tokenizes the task once and each skill once, which is what makes this usable
123
- * on a per-prompt hook path.
162
+ * on a per-prompt hook path. `opts` and `stats` are optional and, with them
163
+ * absent or every flag off, the arithmetic is exactly the Python-parity one.
124
164
  */
125
- export function scoreSkill(taskTerms, skill, terms) {
165
+ export function scoreSkill(taskTerms, skill, terms, opts = {}, stats) {
166
+ if (opts.idfWeighting && !stats) {
167
+ throw new Error('scoreSkill: idfWeighting is set but no TermStats was passed — scoring unweighted here ' +
168
+ 'would publish a baseline number under the idf label. Build stats with buildTermStats.');
169
+ }
126
170
  if (taskTerms.size === 0)
127
171
  return 0;
128
- let inter = 0;
129
- for (const t of taskTerms)
130
- if (terms.has(t))
131
- inter++;
132
- const overlap = inter / Math.max(taskTerms.size, 1);
172
+ let overlap;
173
+ if (opts.idfWeighting && stats) {
174
+ let hit = 0;
175
+ let total = 0;
176
+ for (const t of taskTerms) {
177
+ const w = idf(t, stats);
178
+ total += w;
179
+ if (terms.has(t))
180
+ hit += w;
181
+ }
182
+ overlap = total > 0 ? hit / total : 0;
183
+ }
184
+ else {
185
+ let inter = 0;
186
+ for (const t of taskTerms)
187
+ if (terms.has(t))
188
+ inter++;
189
+ overlap = inter / Math.max(taskTerms.size, 1);
190
+ }
133
191
  let personaHit = 0;
134
192
  const taskLower = [...taskTerms].join(' ');
135
193
  for (const persona of skill.personas ?? []) {
@@ -147,9 +205,12 @@ export function scoreSkill(taskTerms, skill, terms) {
147
205
  */
148
206
  export function rankSkills(task, skills, opts = {}) {
149
207
  const taskTerms = tokenize(task);
208
+ const termSets = skills.map((s) => skillTerms(s, opts));
209
+ const stats = opts.idfWeighting ? buildTermStats(skills, termSets) : undefined;
150
210
  const rows = [];
151
- for (const skill of skills) {
152
- const score = scoreSkill(taskTerms, skill, skillTerms(skill, opts));
211
+ for (let i = 0; i < skills.length; i += 1) {
212
+ const skill = skills[i];
213
+ const score = scoreSkill(taskTerms, skill, termSets[i], opts, stats);
153
214
  if (score > 0)
154
215
  rows.push({ name: skill.name, score, personas: [...(skill.personas ?? [])] });
155
216
  }