@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
@@ -0,0 +1,228 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * Every in-body `${x}` on an artifact that declares `inputs:` is backed by a
4
+ * declaration.
5
+ *
6
+ * road-to-an-invocation-contract-that-reaches-the-wire 2.2.
7
+ *
8
+ * SCOPED TO DECLARING ARTIFACTS, ON PURPOSE
9
+ *
10
+ * An artifact with no `inputs:` block is not checked at all. That is what lets
11
+ * this arrive with zero findings over a corpus where nothing declares anything
12
+ * yet, and grow only with adoption — a check that fired on every artifact would
13
+ * have to be introduced together with a migration nobody asked for, which is
14
+ * exactly what the optional block was designed to avoid.
15
+ *
16
+ * THE COUNTING UNIT IS THE CENSUS'S, IMPORTED
17
+ *
18
+ * A reference counts when it appears in PROSE — outside fenced code blocks,
19
+ * indented blocks and inline code spans. `proseOnly` is imported from
20
+ * `report_invocation_surface.ts` rather than restated, because two copies of
21
+ * that definition would drift and the whole point of this phase is that the
22
+ * declaration and what depends on it cannot disagree.
23
+ *
24
+ * The consequence is stated rather than hidden: a `${target}` inside a fenced
25
+ * usage example is NOT checked. That is the conservative direction. A skill
26
+ * teaching Terraform has `${local.x}` in a fence and would otherwise be
27
+ * reported against a declaration it never claimed to satisfy — a false positive
28
+ * on working content, which is the failure that makes a young gate get
29
+ * disabled. When adoption makes in-fence usage examples common, widening the
30
+ * unit is a deliberate change with its own diff.
31
+ *
32
+ * Exit codes: 0 every reference backed · 1 an unbacked reference · 2 the corpus
33
+ * could not be read.
34
+ */
35
+
36
+ import fs from 'node:fs';
37
+ import os from 'node:os';
38
+ import path from 'node:path';
39
+ import { fileURLToPath, pathToFileURL } from 'node:url';
40
+
41
+ import * as yaml from 'js-yaml';
42
+
43
+ import { GateLedger } from './_lib/gate_ledger.js';
44
+ import { runGateCli, runSelfTest } from './_lib/gate_self_test.js';
45
+ import { assertScanned, reportScanned } from './_lib/scan_scope.js';
46
+ import { proseOnly } from './report_invocation_surface.js';
47
+
48
+ const _HERE = fileURLToPath(import.meta.url);
49
+ const ROOT = path.resolve(path.dirname(_HERE), '..', '..');
50
+
51
+ export const GATE = 'check_input_references';
52
+
53
+ /** The reference form this checks. Only the plurality syntax is a reference. */
54
+ const REFERENCE_RE = /\$\{([a-z][a-z0-9_]*)\}/g;
55
+
56
+ export interface Unbacked {
57
+ readonly file: string;
58
+ readonly name: string;
59
+ readonly declared: readonly string[];
60
+ }
61
+
62
+ /** Declared input names, or `null` when the artifact declares no block at all. */
63
+ export function declaredInputs(text: string): string[] | null {
64
+ const m = /^---\n([\s\S]*?)\n---/.exec(text);
65
+ if (m === null) return null;
66
+ let fm: unknown;
67
+ try {
68
+ fm = yaml.load(m[1]!);
69
+ } catch {
70
+ return null;
71
+ }
72
+ if (fm === null || typeof fm !== 'object') return null;
73
+ const inputs = (fm as Record<string, unknown>)['inputs'];
74
+ if (!Array.isArray(inputs)) return null;
75
+ const names: string[] = [];
76
+ for (const item of inputs) {
77
+ if (item === null || typeof item !== 'object') continue;
78
+ const name = (item as Record<string, unknown>)['name'];
79
+ if (typeof name === 'string') names.push(name);
80
+ }
81
+ return names;
82
+ }
83
+
84
+ /**
85
+ * Prose `${x}` references with no matching declaration.
86
+ *
87
+ * Returns `[]` for an artifact that declares no block — not because it has no
88
+ * references, but because it is out of scope.
89
+ */
90
+ export function unbackedReferences(text: string, file = '<data>'): Unbacked[] {
91
+ const declared = declaredInputs(text);
92
+ if (declared === null) return [];
93
+ const seen = new Set<string>();
94
+ const out: Unbacked[] = [];
95
+ for (const m of proseOnly(text).matchAll(REFERENCE_RE)) {
96
+ const name = m[1]!;
97
+ if (declared.includes(name) || seen.has(name)) continue;
98
+ seen.add(name);
99
+ out.push({ file, name, declared });
100
+ }
101
+ return out;
102
+ }
103
+
104
+ function walk(dir: string, match: (n: string) => boolean, out: string[] = []): string[] {
105
+ if (!fs.existsSync(dir)) return out;
106
+ for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
107
+ const p = path.join(dir, e.name);
108
+ if (e.isDirectory()) walk(p, match, out);
109
+ else if (match(e.name)) out.push(p);
110
+ }
111
+ return out;
112
+ }
113
+
114
+ export function scan(root: string): { findings: Unbacked[]; scanned: number; declaring: number } {
115
+ const files = [
116
+ ...walk(path.join(root, 'dist', 'agent-src', 'commands'), (n) => n.endsWith('.md')),
117
+ ...walk(path.join(root, 'src', 'skills'), (n) => n === 'SKILL.md'),
118
+ ].sort();
119
+
120
+ const findings: Unbacked[] = [];
121
+ let declaring = 0;
122
+ for (const f of files) {
123
+ const text = fs.readFileSync(f, 'utf8');
124
+ if (declaredInputs(text) !== null) declaring += 1;
125
+ findings.push(...unbackedReferences(text, path.relative(root, f)));
126
+ }
127
+ return { findings, scanned: files.length, declaring };
128
+ }
129
+
130
+ export function main(argv: readonly string[]): number {
131
+ if (argv.includes('--self-test')) return selfTest();
132
+ const rootIdx = argv.indexOf('--root');
133
+ const root = rootIdx === -1 ? ROOT : (argv[rootIdx + 1] ?? ROOT);
134
+
135
+ const { findings, scanned, declaring } = scan(root);
136
+ const ledger = new GateLedger(GATE);
137
+ ledger.plan(findings.map((f) => `${f.file}:${f.name}`));
138
+ for (const f of findings) {
139
+ ledger.fail(`${f.file}:${f.name}`, `\`\${${f.name}}\` is not declared`);
140
+ }
141
+
142
+ // A gate that read nothing has not passed. This fires BEFORE the verdict,
143
+ // because certifying against an empty corpus is the false green the coverage
144
+ // manifest exists to refuse — named by the provider-diverse ratification
145
+ // review as one condition that would have flipped its verdict.
146
+ assertScanned({ gate: GATE, scanned: scanned, units: 'artifact(s)', roots: ['dist/agent-src/commands', 'src/skills'] });
147
+
148
+ reportScanned({
149
+ gate: GATE,
150
+ scanned,
151
+ units: 'artifact(s)',
152
+ roots: ['dist/agent-src/commands', 'src/skills'],
153
+ });
154
+ ledger.report();
155
+
156
+ if (findings.length > 0) {
157
+ for (const f of findings) {
158
+ process.stdout.write(
159
+ `❌ ${GATE}: ${f.file} references \`\${${f.name}}\` with no \`inputs.${f.name}\` ` +
160
+ `(declared: ${f.declared.length > 0 ? f.declared.join(', ') : 'none'}).\n`,
161
+ );
162
+ }
163
+ process.stdout.write(
164
+ '\nAdd the declaration, or drop the reference. Only artifacts that declare ' +
165
+ '`inputs:` at all are checked, so this never asks an artifact to start ' +
166
+ 'declaring — it asks a declaration to be complete.\n',
167
+ );
168
+ return 1;
169
+ }
170
+
171
+ process.stdout.write(
172
+ `✅ ${GATE}: every in-body reference is backed ` +
173
+ `(${String(declaring)} of ${String(scanned)} artifact(s) declare \`inputs:\`).\n`,
174
+ );
175
+ return 0;
176
+ }
177
+
178
+ /**
179
+ * A self-test is what proves a gate DISCRIMINATES. An enforced scan floor only
180
+ * proves it read something; the verdict has to move.
181
+ */
182
+ function selfTest(): number {
183
+ const plant = (name: string, body: string): string => {
184
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), `input-refs-${name}-`));
185
+ const skills = path.join(dir, 'src', 'skills', 'probe');
186
+ fs.mkdirSync(skills, { recursive: true });
187
+ fs.writeFileSync(path.join(skills, 'SKILL.md'), body, 'utf-8');
188
+ return dir;
189
+ };
190
+ const declaring = (ref: string): string =>
191
+ `---\nname: probe\ninputs:\n - name: a\n type: string\n---\n\nUses ${ref} here.\n`;
192
+
193
+ const run = (root: string): number =>
194
+ runGateCli(ROOT, path.join('src', 'scripts', 'check_input_references.ts'), ['--root', root], ROOT);
195
+
196
+ return runSelfTest({
197
+ gate: GATE,
198
+ minCases: 4,
199
+ minRejectCases: 2,
200
+ cases: [
201
+ {
202
+ name: 'an empty corpus is refused, not certified green',
203
+ expect: 'reject',
204
+ run: () => run(fs.mkdtempSync(path.join(os.tmpdir(), 'input-refs-empty-'))),
205
+ },
206
+ {
207
+ name: 'a reference the declaration backs passes',
208
+ expect: 'accept',
209
+ run: () => run(plant('backed', declaring('${a}'))),
210
+ },
211
+ {
212
+ name: 'a reference nothing declares fails',
213
+ expect: 'reject',
214
+ run: () => run(plant('unbacked', declaring('${b}'))),
215
+ },
216
+ {
217
+ name: 'an artifact with no declaration is out of scope, however it references',
218
+ expect: 'accept',
219
+ run: () =>
220
+ run(plant('noblock', '---\nname: probe\n---\n\nUses ${anything} here.\n')),
221
+ },
222
+ ],
223
+ });
224
+ }
225
+
226
+ if (process.argv[1] && import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href) {
227
+ process.exit(main(process.argv.slice(2)));
228
+ }
@@ -0,0 +1,235 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * What the MCP server reads from an `inputs:` block equals what a real YAML
4
+ * parser reads from it.
5
+ *
6
+ * road-to-an-invocation-contract-that-reaches-the-wire — added after review.
7
+ *
8
+ * WHY THIS GATE EXISTS
9
+ *
10
+ * The server's `_parse_inputs` is a hand-rolled reader of a YAML subset,
11
+ * because the MCP server is stdlib-only and bundled and must not grow a YAML
12
+ * dependency to read one optional block. A hand-rolled reader of a format it
13
+ * does not fully implement has exactly one dangerous failure mode: reading
14
+ * something DIFFERENT from what the author wrote, silently. A host is then told
15
+ * about an argument that does not exist, or not told about one that does — and
16
+ * the schema validates either way, because the schema checks the YAML, not the
17
+ * reader.
18
+ *
19
+ * An independent review found that failure live: the reader's key scan ran at
20
+ * any depth, so a `default:` mapping whose first child was `name:` overwrote
21
+ * the parameter's own name. It also silently misread `required: True`, the
22
+ * flow form, a comment at column zero, and a block scalar. Every one of those
23
+ * is schema-valid.
24
+ *
25
+ * So the reader now DECLINES what it cannot model, and this gate makes every
26
+ * decline and every divergence a build failure with a named remedy. The
27
+ * contract is: write the block form, or the build tells you. That is strictly
28
+ * better than a reader that is clever and occasionally wrong, and it is why the
29
+ * reader is allowed to stay stdlib-only.
30
+ *
31
+ * Exit codes: 0 parity holds · 1 a divergence · 2 the corpus could not be read.
32
+ */
33
+
34
+ import fs from 'node:fs';
35
+ import os from 'node:os';
36
+ import path from 'node:path';
37
+ import { fileURLToPath, pathToFileURL } from 'node:url';
38
+
39
+ import * as yaml from 'js-yaml';
40
+
41
+ import { GateLedger } from './_lib/gate_ledger.js';
42
+ import { runGateCli, runSelfTest } from './_lib/gate_self_test.js';
43
+ import { assertScanned, reportScanned } from './_lib/scan_scope.js';
44
+ import { _frontmatter_text, _parse_inputs, type PromptInput } from './mcp_server/prompts.js';
45
+
46
+ const _HERE = fileURLToPath(import.meta.url);
47
+ const ROOT = path.resolve(path.dirname(_HERE), '..', '..');
48
+
49
+ export const GATE = 'check_inputs_parity';
50
+
51
+ /** The same reduction `_parse_inputs` produces, taken from a real YAML parse. */
52
+ export function yamlInputs(fmText: string): PromptInput[] | null {
53
+ let doc: unknown;
54
+ try {
55
+ doc = yaml.load(fmText);
56
+ } catch {
57
+ return null;
58
+ }
59
+ if (doc === null || typeof doc !== 'object') return null;
60
+ const raw = (doc as Record<string, unknown>)['inputs'];
61
+ if (raw === undefined) return null;
62
+ if (!Array.isArray(raw)) return [];
63
+ const out: PromptInput[] = [];
64
+ for (const item of raw) {
65
+ if (item === null || typeof item !== 'object') continue;
66
+ const r = item as Record<string, unknown>;
67
+ if (typeof r['name'] !== 'string') continue;
68
+ out.push({
69
+ name: r['name'],
70
+ description: typeof r['description'] === 'string' ? r['description'] : '',
71
+ required: r['required'] === true,
72
+ });
73
+ }
74
+ return out;
75
+ }
76
+
77
+ export interface Divergence {
78
+ readonly file: string;
79
+ readonly server: PromptInput[];
80
+ readonly yaml: PromptInput[];
81
+ }
82
+
83
+ const same = (a: readonly PromptInput[], b: readonly PromptInput[]): boolean =>
84
+ a.length === b.length &&
85
+ a.every(
86
+ (x, i) =>
87
+ x.name === b[i]!.name &&
88
+ x.required === b[i]!.required &&
89
+ x.description === b[i]!.description,
90
+ );
91
+
92
+ /** Compare both readers over one document. `null` when it declares no block. */
93
+ export function compare(text: string, file: string): Divergence | null {
94
+ const fm = _frontmatter_text(text);
95
+ if (fm === '') return null;
96
+ const expected = yamlInputs(fm);
97
+ if (expected === null) return null;
98
+ const actual = _parse_inputs(fm);
99
+ return same(actual, expected) ? null : { file, server: actual, yaml: expected };
100
+ }
101
+
102
+ function walk(dir: string, match: (n: string) => boolean, out: string[] = []): string[] {
103
+ if (!fs.existsSync(dir)) return out;
104
+ for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
105
+ const p = path.join(dir, e.name);
106
+ if (e.isDirectory()) walk(p, match, out);
107
+ else if (match(e.name)) out.push(p);
108
+ }
109
+ return out;
110
+ }
111
+
112
+ export function scan(root: string): { findings: Divergence[]; scanned: number } {
113
+ const files = [
114
+ ...walk(path.join(root, 'src', 'domains'), (n) => n === 'command.md'),
115
+ ...walk(path.join(root, 'src', 'skills'), (n) => n === 'SKILL.md'),
116
+ ...walk(path.join(root, 'dist', 'agent-src', 'commands'), (n) => n.endsWith('.md')),
117
+ ].sort();
118
+
119
+ const findings: Divergence[] = [];
120
+ for (const f of files) {
121
+ const d = compare(fs.readFileSync(f, 'utf8'), path.relative(root, f));
122
+ if (d !== null) findings.push(d);
123
+ }
124
+ return { findings, scanned: files.length };
125
+ }
126
+
127
+ export function main(argv: readonly string[]): number {
128
+ if (argv.includes('--self-test')) return selfTest();
129
+ const rootIdx = argv.indexOf('--root');
130
+ const root = rootIdx === -1 ? ROOT : (argv[rootIdx + 1] ?? ROOT);
131
+
132
+ const { findings, scanned } = scan(root);
133
+ const ledger = new GateLedger(GATE);
134
+ ledger.plan(findings.map((f) => f.file));
135
+ for (const f of findings) {
136
+ ledger.fail(f.file, `server read ${String(f.server.length)}, YAML read ${String(f.yaml.length)}`);
137
+ }
138
+
139
+ // A gate that read nothing has not passed. This fires BEFORE the verdict,
140
+ // because certifying against an empty corpus is the false green the coverage
141
+ // manifest exists to refuse — named by the provider-diverse ratification
142
+ // review as one condition that would have flipped its verdict.
143
+ assertScanned({ gate: GATE, scanned: scanned, units: 'artifact(s)', roots: ['src/domains', 'src/skills', 'dist/agent-src/commands'] });
144
+
145
+ reportScanned({
146
+ gate: GATE,
147
+ scanned,
148
+ units: 'artifact(s)',
149
+ roots: ['src/domains', 'src/skills', 'dist/agent-src/commands'],
150
+ });
151
+ ledger.report();
152
+
153
+ if (findings.length > 0) {
154
+ for (const f of findings) {
155
+ process.stdout.write(
156
+ `❌ ${GATE}: ${f.file} — the MCP reader and YAML disagree about \`inputs:\`.\n` +
157
+ ` server: ${JSON.stringify(f.server)}\n` +
158
+ ` yaml: ${JSON.stringify(f.yaml)}\n`,
159
+ );
160
+ }
161
+ process.stdout.write(
162
+ '\nThe server reads one shape, deliberately — a block sequence of `- name:` items ' +
163
+ 'with scalar values on their own lines. Rewrite the declaration in that shape. ' +
164
+ 'The flow form, a block scalar and a nested mapping under an item key are ' +
165
+ 'refused rather than guessed at, and this gate is how the refusal is visible ' +
166
+ 'instead of becoming a wrong argument on the wire.\n',
167
+ );
168
+ return 1;
169
+ }
170
+
171
+ process.stdout.write(
172
+ `✅ ${GATE}: the MCP reader and YAML agree on every declared \`inputs:\` block.\n`,
173
+ );
174
+ return 0;
175
+ }
176
+
177
+ /**
178
+ * One rejecting case per way the reader and YAML can part company, plus the
179
+ * agreeing case — because a suite that only proves passes proves nothing.
180
+ */
181
+ function selfTest(): number {
182
+ const plant = (name: string, fm: string): string => {
183
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), `inputs-parity-${name}-`));
184
+ const skills = path.join(dir, 'src', 'skills', 'probe');
185
+ fs.mkdirSync(skills, { recursive: true });
186
+ fs.writeFileSync(path.join(skills, 'SKILL.md'), `---\nname: probe\n${fm}---\n\nbody\n`, 'utf-8');
187
+ return dir;
188
+ };
189
+ const run = (root: string): number =>
190
+ runGateCli(ROOT, path.join('src', 'scripts', 'check_inputs_parity.ts'), ['--root', root], ROOT);
191
+
192
+ return runSelfTest({
193
+ gate: GATE,
194
+ minCases: 6,
195
+ minRejectCases: 5,
196
+ cases: [
197
+ {
198
+ name: 'an empty corpus is refused, not certified green',
199
+ expect: 'reject',
200
+ run: () => run(fs.mkdtempSync(path.join(os.tmpdir(), 'inputs-parity-empty-'))),
201
+ },
202
+ {
203
+ name: 'the supported block form agrees',
204
+ expect: 'accept',
205
+ run: () => run(plant('ok', 'inputs:\n - name: a\n type: string\n required: true\n')),
206
+ },
207
+ {
208
+ name: 'the flow form is a divergence',
209
+ expect: 'reject',
210
+ run: () => run(plant('flow', 'inputs: [{name: a, type: string}]\n')),
211
+ },
212
+ {
213
+ name: 'a nested mapping under an item key is a divergence',
214
+ expect: 'reject',
215
+ run: () =>
216
+ run(plant('nested', 'inputs:\n - name: opts\n type: string\n default:\n name: fallback\n')),
217
+ },
218
+ {
219
+ name: 'a block scalar is a divergence',
220
+ expect: 'reject',
221
+ run: () =>
222
+ run(plant('scalar', 'inputs:\n - name: a\n type: string\n description: >\n long\n')),
223
+ },
224
+ {
225
+ name: 'a dash on its own line is a divergence',
226
+ expect: 'reject',
227
+ run: () => run(plant('bareDash', 'inputs:\n -\n name: a\n type: string\n')),
228
+ },
229
+ ],
230
+ });
231
+ }
232
+
233
+ if (process.argv[1] && import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href) {
234
+ process.exit(main(process.argv.slice(2)));
235
+ }
@@ -30,10 +30,14 @@
30
30
  *
31
31
  * Gated: a diff touching a kernel rule under `src/rules/` (the nine of
32
32
  * `_lib/kernel_rules.ts`), a governance hook (`src/scripts/hooks/block_*.ts`),
33
- * or this gate itself — so it cannot be weakened without its own record. Such
34
- * a diff must carry a ratification artifact under
35
- * the ratifications directory with `verdict: ratified`, valid per the
36
- * ratification-artifact contract.
33
+ * hook plumbing — the YAML sources `hook_manifest.yaml` and
34
+ * `host_lowering.yaml`, their compiled siblings `hook_manifest.json` and
35
+ * `host_lowering.json`, the dispatcher `hooks/dispatch_hook.ts`, the
36
+ * kernel-rule list `_lib/kernel_rules.ts`, a `*-dispatcher.sh`, either hook
37
+ * budget file (see `PLUMBING_SOURCE_RE`) — or this gate itself, so it cannot
38
+ * be weakened without its own record. Such a diff must carry a ratification
39
+ * artifact under the ratifications directory with `verdict: ratified`, valid
40
+ * per the ratification-artifact contract.
37
41
  *
38
42
  * Every kernel diff is gated, not only the authority-EXPANDING ones.
39
43
  * ADR-268 § 4 makes the artifact required for authority-expanding edits. Which
@@ -122,6 +126,67 @@ export const ANCHOR_PATHS: readonly string[] = [
122
126
  /** Governance hooks: the blocking PreToolUse guards. */
123
127
  const GOVERNANCE_HOOK_RE = /^src\/scripts\/hooks\/block_[a-z0-9_]+\.ts$/;
124
128
 
129
+ /**
130
+ * Hook-plumbing SOURCES — the files that decide which concern runs, on which
131
+ * host, under which budget.
132
+ *
133
+ * `road-to-a-kernel-that-guards-its-plumbing` 1.1. The nine kernel rules were
134
+ * governed and the plumbing that decides whether a guard runs at all was not,
135
+ * so a diff deleting `block-no-verify` from the manifest carried no record
136
+ * while a typo in the rule it enforces carried one. The asymmetry was the
137
+ * defect: a concern removed from `hook_manifest.yaml` is a refusal that stops
138
+ * happening, which is the same authority change as loosening the rule behind
139
+ * it, reached one file earlier.
140
+ *
141
+ * This is the ADR-268 § 4 mechanism EXTENDED, not a second deny. Nothing new
142
+ * refuses a tool call here; the same CI gate simply reads a wider path set,
143
+ * and every property the gate already had — base-revision code, in-repo quorum
144
+ * policy, the whole diff as its unit — carries over unchanged.
145
+ *
146
+ * `dist/hooks/dispatch.js` and `hooks/hooks.json` are BUILD OUTPUTS that no
147
+ * reader in this repository opens — they exist only inside an installed
148
+ * consumer tree — and they have no legitimate hand edit at all, so they are
149
+ * refused at tool-call time by `block_plumbing_writes.ts` rather than ratified
150
+ * here: a record for a file whose every hand edit is illegitimate would be a
151
+ * record of a mistake.
152
+ *
153
+ * road-to-blocking-severities 2.1 WIDENS this from "sources only" to
154
+ * "everything the dispatcher serves at runtime", and the distinction above is
155
+ * why the two compiled tables land here while the two build outputs do not.
156
+ * `src/scripts/hook_manifest.json` and `src/scripts/hooks/host_lowering.json`
157
+ * are committed in THIS tree and are READ IN PREFERENCE to the YAML they were
158
+ * compiled from — `dispatch_hook._load_yaml` and `host_lowering.resolveTable`
159
+ * both serve the compiled body whenever its fingerprint matches. A diff that
160
+ * edits only the JSON therefore changes what every host is told about which
161
+ * concern runs and which slot can refuse, while the gated YAML beside it is
162
+ * untouched. That is the same authority change as editing the source, reached
163
+ * one file later, and before this step it carried no record.
164
+ *
165
+ * Two further files join for the same reason rather than by analogy:
166
+ *
167
+ * - `src/scripts/hooks/dispatch_hook.ts` is the dispatcher itself. Every
168
+ * concern's verdict passes through it, so an edit here can suppress a
169
+ * refusal without touching the manifest that declares it.
170
+ * - `src/scripts/_lib/kernel_rules.ts` is the list of the nine kernel rules.
171
+ * THIS GATE resolves `is_kernel_rule` through it, so a diff removing a name
172
+ * from that list removes a rule from this gate's own reach — the one edit
173
+ * that could quietly narrow the gate while every other path kept working.
174
+ *
175
+ * Both are also denied at tool-call time, `dispatch_hook.ts` through the
176
+ * plumbing guard's source set and `kernel_rules.ts` through the kernel-rule
177
+ * write guard, so the pairing of deny-plus-record matches what the YAML sources
178
+ * already had.
179
+ *
180
+ * The compiled tables are REGENERATED, not hand-edited, by
181
+ * `./scripts-run src/scripts/compile_hook_manifest --table manifest|host-lowering`,
182
+ * which runs as a script rather than as an edit tool call and so is not what
183
+ * either mechanism refuses. A regeneration lands in the same diff as the YAML
184
+ * change that caused it, which already requires a record; the case this closes
185
+ * is the diff where only the JSON moves.
186
+ */
187
+ const PLUMBING_SOURCE_RE =
188
+ /^(?:src\/scripts\/hook_manifest\.(?:yaml|json)|src\/scripts\/hooks\/host_lowering\.(?:yaml|json)|src\/scripts\/hooks\/dispatch_hook\.ts|src\/scripts\/_lib\/kernel_rules\.ts|src\/scripts\/hooks\/[a-z0-9-]+-dispatcher\.sh|src\/config\/hook-(?:token|latency)-budget\.json)$/;
189
+
125
190
  /**
126
191
  * A kernel rule, in the source tree or in any projection.
127
192
  *
@@ -141,6 +206,8 @@ const KERNEL_RULE_PATH_RE = /(?:^|\/)rules\/([a-z0-9-]+)\.md$/;
141
206
  export interface GatedPaths {
142
207
  kernelRules: string[];
143
208
  governanceHooks: string[];
209
+ /** Hook-plumbing sources — manifest, host lowering, dispatchers, budgets. */
210
+ plumbing: string[];
144
211
  self: boolean;
145
212
  }
146
213
 
@@ -148,6 +215,7 @@ export interface GatedPaths {
148
215
  export function classifyPaths(files: readonly string[]): GatedPaths {
149
216
  const kernelRules: string[] = [];
150
217
  const governanceHooks: string[] = [];
218
+ const plumbing: string[] = [];
151
219
  let self = false;
152
220
  for (const raw of files) {
153
221
  const p = raw.replace(/\\/g, '/').trim();
@@ -171,14 +239,23 @@ export function classifyPaths(files: readonly string[]): GatedPaths {
171
239
  }
172
240
  if (GOVERNANCE_HOOK_RE.test(p)) {
173
241
  governanceHooks.push(p);
242
+ continue;
243
+ }
244
+ if (PLUMBING_SOURCE_RE.test(p)) {
245
+ plumbing.push(p);
174
246
  }
175
247
  }
176
- return { kernelRules, governanceHooks, self };
248
+ return { kernelRules, governanceHooks, plumbing, self };
177
249
  }
178
250
 
179
251
  /** True when anything in the diff requires a ratification artifact. */
180
252
  export function requiresRatification(gated: GatedPaths): boolean {
181
- return gated.kernelRules.length > 0 || gated.governanceHooks.length > 0 || gated.self;
253
+ return (
254
+ gated.kernelRules.length > 0 ||
255
+ gated.governanceHooks.length > 0 ||
256
+ gated.plumbing.length > 0 ||
257
+ gated.self
258
+ );
182
259
  }
183
260
 
184
261
  /** Ratification artifacts present in the diff, as repo-relative paths. */
@@ -253,6 +330,7 @@ export function evaluate(
253
330
  const gatedSet = new Set<string>([
254
331
  ...gated.kernelRules,
255
332
  ...gated.governanceHooks,
333
+ ...gated.plumbing,
256
334
  ...(gated.self ? [SELF_PATH] : []),
257
335
  ]);
258
336
  const artifactSet = new Set(ratificationArtifactsIn(files));
@@ -286,7 +364,8 @@ export function evaluate(
286
364
 
287
365
  if (!requiresRatification(gated)) {
288
366
  lines.push(
289
- '✅ no kernel rule, governance hook or self edit in the diff — nothing to ratify',
367
+ '✅ no kernel rule, governance hook, hook-plumbing source or self edit in the ' +
368
+ 'diff — nothing to ratify',
290
369
  );
291
370
  close(true);
292
371
  return { exitCode: 0, lines, scanned };
@@ -295,6 +374,7 @@ export function evaluate(
295
374
  const touched = [
296
375
  ...gated.kernelRules.map((p) => `kernel rule ${p}`),
297
376
  ...gated.governanceHooks.map((p) => `governance hook ${p}`),
377
+ ...gated.plumbing.map((p) => `hook-plumbing source ${p}`),
298
378
  ...(gated.self ? ['the ratification mechanism itself (gate, reader, policy or workflow)'] : []),
299
379
  ];
300
380
  lines.push(`Gated surfaces in this diff (${touched.length}):`);
@@ -446,8 +526,8 @@ export function main(argv: readonly string[] = process.argv.slice(2)): number {
446
526
  roots: ['<the diff against the base ref>'],
447
527
  allowEmpty:
448
528
  'EMPTY_VALID: the corpus is one diff. A commit range that changed nothing is a ' +
449
- 'real state, and there is then no kernel rule, governance hook or mechanism file ' +
450
- 'to ratify — the gate has read everything there was.',
529
+ 'real state, and there is then no kernel rule, governance hook, plumbing source or ' +
530
+ 'mechanism file to ratify — the gate has read everything there was.',
451
531
  });
452
532
  if (!quiet || result.exitCode !== 0) {
453
533
  for (const l of result.lines) {