@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.
- package/.augment-plugin/marketplace.json +3 -3
- package/.augment-plugin/plugin.json +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +98 -257
- package/README.md +14 -12
- package/dist/agent-src/commands/analyze/inbox.md +1 -1
- package/dist/agent-src/commands/analyze/roadmap-repos.md +1 -1
- package/dist/agent-src/commands/bug/fix.md +17 -2
- package/dist/agent-src/commands/feature/plan.md +1 -1
- package/dist/agent-src/commands/feature/roadmap.md +1 -1
- package/dist/agent-src/commands/fix/ci.md +1 -1
- package/dist/agent-src/commands/implement-ticket.md +1 -1
- package/dist/agent-src/commands/jira-ticket.md +1 -1
- package/dist/agent-src/commands/roadmap/create.md +1 -1
- package/dist/agent-src/commands/roadmap/materialize.md +1 -1
- package/dist/agent-src/commands/roadmap/process-full.md +5 -5
- package/dist/agent-src/commands/roadmap/resolve-blockers.md +361 -0
- package/dist/agent-src/commands/roadmap/triage-parked.md +325 -0
- package/dist/agent-src/commands/roadmap.md +18 -4
- package/dist/agent-src/commands/tests/create.md +17 -3
- package/dist/agent-src/commands/tests/execute.md +22 -5
- package/dist/agent-src/commands/work.md +4 -0
- package/dist/agent-src/contexts/authority/decision-revisit-gate-enforcement.md +43 -0
- package/dist/agent-src/contexts/communication/rules-auto/design-fidelity-enforcement.md +24 -0
- package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +6 -6
- package/dist/agent-src/contexts/execution/autonomy-mechanics.md +4 -8
- package/dist/agent-src/contexts/execution/roadmap-process-loop.md +32 -2
- package/dist/agent-src/contexts/execution/session-canary-enforcement-history.md +67 -0
- package/dist/agent-src/contexts/execution/toolchain-resolver.md +101 -7
- package/dist/agent-src/rules/active-remediation.md +1 -1
- package/dist/agent-src/rules/autonomous-execution.md +1 -0
- package/dist/agent-src/rules/broken-access-control.md +1 -0
- package/dist/agent-src/rules/command-suggestion-policy.md +1 -0
- package/dist/agent-src/rules/context-hygiene.md +1 -1
- package/dist/agent-src/rules/decision-revisit-gate.md +16 -33
- package/dist/agent-src/rules/design-fidelity.md +13 -16
- package/dist/agent-src/rules/doc-screenshot-hygiene.md +1 -0
- package/dist/agent-src/rules/domain-safety-disclaimer.md +1 -0
- package/dist/agent-src/rules/domain-safety-pii.md +1 -0
- package/dist/agent-src/rules/domain-safety-retention.md +1 -0
- package/dist/agent-src/rules/engineering-safety-floor.md +1 -0
- package/dist/agent-src/rules/evaluator-independence.md +3 -2
- package/dist/agent-src/rules/fast-path-marker-visibility.md +1 -0
- package/dist/agent-src/rules/finance-safety-floor.md +1 -0
- package/dist/agent-src/rules/git-history-discipline.md +1 -0
- package/dist/agent-src/rules/image-likeness-and-rights.md +1 -0
- package/dist/agent-src/rules/legal-safety-floor.md +3 -2
- package/dist/agent-src/rules/lethal-trifecta-guard.md +1 -0
- package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +1 -0
- package/dist/agent-src/rules/media-governance-routing.md +14 -17
- package/dist/agent-src/rules/persona-governance.md +2 -2
- package/dist/agent-src/rules/provider-lifecycle-discipline.md +1 -1
- package/dist/agent-src/rules/question-not-instruction.md +1 -0
- package/dist/agent-src/rules/roadmap-progress-sync.md +1 -1
- package/dist/agent-src/rules/runtime-safety.md +1 -0
- package/dist/agent-src/rules/secret-vcs-guard.md +1 -0
- package/dist/agent-src/rules/security-sensitive-stop.md +3 -2
- package/dist/agent-src/rules/session-canary.md +8 -62
- package/dist/agent-src/rules/settings-ask-protocol.md +1 -0
- package/dist/agent-src/rules/source-confidentiality.md +1 -0
- package/dist/agent-src/rules/strategy-safety-floor.md +1 -0
- package/dist/agent-src/rules/tool-safety.md +1 -0
- package/dist/agent-src/rules/ui-audit-gate.md +1 -2
- package/dist/agent-src/rules/untrusted-input-defense.md +1 -0
- package/dist/agent-src/rules/user-interrupt-priority.md +1 -0
- package/dist/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
- package/dist/agent-src/scripts/deferral_carry.ts +339 -0
- package/dist/agent-src/scripts/update_roadmap_progress.ts +4 -1
- package/dist/agent-src/skills/accessibility-auditor/data/aria-patterns.csv +1 -1
- package/dist/agent-src/skills/accessibility-auditor/data/manifest.json +2 -2
- package/dist/agent-src/skills/api-design/data/manifest.json +2 -2
- package/dist/agent-src/skills/api-testing/SKILL.md +17 -0
- package/dist/agent-src/skills/code-intelligence/SKILL.md +14 -2
- package/dist/agent-src/skills/design-review/SKILL.md +30 -4
- package/dist/agent-src/skills/design-review/references/verification-automation.md +32 -0
- package/dist/agent-src/skills/design-system-capture/references/import-procedure.md +1 -1
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +18 -3
- package/dist/agent-src/skills/existing-ui-audit/references/component-taxonomy-detection.md +56 -0
- package/dist/agent-src/skills/fe-design/SKILL.md +1 -1
- package/dist/agent-src/skills/iconography/SKILL.md +1 -1
- package/dist/agent-src/skills/js-library-packaging/SKILL.md +2 -2
- package/dist/agent-src/skills/markitdown/SKILL.md +4 -0
- package/dist/agent-src/skills/monorepo-workspace/SKILL.md +1 -1
- package/dist/agent-src/skills/playwright-testing/SKILL.md +30 -6
- package/dist/agent-src/skills/quality-tools/SKILL.md +11 -1
- package/dist/agent-src/skills/quality-tools/references/go-tools.md +76 -0
- package/dist/agent-src/skills/quality-tools/references/python-tools.md +104 -0
- package/dist/agent-src/skills/review-routing/SKILL.md +2 -2
- package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +1 -1
- package/dist/agent-src/skills/storybook-workshop/SKILL.md +3 -3
- package/dist/agent-src/skills/tailwind-engineer/SKILL.md +1 -1
- package/dist/agent-src/skills/test-case-discovery/SKILL.md +7 -0
- package/dist/agent-src/skills/test-driven-development/SKILL.md +17 -0
- package/dist/agent-src/skills/test-performance/SKILL.md +19 -1
- package/dist/agent-src/skills/ui-component-architect/SKILL.md +25 -2
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/roadmaps.md +30 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/app_spec.ts +10 -4
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +302 -21
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/audit.ts +22 -3
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/scaffold.ts +6 -1
- package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
- package/dist/agent-src/templates/scripts/work_engine/state.ts +57 -7
- package/dist/agent-src/templates/scripts/work_engine/taxonomy/detect.ts +500 -0
- package/dist/agent-src/templates/scripts/work_engine/taxonomy/place.ts +183 -0
- package/dist/cli/python/knowledge_ingest.js +1 -1
- package/dist/cli/python/workspace_drive.js +1 -1
- package/dist/cli/registry.js +1 -1
- package/dist/cli-delegate/archive_completed_roadmaps.js +92 -12
- package/dist/cli-delegate/check_update_banner.js +12 -1
- package/dist/cli-delegate/chunk-523HCFYO.js +90 -0
- package/dist/cli-delegate/{chunk-M2DPGFZ4.js → chunk-6V6TA25H.js} +22 -152
- package/dist/cli-delegate/chunk-7IQE3D5S.js +191 -0
- package/dist/cli-delegate/{chunk-6KFEC3G7.js → chunk-CQWX336L.js} +1 -1
- package/dist/cli-delegate/chunk-DEIV7XP7.js +108 -0
- package/dist/cli-delegate/chunk-EEHDXSYD.js +2040 -0
- package/dist/cli-delegate/{chunk-P6ZHP5W2.js → chunk-GKE7ZVFA.js} +4 -4
- package/dist/cli-delegate/chunk-JQOM7TTM.js +1201 -0
- package/dist/cli-delegate/{chunk-UNCRJBT3.js → chunk-JQVYKIZA.js} +41 -0
- package/dist/cli-delegate/{chunk-FC75PGJE.js → chunk-JY2I2DXV.js} +12 -1
- package/dist/cli-delegate/chunk-KB5FZ655.js +208 -0
- package/dist/cli-delegate/{chunk-YUM5KURG.js → chunk-KR6EM23A.js} +235 -1455
- package/dist/cli-delegate/{chunk-LTYVIY76.js → chunk-LIYTLH6O.js} +1 -1
- package/dist/cli-delegate/chunk-NQ7WT43P.js +2729 -0
- package/dist/cli-delegate/chunk-NXEILF2K.js +2160 -0
- package/dist/cli-delegate/{chunk-5R7HOLAF.js → chunk-NYX3L2PZ.js} +1 -1
- package/dist/cli-delegate/{chunk-4E2W63DA.js → chunk-OKJUIAPS.js} +62 -1
- package/dist/cli-delegate/{chunk-QAJS5YWY.js → chunk-PHD7OOLE.js} +2 -1
- package/dist/cli-delegate/{chunk-RGNIWTEA.js → chunk-QLDHIPWR.js} +1 -1
- package/dist/cli-delegate/{chunk-HDVVGPQW.js → chunk-RQNNW7IF.js} +1405 -567
- package/dist/cli-delegate/{chunk-S3VFXMTM.js → chunk-S4UMZNES.js} +1 -1
- package/dist/cli-delegate/{chunk-6KM6ORRY.js → chunk-S4YWNRKO.js} +24 -8
- package/dist/cli-delegate/{chunk-GJCBB2UG.js → chunk-TRI6DQZ6.js} +3054 -325
- package/dist/cli-delegate/chunk-ULQRUR23.js +208 -0
- package/dist/cli-delegate/{chunk-NUHLI2RX.js → chunk-YCU3TIXH.js} +2 -0
- package/dist/cli-delegate/chunk-ZBZV2G5R.js +210 -0
- package/dist/cli-delegate/{chunk-WGXTVKCQ.js → chunk-ZUZKZYCN.js} +5 -3
- package/dist/cli-delegate/cmd_analyze_session.js +1 -1
- package/dist/cli-delegate/cmd_brand_status.js +1 -1
- package/dist/cli-delegate/cmd_conformance.js +1862 -809
- package/dist/cli-delegate/cmd_doctor.js +13 -6
- package/dist/cli-delegate/cmd_doctor_neighbours.js +23 -0
- package/dist/cli-delegate/cmd_explain.js +5 -5
- package/dist/cli-delegate/cmd_export.js +11 -8
- package/dist/cli-delegate/cmd_fleet.js +3 -3
- package/dist/cli-delegate/cmd_handoff.js +10 -7
- package/dist/cli-delegate/cmd_mcp_available.js +1 -1
- package/dist/cli-delegate/cmd_memory_get.js +3 -1
- package/dist/cli-delegate/cmd_migrate.js +2 -2
- package/dist/cli-delegate/cmd_packs_active.js +3 -3
- package/dist/cli-delegate/cmd_preflight.js +6 -6
- package/dist/cli-delegate/cmd_prune.js +11 -8
- package/dist/cli-delegate/cmd_refresh.js +2 -1
- package/dist/cli-delegate/cmd_route_audit.js +8 -6
- package/dist/cli-delegate/cmd_route_explain.js +4 -4
- package/dist/cli-delegate/cmd_session_recycle.js +4 -3
- package/dist/cli-delegate/cmd_settings_get.js +1 -1
- package/dist/cli-delegate/cmd_settings_migrate.js +11 -8
- package/dist/cli-delegate/cmd_settings_set.js +4 -4
- package/dist/cli-delegate/cmd_sync.js +11 -8
- package/dist/cli-delegate/cmd_uninstall.js +11 -8
- package/dist/cli-delegate/cmd_update.js +1 -1
- package/dist/cli-delegate/cmd_upgrade.js +3 -2
- package/dist/cli-delegate/cmd_validate.js +11 -8
- package/dist/cli-delegate/cmd_versions.js +1 -1
- package/dist/cli-delegate/deferral_carry.js +16 -0
- package/dist/cli-delegate/gate_execute.js +2 -2
- package/dist/cli-delegate/roadmap_gates.js +5 -5
- package/dist/cli-delegate/update_roadmap_progress.js +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +132 -80
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +3 -3
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +7 -5
- package/dist/discovery/trust-report.md +2 -2
- package/dist/discovery/workspaces.json +6 -4
- package/dist/hooks/dispatch.js +7972 -5186
- package/dist/hooks/dispatch.sha256 +1 -0
- package/dist/install/claudePathsPlan.js +47 -6
- package/dist/install/claudeRuleRewrite.js +7 -0
- package/dist/install/emit_host_rules_cli.js +39 -36
- package/dist/install/globalRuleScope.js +87 -0
- package/dist/install/host_rule_ownership.js +160 -0
- package/dist/install/install.mjs +2226 -1055
- package/dist/install/installThinLayer.js +261 -0
- package/dist/install/installedRuleLinks.js +176 -0
- package/dist/install/wizard-plan.js +24 -0
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +40913 -34865
- package/dist/scripts/_lib/agent_settings.js +11 -0
- package/dist/scripts/_lib/claude_settings_hooks.js +10 -8
- package/dist/scripts/_lib/installed_layer.js +378 -0
- package/dist/scripts/_lib/lean_projection_mode.js +218 -15
- package/dist/scripts/_lib/rule_consequence_class.js +45 -0
- package/dist/scripts/_lib/rule_injection.js +67 -10
- package/dist/scripts/_lib/rule_law_section.js +122 -0
- package/dist/scripts/_lib/thin_rules.js +458 -0
- package/dist/scripts/_lib/windsurf_render.js +60 -0
- package/dist/scripts/condense.js +14 -26
- package/dist/scripts/project_thin_rules.js +14 -294
- package/dist/server/schemas/settings.js +29 -0
- package/dist/shared/skillRanking.js +74 -13
- package/dist/ui/assets/index-Cwq4d0hX.js +23 -0
- package/dist/ui/assets/index-Cyjy8bWO.css +1 -0
- package/dist/ui/index.html +2 -2
- package/docs/contracts/settings-classes.md +10 -6
- package/package.json +4 -4
- package/src/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
- package/src/agent-src/scripts/deferral_carry.ts +339 -0
- package/src/agent-src/scripts/update_roadmap_progress.ts +4 -1
- package/src/agent-src/templates/scripts/work_engine/directives/ui/app_spec.ts +10 -4
- package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +302 -21
- package/src/agent-src/templates/scripts/work_engine/directives/ui/audit.ts +22 -3
- package/src/agent-src/templates/scripts/work_engine/directives/ui/scaffold.ts +6 -1
- package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
- package/src/agent-src/templates/scripts/work_engine/state.ts +57 -7
- package/src/agent-src/templates/scripts/work_engine/taxonomy/detect.ts +500 -0
- package/src/agent-src/templates/scripts/work_engine/taxonomy/place.ts +183 -0
- package/src/config/agent-settings.template.yml +91 -22
- package/src/config/ci-local-parity.yml +18 -0
- package/src/config/continuity-surface.json +9 -2
- package/src/config/evaluator-budgets.json +4 -4
- package/src/config/gate-coverage.yml +327 -3
- package/src/config/gate-violation-baselines.json +21 -9
- package/src/config/hook-bundle-budget.json +25 -0
- package/src/config/hook-latency-budget.json +21 -0
- package/src/config/hook-token-budget.json +8 -3
- package/src/config/host-instruction-limits.json +33 -0
- package/src/config/metric-registry.yml +114 -0
- package/src/config/placeholder-drift-budget.json +10 -0
- package/src/config/routing-coverage-seed.json +38 -3
- package/src/config/rule-activation-census.json +7 -3
- package/src/config/rule-consequence-class.json +161 -0
- package/src/config/rule-law-ceilings.json +99 -0
- package/src/install/claudePathsPlan.ts +46 -4
- package/src/install/claudeRuleRewrite.ts +10 -1
- package/src/install/emit_host_rules_cli.ts +43 -34
- package/src/install/globalRuleScope.ts +109 -0
- package/src/install/host_rule_ownership.ts +170 -0
- package/src/install/installThinLayer.ts +312 -0
- package/src/install/installedRuleLinks.ts +220 -0
- package/src/install/wizard-plan.ts +24 -0
- package/src/scripts/_cli/cmd_doctor.ts +28 -90
- package/src/scripts/_cli/cmd_doctor_neighbours.ts +293 -0
- package/src/scripts/_cli/doctor_execution.ts +100 -17
- package/src/scripts/_cli/doctor_network_posture.ts +226 -0
- package/src/scripts/_dispatch.bash +16 -2
- package/src/scripts/_lib/agent_settings.ts +11 -0
- package/src/scripts/_lib/body_portable.ts +102 -0
- package/src/scripts/_lib/cc_transcript.ts +132 -1
- package/src/scripts/_lib/claude_settings_hooks.ts +10 -8
- package/src/scripts/_lib/concern_sla_window.ts +200 -0
- package/src/scripts/_lib/estate_offsets.ts +241 -0
- package/src/scripts/_lib/exemption_shape.ts +143 -0
- package/src/scripts/_lib/fnv.ts +23 -0
- package/src/scripts/_lib/foreign_scan.ts +106 -0
- package/src/scripts/_lib/forge_protection.ts +114 -0
- package/src/scripts/_lib/forge_reader.ts +558 -0
- package/src/scripts/_lib/gitignore_block.ts +314 -0
- package/src/scripts/_lib/global_deploy_inventory.ts +32 -0
- package/src/scripts/_lib/graph_feeder_record.ts +214 -0
- package/src/scripts/_lib/hook_settings.ts +73 -0
- package/src/scripts/_lib/host_capability.ts +40 -19
- package/src/scripts/_lib/host_env_write.ts +111 -0
- package/src/scripts/_lib/host_hook_merge.ts +165 -0
- package/src/scripts/_lib/installed_layer.ts +538 -0
- package/src/scripts/_lib/json_merge.ts +82 -0
- package/src/scripts/_lib/json_pointers.ts +93 -11
- package/src/scripts/_lib/lean_projection_mode.ts +275 -15
- package/src/scripts/_lib/llm_proposer_transport.ts +14 -4
- package/src/scripts/_lib/machine_wake.ts +16 -3
- package/src/scripts/_lib/neighbour_census.ts +760 -0
- package/src/scripts/_lib/neighbour_scan.ts +122 -0
- package/src/scripts/_lib/neighbour_tool_use.ts +189 -0
- package/src/scripts/_lib/obligations.ts +119 -8
- package/src/scripts/_lib/probe_inputs.ts +271 -0
- package/src/scripts/_lib/prompt_shape.ts +46 -0
- package/src/scripts/_lib/read_surface_scan.ts +322 -0
- package/src/scripts/_lib/release_highlights.ts +2 -1
- package/src/scripts/_lib/release_migration_gate.ts +19 -3
- package/src/scripts/_lib/reserved_name_sweep.ts +73 -0
- package/src/scripts/_lib/retrieval_sanitize.ts +77 -16
- package/src/scripts/_lib/review_coverage.ts +134 -0
- package/src/scripts/_lib/rule_consequence_class.ts +71 -0
- package/src/scripts/_lib/rule_injection.ts +130 -10
- package/src/scripts/_lib/rule_law_section.ts +147 -0
- package/src/scripts/_lib/rule_layer_overlap.ts +58 -0
- package/src/scripts/_lib/shell_write_shapes.ts +108 -0
- package/src/scripts/_lib/skill_origin.ts +254 -0
- package/src/scripts/_lib/structural_hiding.ts +622 -0
- package/src/scripts/_lib/structured_ask.ts +64 -21
- package/src/scripts/_lib/thin_rules.ts +540 -0
- package/src/scripts/_lib/touched_file_quality.ts +434 -0
- package/src/scripts/_lib/turn_end_refusals.ts +600 -4
- package/src/scripts/_lib/turn_end_transcript.ts +216 -0
- package/src/scripts/_lib/verification_command.ts +324 -0
- package/src/scripts/_lib/verification_evidence.ts +647 -0
- package/src/scripts/_lib/verify_clause.ts +280 -0
- package/src/scripts/_lib/windsurf_render.ts +63 -0
- package/src/scripts/ai_council/cli_call_budget.ts +13 -5
- package/src/scripts/ai_council/clients.ts +26 -57
- package/src/scripts/ai_council/config.ts +1 -1
- package/src/scripts/ai_council/vendor_defaults.ts +45 -0
- package/src/scripts/ai_team/team_dispatch.ts +4 -0
- package/src/scripts/audit_skill_overlap.ts +261 -0
- package/src/scripts/before_complete_hook.ts +573 -25
- package/src/scripts/bench_hook_latency.ts +412 -5
- package/src/scripts/bench_touched_file_quality.ts +238 -0
- package/src/scripts/cache_realization_report.ts +61 -1
- package/src/scripts/check_argument_hint.ts +287 -0
- package/src/scripts/check_claims.ts +125 -1
- package/src/scripts/check_enforcement_coverage.ts +38 -9
- package/src/scripts/check_enforcement_matrix.ts +621 -22
- package/src/scripts/check_estate_count.ts +130 -153
- package/src/scripts/check_finding_dispositions.ts +138 -7
- package/src/scripts/check_generator_sync.ts +71 -0
- package/src/scripts/check_hook_bundle_composition.ts +370 -0
- package/src/scripts/check_host_docs_digest.ts +786 -0
- package/src/scripts/check_host_format_column.ts +559 -0
- package/src/scripts/check_input_references.ts +228 -0
- package/src/scripts/check_inputs_parity.ts +235 -0
- package/src/scripts/check_kernel_edit_ratified.ts +89 -9
- package/src/scripts/check_kill_switch_table.ts +294 -0
- package/src/scripts/check_memory.ts +7 -1
- package/src/scripts/check_placeholder_drift.ts +221 -0
- package/src/scripts/check_read_surface_coverage.ts +515 -0
- package/src/scripts/check_release_highlights.ts +10 -0
- package/src/scripts/check_release_holds.ts +2 -1
- package/src/scripts/check_release_pr_shape.ts +38 -15
- package/src/scripts/check_routing_coverage.ts +378 -11
- package/src/scripts/check_standing_rule_delivery.ts +33 -13
- package/src/scripts/check_static_parity.ts +17 -0
- package/src/scripts/check_verify_expectation_delta.ts +521 -0
- package/src/scripts/ci_settle.ts +145 -19
- package/src/scripts/closure_scan.ts +115 -1
- package/src/scripts/code_graph/detect.ts +127 -7
- package/src/scripts/code_graph/foreign.ts +194 -0
- package/src/scripts/code_graph/query.ts +217 -4
- package/src/scripts/code_graph/types.ts +26 -2
- package/src/scripts/code_graph/validate.ts +3 -1
- package/src/scripts/code_graph/verbs.ts +103 -0
- package/src/scripts/compile_hook_manifest.ts +90 -14
- package/src/scripts/condense.ts +14 -27
- package/src/scripts/estate_exemption_shape.ts +202 -0
- package/src/scripts/external_sources_denylist.json +29 -4
- package/src/scripts/generate_host_cost_table.ts +1 -1
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +192 -14
- package/src/scripts/hooks/block_config_weakening.ts +294 -4
- package/src/scripts/hooks/block_kernel_rule_writes.ts +9 -78
- package/src/scripts/hooks/block_plumbing_writes.ts +342 -0
- package/src/scripts/hooks/bundle_integrity.ts +291 -0
- package/src/scripts/hooks/chain_nudge_hook.ts +1 -2
- package/src/scripts/hooks/code_graph_context_hook.ts +253 -25
- package/src/scripts/hooks/comment_discipline_hook.ts +1 -3
- package/src/scripts/hooks/concern_failure_policy.ts +280 -0
- package/src/scripts/hooks/concern_registry.ts +2 -0
- package/src/scripts/hooks/concern_timings.ts +94 -0
- package/src/scripts/hooks/delegation_nudge_hook.ts +1 -2
- package/src/scripts/hooks/design_pass_hook.ts +100 -9
- package/src/scripts/hooks/design_slop_hook.ts +1 -2
- package/src/scripts/hooks/dispatch_hook.ts +77 -71
- package/src/scripts/hooks/edit_shape_hook.ts +1 -2
- package/src/scripts/hooks/end_review_nudge_hook.ts +1 -1
- package/src/scripts/hooks/evidence_independence.ts +1 -2
- package/src/scripts/hooks/exit_codes.ts +129 -0
- package/src/scripts/hooks/host_lowering.json +1 -0
- package/src/scripts/hooks/host_lowering.ts +146 -3
- package/src/scripts/hooks/host_lowering.yaml +262 -46
- package/src/scripts/hooks/host_semantics.ts +30 -2
- package/src/scripts/hooks/injection_budget.ts +9 -2
- package/src/scripts/hooks/interruption_ledger_hook.ts +1 -2
- package/src/scripts/hooks/journal_record_hook.ts +1 -2
- package/src/scripts/hooks/memory_recall_hook.ts +1 -2
- package/src/scripts/hooks/obligation_settle_hook.ts +151 -5
- package/src/scripts/hooks/one_question_per_ask_hook.ts +43 -6
- package/src/scripts/hooks/orchestration_record_hook.ts +1 -2
- package/src/scripts/hooks/payload_stub.ts +10 -1
- package/src/scripts/hooks/permission_gate.ts +1 -2
- package/src/scripts/hooks/push_settle_hook.ts +1 -3
- package/src/scripts/hooks/replay_hook.ts +2 -1
- package/src/scripts/hooks/reread_guard_hook.ts +1 -2
- package/src/scripts/hooks/review_baseline_hook.ts +1 -2
- package/src/scripts/hooks/rtk_wrap_hook.ts +1 -2
- package/src/scripts/hooks/rule_inject_hook.ts +765 -68
- package/src/scripts/hooks/run_continuation_hook.ts +13 -15
- package/src/scripts/hooks/skill_route_hook.ts +1 -2
- package/src/scripts/hooks/source_first_gate_hook.ts +1 -2
- package/src/scripts/hooks/spawn_guard_shadow_hook.ts +1 -2
- package/src/scripts/hooks/subagent_ledger_hook.ts +1 -2
- package/src/scripts/hooks/suggestion_capture_hook.ts +1 -1
- package/src/scripts/hooks/table_fingerprint.ts +70 -0
- package/src/scripts/hooks/telemetry_flush_hook.ts +1 -2
- package/src/scripts/hooks/telemetry_usage_hook.ts +65 -10
- package/src/scripts/hooks/tool_result_bytes_hook.ts +93 -9
- package/src/scripts/hooks/turn_end_gate_hook.ts +421 -324
- package/src/scripts/hooks/ui_route_nudge_hook.ts +1 -2
- package/src/scripts/hooks_status.ts +112 -0
- package/src/scripts/injection_scan_hook.ts +7 -0
- package/src/scripts/install.ts +75 -189
- package/src/scripts/installed_layer_report.ts +103 -0
- package/src/scripts/language_mirror_hook.ts +15 -6
- package/src/scripts/learning_sidecar.ts +119 -8
- package/src/scripts/lint_deny_text.ts +419 -0
- package/src/scripts/lint_exit_codes.ts +262 -0
- package/src/scripts/lint_hook_manifest.ts +108 -0
- package/src/scripts/lint_major_migration_sections.ts +156 -26
- package/src/scripts/lint_pack_boundaries.ts +63 -5
- package/src/scripts/lint_roadmap_blockers.ts +78 -12
- package/src/scripts/lint_rule_law_section.ts +517 -0
- package/src/scripts/lint_skill_descriptions.ts +1 -1
- package/src/scripts/lint_skill_scripts_readonly.ts +1 -1
- package/src/scripts/lint_workflow_security.ts +161 -5
- package/src/scripts/mcp_server/consumer_tool_catalog.json +53 -0
- package/src/scripts/mcp_server/graph_tools.ts +72 -3
- package/src/scripts/mcp_server/prompts.ts +142 -1
- package/src/scripts/measure_routing_signal.ts +54 -16
- package/src/scripts/measure_skill_ranker_baseline.ts +515 -53
- package/src/scripts/measure_turn_end_gate.ts +193 -0
- package/src/scripts/memory_learn_hook.ts +91 -6
- package/src/scripts/memory_lookup.ts +1 -1
- package/src/scripts/model_rule_injection.ts +52 -5
- package/src/scripts/prepack-check.mjs +53 -0
- package/src/scripts/project_thin_rules.ts +34 -327
- package/src/scripts/release_publication.ts +13 -1
- package/src/scripts/report_evidence_temperature.ts +657 -0
- package/src/scripts/report_installed_rule_links.ts +157 -0
- package/src/scripts/report_invocation_surface.ts +383 -0
- package/src/scripts/report_label_agreement.ts +233 -0
- package/src/scripts/report_obligation_carriers.ts +699 -0
- package/src/scripts/report_obligation_mechanism.ts +230 -0
- package/src/scripts/report_obligation_writer_split.ts +236 -0
- package/src/scripts/report_single_token_triggers.ts +277 -0
- package/src/scripts/report_skill_menu_census.ts +208 -0
- package/src/scripts/report_skill_ranker_confusion.ts +442 -0
- package/src/scripts/report_standing_payload_by_host.ts +188 -15
- package/src/scripts/report_verification_record_coverage.ts +306 -0
- package/src/scripts/roadmap_verify_share.ts +213 -0
- package/src/scripts/rule_activation_census.ts +5 -2
- package/src/scripts/rule_trigger_eval.ts +9 -9
- package/src/scripts/schemas/command.schema.json +44 -0
- package/src/scripts/schemas/review-findings.schema.json +7 -2
- package/src/scripts/schemas/rule.schema.json +5 -0
- package/src/scripts/schemas/skill.schema.json +44 -0
- package/src/scripts/self_review_gate.ts +421 -17
- package/src/scripts/semantic_parity_census.ts +314 -0
- package/src/scripts/session_eol_report.ts +54 -1
- package/src/scripts/skill_tools/score_skill_relevance.ts +290 -25
- package/src/scripts/sweep_dead_scan_roots.ts +1 -1
- package/src/scripts/sweep_skill_ranker_signals.ts +129 -0
- package/src/scripts/sync_gitignore.ts +29 -235
- package/src/scripts/trigger_eval_grandfather.json +0 -7
- package/src/scripts/trigger_eval_rotation.ts +122 -27
- package/src/scripts/ui_conformance_probe.ts +156 -4
- package/src/scripts/update_prices.ts +85 -3
- package/src/scripts/write_bundle_digest.mjs +74 -0
- package/src/server/schemas/settings.ts +41 -0
- package/src/shared/skillRanking.ts +117 -11
- package/src/templates/consumer-settings/ONBOARDING.md +1 -0
- package/dist/cli-delegate/chunk-FXYUYU4N.js +0 -4416
- package/dist/cli-delegate/chunk-QJWAUMJW.js +0 -1072
- package/dist/cli-delegate/chunk-YDPILCOL.js +0 -152
- package/dist/ui/assets/index-DH1xc62v.js +0 -29
- package/dist/ui/assets/index-jSfMW8_t.css +0 -1
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The hook exit-code table — one frozen definition, imported everywhere.
|
|
3
|
+
*
|
|
4
|
+
* road-to-a-kernel-that-guards-its-plumbing 4.1.
|
|
5
|
+
*
|
|
6
|
+
* WHAT WAS WRONG. Thirty-three files under `src/scripts/hooks/` each declared
|
|
7
|
+
* their own `const EXIT_ALLOW = 0` / `EXIT_BLOCK = 1` / `EXIT_WARN = 2`, two of
|
|
8
|
+
* them under a third name (`EXIT_OK`). Thirty-three copies of a contract is
|
|
9
|
+
* thirty-three places it can be changed in one and not the others, and the
|
|
10
|
+
* change that matters here is not a typo: exit 1 and exit 2 mean the OPPOSITE
|
|
11
|
+
* things on Claude Code from what they mean in this tree's internal language
|
|
12
|
+
* (`host_semantics.ts` exists entirely to lower one onto the other). A number
|
|
13
|
+
* that means "advisory" here and "hard deny" there is not a constant anyone
|
|
14
|
+
* should be re-deriving per file.
|
|
15
|
+
*
|
|
16
|
+
* WHAT THE TABLE ADDS BEYOND THE NUMBERS. `owner` and `authorizedBy` — who
|
|
17
|
+
* decides that a concern emits this code, and what authorises the dispatcher to
|
|
18
|
+
* act on it. A bare `1` in a concern says nothing about whether that concern was
|
|
19
|
+
* ever allowed to refuse; the manifest's `severity` is what authorises it, and
|
|
20
|
+
* the dispatcher enforces that ceiling (`_is_advisory`). Recording it beside the
|
|
21
|
+
* number is what makes the table a contract rather than an enum.
|
|
22
|
+
*
|
|
23
|
+
* WHAT IS NOT IN SCOPE. The `*-dispatcher.sh` trampolines carry inline
|
|
24
|
+
* `process.exit(0)` in a `node -e` one-liner that reads a workspace root off
|
|
25
|
+
* stdin. They are shell, they cannot import, and their exit code is the
|
|
26
|
+
* one-liner's, never a verdict. `lint_exit_codes` scans `.ts` only.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/** Allow — the concern has no objection. The overwhelmingly common verdict. */
|
|
30
|
+
export const EXIT_ALLOW = 0;
|
|
31
|
+
|
|
32
|
+
/** Block — the concern refuses. Only a `severity: blocking` concern may. */
|
|
33
|
+
export const EXIT_BLOCK = 1;
|
|
34
|
+
|
|
35
|
+
/** Warn — advisory. The dispatcher exits 0 and surfaces the reason. */
|
|
36
|
+
export const EXIT_WARN = 2;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Error — the concern crashed or could not decide.
|
|
40
|
+
*
|
|
41
|
+
* `3` is the floor, not the only value: the dispatcher treats every rc ≥ 3 the
|
|
42
|
+
* same way, and what that way IS depends on the concern's declared severity.
|
|
43
|
+
*/
|
|
44
|
+
export const EXIT_ERROR = 3;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Usage error on the process's OWN argv — not a verdict, and not a row.
|
|
48
|
+
*
|
|
49
|
+
* `dispatch_hook` and `replay_hook` are also CLIs: run with `--platform`
|
|
50
|
+
* missing they exit before any concern is consulted. The number is 2 by the
|
|
51
|
+
* POSIX convention for a usage error, which COLLIDES with `EXIT_WARN` by
|
|
52
|
+
* coincidence and not by meaning — nothing advisory has happened, and no
|
|
53
|
+
* concern has spoken.
|
|
54
|
+
*
|
|
55
|
+
* Named rather than left as a bare `2`, and kept OUT of `EXIT_CODES`, because
|
|
56
|
+
* both readings are wrong: importing `EXIT_WARN` here would assert a verdict
|
|
57
|
+
* that was never reached, and adding a fifth row would put a non-verdict in a
|
|
58
|
+
* table whose whole subject is what a concern may say. `lint_exit_codes`
|
|
59
|
+
* refuses the bare literal, so the next writer has to pick one of the two
|
|
60
|
+
* deliberately.
|
|
61
|
+
*/
|
|
62
|
+
export const EXIT_USAGE = 2;
|
|
63
|
+
|
|
64
|
+
export interface ExitCodeRow {
|
|
65
|
+
/** The numeric code, or its floor for the open-ended error band. */
|
|
66
|
+
readonly code: number;
|
|
67
|
+
readonly name: 'allow' | 'block' | 'warn' | 'error';
|
|
68
|
+
readonly meaning: string;
|
|
69
|
+
/** Who decides a concern emits this code. */
|
|
70
|
+
readonly owner: string;
|
|
71
|
+
/** What authorises the dispatcher to act on it. */
|
|
72
|
+
readonly authorizedBy: string;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* The frozen table. Ordered by code; the last row is a band, not a value.
|
|
77
|
+
*
|
|
78
|
+
* `as const` plus `Object.freeze` rather than a plain array: this is the kind of
|
|
79
|
+
* structure a later convenience ("just push a row for the new verdict") turns
|
|
80
|
+
* into a fourth dialect, and the whole point of the file is that there is one.
|
|
81
|
+
*/
|
|
82
|
+
export const EXIT_CODES: readonly ExitCodeRow[] = Object.freeze([
|
|
83
|
+
Object.freeze({
|
|
84
|
+
code: EXIT_ALLOW,
|
|
85
|
+
name: 'allow',
|
|
86
|
+
meaning: 'no objection; the dispatcher passes the call through',
|
|
87
|
+
owner: 'every concern — the default verdict',
|
|
88
|
+
authorizedBy: 'nothing; allowing needs no authority',
|
|
89
|
+
}),
|
|
90
|
+
Object.freeze({
|
|
91
|
+
code: EXIT_BLOCK,
|
|
92
|
+
name: 'block',
|
|
93
|
+
meaning: 'refuse the call; the dispatcher lowers this onto the host deny channel',
|
|
94
|
+
owner: 'a concern declared `severity: blocking` in hook_manifest.yaml',
|
|
95
|
+
authorizedBy:
|
|
96
|
+
'the manifest entry plus its row in the BLOCKING_ALLOWLIST of ' +
|
|
97
|
+
'tests/hooks/concern_severity.test.ts — an advisory concern emitting this is ' +
|
|
98
|
+
'downgraded to warn by dispatch_hook._is_advisory',
|
|
99
|
+
}),
|
|
100
|
+
Object.freeze({
|
|
101
|
+
code: EXIT_WARN,
|
|
102
|
+
name: 'warn',
|
|
103
|
+
meaning: 'advisory; the dispatcher exits 0 and surfaces the reason',
|
|
104
|
+
owner: 'any concern',
|
|
105
|
+
authorizedBy:
|
|
106
|
+
'nothing; warning is the ceiling for an advisory concern and is always available ' +
|
|
107
|
+
'to a blocking one',
|
|
108
|
+
}),
|
|
109
|
+
Object.freeze({
|
|
110
|
+
code: EXIT_ERROR,
|
|
111
|
+
name: 'error',
|
|
112
|
+
meaning:
|
|
113
|
+
'the concern crashed, timed out, or could not decide — any rc >= 3. The dispatcher ' +
|
|
114
|
+
'resolves it by the concern`s declared severity, never by the number itself',
|
|
115
|
+
owner: 'no concern emits this on purpose; the runtime does',
|
|
116
|
+
authorizedBy:
|
|
117
|
+
'hook_manifest.yaml `severity` alone — blocking refuses, anything else fails ' +
|
|
118
|
+
'open; `fail_closed` is no longer read on this branch. See ' +
|
|
119
|
+
'docs/contracts/hook-architecture-v1.md § Exit-code semantics',
|
|
120
|
+
}),
|
|
121
|
+
] as const);
|
|
122
|
+
|
|
123
|
+
/** The row a raw exit code resolves to, or `null` for a negative code. */
|
|
124
|
+
export function rowFor(code: number): ExitCodeRow | null {
|
|
125
|
+
if (code >= EXIT_ERROR) {
|
|
126
|
+
return EXIT_CODES[3] ?? null;
|
|
127
|
+
}
|
|
128
|
+
return EXIT_CODES.find((r) => r.code === code) ?? null;
|
|
129
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"fingerprint":"08575a71d81fd8a5ef9e4b400f4a38cb66c26e1dd701d98f3cdc0bdc9e4758b4:22235","body_fingerprint":"26a02a8e0fb2b6be6eb1def6ae8792c021425598bd672c850e6582726d96a6a5:6376","table":{"schema_version":1,"hosts":{"claude":{"surfaces":{"any":{"entry_shape":"claude-settings-hooks","json_shape":"hook-specific-output","fail_policy":"propagate","timeout_unit":"seconds","timeout_default":null,"verified":{"docs_at":"2026-09-29","docs_url":"https://code.claude.com/docs/en/hooks.md","docs_digest":"9dd68316c1111c118e3ddb82861ac6271a8cd164cee0d371b26165efff35fe88","probe_at":"2026-09-06","host_version":"2.1.263","expires":"2027-09-06"},"slots":{"session_start":{"native":"SessionStart","block_exit":null,"answered_at":"2026-09-29"},"session_end":{"native":"SessionEnd","block_exit":null,"answered_at":"2026-09-29"},"stop":{"native":"Stop","block_exit":2,"answered_at":"2026-09-29"},"user_prompt_submit":{"native":"UserPromptSubmit","block_exit":2,"answered_at":"2026-09-29"},"pre_tool_use":{"native":"PreToolUse","block_exit":2,"answered_at":"2026-09-29"},"post_tool_use":{"native":"PostToolUse","block_exit":null,"answered_at":"2026-09-29"},"pre_compact":{"native":"PreCompact","block_exit":null,"answered_at":"2026-09-29"},"subagent_start":{"native":"SubagentStart","block_exit":null,"answered_at":"2026-09-29"},"subagent_stop":{"native":"SubagentStop","block_exit":null,"answered_at":"2026-09-29"}}}}},"augment":{"surfaces":{"any":{"entry_shape":"augment-settings-hooks","json_shape":"none","fail_policy":"discard","timeout_unit":"unknown","timeout_default":null,"verified":{"docs_at":"2026-09-29","docs_url":"https://docs.augmentcode.com/cli/hooks.md","docs_digest":"e500823be8303717020c1823f670e06d100108f6e3ac4b8d12a46d91fd1898fa","probe_at":null,"host_version":null,"expires":"2027-09-29"},"slots":{"session_start":{"native":"SessionStart","block_exit":null,"answered_at":"2026-09-29"},"session_end":{"native":"SessionEnd","block_exit":null,"answered_at":"2026-09-29"},"stop":{"native":"Stop","block_exit":null,"answered_at":"2026-09-29"},"pre_tool_use":{"native":"PreToolUse","block_exit":null,"answered_at":"2026-09-29"},"post_tool_use":{"native":"PostToolUse","block_exit":null,"answered_at":"2026-09-29"}}}}},"cursor":{"surfaces":{"any":{"entry_shape":"cursor-hooks-json","json_shape":"none","fail_policy":"propagate","timeout_unit":"unknown","timeout_default":null,"verified":{"docs_at":"2026-09-29","docs_url":"https://cursor.com/docs/hooks.md","docs_digest":"7294a2d63b19d79a5283c948afe174cba8b06a7585563d34a2c41b90f5df0d39","probe_at":null,"host_version":null,"expires":"2027-09-29"},"slots":{"session_start":{"native":"sessionStart","block_exit":null,"answered_at":"2026-09-29"},"session_end":{"native":"sessionEnd","block_exit":null,"answered_at":"2026-09-29"},"stop":{"native":"stop","block_exit":null,"answered_at":"2026-09-29"},"user_prompt_submit":{"native":"beforeSubmitPrompt","block_exit":null,"answered_at":"2026-09-29"},"post_tool_use":{"native":"postToolUse","block_exit":null,"answered_at":"2026-09-29"}}}}},"cline":{"surfaces":{"any":{"entry_shape":"cline-per-event-script","json_shape":"none","fail_policy":"discard","timeout_unit":"unknown","timeout_default":null,"verified":{"docs_at":"2026-09-29","docs_url":"https://docs.cline.bot/customization/hooks.md","docs_digest":"ef87561721f4cb80fe6d682b6866d638a4952dd416d36cd5ab398426ce64084b","probe_at":null,"host_version":null,"expires":"2027-09-29"},"slots":{"session_start":{"native":["TaskStart","TaskResume"],"block_exit":null,"answered_at":"2026-09-29"},"session_end":{"native":"TaskComplete","block_exit":null,"answered_at":"2026-09-29"},"stop":{"native":"TaskCancel","block_exit":null,"answered_at":"2026-09-29"},"user_prompt_submit":{"native":"UserPromptSubmit","block_exit":null,"answered_at":"2026-09-29"},"post_tool_use":{"native":"PostToolUse","block_exit":null,"answered_at":"2026-09-29"}}}}},"windsurf":{"surfaces":{"any":{"entry_shape":"windsurf-hooks-json","json_shape":"none","fail_policy":"propagate","timeout_unit":"unknown","timeout_default":null,"verified":{"docs_at":"2026-09-29","docs_url":"https://docs.devin.ai/desktop/cascade/hooks.md","docs_digest":"460ffe7aa91998804920f6722c0153b9948eadd5edafa19582298475a19835a2","probe_at":null,"host_version":null,"expires":"2027-09-29"},"slots":{"session_start":{"native":"post_setup_worktree","block_exit":null,"answered_at":"2026-09-29"},"user_prompt_submit":{"native":"pre_user_prompt","block_exit":null,"answered_at":"2026-09-29"},"stop":{"native":"post_cascade_response","block_exit":null,"answered_at":"2026-09-29"}}}}},"gemini":{"surfaces":{"any":{"entry_shape":"gemini-settings-hooks","json_shape":"none","fail_policy":"propagate","timeout_unit":"unknown","timeout_default":null,"verified":{"docs_at":"2026-09-29","docs_url":"https://geminicli.com/docs/hooks/reference.md","docs_digest":"06d37f2f66812ee78bb46c37a112203376f0bae4d3b8b44ac79d0bda4b86a118","probe_at":null,"host_version":null,"expires":"2027-09-29"},"slots":{"session_start":{"native":"SessionStart","block_exit":null,"answered_at":"2026-09-29","matcher":""},"session_end":{"native":"SessionEnd","block_exit":null,"answered_at":"2026-09-29","matcher":""},"stop":{"native":"AfterAgent","block_exit":null,"answered_at":"2026-09-29","matcher":""},"user_prompt_submit":{"native":"BeforeAgent","block_exit":null,"answered_at":"2026-09-29","matcher":""},"post_tool_use":{"native":"AfterTool","block_exit":null,"answered_at":"2026-09-29","matcher":".*"}}}}},"cowork":{"surfaces":{"any":{"entry_shape":"none","json_shape":"none","fail_policy":"discard","timeout_unit":"unknown","timeout_default":null,"verified":{"docs_at":"2026-09-29","docs_url":null,"docs_digest":null,"probe_at":null,"host_version":null,"expires":"2027-09-29"},"slots":{}}}},"copilot":{"surfaces":{"any":{"entry_shape":"none","json_shape":"none","fail_policy":"discard","timeout_unit":"unknown","timeout_default":null,"verified":{"docs_at":"2026-09-29","docs_url":"https://docs.github.com/en/copilot/concepts/agents/hooks.md","docs_digest":"bfd40aa93ad62133efc17a50f189034f01594dc89a5d31a13a0c541d691acede","probe_at":null,"host_version":null,"expires":"2027-09-29"},"slots":{}}}},"codex":{"surfaces":{"any":{"entry_shape":"none","json_shape":"none","fail_policy":"discard","timeout_unit":"unknown","timeout_default":null,"verified":{"docs_at":"2026-09-29","docs_url":"https://developers.openai.com/codex/hooks.md","docs_digest":"724881d81f1a9fdb35ea42d4851a11b1f6606bbc6e9d2d05c1e8c466fc25c630","probe_at":"2026-10-01","host_version":"0.148.0","expires":"2027-09-29"},"slots":{}}}}}}}
|
|
@@ -21,6 +21,8 @@ import { fileURLToPath } from 'node:url';
|
|
|
21
21
|
|
|
22
22
|
import { parse as parseYaml } from 'yaml';
|
|
23
23
|
|
|
24
|
+
import { tableFingerprint } from './table_fingerprint.js';
|
|
25
|
+
|
|
24
26
|
declare const __AGENT_CONFIG_BUNDLE__: boolean | undefined;
|
|
25
27
|
const _IN_BUNDLE = typeof __AGENT_CONFIG_BUNDLE__ !== 'undefined' && __AGENT_CONFIG_BUNDLE__;
|
|
26
28
|
const _REPO_ROOT = path.resolve(
|
|
@@ -30,10 +32,59 @@ const _REPO_ROOT = path.resolve(
|
|
|
30
32
|
|
|
31
33
|
export const HOST_LOWERING_PATH = path.join(_REPO_ROOT, 'src', 'scripts', 'hooks', 'host_lowering.yaml');
|
|
32
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Compiled sibling of the table above — the same data with comments stripped.
|
|
37
|
+
*
|
|
38
|
+
* WHY IT EXISTS, measured rather than assumed. The dispatcher consults this
|
|
39
|
+
* table on EVERY dispatch (`emitFor` needs `blockExitFor`), and since
|
|
40
|
+
* `hook_manifest.json` landed it is the ONLY remaining YAML reader on that
|
|
41
|
+
* path — so it pays both its own parse and the cold load of the `yaml` module
|
|
42
|
+
* nothing else pulls in any more. Measured on one developer machine: the
|
|
43
|
+
* 16.8 kB source parses in 3.1-7.0 ms and the `yaml` module costs a further
|
|
44
|
+
* 8.1 ms to load, against `JSON.parse` of the 5.9 kB compiled form at 0.03 ms.
|
|
45
|
+
*
|
|
46
|
+
* Exactly the shape `compile_hook_manifest` already established for the
|
|
47
|
+
* manifest, including the content fingerprint — see `table_fingerprint` for
|
|
48
|
+
* why freshness is decided by content and never by mtime.
|
|
49
|
+
*/
|
|
50
|
+
export const HOST_LOWERING_JSON_PATH = path.join(_REPO_ROOT, 'src', 'scripts', 'hooks', 'host_lowering.json');
|
|
51
|
+
|
|
33
52
|
/** Provenance of a row. Every field may be null; `expires` may not. */
|
|
34
53
|
export interface VerifiedBlock {
|
|
35
54
|
docs_at: string | null;
|
|
36
55
|
docs_url: string | null;
|
|
56
|
+
/**
|
|
57
|
+
* sha256 of the `docs_url` body as last ESTABLISHED for this row.
|
|
58
|
+
*
|
|
59
|
+
* "Established" means recorded by a human-run fill, not merely seen. The
|
|
60
|
+
* watcher re-hashes the page on every run and writes the new value only
|
|
61
|
+
* when the field was empty; on a DRIFT it deliberately leaves the recorded
|
|
62
|
+
* digest alone, so the field keeps pointing at the body someone actually
|
|
63
|
+
* read while `expires` carries the alarm.
|
|
64
|
+
*
|
|
65
|
+
* Three earlier wordings were wrong and all three are named rather than
|
|
66
|
+
* quietly replaced, because each was corrected by evidence the next one
|
|
67
|
+
* then contradicted. "As fetched on `docs_at`" was refuted by the very
|
|
68
|
+
* first fill (digests taken 2026-10-01 against rows whose `docs_at` is
|
|
69
|
+
* 2026-09-29). "As fetched by the LAST digest run" was refuted by the
|
|
70
|
+
* writer (after a drift the last run computed a different hash than the
|
|
71
|
+
* field holds). "`docs_at` + `docs_digest` are ONE pair" was refuted by
|
|
72
|
+
* the same committed data as the first — stating it was a relapse, caught
|
|
73
|
+
* in review.
|
|
74
|
+
*
|
|
75
|
+
* The two fields are simply INDEPENDENT. `docs_at` dates a human reading
|
|
76
|
+
* the page for the row's ANSWERS; `docs_digest` names the body the watcher
|
|
77
|
+
* compares against. Nothing guarantees they were the same fetch, and no
|
|
78
|
+
* wording that implies they were can survive this table's own rows.
|
|
79
|
+
*
|
|
80
|
+
* Null where there is nothing to hash — a row whose `docs_url` is null —
|
|
81
|
+
* and null is also the pre-fill state `check_host_docs_digest --fetch
|
|
82
|
+
* --write` resolves. It is deliberately NOT part of the expiry test: a
|
|
83
|
+
* digest is evidence about the page, `expires` is this package's review-by
|
|
84
|
+
* date, and collapsing the two would make a vendor's CSS rebuild look like
|
|
85
|
+
* a lapsed citation.
|
|
86
|
+
*/
|
|
87
|
+
docs_digest: string | null;
|
|
37
88
|
probe_at: string | null;
|
|
38
89
|
host_version: string | null;
|
|
39
90
|
expires: string;
|
|
@@ -44,6 +95,21 @@ export interface SlotRow {
|
|
|
44
95
|
native: string[];
|
|
45
96
|
/** Exit code the host honours as a refusal here, or null if unestablished. */
|
|
46
97
|
block_exit: number | null;
|
|
98
|
+
/**
|
|
99
|
+
* The date this pair was last answered, or null when it never was.
|
|
100
|
+
*
|
|
101
|
+
* `block_exit: null` alone cannot distinguish "looked, found none" from
|
|
102
|
+
* "nobody looked", and the whole point of this table is that a zero is a
|
|
103
|
+
* fact with a date on it. `lint_hook_manifest` requires the date; the
|
|
104
|
+
* parser keeps it nullable so a malformed table still parses into
|
|
105
|
+
* something the linter can report on rather than throwing first.
|
|
106
|
+
*/
|
|
107
|
+
answered_at: string | null;
|
|
108
|
+
/**
|
|
109
|
+
* Citation for this pair, when it differs from the row's
|
|
110
|
+
* `verified.docs_url`. Absent means the row's URL is the citation.
|
|
111
|
+
*/
|
|
112
|
+
docs_url: string | null;
|
|
47
113
|
/** Entry-shape-specific extra (gemini's per-binding matcher). */
|
|
48
114
|
matcher?: string;
|
|
49
115
|
}
|
|
@@ -72,7 +138,18 @@ function _asString(v: unknown): string | null {
|
|
|
72
138
|
}
|
|
73
139
|
|
|
74
140
|
function _parse(text: string): HostLowering {
|
|
75
|
-
|
|
141
|
+
return _structure(parseYaml(text) as Record<string, unknown> | null);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Build the table from an ALREADY-PARSED document.
|
|
146
|
+
*
|
|
147
|
+
* Split out of `_parse` so the compiled-JSON fast path below reaches exactly
|
|
148
|
+
* the same validation on exactly the same shape — the YAML step is the only
|
|
149
|
+
* thing it skips. A second structuring function would be a second thing to
|
|
150
|
+
* drift; there is one, and both paths call it.
|
|
151
|
+
*/
|
|
152
|
+
function _structure(raw: Record<string, unknown> | null): HostLowering {
|
|
76
153
|
const hostsRaw = raw?.['hosts'];
|
|
77
154
|
if (typeof hostsRaw !== 'object' || hostsRaw === null) {
|
|
78
155
|
throw new Error('host_lowering.yaml: missing `hosts:` map');
|
|
@@ -96,6 +173,7 @@ function _parse(text: string): HostLowering {
|
|
|
96
173
|
verified = {
|
|
97
174
|
docs_at: _asString(verifiedRaw['docs_at']),
|
|
98
175
|
docs_url: _asString(verifiedRaw['docs_url']),
|
|
176
|
+
docs_digest: _asString(verifiedRaw['docs_digest']),
|
|
99
177
|
probe_at: _asString(verifiedRaw['probe_at']),
|
|
100
178
|
host_version: _asString(verifiedRaw['host_version']),
|
|
101
179
|
expires,
|
|
@@ -110,6 +188,8 @@ function _parse(text: string): HostLowering {
|
|
|
110
188
|
const row: SlotRow = {
|
|
111
189
|
native,
|
|
112
190
|
block_exit: typeof be === 'number' ? be : null,
|
|
191
|
+
answered_at: _asString(rv['answered_at']),
|
|
192
|
+
docs_url: _asString(rv['docs_url']),
|
|
113
193
|
};
|
|
114
194
|
if (typeof rv['matcher'] === 'string') row.matcher = rv['matcher'];
|
|
115
195
|
slots.set(slot, row);
|
|
@@ -131,12 +211,75 @@ function _parse(text: string): HostLowering {
|
|
|
131
211
|
|
|
132
212
|
let _cache: HostLowering | null = null;
|
|
133
213
|
|
|
134
|
-
/**
|
|
214
|
+
/**
|
|
215
|
+
* Parse the table once per process. Throws on a missing or malformed file.
|
|
216
|
+
*
|
|
217
|
+
* Tries the compiled sibling first and falls through to the YAML source on
|
|
218
|
+
* anything unexpected — missing, unreadable, malformed, or a fingerprint that
|
|
219
|
+
* does not match the live source. A stale or absent compiled file is therefore
|
|
220
|
+
* SLOW and never WRONG, which is the property that lets the optimisation ship
|
|
221
|
+
* without a second correctness argument.
|
|
222
|
+
*/
|
|
135
223
|
export function loadHostLowering(): HostLowering {
|
|
136
|
-
if (_cache
|
|
224
|
+
if (_cache !== null) return _cache;
|
|
225
|
+
// Reading the YAML unconditionally costs ~0.03 ms — it is the PARSE that is
|
|
226
|
+
// expensive — so the fast path still skips the whole 11-15 ms.
|
|
227
|
+
const text = fs.readFileSync(HOST_LOWERING_PATH, 'utf-8');
|
|
228
|
+
let compiled: string | null;
|
|
229
|
+
try {
|
|
230
|
+
compiled = fs.readFileSync(HOST_LOWERING_JSON_PATH, 'utf-8');
|
|
231
|
+
} catch {
|
|
232
|
+
compiled = null;
|
|
233
|
+
}
|
|
234
|
+
_cache = resolveTable(text, compiled);
|
|
137
235
|
return _cache;
|
|
138
236
|
}
|
|
139
237
|
|
|
238
|
+
/**
|
|
239
|
+
* Pick the path and build the table — the whole decision, with no I/O.
|
|
240
|
+
*
|
|
241
|
+
* Split from `loadHostLowering` so the FALLBACK semantics are testable. They
|
|
242
|
+
* are the half that carries the risk: the fast path is easy to verify and a
|
|
243
|
+
* mis-shaped fallback would be a wrong table rather than a slow one. A test
|
|
244
|
+
* that could only reach the happy path would be watching the safe half.
|
|
245
|
+
*/
|
|
246
|
+
export function resolveTable(yamlText: string, compiledText: string | null): HostLowering {
|
|
247
|
+
if (compiledText !== null) {
|
|
248
|
+
try {
|
|
249
|
+
const raw = JSON.parse(compiledText) as Record<string, unknown>;
|
|
250
|
+
const table = raw['table'];
|
|
251
|
+
if (
|
|
252
|
+
raw['fingerprint'] === tableFingerprint(yamlText) &&
|
|
253
|
+
typeof table === 'object' &&
|
|
254
|
+
table !== null &&
|
|
255
|
+
// road-to-blocking-severities 2.3 — the BODY, not only its
|
|
256
|
+
// label. `fingerprint` above says the file was compiled from
|
|
257
|
+
// the YAML as it stands; it says nothing about whether the
|
|
258
|
+
// body underneath was edited afterwards, and an edited body
|
|
259
|
+
// with an untouched label was served. `body_fingerprint` is
|
|
260
|
+
// the fingerprint of the exact bytes the compiler emitted, so
|
|
261
|
+
// re-stringifying what we just parsed recovers them.
|
|
262
|
+
//
|
|
263
|
+
// A compiled file WITHOUT the field — one written before 2.3 —
|
|
264
|
+
// falls through here, which is slow and correct: accepting it
|
|
265
|
+
// would make the check optional and therefore absent.
|
|
266
|
+
//
|
|
267
|
+
// What it covers is a partial edit, never an author: anyone
|
|
268
|
+
// who edits the body can recompute this as easily as the
|
|
269
|
+
// compiler. The deny in `block_plumbing_writes` and the
|
|
270
|
+
// ratification record are the mechanisms aimed at an author;
|
|
271
|
+
// this one is aimed at a mistake.
|
|
272
|
+
raw['body_fingerprint'] === tableFingerprint(JSON.stringify(table))
|
|
273
|
+
) {
|
|
274
|
+
return _structure(table as Record<string, unknown>);
|
|
275
|
+
}
|
|
276
|
+
} catch {
|
|
277
|
+
// Malformed JSON → the source below. Never fail on the optimisation.
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return _parse(yamlText);
|
|
281
|
+
}
|
|
282
|
+
|
|
140
283
|
/** Test seam — drop the memoized table so a fixture can be loaded instead. */
|
|
141
284
|
export function _resetHostLoweringCache(table?: HostLowering): void {
|
|
142
285
|
_cache = table ?? null;
|