@event4u/agent-config 16.2.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 (332) 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 +89 -237
  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 +4 -4
  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/contexts/authority/decision-revisit-gate-enforcement.md +43 -0
  23. package/dist/agent-src/contexts/communication/rules-auto/design-fidelity-enforcement.md +24 -0
  24. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +6 -6
  25. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +32 -2
  26. package/dist/agent-src/contexts/execution/session-canary-enforcement-history.md +67 -0
  27. package/dist/agent-src/contexts/execution/toolchain-resolver.md +101 -7
  28. package/dist/agent-src/rules/active-remediation.md +1 -1
  29. package/dist/agent-src/rules/autonomous-execution.md +1 -0
  30. package/dist/agent-src/rules/broken-access-control.md +1 -0
  31. package/dist/agent-src/rules/command-suggestion-policy.md +1 -0
  32. package/dist/agent-src/rules/context-hygiene.md +1 -1
  33. package/dist/agent-src/rules/decision-revisit-gate.md +16 -33
  34. package/dist/agent-src/rules/design-fidelity.md +13 -16
  35. package/dist/agent-src/rules/doc-screenshot-hygiene.md +1 -0
  36. package/dist/agent-src/rules/domain-safety-disclaimer.md +1 -0
  37. package/dist/agent-src/rules/domain-safety-pii.md +1 -0
  38. package/dist/agent-src/rules/domain-safety-retention.md +1 -0
  39. package/dist/agent-src/rules/engineering-safety-floor.md +1 -0
  40. package/dist/agent-src/rules/evaluator-independence.md +3 -2
  41. package/dist/agent-src/rules/fast-path-marker-visibility.md +1 -0
  42. package/dist/agent-src/rules/finance-safety-floor.md +1 -0
  43. package/dist/agent-src/rules/git-history-discipline.md +1 -0
  44. package/dist/agent-src/rules/image-likeness-and-rights.md +1 -0
  45. package/dist/agent-src/rules/legal-safety-floor.md +3 -2
  46. package/dist/agent-src/rules/lethal-trifecta-guard.md +1 -0
  47. package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +1 -0
  48. package/dist/agent-src/rules/media-governance-routing.md +14 -17
  49. package/dist/agent-src/rules/persona-governance.md +2 -2
  50. package/dist/agent-src/rules/provider-lifecycle-discipline.md +1 -1
  51. package/dist/agent-src/rules/question-not-instruction.md +1 -0
  52. package/dist/agent-src/rules/roadmap-progress-sync.md +1 -1
  53. package/dist/agent-src/rules/runtime-safety.md +1 -0
  54. package/dist/agent-src/rules/secret-vcs-guard.md +1 -0
  55. package/dist/agent-src/rules/security-sensitive-stop.md +3 -2
  56. package/dist/agent-src/rules/session-canary.md +8 -62
  57. package/dist/agent-src/rules/settings-ask-protocol.md +1 -0
  58. package/dist/agent-src/rules/source-confidentiality.md +1 -0
  59. package/dist/agent-src/rules/strategy-safety-floor.md +1 -0
  60. package/dist/agent-src/rules/tool-safety.md +1 -0
  61. package/dist/agent-src/rules/untrusted-input-defense.md +1 -0
  62. package/dist/agent-src/rules/user-interrupt-priority.md +1 -0
  63. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
  64. package/dist/agent-src/scripts/deferral_carry.ts +339 -0
  65. package/dist/agent-src/scripts/update_roadmap_progress.ts +4 -1
  66. package/dist/agent-src/skills/api-design/data/manifest.json +2 -2
  67. package/dist/agent-src/skills/api-testing/SKILL.md +17 -0
  68. package/dist/agent-src/skills/code-intelligence/SKILL.md +14 -2
  69. package/dist/agent-src/skills/design-system-capture/references/import-procedure.md +1 -1
  70. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +2 -2
  71. package/dist/agent-src/skills/fe-design/SKILL.md +1 -1
  72. package/dist/agent-src/skills/iconography/SKILL.md +1 -1
  73. package/dist/agent-src/skills/js-library-packaging/SKILL.md +2 -2
  74. package/dist/agent-src/skills/monorepo-workspace/SKILL.md +1 -1
  75. package/dist/agent-src/skills/quality-tools/SKILL.md +11 -1
  76. package/dist/agent-src/skills/quality-tools/references/go-tools.md +76 -0
  77. package/dist/agent-src/skills/quality-tools/references/python-tools.md +104 -0
  78. package/dist/agent-src/skills/review-routing/SKILL.md +2 -2
  79. package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +1 -1
  80. package/dist/agent-src/skills/storybook-workshop/SKILL.md +3 -3
  81. package/dist/agent-src/skills/tailwind-engineer/SKILL.md +1 -1
  82. package/dist/agent-src/skills/test-case-discovery/SKILL.md +7 -0
  83. package/dist/agent-src/skills/test-driven-development/SKILL.md +17 -0
  84. package/dist/agent-src/skills/test-performance/SKILL.md +19 -1
  85. package/dist/agent-src/skills/ui-component-architect/SKILL.md +2 -2
  86. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  87. package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +48 -6
  88. package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
  89. package/dist/cli/registry.js +1 -1
  90. package/dist/cli-delegate/archive_completed_roadmaps.js +92 -12
  91. package/dist/cli-delegate/check_update_banner.js +12 -1
  92. package/dist/cli-delegate/chunk-523HCFYO.js +90 -0
  93. package/dist/cli-delegate/{chunk-M2DPGFZ4.js → chunk-6V6TA25H.js} +22 -152
  94. package/dist/cli-delegate/chunk-7IQE3D5S.js +191 -0
  95. package/dist/cli-delegate/{chunk-6KFEC3G7.js → chunk-CQWX336L.js} +1 -1
  96. package/dist/cli-delegate/chunk-DEIV7XP7.js +108 -0
  97. package/dist/cli-delegate/chunk-EEHDXSYD.js +2040 -0
  98. package/dist/cli-delegate/{chunk-P6ZHP5W2.js → chunk-GKE7ZVFA.js} +4 -4
  99. package/dist/cli-delegate/chunk-JQOM7TTM.js +1201 -0
  100. package/dist/cli-delegate/{chunk-IGD6ERX6.js → chunk-JQVYKIZA.js} +10 -0
  101. package/dist/cli-delegate/{chunk-FC75PGJE.js → chunk-JY2I2DXV.js} +12 -1
  102. package/dist/cli-delegate/chunk-KB5FZ655.js +208 -0
  103. package/dist/cli-delegate/{chunk-7RQP4UDH.js → chunk-KR6EM23A.js} +235 -1455
  104. package/dist/cli-delegate/{chunk-LTYVIY76.js → chunk-LIYTLH6O.js} +1 -1
  105. package/dist/cli-delegate/{chunk-YJ72UIAK.js → chunk-NQ7WT43P.js} +1186 -244
  106. package/dist/cli-delegate/chunk-NXEILF2K.js +2160 -0
  107. package/dist/cli-delegate/{chunk-5R7HOLAF.js → chunk-NYX3L2PZ.js} +1 -1
  108. package/dist/cli-delegate/{chunk-4E2W63DA.js → chunk-OKJUIAPS.js} +62 -1
  109. package/dist/cli-delegate/{chunk-QAJS5YWY.js → chunk-PHD7OOLE.js} +2 -1
  110. package/dist/cli-delegate/{chunk-RGNIWTEA.js → chunk-QLDHIPWR.js} +1 -1
  111. package/dist/cli-delegate/{chunk-7XGBX6ZH.js → chunk-RQNNW7IF.js} +1314 -560
  112. package/dist/cli-delegate/{chunk-4XFP2Y3E.js → chunk-S4UMZNES.js} +1 -1
  113. package/dist/cli-delegate/{chunk-6KM6ORRY.js → chunk-S4YWNRKO.js} +24 -8
  114. package/dist/cli-delegate/{chunk-FP36SWJD.js → chunk-TRI6DQZ6.js} +2781 -340
  115. package/dist/cli-delegate/chunk-ULQRUR23.js +208 -0
  116. package/dist/cli-delegate/{chunk-NUHLI2RX.js → chunk-YCU3TIXH.js} +2 -0
  117. package/dist/cli-delegate/chunk-ZBZV2G5R.js +210 -0
  118. package/dist/cli-delegate/{chunk-WGXTVKCQ.js → chunk-ZUZKZYCN.js} +5 -3
  119. package/dist/cli-delegate/cmd_analyze_session.js +1 -1
  120. package/dist/cli-delegate/cmd_brand_status.js +1 -1
  121. package/dist/cli-delegate/cmd_conformance.js +1167 -234
  122. package/dist/cli-delegate/cmd_doctor.js +13 -6
  123. package/dist/cli-delegate/cmd_doctor_neighbours.js +23 -0
  124. package/dist/cli-delegate/cmd_explain.js +5 -5
  125. package/dist/cli-delegate/cmd_export.js +11 -8
  126. package/dist/cli-delegate/cmd_fleet.js +3 -3
  127. package/dist/cli-delegate/cmd_handoff.js +10 -7
  128. package/dist/cli-delegate/cmd_mcp_available.js +1 -1
  129. package/dist/cli-delegate/cmd_memory_get.js +3 -1
  130. package/dist/cli-delegate/cmd_migrate.js +2 -2
  131. package/dist/cli-delegate/cmd_packs_active.js +3 -3
  132. package/dist/cli-delegate/cmd_preflight.js +6 -6
  133. package/dist/cli-delegate/cmd_prune.js +11 -8
  134. package/dist/cli-delegate/cmd_refresh.js +2 -1
  135. package/dist/cli-delegate/cmd_route_audit.js +8 -6
  136. package/dist/cli-delegate/cmd_route_explain.js +4 -4
  137. package/dist/cli-delegate/cmd_session_recycle.js +4 -3
  138. package/dist/cli-delegate/cmd_settings_get.js +1 -1
  139. package/dist/cli-delegate/cmd_settings_migrate.js +11 -8
  140. package/dist/cli-delegate/cmd_settings_set.js +4 -4
  141. package/dist/cli-delegate/cmd_sync.js +11 -8
  142. package/dist/cli-delegate/cmd_uninstall.js +11 -8
  143. package/dist/cli-delegate/cmd_update.js +1 -1
  144. package/dist/cli-delegate/cmd_upgrade.js +3 -2
  145. package/dist/cli-delegate/cmd_validate.js +11 -8
  146. package/dist/cli-delegate/cmd_versions.js +1 -1
  147. package/dist/cli-delegate/deferral_carry.js +16 -0
  148. package/dist/cli-delegate/gate_execute.js +2 -2
  149. package/dist/cli-delegate/roadmap_gates.js +5 -5
  150. package/dist/cli-delegate/update_roadmap_progress.js +1 -1
  151. package/dist/discovery/deprecation-report.md +1 -1
  152. package/dist/discovery/discovery-manifest.json +127 -75
  153. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  154. package/dist/discovery/discovery-manifest.summary.md +3 -3
  155. package/dist/discovery/dormancy-report.md +1 -1
  156. package/dist/discovery/orphan-report.md +1 -1
  157. package/dist/discovery/packs.json +7 -5
  158. package/dist/discovery/trust-report.md +2 -2
  159. package/dist/discovery/workspaces.json +6 -4
  160. package/dist/hooks/dispatch.js +5357 -6656
  161. package/dist/hooks/dispatch.sha256 +1 -1
  162. package/dist/install/claudePathsPlan.js +47 -6
  163. package/dist/install/claudeRuleRewrite.js +7 -0
  164. package/dist/install/emit_host_rules_cli.js +39 -36
  165. package/dist/install/globalRuleScope.js +87 -0
  166. package/dist/install/host_rule_ownership.js +160 -0
  167. package/dist/install/install.mjs +2080 -1024
  168. package/dist/install/installThinLayer.js +261 -0
  169. package/dist/install/installedRuleLinks.js +176 -0
  170. package/dist/install/wizard-plan.js +24 -0
  171. package/dist/mcp/registry-manifest.json +3 -3
  172. package/dist/mcp/server.json +2 -2
  173. package/dist/mcp/server.mjs +31965 -27154
  174. package/dist/scripts/_lib/agent_settings.js +11 -0
  175. package/dist/scripts/_lib/claude_settings_hooks.js +10 -8
  176. package/dist/scripts/_lib/installed_layer.js +378 -0
  177. package/dist/scripts/_lib/lean_projection_mode.js +218 -15
  178. package/dist/scripts/_lib/rule_consequence_class.js +45 -0
  179. package/dist/scripts/_lib/rule_injection.js +67 -10
  180. package/dist/scripts/_lib/rule_law_section.js +122 -0
  181. package/dist/scripts/_lib/thin_rules.js +458 -0
  182. package/dist/scripts/_lib/windsurf_render.js +60 -0
  183. package/dist/scripts/condense.js +14 -26
  184. package/dist/scripts/project_thin_rules.js +14 -294
  185. package/dist/server/schemas/settings.js +6 -0
  186. package/dist/shared/skillRanking.js +74 -13
  187. package/docs/contracts/settings-classes.md +7 -5
  188. package/package.json +1 -1
  189. package/src/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
  190. package/src/agent-src/scripts/deferral_carry.ts +339 -0
  191. package/src/agent-src/scripts/update_roadmap_progress.ts +4 -1
  192. package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +48 -6
  193. package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
  194. package/src/config/agent-settings.template.yml +62 -22
  195. package/src/config/continuity-surface.json +7 -0
  196. package/src/config/evaluator-budgets.json +4 -4
  197. package/src/config/gate-coverage.yml +96 -3
  198. package/src/config/gate-violation-baselines.json +17 -9
  199. package/src/config/hook-bundle-budget.json +25 -0
  200. package/src/config/hook-token-budget.json +6 -1
  201. package/src/config/host-instruction-limits.json +33 -0
  202. package/src/config/routing-coverage-seed.json +24 -3
  203. package/src/config/rule-activation-census.json +7 -3
  204. package/src/config/rule-consequence-class.json +161 -0
  205. package/src/config/rule-law-ceilings.json +99 -0
  206. package/src/install/claudePathsPlan.ts +46 -4
  207. package/src/install/claudeRuleRewrite.ts +10 -1
  208. package/src/install/emit_host_rules_cli.ts +43 -34
  209. package/src/install/globalRuleScope.ts +109 -0
  210. package/src/install/host_rule_ownership.ts +170 -0
  211. package/src/install/installThinLayer.ts +312 -0
  212. package/src/install/installedRuleLinks.ts +220 -0
  213. package/src/install/wizard-plan.ts +24 -0
  214. package/src/scripts/_cli/cmd_doctor.ts +23 -71
  215. package/src/scripts/_cli/cmd_doctor_neighbours.ts +293 -0
  216. package/src/scripts/_dispatch.bash +16 -2
  217. package/src/scripts/_lib/agent_settings.ts +11 -0
  218. package/src/scripts/_lib/claude_settings_hooks.ts +10 -8
  219. package/src/scripts/_lib/estate_offsets.ts +241 -0
  220. package/src/scripts/_lib/exemption_shape.ts +143 -0
  221. package/src/scripts/_lib/fnv.ts +23 -0
  222. package/src/scripts/_lib/foreign_scan.ts +106 -0
  223. package/src/scripts/_lib/gitignore_block.ts +314 -0
  224. package/src/scripts/_lib/global_deploy_inventory.ts +32 -0
  225. package/src/scripts/_lib/graph_feeder_record.ts +214 -0
  226. package/src/scripts/_lib/hook_settings.ts +73 -0
  227. package/src/scripts/_lib/host_capability.ts +40 -19
  228. package/src/scripts/_lib/host_hook_merge.ts +165 -0
  229. package/src/scripts/_lib/installed_layer.ts +538 -0
  230. package/src/scripts/_lib/json_merge.ts +82 -0
  231. package/src/scripts/_lib/json_pointers.ts +93 -11
  232. package/src/scripts/_lib/lean_projection_mode.ts +275 -15
  233. package/src/scripts/_lib/machine_wake.ts +16 -3
  234. package/src/scripts/_lib/neighbour_census.ts +760 -0
  235. package/src/scripts/_lib/neighbour_scan.ts +122 -0
  236. package/src/scripts/_lib/neighbour_tool_use.ts +189 -0
  237. package/src/scripts/_lib/prompt_shape.ts +46 -0
  238. package/src/scripts/_lib/release_migration_gate.ts +19 -3
  239. package/src/scripts/_lib/reserved_name_sweep.ts +73 -0
  240. package/src/scripts/_lib/review_coverage.ts +134 -0
  241. package/src/scripts/_lib/rule_consequence_class.ts +71 -0
  242. package/src/scripts/_lib/rule_injection.ts +130 -10
  243. package/src/scripts/_lib/rule_law_section.ts +147 -0
  244. package/src/scripts/_lib/rule_layer_overlap.ts +58 -0
  245. package/src/scripts/_lib/skill_origin.ts +254 -0
  246. package/src/scripts/_lib/structured_ask.ts +64 -21
  247. package/src/scripts/_lib/thin_rules.ts +540 -0
  248. package/src/scripts/_lib/touched_file_quality.ts +434 -0
  249. package/src/scripts/_lib/turn_end_refusals.ts +77 -2
  250. package/src/scripts/_lib/windsurf_render.ts +63 -0
  251. package/src/scripts/ai_council/cli_call_budget.ts +13 -5
  252. package/src/scripts/ai_council/clients.ts +26 -57
  253. package/src/scripts/ai_council/config.ts +1 -1
  254. package/src/scripts/ai_council/vendor_defaults.ts +45 -0
  255. package/src/scripts/audit_skill_overlap.ts +261 -0
  256. package/src/scripts/before_complete_hook.ts +243 -12
  257. package/src/scripts/bench_touched_file_quality.ts +238 -0
  258. package/src/scripts/check_enforcement_matrix.ts +377 -20
  259. package/src/scripts/check_estate_count.ts +130 -153
  260. package/src/scripts/check_finding_dispositions.ts +116 -4
  261. package/src/scripts/check_hook_bundle_composition.ts +370 -0
  262. package/src/scripts/check_kernel_edit_ratified.ts +49 -11
  263. package/src/scripts/check_memory.ts +7 -1
  264. package/src/scripts/check_release_highlights.ts +10 -0
  265. package/src/scripts/check_release_pr_shape.ts +38 -15
  266. package/src/scripts/check_standing_rule_delivery.ts +33 -13
  267. package/src/scripts/check_verify_expectation_delta.ts +521 -0
  268. package/src/scripts/code_graph/detect.ts +127 -7
  269. package/src/scripts/code_graph/foreign.ts +194 -0
  270. package/src/scripts/code_graph/query.ts +217 -4
  271. package/src/scripts/code_graph/types.ts +26 -2
  272. package/src/scripts/code_graph/validate.ts +3 -1
  273. package/src/scripts/code_graph/verbs.ts +103 -0
  274. package/src/scripts/compile_hook_manifest.ts +33 -1
  275. package/src/scripts/condense.ts +14 -27
  276. package/src/scripts/estate_exemption_shape.ts +202 -0
  277. package/src/scripts/generate_host_cost_table.ts +1 -1
  278. package/src/scripts/hook_manifest.json +1 -1
  279. package/src/scripts/hook_manifest.yaml +150 -9
  280. package/src/scripts/hooks/block_config_weakening.ts +67 -2
  281. package/src/scripts/hooks/block_plumbing_writes.ts +29 -1
  282. package/src/scripts/hooks/code_graph_context_hook.ts +252 -23
  283. package/src/scripts/hooks/concern_failure_policy.ts +280 -0
  284. package/src/scripts/hooks/dispatch_hook.ts +52 -52
  285. package/src/scripts/hooks/exit_codes.ts +2 -1
  286. package/src/scripts/hooks/host_lowering.json +1 -1
  287. package/src/scripts/hooks/host_lowering.ts +19 -1
  288. package/src/scripts/hooks/one_question_per_ask_hook.ts +41 -25
  289. package/src/scripts/hooks/payload_stub.ts +10 -1
  290. package/src/scripts/hooks/rule_inject_hook.ts +757 -63
  291. package/src/scripts/hooks/table_fingerprint.ts +21 -0
  292. package/src/scripts/hooks/telemetry_usage_hook.ts +64 -8
  293. package/src/scripts/hooks/turn_end_gate_hook.ts +84 -0
  294. package/src/scripts/hooks_status.ts +112 -0
  295. package/src/scripts/injection_scan_hook.ts +7 -0
  296. package/src/scripts/install.ts +72 -185
  297. package/src/scripts/installed_layer_report.ts +103 -0
  298. package/src/scripts/language_mirror_hook.ts +15 -6
  299. package/src/scripts/learning_sidecar.ts +119 -8
  300. package/src/scripts/lint_hook_manifest.ts +53 -0
  301. package/src/scripts/lint_major_migration_sections.ts +156 -26
  302. package/src/scripts/lint_pack_boundaries.ts +63 -5
  303. package/src/scripts/lint_rule_law_section.ts +517 -0
  304. package/src/scripts/lint_workflow_security.ts +161 -5
  305. package/src/scripts/mcp_server/consumer_tool_catalog.json +53 -0
  306. package/src/scripts/mcp_server/graph_tools.ts +72 -3
  307. package/src/scripts/measure_routing_signal.ts +54 -16
  308. package/src/scripts/measure_skill_ranker_baseline.ts +216 -8
  309. package/src/scripts/memory_learn_hook.ts +91 -6
  310. package/src/scripts/model_rule_injection.ts +52 -5
  311. package/src/scripts/project_thin_rules.ts +34 -327
  312. package/src/scripts/report_evidence_temperature.ts +657 -0
  313. package/src/scripts/report_installed_rule_links.ts +157 -0
  314. package/src/scripts/report_label_agreement.ts +233 -0
  315. package/src/scripts/report_obligation_mechanism.ts +230 -0
  316. package/src/scripts/report_single_token_triggers.ts +277 -0
  317. package/src/scripts/report_skill_ranker_confusion.ts +442 -0
  318. package/src/scripts/report_standing_payload_by_host.ts +188 -15
  319. package/src/scripts/report_verification_record_coverage.ts +306 -0
  320. package/src/scripts/rule_activation_census.ts +5 -2
  321. package/src/scripts/rule_trigger_eval.ts +9 -9
  322. package/src/scripts/schemas/review-findings.schema.json +3 -2
  323. package/src/scripts/schemas/rule.schema.json +5 -0
  324. package/src/scripts/self_review_gate.ts +62 -7
  325. package/src/scripts/skill_tools/score_skill_relevance.ts +290 -25
  326. package/src/scripts/sweep_skill_ranker_signals.ts +129 -0
  327. package/src/scripts/sync_gitignore.ts +29 -235
  328. package/src/scripts/trigger_eval_grandfather.json +0 -5
  329. package/src/server/schemas/settings.ts +10 -0
  330. package/src/shared/skillRanking.ts +117 -11
  331. package/dist/cli-delegate/chunk-JNMVLWLR.js +0 -4457
  332. package/dist/cli-delegate/chunk-YDPILCOL.js +0 -152
@@ -9,6 +9,27 @@ import { createHash } from 'node:crypto';
9
9
  * dispatcher: `dispatch_hook` → `host_semantics` → `host_lowering` is a live
10
10
  * import chain, so the reverse edge would be a cycle.
11
11
  *
12
+ * THE RETIRED ARGUMENT, kept because both callers point here for it rather
13
+ * than restating it. `dispatch_hook._manifest_fingerprint` argued AGAINST a
14
+ * cryptographic hash on two grounds, and by the time road-to-blocking-
15
+ * severities 3.1 read that header the body had already been delegating here for
16
+ * a release — so a reader checking whether the dispatcher resists a CRAFTED
17
+ * sibling met a disclaimer the code had stopped making. Both grounds were
18
+ * re-measured when this module was extracted, and both were stale:
19
+ *
20
+ * - "`require('node:crypto')` costs 8 ms of process start, which is most of
21
+ * what the precompiled manifest exists to save." The module is already
22
+ * loaded: `dist/hooks/dispatch.js` carries 23 top-level
23
+ * `import … from "node:crypto"` statements from other parts of the graph,
24
+ * so the cost is paid whether this function uses it or not.
25
+ * - "An FNV-1a loop runs in about 0.2 ms and is the right trade." SHA-256
26
+ * measured FASTER — 0.106 ms against 0.113 ms over the 99,792-byte
27
+ * manifest — because Node's digest is native and the loop was that many
28
+ * interpreted `charCodeAt` calls.
29
+ *
30
+ * Both readers now point here instead of restating it, so the argument and the
31
+ * numbers that retired it cannot part company again.
32
+ *
12
33
  * DELIBERATELY CONTENT-DERIVED, NOT MTIME. The first version of the manifest
13
34
  * fast path compared mtimes and that was a measured defect, not a theoretical
14
35
  * one: on a fresh `actions/checkout` both files carry the checkout timestamp in
@@ -22,12 +22,31 @@
22
22
  * activates only when `enabled` is true AND the org pack supplied an
23
23
  * endpoint, an org id, and a salt. An external clone of this repository
24
24
  * carries the key names and no values, so copying the tree cannot reach the
25
- * write path. When inactive this concern performs zero telemetry file
26
- * operations — no log write, no directory creation — and zero network calls.
25
+ * write path. When inactive this concern performs zero TELEMETRY file
26
+ * operations — no log write, no spool, no directory under the configured
27
+ * output path — and zero network calls.
27
28
  * (It does read `.agent-settings.yml`, once per process and memoised: the
28
29
  * settings file is how it learns it is off, the same as the artefact-
29
30
  * engagement surface it mirrors.)
30
31
  *
32
+ * THAT SENTENCE USED TO READ "no directory creation", UNQUALIFIED, AND IS
33
+ * NARROWED RATHER THAN QUIETLY LEFT STANDING. The foreign-MCP recorder below
34
+ * writes `agents/runtime/neighbour-tool-use.json` on an install that never
35
+ * enabled telemetry, and creates that directory and a lock sentinel beside it.
36
+ * That is deliberate — the store is a local census input, not telemetry, and
37
+ * gating it on the org switch would print `0` everywhere (roadmap decision D9)
38
+ * — but it IS a file operation, so the guarantee now says which operations it
39
+ * covers. An unqualified claim this file's own code contradicts is worse than
40
+ * the narrower one it is replaced by.
41
+ *
42
+ * NOT REACHED YET, AND SAYING SO HERE BECAUSE THIS IS WHERE A READER LOOKS.
43
+ * The manifest entry for this concern carries `tools: [Skill]`, which the
44
+ * dispatcher matches exactly, so it is not invoked for an MCP call at all and
45
+ * the branch below is dead in production. Held as the
46
+ * `mcp-recorder-unreachable-behind-the-tools-filter` blocker on
47
+ * road-to-neighbours-that-pull-their-weight: the manifest is a gated
48
+ * governance surface and the council split on the edit rather than converging.
49
+ *
31
50
  * NO OUTBOUND CALL EXISTS HERE, DELIBERATELY. Transport is Phase 2 and is
32
51
  * blocked on `sink-choice`; org-wide enablement is Phase 3 and is blocked on
33
52
  * `dpo-signoff`. This concern appends to a local JSONL file and stops.
@@ -55,7 +74,12 @@ import {
55
74
  FLUSH_SESSION_END,
56
75
  spool_path_for,
57
76
  } from '../../agent-src/templates/scripts/telemetry/transport.js';
58
- import { is_replay_mode } from './state_io.js';
77
+ import {
78
+ FOREIGN_TOOL_USE_REL,
79
+ MCP_TOOL_PREFIX,
80
+ usageDay,
81
+ } from '../_lib/neighbour_tool_use.js';
82
+ import { is_replay_mode, update_json_under_lock } from './state_io.js';
59
83
  import { readHookStdin } from './hook_stdin.js';
60
84
  import { EXIT_ALLOW } from './exit_codes.js';
61
85
 
@@ -247,7 +271,30 @@ function processEnvelope(envelope: JsonValue, consumer_root: string): number {
247
271
  if (!isObject(envelope)) return EXIT_ALLOW;
248
272
 
249
273
  const payload = unwrapPayload(envelope);
250
- if (extractToolName(payload) !== SKILL_TOOL_NAME) return EXIT_ALLOW;
274
+ const tool = extractToolName(payload);
275
+ if (tool !== SKILL_TOOL_NAME) {
276
+ // The other half of this slot's observation, and the only half a
277
+ // `post_tool_use` envelope can supply: the tool's NAME. The MCP
278
+ // fingerprint store wants a tool DEFINITION, which this envelope
279
+ // never carries (roadmap decision D2), so what is recorded here is
280
+ // what was actually seen. Rooted at the settings directory, not at
281
+ // the session cwd, for the same reason the Class-A log below is.
282
+ if (tool !== null && tool.startsWith(MCP_TOOL_PREFIX)) {
283
+ // The mutator's cast is safe at the only place that matters:
284
+ // the reader in `neighbour_tool_use` drops any value that is
285
+ // not a string, so a hand-edited store cannot widen this.
286
+ // Kept OUT of the argument list below — esbuild preserves a
287
+ // comment in that position and it would cost the shared
288
+ // bundle ~190 bytes of prose nothing executes.
289
+ const day = usageDay(new Date());
290
+ update_json_under_lock<Record<string, string>>(
291
+ path.join(readSettingsFor(consumer_root).root, FOREIGN_TOOL_USE_REL),
292
+ (seen) => (seen[tool] === day ? null : ({ ...seen, [tool]: day } as Record<string, string>)),
293
+ { blocking: false },
294
+ );
295
+ }
296
+ return EXIT_ALLOW;
297
+ }
251
298
 
252
299
  const { settings, text, root } = readSettingsFor(consumer_root);
253
300
  if (!settings.active) return EXIT_ALLOW;
@@ -339,11 +386,18 @@ export function main(): number {
339
386
 
340
387
  // Bundle-safety: never auto-run when inlined into an esbuild bundle, where
341
388
  // every module shares the bundle's `import.meta.url` (see cmd_migrate.ts).
389
+ //
390
+ // The bundle test is at the CALL SITE rather than at the top of
391
+ // `_isCliEntry`, and that placement is the whole point. Inside the function
392
+ // esbuild folds the condition to `if (true) return false` and then emits the
393
+ // nine unreachable lines below it anyway — measured at 475 bytes of dead code
394
+ // in a bundle `check_hook_bundle_composition` caps. Guarding the call instead
395
+ // makes the whole statement `if (false)`, which esbuild drops, taking the now
396
+ // unreferenced function with it. Behavior outside the bundle is unchanged:
397
+ // `__AGENT_CONFIG_BUNDLE__` is undeclared there, the first operand is true,
398
+ // and `!__AGENT_CONFIG_BUNDLE__` is never evaluated — so no ReferenceError.
342
399
  declare const __AGENT_CONFIG_BUNDLE__: boolean | undefined;
343
400
  function _isCliEntry(): boolean {
344
- if (typeof __AGENT_CONFIG_BUNDLE__ !== 'undefined' && __AGENT_CONFIG_BUNDLE__) {
345
- return false;
346
- }
347
401
  if (process.argv[1] === undefined) return false;
348
402
  const argvUrl = pathToFileURL(path.resolve(process.argv[1])).href;
349
403
  if (import.meta.url === argvUrl) return true;
@@ -353,4 +407,6 @@ function _isCliEntry(): boolean {
353
407
  return false;
354
408
  }
355
409
  }
356
- if (_isCliEntry()) process.exit(main());
410
+ if (typeof __AGENT_CONFIG_BUNDLE__ === 'undefined' || !__AGENT_CONFIG_BUNDLE__) {
411
+ if (_isCliEntry()) process.exit(main());
412
+ }
@@ -186,6 +186,17 @@ export { readTurnRunState };
186
186
  // Detector E, extracted to `_lib` where its prose costs no ratchet debt.
187
187
  // Re-exported so every existing importer of this module is unchanged.
188
188
  import { detectDroppedDecision } from '../_lib/dropped_decision.js';
189
+ // Step 3.2 of `road-to-a-graph-that-feeds-the-gate` — the shadow feeder. It
190
+ // lives in `_lib` for the reason every other extraction here does: this file
191
+ // sits against a 1,500-line shrink-only source budget, and the module it would
192
+ // otherwise grow into is one a recall reading has to be able to open on its own.
193
+ import {
194
+ appendFeederRow,
195
+ buildFeederRow,
196
+ type FeederLayer,
197
+ graphUntestedVerdict,
198
+ } from '../_lib/graph_feeder_record.js';
199
+ import { type GraphState, graphState } from '../code_graph/detect.js';
189
200
  import { isVerificationCommand } from '../_lib/verification_command.js';
190
201
  // Round 8 — the record path detector C prefers over its own regex. The regex
191
202
  // reads a command's TEXT and `echo test` matches it; these read what the run
@@ -215,6 +226,7 @@ import {
215
226
  readInstallBoundary,
216
227
  sessionRefusalFile,
217
228
  sessionShadowFile,
229
+ shadowSetBy,
218
230
  type RefusalRecord,
219
231
  type ShadowLayer,
220
232
  type ShadowRecord,
@@ -1276,6 +1288,65 @@ function runDetectors(inputs: DetectorInputs): Finding[] {
1276
1288
  return findings;
1277
1289
  }
1278
1290
 
1291
+ /**
1292
+ * Write the graph feeder row for ONE stop (step 3.2).
1293
+ *
1294
+ * Called from both stop paths with the findings that path already computed, so
1295
+ * the F verdict in the row is the SAME verdict the gate acted on — never a
1296
+ * second evaluation written beside it, which is the shape
1297
+ * `obligation_settle_hook.ts` names as measuring nothing.
1298
+ *
1299
+ * It changes no exit code, and the whole body is wrapped: a stop that crashed on
1300
+ * its own instrument would be a new failure mode on a path that is supposed to
1301
+ * cost nothing. The graph half is skipped outright unless the state is `fresh`
1302
+ * or `edited` — an answer from an index that predates the change is not evidence
1303
+ * about the change.
1304
+ */
1305
+ function recordGraphFeeder(
1306
+ inputs: DetectorInputs,
1307
+ findings: readonly Finding[],
1308
+ layer: FeederLayer,
1309
+ ): void {
1310
+ if (is_replay_mode()) return;
1311
+ try {
1312
+ let state: GraphState;
1313
+ try {
1314
+ state = graphState(inputs.workspaceRoot);
1315
+ } catch {
1316
+ return;
1317
+ }
1318
+ // No graph at all is the silent case, exactly as it is for the context
1319
+ // hook: a consumer who never builds one never grows this file.
1320
+ if (state === 'absent') return;
1321
+ // The SAME path set detector F reads, filtered by the SAME predicate.
1322
+ // A completion review found the two arms running over different inputs:
1323
+ // the feeder passed every edit path while F filters to production
1324
+ // source, so the graph arm would have fired on precisely the turns F is
1325
+ // silent for — a recall comparison between two detectors answering
1326
+ // different questions, which is worse than no comparison.
1327
+ const paths = inputs.toolCalls
1328
+ .filter((c) => _EDIT_TOOLS.has(c.name) && c.path !== undefined)
1329
+ .map((c) => c.path as string)
1330
+ .filter(_isProductionSource);
1331
+ const f = findings.find((x) => x.detector === 'untested');
1332
+ appendFeederRow(
1333
+ inputs.workspaceRoot,
1334
+ inputs.sessionKey,
1335
+ buildFeederRow({
1336
+ turn: inputs.turnOrdinal,
1337
+ layer,
1338
+ state,
1339
+ fFired: f !== undefined,
1340
+ fMode: f?.mode ?? null,
1341
+ paths,
1342
+ graph: graphUntestedVerdict(inputs.workspaceRoot, state, paths),
1343
+ }),
1344
+ );
1345
+ } catch {
1346
+ // An instrument is never a reason to change what the gate does.
1347
+ }
1348
+ }
1349
+
1279
1350
  /**
1280
1351
  * Record what this retry WOULD have been refused for, then let it end.
1281
1352
  *
@@ -1289,6 +1360,14 @@ function recordShadow(inputs: DetectorInputs, layer: ShadowLayer): void {
1289
1360
  if (is_replay_mode()) return;
1290
1361
  try {
1291
1362
  const findings = runDetectors(inputs);
1363
+ // On `refused_turn` the answer is `ours` by construction — that marker
1364
+ // is this gate's own and nothing else writes it. On `stop_hook_active`
1365
+ // the host sets the flag for ANY stop hook's block, so it has to be
1366
+ // read from our own refusal record rather than assumed.
1367
+ const setBy = layer === 'refused_turn'
1368
+ ? 'ours'
1369
+ : shadowSetBy(inputs.workspaceRoot, inputs.sessionKey);
1370
+ recordGraphFeeder(inputs, findings, layer);
1292
1371
  const file = sessionShadowFile(inputs.workspaceRoot, inputs.sessionKey);
1293
1372
  let prev: ShadowRecord | null = null;
1294
1373
  try {
@@ -1303,6 +1382,7 @@ function recordShadow(inputs: DetectorInputs, layer: ShadowLayer): void {
1303
1382
  turnOrdinal: inputs.turnOrdinal,
1304
1383
  at: new Date().toISOString(),
1305
1384
  layer,
1385
+ setBy,
1306
1386
  }) as unknown as Record<string, unknown>,
1307
1387
  );
1308
1388
  } catch {
@@ -1361,6 +1441,10 @@ export function main(): number {
1361
1441
  // warranted"; there is no second, configurable notion of warranted layered
1362
1442
  // on top of it.
1363
1443
  const findings = runDetectors(inputs);
1444
+ // The live verdict's own row. It is written BEFORE the branch below, so a
1445
+ // turn the gate allows and a turn it refuses are both in the record — a
1446
+ // recall reading needs the allowed turns as its negative arm.
1447
+ recordGraphFeeder(inputs, findings, 'live');
1364
1448
  if (findings.length === 0) return EXIT_ALLOW;
1365
1449
 
1366
1450
  markRefusedTurn(
@@ -23,11 +23,14 @@ import fs from "node:fs";
23
23
  import path from "node:path";
24
24
  import { fileURLToPath, pathToFileURL } from "node:url";
25
25
 
26
+ import { enforcementFor } from "./check_enforcement_matrix.js";
26
27
  import {
27
28
  type JsonObject,
28
29
  type JsonValue,
29
30
  _load_yaml,
30
31
  } from "./hooks/dispatch_hook.js";
32
+ import { loadHostLowering } from "./hooks/host_lowering.js";
33
+ import { type SlotReading, readSlots } from "./report_enforcement_drift.js";
31
34
 
32
35
  // src/scripts/hooks_status.ts → parents[1] is the repo root (.../parents[2]
33
36
  // in the Python which lives one level deeper relative computation).
@@ -90,6 +93,18 @@ export interface PlatformRow {
90
93
  */
91
94
  ask: AskShape;
92
95
  bindings: Record<string, string[]>;
96
+ /**
97
+ * For each slot that binds at least one `blocking` concern, what that host's
98
+ * slot can actually carry — `refusal`, `warning-only`, `unverified` or
99
+ * `proof-expired` (road-to-blocking-severities 1.2).
100
+ *
101
+ * Slots with no blocking concern are ABSENT rather than present with a
102
+ * value, so a reader cannot mistake "nothing here claims to refuse" for a
103
+ * capability reading. Derived from `host_lowering.yaml`, never from the
104
+ * manifest: the manifest declares intent and only the lowering table records
105
+ * whether a refusal can land.
106
+ */
107
+ blocking_enforcement: Record<string, string>;
93
108
  hint: string | null;
94
109
  }
95
110
 
@@ -123,10 +138,79 @@ function _bridge_status(project_root: string, rel_path: string): string {
123
138
  return stat && stat.isFile() ? "installed" : "missing";
124
139
  }
125
140
 
141
+ /**
142
+ * `severity` per concern, read off the manifest this report already loaded.
143
+ *
144
+ * `(undeclared)` is folded into "not blocking": this report publishes the
145
+ * enforcement of concerns that CLAIM to refuse, and a concern that claims
146
+ * nothing has nothing to reconcile. `lint_hook_manifest` is what refuses an
147
+ * undeclared severity; duplicating that judgement here would put two answers
148
+ * in the tree.
149
+ */
150
+ function _severities(manifest: JsonObject): Map<string, string> {
151
+ const out = new Map<string, string>();
152
+ const concerns = manifest["concerns"];
153
+ if (!_isObject(concerns)) {
154
+ return out;
155
+ }
156
+ for (const [name, spec] of Object.entries(concerns)) {
157
+ const sev = _isObject(spec) ? spec["severity"] : undefined;
158
+ if (typeof sev === "string") {
159
+ out.set(name, sev);
160
+ }
161
+ }
162
+ return out;
163
+ }
164
+
165
+ /**
166
+ * What each slot carrying a `blocking` concern can actually do on this host.
167
+ *
168
+ * road-to-blocking-severities 1.2, the third surface. The decision and the
169
+ * vocabulary live in `check_enforcement_matrix`; this reads them rather than
170
+ * restating them, so the published document and this report cannot drift into
171
+ * two different answers to one question.
172
+ *
173
+ * Failure is SILENT and the field is simply absent. This is a read-only status
174
+ * report that the post-install smoke probe runs, and a malformed or missing
175
+ * lowering table must degrade it, never abort it — the gate is where a broken
176
+ * lowering table is supposed to fail.
177
+ */
178
+ function _blocking_enforcement(
179
+ platform: string,
180
+ bindings: Record<string, string[]>,
181
+ severities: Map<string, string>,
182
+ ): Record<string, string> {
183
+ const out: Record<string, string> = {};
184
+ let slots: SlotReading[];
185
+ try {
186
+ slots = readSlots(loadHostLowering(), platform).slots;
187
+ } catch {
188
+ return out;
189
+ }
190
+ const bySlot = new Map(slots.map((s) => [s.slot, s]));
191
+ for (const [event, concerns] of Object.entries(bindings)) {
192
+ if (!concerns.some((c) => severities.get(c) === "blocking")) {
193
+ continue;
194
+ }
195
+ const row = bySlot.get(event);
196
+ out[event] = enforcementFor(
197
+ row === undefined
198
+ ? "unlowerable"
199
+ : row.literal === null
200
+ ? "null-block"
201
+ : row.effective === null
202
+ ? "stale-proof"
203
+ : null,
204
+ );
205
+ }
206
+ return out;
207
+ }
208
+
126
209
  /** Build the runtime matrix as a plain object — JSON-serialisable. */
127
210
  export function collect(project_root: string, manifest: JsonObject): StatusMatrix {
128
211
  const platformsRaw = manifest["platforms"];
129
212
  const platforms = _isObject(platformsRaw) ? platformsRaw : {};
213
+ const severities = _severities(manifest);
130
214
  const rows: PlatformRow[] = [];
131
215
  for (const platform of Object.keys(PLATFORM_BRIDGES)) {
132
216
  const [rel, hint] = PLATFORM_BRIDGES[platform] as [string, string];
@@ -148,6 +232,7 @@ export function collect(project_root: string, manifest: JsonObject): StatusMatri
148
232
  rows.push({
149
233
  platform,
150
234
  status,
235
+ blocking_enforcement: _blocking_enforcement(platform, bindings, severities),
151
236
  bridge_path: rel || null,
152
237
  fallback_only,
153
238
  ask,
@@ -160,6 +245,23 @@ export function collect(project_root: string, manifest: JsonObject): StatusMatri
160
245
  return { schema_version: 1, platforms: rows };
161
246
  }
162
247
 
248
+ /**
249
+ * One short line per enforcement value, for the table.
250
+ *
251
+ * `unverified` says what is MISSING, never what the host cannot do — the same
252
+ * wording discipline `docs/enforcement-by-host.md` carries, and the reason this
253
+ * report distinguishes the two values at all.
254
+ */
255
+ const _ENFORCEMENT_NOTE: Record<string, string> = {
256
+ refusal: "the slot denies, so a blocking verdict stops the call",
257
+ "proof-expired":
258
+ "the slot can deny; this package's `verified` citation has lapsed",
259
+ "warning-only":
260
+ "`block_exit` is null here — they run and warn, they cannot refuse",
261
+ unverified:
262
+ "no lowering row for this slot — nothing bound natively, nothing established",
263
+ };
264
+
163
265
  const _STATUS_MARKER: Record<string, string> = {
164
266
  installed: "✅ ",
165
267
  missing: "❌ ",
@@ -199,6 +301,16 @@ export function _render_table(matrix: StatusMatrix): string {
199
301
  for (const event of Object.keys(row.bindings).sort()) {
200
302
  const concerns = row.bindings[event]?.join(", ") || "—";
201
303
  lines.push(` ${event.padEnd(22)} → ${concerns}`);
304
+ // road-to-blocking-severities 1.2 — printed only where a concern on this
305
+ // slot DECLARES `blocking`, and worded so `unverified` never reads as a
306
+ // claim about the host.
307
+ const enforcement = row.blocking_enforcement[event];
308
+ if (enforcement !== undefined) {
309
+ lines.push(
310
+ ` ${" ".repeat(22)} blocking concerns here: ${enforcement} — ` +
311
+ `${_ENFORCEMENT_NOTE[enforcement] ?? "see docs/enforcement-by-host.md"}`,
312
+ );
313
+ }
202
314
  }
203
315
  if (row.hint) {
204
316
  lines.push(` hint: ${row.hint}`);
@@ -214,6 +214,13 @@ export const OUTPUT_KEYS: readonly string[] = [
214
214
  "toolResponse",
215
215
  "tool_result",
216
216
  "toolUseResult",
217
+ // The failure event's result body. A FAILING command on claude carries its
218
+ // stdout and stderr here and carries no `tool_response` at all, so without
219
+ // this line a failed `curl` of a hostile page would reach the model with
220
+ // nothing scanned — the one direction where the output is most likely to be
221
+ // attacker-shaped. Caught by this concern's own coverage test, which pins
222
+ // OUTPUT_KEYS as a superset of what the dispatcher serves.
223
+ "error",
217
224
  // Generic spellings accepted since this concern shipped.
218
225
  "output",
219
226
  "result",