@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
@@ -152,10 +152,9 @@ import {
152
152
  sessionRefusalFile,
153
153
  } from '../_lib/turn_end_refusals.js';
154
154
  import { phaseLines } from '../_lib/roadmap_checkboxes.js';
155
+ import { commandBearing, renderVerifyLine, type VerifyClause } from '../_lib/verify_clause.js';
155
156
 
156
- const EXIT_ALLOW = 0;
157
157
  /** Dispatcher-internal block code; the dispatcher maps stop-slot 1 → host 2. */
158
- const EXIT_BLOCK = 1;
159
158
 
160
159
  /**
161
160
  * The gate's cap, IMPORTED rather than restated — the two must agree by
@@ -194,6 +193,7 @@ import {
194
193
  WALL_CLOCK_CAP_MS,
195
194
  type LadderAction,
196
195
  } from '../_lib/continuation_ladder.js';
196
+ import { EXIT_ALLOW, EXIT_BLOCK } from './exit_codes.js';
197
197
 
198
198
  /**
199
199
  * DECLARED in `_lib/continuation_ladder.ts`, re-exported here: one declaration,
@@ -375,8 +375,8 @@ export function isDuplicateFire(
375
375
  export interface NextStep {
376
376
  /** The step's own line, checkbox stripped, truncated for the message. */
377
377
  text: string;
378
- /** The step's `verify:` command, when its line carries one. */
379
- verify: string | null;
378
+ /** The step's `verify:` clause — command plus optional expectation. */
379
+ verify: VerifyClause | null;
380
380
  }
381
381
 
382
382
  export interface ScanResult {
@@ -481,15 +481,15 @@ export function scanOpenSteps(text: string): ScanResult {
481
481
  * The comment form wins when both are present: it is the machine-readable one,
482
482
  * and a step carrying both has a human-facing line and a tooling-facing line
483
483
  * rather than two commands.
484
+ *
485
+ * The hook's narrowing only — a prose clause is not a command, and the
486
+ * continuation message renders commands. It parses nothing itself: a second
487
+ * copy of the arrow grammar is how this hook and `closure_scan` would drift,
488
+ * and a drifted grammar stops reading expectations without failing anything.
489
+ * `_lib/verify_clause.ts` owns the grammar and the sweep that keeps it single.
484
490
  */
485
- export function extractVerify(stepText: string): string | null {
486
- const html = /<!--\s*verify:\s*(.*?)\s*-->/.exec(stepText);
487
- if (html !== null) return (html[1] as string).trim() || null;
488
- // `verify:` then the command, both backticked. The label's own backticks
489
- // are optional because the tree carries `verify:` and `` `verify:` ``.
490
- const backticked = /`?verify:`?\s*`([^`]+)`/.exec(stepText);
491
- if (backticked !== null) return (backticked[1] as string).trim() || null;
492
- return null;
491
+ export function extractVerify(stepText: string): VerifyClause | null {
492
+ return commandBearing(stepText);
493
493
  }
494
494
 
495
495
  /**
@@ -1259,7 +1259,6 @@ export function main(): number {
1259
1259
  return EXIT_ALLOW;
1260
1260
  }
1261
1261
 
1262
-
1263
1262
  // The two-tree provenance, carried on every event this run emits. See
1264
1263
  // `provenance()` for the six fields and why none of them is a boolean.
1265
1264
  //
@@ -1487,8 +1486,7 @@ export function main(): number {
1487
1486
 
1488
1487
  function _continuationText(slug: string, scan: ScanResult, iteration: number): string {
1489
1488
  const stepLine = scan.next
1490
- ? `Next step: ${scan.next.text}` +
1491
- (scan.next.verify ? `\n verify: ${scan.next.verify}` : '')
1489
+ ? `Next step: ${scan.next.text}${renderVerifyLine(scan.next.verify)}`
1492
1490
  : 'Next step: (first open checkbox in the roadmap)';
1493
1491
  return (
1494
1492
  `run-continuation: the contracted roadmap \`${slug}\` has ${scan.open} open ` +
@@ -143,10 +143,9 @@ import { isSyntheticPrompt } from "../_lib/prompt_shape.js";
143
143
  import { OBSERVATION_LOG, readObservationLog, resolveSkillCatalogueRoots } from "../_lib/skill_catalogue.js";
144
144
  import { knownBareNames } from "../_lib/skill_catalogue_series.js";
145
145
  import { _tokenize, rank, type RankRow } from "../skill_tools/score_skill_relevance.js";
146
+ import { EXIT_ALLOW, EXIT_WARN } from './exit_codes.js';
146
147
 
147
- const EXIT_ALLOW = 0;
148
148
  /** See the header: reduced to a real exit of 0 by `emitFor`'s warn branch. */
149
- const EXIT_WARN = 2;
150
149
 
151
150
  /**
152
151
  * Minimum top-1 ranker score before this concern speaks.
@@ -95,8 +95,7 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
95
95
  import { is_replay_mode } from './state_io.js';
96
96
  import { readHookStdin } from './hook_stdin.js';
97
97
  import { resolveConsumerRoot } from './subagent_ledger_hook.js';
98
-
99
- const EXIT_ALLOW = 0;
98
+ import { EXIT_ALLOW } from './exit_codes.js';
100
99
 
101
100
  /** Would-warns per session before the valve goes silent — `MAX_NUDGES` shape. */
102
101
  export const MAX_SHADOW_WARNS = 2;
@@ -55,8 +55,7 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
55
55
 
56
56
  import { appendLedgerLine, openRecordStats, resolveConsumerRoot } from './subagent_ledger_hook.js';
57
57
  import { readHookStdin } from './hook_stdin.js';
58
-
59
- const EXIT_ALLOW = 0;
58
+ import { EXIT_ALLOW } from './exit_codes.js';
60
59
 
61
60
  type JsonValue = string | number | boolean | null | JsonValue[] | { [k: string]: JsonValue };
62
61
  type JsonObject = { [k: string]: JsonValue };
@@ -115,8 +115,7 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
115
115
  import { countContractFields, validateResponse } from '../_lib/subagent_response.js';
116
116
  import { atomic_write_json, is_replay_mode } from './state_io.js';
117
117
  import { readHookStdin } from './hook_stdin.js';
118
-
119
- const EXIT_ALLOW = 0;
118
+ import { EXIT_ALLOW } from './exit_codes.js';
120
119
 
121
120
  type JsonValue = string | number | boolean | null | JsonValue[] | { [k: string]: JsonValue };
122
121
  type JsonObject = { [k: string]: JsonValue };
@@ -51,8 +51,8 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
51
51
  import { unwrap } from './envelope.js';
52
52
  import { readHookStdin } from './hook_stdin.js';
53
53
  import { humanTypedThisTurn } from '../_lib/machine_wake.js';
54
+ import { EXIT_ALLOW } from './exit_codes.js';
54
55
 
55
- const EXIT_ALLOW = 0;
56
56
  const SETTINGS_FILE = '.agent-settings.yml';
57
57
  const SINK_REL = path.join('agents', 'runtime', 'state', 'audit', 'suggestion-capture.jsonl');
58
58
  const LATCH_REL = path.join('agents', 'runtime', 'state', 'suggestion-latch.json');
@@ -0,0 +1,70 @@
1
+ import { createHash } from 'node:crypto';
2
+
3
+ /**
4
+ * table_fingerprint — the content fingerprint a compiled plumbing table is
5
+ * validated against.
6
+ *
7
+ * Extracted from `dispatch_hook._manifest_fingerprint` so a SECOND table
8
+ * (`host_lowering.yaml`) can use the same helper without importing the
9
+ * dispatcher: `dispatch_hook` → `host_semantics` → `host_lowering` is a live
10
+ * import chain, so the reverse edge would be a cycle.
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
+ *
33
+ * DELIBERATELY CONTENT-DERIVED, NOT MTIME. The first version of the manifest
34
+ * fast path compared mtimes and that was a measured defect, not a theoretical
35
+ * one: on a fresh `actions/checkout` both files carry the checkout timestamp in
36
+ * whatever order git wrote them, so whether the optimisation applied at all was
37
+ * a coin flip — it won on a PR run (p95 129 ms) and lost on the trunk
38
+ * (p95 186 ms) for the same commit. A fingerprint is deterministic wherever the
39
+ * tree came from.
40
+ *
41
+ * SHA-256 over the UTF-8 bytes, plus the length. This replaced an FNV-1a loop
42
+ * in step 3.1 of `road-to-a-kernel-that-guards-its-plumbing`, and the reason
43
+ * the old one existed no longer holds. Its header said a cryptographic hash was
44
+ * refused because `require('node:crypto')` costs 8 ms of process start, which
45
+ * is most of what the precompiled table saves. Both halves were re-measured
46
+ * against the tree as it now stands, and both had gone stale:
47
+ *
48
+ * - The module is ALREADY LOADED. `dist/hooks/dispatch.js` carries 23
49
+ * top-level `import … from "node:crypto"` statements from other parts of the
50
+ * graph, so the 8 ms is paid on every dispatch whether this function uses it
51
+ * or not. There is no startup cost left to avoid.
52
+ * - SHA-256 is FASTER here, not slower: 0.106 ms against 0.113 ms over the
53
+ * 99,792-byte manifest, because Node's digest is native and the FNV-1a loop
54
+ * was 99,792 interpreted `charCodeAt` calls.
55
+ *
56
+ * The change is therefore free, and it buys the property the old comment had to
57
+ * disclaim: this now guards against a CRAFTED sibling as well as a stale one,
58
+ * which is what a file called a fingerprint should mean when the roadmap around
59
+ * it is about integrity.
60
+ *
61
+ * Producer and both consumers import THIS function — `compile_hook_manifest`
62
+ * writes the value, `dispatch_hook` and `host_lowering` check it — so the
63
+ * algorithm can never drift between the two sides. A mismatch is not a failure
64
+ * either way: the reader falls through to parsing the YAML source, which is
65
+ * correct and merely slower.
66
+ */
67
+ export function tableFingerprint(text: string): string {
68
+ const digest = createHash('sha256').update(text, 'utf-8').digest('hex');
69
+ return `${digest}:${String(text.length)}`;
70
+ }
@@ -45,8 +45,7 @@ import {
45
45
  import { is_replay_mode } from './state_io.js';
46
46
  import { readHookStdin } from './hook_stdin.js';
47
47
  import { _resolveRoot, readSettingsFor } from './telemetry_usage_hook.js';
48
-
49
- const EXIT_ALLOW = 0;
48
+ import { EXIT_ALLOW } from './exit_codes.js';
50
49
 
51
50
  /**
52
51
  * Where `flush_sender.mjs` lives, relative to this module.
@@ -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,10 +74,14 @@ 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
-
61
- const EXIT_ALLOW = 0;
84
+ import { EXIT_ALLOW } from './exit_codes.js';
62
85
 
63
86
  /** The tool name Phase 0 spike 1 confirmed for a skill invocation. */
64
87
  export const SKILL_TOOL_NAME = 'Skill';
@@ -248,7 +271,30 @@ function processEnvelope(envelope: JsonValue, consumer_root: string): number {
248
271
  if (!isObject(envelope)) return EXIT_ALLOW;
249
272
 
250
273
  const payload = unwrapPayload(envelope);
251
- 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
+ }
252
298
 
253
299
  const { settings, text, root } = readSettingsFor(consumer_root);
254
300
  if (!settings.active) return EXIT_ALLOW;
@@ -340,11 +386,18 @@ export function main(): number {
340
386
 
341
387
  // Bundle-safety: never auto-run when inlined into an esbuild bundle, where
342
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.
343
399
  declare const __AGENT_CONFIG_BUNDLE__: boolean | undefined;
344
400
  function _isCliEntry(): boolean {
345
- if (typeof __AGENT_CONFIG_BUNDLE__ !== 'undefined' && __AGENT_CONFIG_BUNDLE__) {
346
- return false;
347
- }
348
401
  if (process.argv[1] === undefined) return false;
349
402
  const argvUrl = pathToFileURL(path.resolve(process.argv[1])).href;
350
403
  if (import.meta.url === argvUrl) return true;
@@ -354,4 +407,6 @@ function _isCliEntry(): boolean {
354
407
  return false;
355
408
  }
356
409
  }
357
- if (_isCliEntry()) process.exit(main());
410
+ if (typeof __AGENT_CONFIG_BUNDLE__ === 'undefined' || !__AGENT_CONFIG_BUNDLE__) {
411
+ if (_isCliEntry()) process.exit(main());
412
+ }
@@ -24,10 +24,10 @@
24
24
  *
25
25
  * PRIVACY BY CONSTRUCTION — never widen this file to record content.
26
26
  *
27
- * The record type has exactly three fields and NONE of them can hold free
27
+ * The record type has exactly four fields and NONE of them can hold free
28
28
  * text: a timestamp, a tool NAME (an id-shaped enum — `Read`, `Bash`,
29
29
  * `Grep` — the same single host string `orchestration_record_hook` already
30
- * records), and a BYTE COUNT. A tool result routinely carries file
30
+ * records), and TWO BYTE COUNTS. A tool result routinely carries file
31
31
  * contents, command output, secrets in an env dump, and customer data from
32
32
  * an API response. None of it reaches this file's output, because the
33
33
  * output has no field able to carry it. A record shape that cannot hold a
@@ -47,6 +47,34 @@
47
47
  * identical while the cost came back. The `RESULT_KEYS` literals below are the
48
48
  * key NAMES this concern looks under, not a read of the body.
49
49
  *
50
+ * TWO COUNTS, ONE OF THEM REDUNDANT TODAY. `raw_bytes` is what
51
+ * the host handed the dispatcher; `delivered_bytes` is what reached the
52
+ * model. Today they are EQUAL BY CONSTRUCTION, and the construction is
53
+ * checkable: nothing under `src/` or `docs/` emits the host's result-rewrite
54
+ * field, so no concern can rewrite a tool result on its way past. That
55
+ * absence is a grep, and the grep lives in this concern's test rather than
56
+ * in this sentence - a claim in a comment is not falsifiable, and naming the
57
+ * field here would put a match in the very tree the grep sweeps.
58
+ *
59
+ * Recording both NOW is what makes a later reduction measurable instead of
60
+ * asserted. With one field, a future release that starts trimming results
61
+ * has no before-number and can only claim an improvement; with two, the
62
+ * delta is in the census the day the trimming lands. The cost of the second
63
+ * field is one integer per line in one workspace — see the gate below.
64
+ *
65
+ * DEFAULT OFF OUTSIDE THE MAINTAINER WORKSPACE. A byte counter on every
66
+ * tool call in every consumer install is
67
+ * the cheapest possible way to add a second unread instrument: it costs a
68
+ * write per tool call, accumulates volume, and answers a question only this
69
+ * package's maintainers have asked. So {@link resolvesMaintainerWorkspace}
70
+ * gates the write, and with no maintainer workspace resolved a dispatch
71
+ * writes nothing at all — not an empty line, not a file.
72
+ *
73
+ * A consumer who WANTS the census sets `AGENT_CONFIG_TOOL_BYTE_CENSUS=1`.
74
+ * That is a deliberate opt-in and it is the only other way the write
75
+ * happens; there is no settings key, because a key would put the decision in
76
+ * a file this concern would then have to parse on the hot path.
77
+ *
50
78
  * ── Always exit 0 ─────────────────────────────────────────────────────
51
79
  *
52
80
  * A `warn` (exit 2) is read as a hard BLOCK on this host, and this concern
@@ -56,8 +84,8 @@
56
84
  *
57
85
  * ── Absence is recorded, not inferred ─────────────────────────────────
58
86
  *
59
- * A payload carrying no readable result writes a line with `bytes: null`
60
- * and `measurable: false` rather than writing nothing. The two cases are
87
+ * A payload carrying no readable result writes a line with both byte fields
88
+ * null and `measurable: false` rather than writing nothing. The two cases are
61
89
  * otherwise byte-identical in the output — "this host does not carry tool
62
90
  * results in its PostToolUse payload" and "no tools ran" would produce the
63
91
  * same empty file, and the first is a finding about the instrument's own
@@ -72,8 +100,7 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
72
100
  import { is_replay_mode } from './state_io.js';
73
101
  import { readHookStdin } from './hook_stdin.js';
74
102
  import { stubbedBytes } from './payload_stub.js';
75
-
76
- const EXIT_ALLOW = 0;
103
+ import { EXIT_ALLOW } from './exit_codes.js';
77
104
 
78
105
  type JsonValue = string | number | boolean | null | JsonValue[] | { [k: string]: JsonValue };
79
106
  type JsonObject = { [k: string]: JsonValue };
@@ -85,7 +112,7 @@ function isObject(v: unknown): v is JsonObject {
85
112
  /**
86
113
  * Census file, relative to the consumer repo root. Sibling of
87
114
  * `injection-census.jsonl` in the same directory and the same
88
- * `{ts, …, bytes}` line shape — one family, two units: that file counts
115
+ * `{ts, …, bytes}` line family — one family, two units: that file counts
89
116
  * bytes this suite injects, this one counts bytes the host's tools do.
90
117
  * Gitignored via `/agents/runtime/`.
91
118
  */
@@ -169,13 +196,65 @@ function censusFile(consumerRoot: string): string {
169
196
  export interface CensusLine {
170
197
  ts: string;
171
198
  tool: string | null;
172
- bytes: number | null;
199
+ /** UTF-8 bytes the host handed the dispatcher. `null` ⇒ unmeasurable. */
200
+ raw_bytes: number | null;
201
+ /**
202
+ * UTF-8 bytes that reached the model.
203
+ *
204
+ * Equal to {@link CensusLine.raw_bytes} by construction today — nothing in
205
+ * this tree rewrites a tool result. It is recorded anyway so that a later
206
+ * reduction is a measured delta rather than a claim. See the header.
207
+ */
208
+ delivered_bytes: number | null;
173
209
  /** `false` ⇒ the payload carried no readable result. See the header. */
174
210
  measurable: boolean;
175
211
  }
176
212
 
213
+ /** `package.json.name` of the workspace this census is for. */
214
+ export const MAINTAINER_PACKAGE_NAME = '@event4u/agent-config';
215
+
216
+ /** Deliberate consumer opt-in. Any other value, or unset, leaves the census off. */
217
+ export const CENSUS_OPT_IN_ENV = 'AGENT_CONFIG_TOOL_BYTE_CENSUS';
218
+
219
+ /** Memoised per root: this is read once per dispatched tool call otherwise. */
220
+ const _maintainerCache = new Map<string, boolean>();
221
+
222
+ /** Test seam — the cache would otherwise outlive a fixture root's contents. */
223
+ export function _resetMaintainerCache(): void {
224
+ _maintainerCache.clear();
225
+ }
226
+
227
+ /**
228
+ * Does this root resolve the maintainer workspace?
229
+ *
230
+ * Read off `package.json.name`, which is the cheapest unambiguous marker of
231
+ * the one workspace whose `workspaces: [agent-config-maintainer]` artefacts
232
+ * are active. A settings key was rejected: it would put a YAML parse on the
233
+ * post_tool_use path for a decision that never changes within a checkout.
234
+ *
235
+ * Any failure — no `package.json`, unreadable, unparseable, a different name
236
+ * — resolves to FALSE. The default is silence, which is the safe direction
237
+ * for an instrument nobody in that workspace is going to read.
238
+ */
239
+ export function resolvesMaintainerWorkspace(consumerRoot: string): boolean {
240
+ if (process.env[CENSUS_OPT_IN_ENV] === '1') return true;
241
+ const cached = _maintainerCache.get(consumerRoot);
242
+ if (cached !== undefined) return cached;
243
+ let verdict = false;
244
+ try {
245
+ const raw = fs.readFileSync(path.join(consumerRoot, 'package.json'), 'utf8');
246
+ const parsed = JSON.parse(raw) as unknown;
247
+ verdict = isObject(parsed) && parsed['name'] === MAINTAINER_PACKAGE_NAME;
248
+ } catch {
249
+ verdict = false;
250
+ }
251
+ _maintainerCache.set(consumerRoot, verdict);
252
+ return verdict;
253
+ }
254
+
177
255
  export function _appendCensusLine(consumerRoot: string, line: CensusLine): void {
178
256
  if (is_replay_mode()) return;
257
+ if (!resolvesMaintainerWorkspace(consumerRoot)) return;
179
258
  const file = censusFile(consumerRoot);
180
259
  fs.mkdirSync(path.dirname(file), { recursive: true });
181
260
  fs.appendFileSync(file, `${JSON.stringify(line)}\n`, 'utf8');
@@ -193,7 +272,12 @@ export function processEnvelope(envelope: JsonValue, consumerRoot: string): numb
193
272
  _appendCensusLine(consumerRoot, {
194
273
  ts: new Date().toISOString(),
195
274
  tool: _toolName(payload, envelope),
196
- bytes,
275
+ raw_bytes: bytes,
276
+ // Equal BY CONSTRUCTION, not by copy-as-convenience: no concern
277
+ // can rewrite a result between the host and the model, because
278
+ // nothing under src/ or docs/ emits the host's rewrite field. The
279
+ // test pins that as a grep; naming the field here would match it.
280
+ delivered_bytes: bytes,
197
281
  measurable: bytes !== null,
198
282
  });
199
283
  } catch {