@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,262 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* A hook's exit code comes from the table, never from a numeral.
|
|
4
|
+
*
|
|
5
|
+
* road-to-a-kernel-that-guards-its-plumbing 4.1, the enforcing half.
|
|
6
|
+
* `hooks/exit_codes.ts` is the table; this is what keeps it the only one.
|
|
7
|
+
*
|
|
8
|
+
* WHAT THE NUMERALS COST. Thirty-three files under `src/scripts/hooks/` each
|
|
9
|
+
* declared their own `EXIT_ALLOW = 0` / `EXIT_BLOCK = 1` / `EXIT_WARN = 2`, two
|
|
10
|
+
* of them under a third name. The danger is not a typo: 1 and 2 mean the
|
|
11
|
+
* OPPOSITE things on Claude Code from what they mean in this tree's internal
|
|
12
|
+
* language, which is why `host_semantics.ts` exists to lower one onto the
|
|
13
|
+
* other. A bare `process.exit(1)` in a concern is a claim about which of the
|
|
14
|
+
* two dialects the writer had in mind, and the source does not record which.
|
|
15
|
+
*
|
|
16
|
+
* WHAT IT SCANS. `.ts` under `src/scripts/hooks/`, refusing a call whose
|
|
17
|
+
* argument is a bare numeric literal. An identifier is accepted whatever it is
|
|
18
|
+
* called — this gate does not verify that the identifier came from the table,
|
|
19
|
+
* because a gate that resolved imports would be a type-checker, and the thing
|
|
20
|
+
* it would catch (a local `const EXIT_BLOCK = 1` shadowing the import) is
|
|
21
|
+
* already visible in review as a duplicate declaration. Stated rather than left
|
|
22
|
+
* for a reader to assume the green covers it.
|
|
23
|
+
*
|
|
24
|
+
* WHY THE DISPATCHERS ARE OUT OF SCOPE. The `*-dispatcher.sh` trampolines carry
|
|
25
|
+
* `process.exit(0)` inside a `node -e` one-liner that reads a workspace root
|
|
26
|
+
* off stdin. They are shell, they cannot import, and their exit code is the
|
|
27
|
+
* one-liner's, never a verdict. The table's own header says so; this gate scans
|
|
28
|
+
* `.ts` only, which is the same boundary stated once more where it is enforced.
|
|
29
|
+
*
|
|
30
|
+
* THE TABLE FILE ITSELF is excluded, and that is the one exclusion: it is where
|
|
31
|
+
* the numerals are DEFINED, so a gate that refused them there would forbid the
|
|
32
|
+
* fix it exists to require.
|
|
33
|
+
*
|
|
34
|
+
* Exit codes: 0 clean · 1 a bare numeral reached `process.exit` · 2 the corpus
|
|
35
|
+
* could not be read.
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
import fs from 'node:fs';
|
|
39
|
+
import os from 'node:os';
|
|
40
|
+
import path from 'node:path';
|
|
41
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
42
|
+
|
|
43
|
+
import { GateLedger } from './_lib/gate_ledger.js';
|
|
44
|
+
import { runGateCli, runSelfTest } from './_lib/gate_self_test.js';
|
|
45
|
+
import { reportScanned } from './_lib/scan_scope.js';
|
|
46
|
+
|
|
47
|
+
const _HERE = fileURLToPath(import.meta.url);
|
|
48
|
+
const ROOT = path.resolve(path.dirname(_HERE), '..', '..');
|
|
49
|
+
|
|
50
|
+
export const GATE = 'lint_exit_codes';
|
|
51
|
+
|
|
52
|
+
const HOOKS_REL = path.join('src', 'scripts', 'hooks');
|
|
53
|
+
|
|
54
|
+
/** The file that DEFINES the numerals. Excluding it is not a carve-out. */
|
|
55
|
+
const TABLE_BASENAME = 'exit_codes.ts';
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The fixture import line, ASSEMBLED rather than written out.
|
|
59
|
+
*
|
|
60
|
+
* `prepack-check.mjs` scans source text for relative imports and cannot tell a
|
|
61
|
+
* string literal from a real one, so a fixture containing the words
|
|
62
|
+
* `from './exit_codes.js'` reads as this file importing a sibling that does not
|
|
63
|
+
* exist beside it — the table lives under `hooks/`. It reported exactly that
|
|
64
|
+
* before this was assembled. Splitting the specifier is the smallest change
|
|
65
|
+
* that keeps the fixture honest about what a passing hook file looks like
|
|
66
|
+
* without asserting an import this file does not make.
|
|
67
|
+
*/
|
|
68
|
+
const FIXTURE_IMPORT = (name: string): string => `import { ${name} } from '.` + `/${TABLE_BASENAME.replace('.ts', '.js')}';\n`;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* `process.exit(<digits>)`, with optional whitespace.
|
|
72
|
+
*
|
|
73
|
+
* Deliberately anchored on `process.exit` rather than on any `exit(`: a
|
|
74
|
+
* concern's own helper named `exit` is not the process boundary, and widening
|
|
75
|
+
* the pattern to catch it would red on ordinary code.
|
|
76
|
+
*/
|
|
77
|
+
const BARE_EXIT = /process\s*\.\s*exit\s*\(\s*(-?\d+)\s*\)/g;
|
|
78
|
+
|
|
79
|
+
export interface ExitFinding {
|
|
80
|
+
readonly file: string;
|
|
81
|
+
readonly line: number;
|
|
82
|
+
readonly code: string;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** Findings in one file's text. Pure, so a test reads the decision. */
|
|
86
|
+
export function findBareExits(rel: string, text: string): ExitFinding[] {
|
|
87
|
+
const out: ExitFinding[] = [];
|
|
88
|
+
const lines = text.split('\n');
|
|
89
|
+
for (let i = 0; i < lines.length; i++) {
|
|
90
|
+
const line = lines[i] as string;
|
|
91
|
+
// A commented example is prose about the rule, not an exit.
|
|
92
|
+
if (/^\s*(\*|\/\/)/.test(line)) continue;
|
|
93
|
+
BARE_EXIT.lastIndex = 0;
|
|
94
|
+
let m: RegExpExecArray | null;
|
|
95
|
+
while ((m = BARE_EXIT.exec(line)) !== null) {
|
|
96
|
+
out.push({ file: rel, line: i + 1, code: m[1] as string });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return out;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function hookFiles(root: string): string[] {
|
|
103
|
+
const dir = path.join(root, HOOKS_REL);
|
|
104
|
+
let entries: string[];
|
|
105
|
+
try {
|
|
106
|
+
entries = fs.readdirSync(dir);
|
|
107
|
+
} catch {
|
|
108
|
+
return [];
|
|
109
|
+
}
|
|
110
|
+
return entries
|
|
111
|
+
.filter((f) => f.endsWith('.ts') && f !== TABLE_BASENAME)
|
|
112
|
+
.map((f) => path.join(HOOKS_REL, f))
|
|
113
|
+
.sort();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function main(argv: readonly string[] = process.argv.slice(2)): number {
|
|
117
|
+
if (argv.includes('--self-test')) return selfTest();
|
|
118
|
+
const i = argv.indexOf('--root');
|
|
119
|
+
if (i !== -1 && (argv[i + 1] === undefined || argv[i + 1]?.startsWith('-') === true)) {
|
|
120
|
+
process.stderr.write(`${GATE}: \`--root\` needs a directory.\n`);
|
|
121
|
+
return 2;
|
|
122
|
+
}
|
|
123
|
+
const root = i === -1 ? ROOT : (argv[i + 1] as string);
|
|
124
|
+
|
|
125
|
+
const files = hookFiles(root);
|
|
126
|
+
const findings: ExitFinding[] = [];
|
|
127
|
+
// A file the gate cannot READ is not a file it cleared. The first version
|
|
128
|
+
// of this loop skipped it and then counted it complete, which is a false
|
|
129
|
+
// green with a number behind it — the exact shape `assertScanned` exists to
|
|
130
|
+
// refuse one level up, reintroduced inside the loop. Reported by an
|
|
131
|
+
// independent review before this landed.
|
|
132
|
+
const unreadable: string[] = [];
|
|
133
|
+
for (const rel of files) {
|
|
134
|
+
let text: string;
|
|
135
|
+
try {
|
|
136
|
+
text = fs.readFileSync(path.join(root, rel), 'utf-8');
|
|
137
|
+
} catch {
|
|
138
|
+
unreadable.push(rel);
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
findings.push(...findBareExits(rel, text));
|
|
142
|
+
}
|
|
143
|
+
if (unreadable.length > 0) {
|
|
144
|
+
for (const rel of unreadable) {
|
|
145
|
+
process.stderr.write(`❌ ${GATE}: cannot read ${rel} — the corpus is incomplete.\n`);
|
|
146
|
+
}
|
|
147
|
+
return 2;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Before the verdict: a corpus of zero is a gate that read nothing, and a
|
|
151
|
+
// green over it says the tree is clean when nobody looked.
|
|
152
|
+
try {
|
|
153
|
+
reportScanned({ gate: GATE, scanned: files.length, units: 'hook file(s)', roots: [HOOKS_REL] });
|
|
154
|
+
} catch (exc) {
|
|
155
|
+
process.stderr.write(`❌ ${String((exc as Error).message)}\n`);
|
|
156
|
+
return 2;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const ledger = new GateLedger(GATE);
|
|
160
|
+
ledger.plan(files);
|
|
161
|
+
const failed = new Set(findings.map((f) => f.file));
|
|
162
|
+
for (const f of findings) {
|
|
163
|
+
ledger.fail(f.file, `bare exit numeral ${f.code} at line ${String(f.line)}`);
|
|
164
|
+
}
|
|
165
|
+
for (const rel of files) if (!failed.has(rel)) ledger.complete(rel);
|
|
166
|
+
ledger.report();
|
|
167
|
+
|
|
168
|
+
if (findings.length > 0) {
|
|
169
|
+
for (const f of findings) {
|
|
170
|
+
process.stdout.write(
|
|
171
|
+
`❌ ${GATE}: ${f.file}:${String(f.line)} exits with the bare numeral ` +
|
|
172
|
+
`\`${f.code}\`. Import the name from \`hooks/exit_codes.ts\` — the numbers ` +
|
|
173
|
+
'mean opposite things in this tree and on the host, and a numeral records ' +
|
|
174
|
+
'neither.\n',
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
return 1;
|
|
178
|
+
}
|
|
179
|
+
process.stdout.write(
|
|
180
|
+
`✅ ${GATE}: ${String(files.length)} hook file(s), no bare exit numeral.\n`,
|
|
181
|
+
);
|
|
182
|
+
return 0;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function selfTest(): number {
|
|
186
|
+
const plant = (name: string, body: string): string => {
|
|
187
|
+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), `exit-codes-${name}-`));
|
|
188
|
+
fs.mkdirSync(path.join(dir, HOOKS_REL), { recursive: true });
|
|
189
|
+
fs.writeFileSync(path.join(dir, HOOKS_REL, 'probe_hook.ts'), body, 'utf-8');
|
|
190
|
+
// The table itself, so the exclusion is exercised rather than assumed.
|
|
191
|
+
fs.writeFileSync(
|
|
192
|
+
path.join(dir, HOOKS_REL, TABLE_BASENAME),
|
|
193
|
+
'export const EXIT_ALLOW = 0;\nprocess.exit(0);\n',
|
|
194
|
+
'utf-8',
|
|
195
|
+
);
|
|
196
|
+
return dir;
|
|
197
|
+
};
|
|
198
|
+
const run = (root: string): number =>
|
|
199
|
+
runGateCli(ROOT, path.join('src', 'scripts', 'lint_exit_codes.ts'), ['--root', root], ROOT);
|
|
200
|
+
|
|
201
|
+
return runSelfTest({
|
|
202
|
+
gate: GATE,
|
|
203
|
+
minCases: 6,
|
|
204
|
+
minRejectCases: 4,
|
|
205
|
+
cases: [
|
|
206
|
+
{
|
|
207
|
+
name: 'an empty corpus is refused, not certified green',
|
|
208
|
+
expect: 'reject',
|
|
209
|
+
run: () => run(fs.mkdtempSync(path.join(os.tmpdir(), 'exit-codes-empty-'))),
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
name: 'a bare deny numeral fails',
|
|
213
|
+
expect: 'reject',
|
|
214
|
+
run: () => run(plant('block', 'process.exit(1);\n')),
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
name: 'a bare allow numeral fails too — 0 is the one people think is harmless',
|
|
218
|
+
expect: 'reject',
|
|
219
|
+
run: () => run(plant('allow', 'process.exit(0);\n')),
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
name: 'whitespace inside the call does not hide it',
|
|
223
|
+
expect: 'reject',
|
|
224
|
+
run: () => run(plant('spaced', 'process . exit ( 2 );\n')),
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
name: 'an imported name passes',
|
|
228
|
+
expect: 'accept',
|
|
229
|
+
run: () =>
|
|
230
|
+
run(
|
|
231
|
+
plant(
|
|
232
|
+
'named',
|
|
233
|
+
`${FIXTURE_IMPORT('EXIT_ALLOW')}process.exit(EXIT_ALLOW);\n`,
|
|
234
|
+
),
|
|
235
|
+
),
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
// The table defines the numerals; refusing them there would
|
|
239
|
+
// forbid the fix this gate exists to require. Exercised, not
|
|
240
|
+
// assumed — the plant writes a bare exit into it every time.
|
|
241
|
+
name: 'the table file is excluded even though it carries a numeral',
|
|
242
|
+
expect: 'accept',
|
|
243
|
+
run: () =>
|
|
244
|
+
run(
|
|
245
|
+
plant(
|
|
246
|
+
'table',
|
|
247
|
+
`${FIXTURE_IMPORT('EXIT_WARN')}process.exit(EXIT_WARN);\n`,
|
|
248
|
+
),
|
|
249
|
+
),
|
|
250
|
+
},
|
|
251
|
+
],
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
function _isCliEntry(): boolean {
|
|
256
|
+
const entry = process.argv[1];
|
|
257
|
+
return entry !== undefined && import.meta.url === pathToFileURL(entry).href;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (_isCliEntry()) {
|
|
261
|
+
process.exit(main());
|
|
262
|
+
}
|
|
@@ -52,6 +52,33 @@ const DEFAULT_MANIFEST = path.join(
|
|
|
52
52
|
const HOOKS_DIR = path.join(REPO_ROOT, "src", "scripts", "hooks");
|
|
53
53
|
const DEFAULT_HOST_LOWERING = path.join(HOOKS_DIR, "host_lowering.yaml");
|
|
54
54
|
|
|
55
|
+
/**
|
|
56
|
+
* What a concern does to a turn — the closed set `effect:` draws from.
|
|
57
|
+
*
|
|
58
|
+
* Read by the neighbour census, which needs to say what sharing an event with
|
|
59
|
+
* a foreign entry actually risks. A foreign entry's effect is `unknown` unless
|
|
60
|
+
* its output shape has been observed: no host exposes another package's hook
|
|
61
|
+
* execution, so the honest default is that the neighbour's effect cannot be
|
|
62
|
+
* read off its registration.
|
|
63
|
+
*
|
|
64
|
+
* - `permission` can refuse the thing it fires on
|
|
65
|
+
* - `context` puts text in front of the model
|
|
66
|
+
* - `verification` checks a claim or a shape and reports what it found
|
|
67
|
+
* - `telemetry` records state, a ledger, a counter
|
|
68
|
+
* - `memory` reads or writes the memory layer
|
|
69
|
+
* - `notification` tells the human something and changes nothing else
|
|
70
|
+
* - `formatting` reshapes a command or a generated file
|
|
71
|
+
*/
|
|
72
|
+
export const CONCERN_EFFECTS: ReadonlySet<string> = new Set([
|
|
73
|
+
"permission",
|
|
74
|
+
"context",
|
|
75
|
+
"verification",
|
|
76
|
+
"telemetry",
|
|
77
|
+
"memory",
|
|
78
|
+
"notification",
|
|
79
|
+
"formatting",
|
|
80
|
+
]);
|
|
81
|
+
|
|
55
82
|
// Canonical event vocabulary — keep in lock-step with
|
|
56
83
|
// docs/contracts/hook-architecture-v1.md and dispatch_hook.EVENT_VOCABULARY.
|
|
57
84
|
const EVENT_VOCABULARY: ReadonlySet<string> = new Set([
|
|
@@ -159,6 +186,32 @@ function _check_concerns(manifest: YamlObject, errors: string[]): Set<string> {
|
|
|
159
186
|
if (!_isFile(path.join(REPO_ROOT, script))) {
|
|
160
187
|
errors.push(`concerns.${name}: script not found at '${script}'`);
|
|
161
188
|
}
|
|
189
|
+
// `effect:` — what this concern DOES to a turn, from a closed set. It is
|
|
190
|
+
// what lets the neighbour census say "a foreign entry shares this event
|
|
191
|
+
// with something of ours that can refuse" rather than only "two entries".
|
|
192
|
+
// Required and enum-checked, which is a stricter rule than the optional
|
|
193
|
+
// keys below for one reason: a concern with no effect, or with a
|
|
194
|
+
// misspelled one, would silently drop out of every double-gate comparison
|
|
195
|
+
// — the warning would stay quiet and read as "no conflict", which is the
|
|
196
|
+
// wrong answer rather than a missing one. There is no unknown-key guard
|
|
197
|
+
// on this mapping, so nothing else would catch `effects:`.
|
|
198
|
+
const effect = spec["effect"];
|
|
199
|
+
if (typeof effect !== "string" || !CONCERN_EFFECTS.has(effect)) {
|
|
200
|
+
errors.push(
|
|
201
|
+
`concerns.${name}: 'effect' must be one of ` +
|
|
202
|
+
`${[...CONCERN_EFFECTS].sort().join(" | ")} (got ${JSON.stringify(effect)})`,
|
|
203
|
+
);
|
|
204
|
+
} else if ((spec["severity"] === "blocking") !== (effect === "permission")) {
|
|
205
|
+
// The two fields answer the same question from different sides, so a
|
|
206
|
+
// disagreement is a mistake in one of them, never a shade of meaning:
|
|
207
|
+
// `blocking` is the dispatcher's word for "this can refuse" and
|
|
208
|
+
// `permission` is the census's.
|
|
209
|
+
errors.push(
|
|
210
|
+
`concerns.${name}: 'effect: ${effect}' contradicts ` +
|
|
211
|
+
`'severity: ${String(spec["severity"])}' — a concern that can refuse ` +
|
|
212
|
+
`is 'permission', and only those are 'blocking'`,
|
|
213
|
+
);
|
|
214
|
+
}
|
|
162
215
|
// `tools:` — the optional per-concern tool filter the dispatcher applies
|
|
163
216
|
// in-process (`_concern_matches_tool`). Validated because the failure mode
|
|
164
217
|
// is silent: the dispatcher fails toward RUNNING the concern on anything
|
|
@@ -716,6 +769,61 @@ export function _check_host_lowering(
|
|
|
716
769
|
}
|
|
717
770
|
}
|
|
718
771
|
}
|
|
772
|
+
_check_slot_answers(table, errors);
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
/**
|
|
776
|
+
* Every (host, slot) pair carries a date, and a citation to go with it.
|
|
777
|
+
*
|
|
778
|
+
* WHY AN ERROR AND NOT A WARNING. `block_exit: null` is the value the table
|
|
779
|
+
* carries on 29 of its 32 pairs, and until this check it meant two different
|
|
780
|
+
* things at once: "read the host's contract, it honours no refusal here" and
|
|
781
|
+
* "nobody has ever looked at this pair". Those are opposite epistemic states
|
|
782
|
+
* printed as the same byte, and the file's own header promises the first one
|
|
783
|
+
* ("`verified: null` means nobody established anything") without giving the
|
|
784
|
+
* per-slot layer any way to say it. `answered_at` is that way, and a soft
|
|
785
|
+
* warning would let the ambiguity back in one undated slot at a time — the
|
|
786
|
+
* exact drift the row-level `verified` gate was added to stop one level up.
|
|
787
|
+
*
|
|
788
|
+
* THE CITATION MAY BE INHERITED. A host publishes ONE hooks page, so requiring
|
|
789
|
+
* a per-slot `docs_url` would mean five copies of the same URL per host and
|
|
790
|
+
* five places for it to rot. The row's `verified.docs_url` is the citation
|
|
791
|
+
* unless the slot overrides it; what the check refuses is a dated answer with
|
|
792
|
+
* no reachable citation at all.
|
|
793
|
+
*
|
|
794
|
+
* A slot on a row with NO `verified` block is exempt from the citation half
|
|
795
|
+
* and not from the date: an undated row is already an error wherever it carries
|
|
796
|
+
* a blocking binding, and demanding a URL from a row that has none would report
|
|
797
|
+
* the same missing provenance twice in different words.
|
|
798
|
+
*/
|
|
799
|
+
export function _check_slot_answers(table: HostLowering, errors: string[]): void {
|
|
800
|
+
for (const [host, surfaces] of table) {
|
|
801
|
+
for (const [surface, row] of surfaces) {
|
|
802
|
+
for (const [slot, s] of row.slots) {
|
|
803
|
+
const where = `host_lowering ${host}/${surface}/${slot}`;
|
|
804
|
+
if (s.answered_at === null) {
|
|
805
|
+
errors.push(
|
|
806
|
+
`${where}: no \`answered_at\`. Every host-slot pair carries the date it was ` +
|
|
807
|
+
"last answered, so that a `block_exit: null` is a finding with a date on it " +
|
|
808
|
+
"rather than a slot nobody looked at.",
|
|
809
|
+
);
|
|
810
|
+
continue;
|
|
811
|
+
}
|
|
812
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(s.answered_at)) {
|
|
813
|
+
errors.push(`${where}: \`answered_at: ${s.answered_at}\` is not an ISO \`YYYY-MM-DD\` date.`);
|
|
814
|
+
}
|
|
815
|
+
// The row-level exemption the block comment above states: a row with no
|
|
816
|
+
// `verified` block already reports its missing provenance once, at row level.
|
|
817
|
+
if (row.verified !== null && s.docs_url === null && row.verified.docs_url === null) {
|
|
818
|
+
errors.push(
|
|
819
|
+
`${where}: dated \`${s.answered_at}\` with no citation — the slot carries no ` +
|
|
820
|
+
"`docs_url` and the row's `verified.docs_url` is absent. Cite the page the " +
|
|
821
|
+
"answer was read off, on the slot or on the row.",
|
|
822
|
+
);
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
}
|
|
719
827
|
}
|
|
720
828
|
|
|
721
829
|
export function lint(
|