@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,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"owner": "maintainer",
|
|
3
|
+
"review_by": "2027-09-29",
|
|
4
|
+
"seeded_at": "2026-09-29",
|
|
5
|
+
"note": "Shrink-only ceilings on FOREIGN placeholder syntaxes in prose, per road-to-an-invocation-contract-that-reaches-the-wire 1.2. The unit is a token outside fenced blocks, indented blocks and inline code spans — defined and argued in src/scripts/report_invocation_surface.ts's module header, with the per-file breakdown in agents/evidence/analysis/invocation-surface-census.md. Seeded at what this tree measures, not at the roadmap's figures: those counted tokens inside demonstrated code (JS template literals, HCL, a table-cell marker the prose talks about) and do not reproduce. The plurality form is deliberately ungated. Raising a ceiling is a reviewable diff, and the reason belongs in it.",
|
|
6
|
+
"ceilings": {
|
|
7
|
+
"angle-upper": 3,
|
|
8
|
+
"double-brace": 0
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -10,12 +10,12 @@
|
|
|
10
10
|
},
|
|
11
11
|
"seed": {
|
|
12
12
|
"rules": 0.9623,
|
|
13
|
-
"skills": 0.
|
|
13
|
+
"skills": 0.3746
|
|
14
14
|
},
|
|
15
15
|
"seed_provenance": {
|
|
16
16
|
"rules": "102 covered of 106 routed rules on 2026-09-13; was 101 of 105 on 2026-09-08 and 94 of 105 (tier-1 21/24, tier-2 73/81) on 2026-08-25.",
|
|
17
|
-
"skills": "
|
|
18
|
-
"finding": "The gap between the two seeds IS the roadmap defect D1, quantified. The rules surface is ~90% covered by a deterministic corpus that can fail a PR; the skills surface -- the one production routes on -- is
|
|
17
|
+
"skills": "112 of 299 skills carry evals/triggers.json on 2026-10-04; was 111 on 2026-10-02, 107 on 2026-10-01, 103 earlier that day, 102 on 2026-09-30, 101 on 2026-09-19 and 100 on 2026-08-30.",
|
|
18
|
+
"finding": "The gap between the two seeds IS the roadmap defect D1, quantified. The rules surface is ~90% covered by a deterministic corpus that can fail a PR; the skills surface -- the one production routes on -- is far lower and is covered only by a harness that is advisory only, never gating (rule_trigger_eval.ts:4). The figure is deliberately not restated here (corrected 2026-10-01): it read `25%` against a seed that had since moved to 0.3445, which is the same count-drift this file's own history entries keep repairing one field away. The live value is `seed.skills`, two keys above."
|
|
19
19
|
},
|
|
20
20
|
"history": [
|
|
21
21
|
{
|
|
@@ -59,6 +59,41 @@
|
|
|
59
59
|
"from": 0.3344,
|
|
60
60
|
"to": 0.3378,
|
|
61
61
|
"reason": "road-to-release-holds-that-refuse step 1.4 authored one corpus file for `roadmap-writing` (100 -> 101 of 299) and removed its now-false entry from trigger_eval_grandfather.json. ONE file rather than a wave: the step asked for a single positive case whose expected output is a re-sequenced phase rather than a hold, and the eval set is where that expectation is pinned. The seed rises so the gain cannot be given back silently; it may never be LOWERED. Two published measurements moved with it and were re-taken in the same change -- routing-body-signal-verdict.json and the measure_delivery_sets record -- because the trigger corpus is their input, so any skill gaining an eval set re-takes both."
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"date": "2026-09-30",
|
|
65
|
+
"scope": "skills",
|
|
66
|
+
"from": 0.3378,
|
|
67
|
+
"to": 0.3411,
|
|
68
|
+
"reason": "road-to-a-component-taxonomy-we-follow-but-never-force authored one corpus file for `ui-component-architect` (101 -> 102 of 299). Not a sought gain: the branch edits that skill's placement section, and check_routing_coverage requires a corpus for every skill a diff touches, so the file is the gate's own remedy rather than a coverage push. Five should-trigger cases, one per shape the skill decides, and five near misses whose vocabulary overlaps hardest -- styling an existing component, inventorying what the project owns (existing-ui-audit, which runs first and feeds this one), a backend composition question, a prop rename, and general React knowledge with no component to shape. The seed rises so the gain cannot be given back silently; it may never be LOWERED. The two published measurements the 2026-09-19 entry names -- routing-body-signal-verdict.json and the measure_delivery_sets record -- are re-taken in the same change, for the reason that entry gives: the trigger corpus is their input."
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"date": "2026-10-01",
|
|
72
|
+
"scope": "skills",
|
|
73
|
+
"from": 0.3411,
|
|
74
|
+
"to": 0.3445,
|
|
75
|
+
"reason": "road-to-corpus-refresh-cadence-shape step 1.2a authored one corpus file for `accessibility-auditor` (102 -> 103 of 299). Same shape as the 2026-09-30 entry and for the same reason: that step re-checked the skill's grounding corpus against WCAG 2.2 and the APG, which edited src/skills/accessibility-auditor/data/, and check_routing_coverage requires a corpus for every skill a diff touches. Ten cases -- five exemplars including the German phrasing the skill's own description names, three near-misses -- tailwind-engineer for token-level contrast and ui-component-architect for landmarks and heading order, both named in that skill's SKILL.md, plus existing-ui-audit for component inventory, which it does not name and which is included because it runs first over the same surface -- and two counterexamples, one guarding the 'accessible' homonym. The seed rises so the gain cannot be given back silently; it may never be LOWERED. The trigger-corpus holdout pin is re-taken in the same change -- and this growth moves it for the first time on the HOLDOUT side (18 -> 19), because sha256('accessibility-auditor')[0:2] is 0x2f = 47, below the ceiling of 51. That is recorded in the holdout artefact with its ordering claim explicitly scoped to the 18 originally sealed rows. The two published measurements the 2026-09-19 and 2026-09-30 entries name -- routing-body-signal-verdict.json and the measure_delivery_sets record -- are deliberately NOT re-taken here, and the departure from those two entries is stated rather than left to be noticed. The reason is the partition, not the date: this growth is HOLDOUT-side, so the train input both measurements read is byte-identical to what it was before this change -- all 84 train rows reproduce -- and re-taking them would publish the same measurement under a newer date, which is a freshness claim nothing earned. The two artefacts are NOT in the same state, and conflating them would repeat the error this sentence replaces: routing-body-signal-verdict.json carries `corpus.partition: train` and `train_corpora: 84` and is current for the train partition; delivery-set-result-2026-08-31.md still reads `82 train corpora, 764 distinct prompts` and carries no re-take section for either the 2026-09-19 or the 2026-09-30 growth, so it is two corpora stale and those two entries' claim that it `is re-taken in the same change` is not backed by the tree. Repairing it is a train-side measurement re-run, out of scope for a holdout-side growth, and is named here so the gap is attributed rather than inherited silently. A FUTURE train-side growth owes both re-takes. Separately, TWO entries were removed from trigger_eval_grandfather.json, and the two reds are of different kinds. `ui-component-architect` was red ON MAIN: it gained a corpus on 2026-09-30 and its now-false allowlist entry was not removed then, which is the convention the 2026-09-19 entry sets and the 2026-09-30 entry omitted. `accessibility-auditor` was NOT red on main -- on main it ships no corpus at all, and check_trigger_eval_presence fires only on an allowlist entry whose skill HAS one, so its entry went stale the moment this change added the corpus. That red is created here and removed here, in the same change. Stated separately because a reader auditing why two entries were dropped would otherwise be told one pre-existing condition explains both."
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"date": "2026-10-01",
|
|
79
|
+
"scope": "skills",
|
|
80
|
+
"from": 0.3445,
|
|
81
|
+
"to": 0.3579,
|
|
82
|
+
"reason": "road-to-a-trunk-whose-own-gates-are-green authored FOUR corpus files (103 -> 107 of 299) for review-routing, skill-improvement-pipeline, tailwind-engineer and design-system-capture. Same shape as the 2026-09-30 and the earlier 2026-10-01 entries and for the same reason: that branch de-links cross-pack references in those four skills, and check_routing_coverage requires a corpus for every skill a diff touches, so the files are the gate own remedy rather than a coverage push. Four at once rather than one because one de-link pass touched four grandfathered skills in a single change. Each file carries three positives including one German, two near-misses and one counterexample, with the case class declared per query because that discipline is forward-only and these are added files; the near-misses are the surfaces one step either side rather than easy negatives. The seed rises so the gain cannot be given back silently; it may never be LOWERED. Four entries were removed from trigger_eval_grandfather.json (196 -> 192), none of them red on main beforehand: the gate fires only on an allowlist entry whose skill HAS a corpus, so all four went stale the moment this change added one, and each red is created and removed in the same change. The partition split is 3 holdout / 1 train by name hash, which is why BOTH published train-side measurements the 2026-09-19 entry names are re-taken here rather than skipped the way the holdout-only growth above skipped them: routing-body-signal-verdict.json and delivery-set-measurement-2026-08-31.json both move, and the holdout pin gains three sealed rows plus a new set hash with its ordering claim explicitly NOT extended to them."
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"date": "2026-10-02",
|
|
86
|
+
"scope": "skills",
|
|
87
|
+
"from": 0.3579,
|
|
88
|
+
"to": 0.3712,
|
|
89
|
+
"reason": "road-to-stacks-beyond-php steps 1.2 and 1.4 authored FOUR corpus files (107 -> 111 of 299) for quality-tools, test-driven-development, api-testing and test-performance. Same shape as both 2026-10-01 entries and for the same reason: that lane adds one ecosystem-keyed paragraph to three skill bodies and two reference bodies under a fourth, and check_routing_coverage requires a corpus for every skill a diff touches \u2014 so the files are the gate's own remedy rather than a coverage push. Each carries exemplars in DE and EN, near-misses naming the neighbour that actually owns the adjacent job rather than easy negatives, and counterexamples for the two directions its vocabulary over-claims, with the case class declared per query. The seed rises so the gain cannot be given back silently; it may never be LOWERED. The partition split is 2 holdout / 2 train by name hash \u2014 quality-tools at 0x20 = 32 and test-performance at 0x10 = 16 seal; test-driven-development at 0x47 = 71 and api-testing at 0x67 = 103 train \u2014 so BOTH published train-side measurements are re-taken here on the terms the 2026-10-01 entries set for a train-side growth: routing-body-signal-verdict.json (verdict unchanged in kind, still `harmful`, false activation +7.35 pp against the +2.0 pp guard) and delivery-set-measurement-2026-08-31.json. The holdout pin gains two sealed rows with its ordering claim NOT extended to them, for the reason the 19th row already established: a row authored today predates nothing."
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"date": "2026-10-04",
|
|
93
|
+
"scope": "skills",
|
|
94
|
+
"from": 0.3712,
|
|
95
|
+
"to": 0.3746,
|
|
96
|
+
"reason": "road-to-corpus-refresh-cadence-shape step 1.2b authored ONE corpus file for `api-design` (111 -> 112 of 299). Same shape as the 2026-10-01 entry this roadmap's 1.2a wrote, and for the same reason: that step re-checked the skill's grounding corpus against RFC 9110/9457/7396/8288, which edited src/skills/api-design/data/, and check_routing_coverage requires a corpus for every skill a diff touches -- so the file is the gate's own remedy rather than a coverage push. Ten cases: five exemplars including the 'expose this as an endpoint' phrasing the skill's own description names and one German, three near-misses -- api-endpoint for implementing an already-designed route and api-testing for covering one, both named in that skill's SKILL.md 'Do NOT use when' block, plus openapi for documenting an existing endpoint set, which it does not name and which is included because it runs over the same endpoint list immediately after design -- and two counterexamples, one guarding the 'API' homonym (consuming a third-party interface rather than designing ours). The seed rises so the gain cannot be given back silently; it may never be LOWERED. The partition is TRAIN, not holdout: sha256('api-design')[0:2] is 0xbb = 187, above the holdout ceiling of 51, which is why BOTH published train-side measurements are re-taken here on the terms the 2026-10-01 and 2026-10-02 entries set for a train-side growth -- routing-body-signal-verdict.json and delivery-set-measurement-2026-08-31.json -- and why the holdout pin is NOT touched: its sealed rows are unchanged by a train-side addition, and re-taking it would publish the same measurement under a newer date, which is a freshness claim nothing earned. ONE entry was removed from trigger_eval_grandfather.json (192 -> 191): `api-design` was NOT red on main -- on main it ships no corpus at all, and check_trigger_eval_presence fires only on an allowlist entry whose skill HAS one, so its entry went stale the moment this change added the corpus. That red is created here and removed here, in the same change. FOUR further entries are red on that gate and are deliberately left alone, with the reason named rather than inherited silently: api-testing, quality-tools, test-driven-development and test-performance all carry a corpus on origin/main already, verified by listing that tree, so their stale allowlist entries are pre-existing debt from the 2026-10-02 growth rather than anything this change created. The gate is bound in no workflow, so none of the five blocks a pull request."
|
|
62
97
|
}
|
|
63
98
|
]
|
|
64
99
|
}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_comment": "Rule-activation ratchet baseline (road-to-mixed-trigger-activation-cost step 4.1). Two axes: the scoped/mixed ID SETS are pinned by identity, and the unconditional token total may only walk DOWN. Raising a number here to clear a failing check is the config-weakening move this repo blocks by construction — every raise needs a baseline_history entry whose reason is a real sentence. Regenerate with `check_rule_activation_census --write-baseline`; never hand-edit the counts.",
|
|
3
|
-
"measured_at_commit": "
|
|
3
|
+
"measured_at_commit": "b78ae3dbc4e328b0c91dc355e753b3ae545a1c23",
|
|
4
4
|
"tokens_exact": true,
|
|
5
|
-
"unconditional_tokens":
|
|
5
|
+
"unconditional_tokens": 116633,
|
|
6
6
|
"scoped_ids": [
|
|
7
7
|
"design-review-after-ui-write",
|
|
8
|
-
"roadmap-progress-sync",
|
|
9
8
|
"source-of-truth",
|
|
10
9
|
"ui-audit-gate"
|
|
11
10
|
],
|
|
@@ -26,6 +25,7 @@
|
|
|
26
25
|
"php-coding",
|
|
27
26
|
"provider-lifecycle-discipline",
|
|
28
27
|
"roadmap-ci-steps-policy",
|
|
28
|
+
"roadmap-progress-sync",
|
|
29
29
|
"settings-ask-protocol"
|
|
30
30
|
],
|
|
31
31
|
"baseline_history": [
|
|
@@ -48,6 +48,10 @@
|
|
|
48
48
|
{
|
|
49
49
|
"date": "2026-08-23",
|
|
50
50
|
"reason": "Re-anchored for one new rule, playbook-precedence, which ships with ADR-244's sixth context type and states that a repository's OWN configured playbook outranks a shipped skill for the same task. WHY THE DELTA IS THIS LARGE, stated rather than implied: the rule is 4,398 chars of source, but it declares seven triggers and every one of them is a keyword or phrase, so the emitter writes NO `paths:` block at all and the host loads it in every session -- the same mixed-trigger cost `ui-audit-gate` and `design-review-after-ui-write` each paid before being re-scoped to paths in road-to-mixed-trigger-activation-cost Phase 2. That is the honest reading of this number: it is not the price of the obligation, it is the price of expressing the obligation with keywords. A playbook lives at a known location, so a path-scoped form is available and would return most of these tokens; it is not cut here because the trigger set is the rule author's design decision and re-cutting it inside a merge-queue drain would change routing behaviour nobody reviewed. Recorded as the next candidate for that Phase-2 treatment rather than silently absorbed."
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"date": "2026-10-02",
|
|
54
|
+
"reason": "RE-ANCHOR for road-to-rule-triggers-and-links-that-hold step 1.1, and the moved rule is the whole point rather than a side effect. _has_non_path_trigger enumerated keyword and phrase, so a command trigger did not count: roadmap-progress-sync declares one path_prefix and three command triggers and was therefore emitted with an exclusive paths: on Claude Code, where that key is the whole gate, so its three command routes never fired. The predicate is now a negation of the two path-shaped keys. scoped 4 -> 3 and mixed 17 -> 18 are that one rule moving, and it moves in the direction that RESTORES a route rather than removing one. THE COST IS REAL AND IS NOT HIDDEN: the unconditional corpus grows 113,699 -> 116,633 exact-BPE tokens, +2,934, which is roadmap-progress-sync now loading unconditionally instead of on a path match. That is exactly the trade the roadmaps risk register anticipated (row 1, Phase 1): a rule that gains paths-less emission becomes standing text on every session, and only rules with a non-path trigger change. Paying 2,934 tokens to stop silently dropping three command routes is the trade this roadmap chose; the alternative was a rule that fires on a file touch and never on the command that is its actual subject. REVISIT IF: the thinning work lands and roadmap-progress-sync becomes a delivery-mode stub, at which point the unconditional total should fall well below this anchor rather than being re-raised."
|
|
51
55
|
}
|
|
52
56
|
]
|
|
53
57
|
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_comment": "The high-consequence rule class (road-to-rule-laws-that-can-stand Phase 2). The CRITERION lives in the `consequence_class` property of src/scripts/schemas/rule.schema.json and is the only thing that selects a member — this file is the list the criterion produced, not a list chosen first, which is why `excluded` carries a reason per row and is walked by id against the router. A rule earns a row by what its own law section obligates, never by its name or its pack. `members` is the whole class. `no_stub` is the subset whose law cannot stand in a stub today — missing, or over the 2,000-char ceiling — each with the reason; those project FULL-BODIED, which is strictly safer than a shortened copy, and the subset is what stops the class being quietly shrunk by not writing a law. A member in that state and NOT in `no_stub` fails the projection. Checked by tests/scripts/rule_consequence_class.test.ts.",
|
|
3
|
+
"criterion_ref": "src/scripts/schemas/rule.schema.json#/properties/consequence_class",
|
|
4
|
+
"members": {
|
|
5
|
+
"autonomous-execution": {
|
|
6
|
+
"clause": "authority-bypass",
|
|
7
|
+
"why": "The Hard Floor and the commit default are authority boundaries."
|
|
8
|
+
},
|
|
9
|
+
"broken-access-control": {
|
|
10
|
+
"clause": "security-boundary",
|
|
11
|
+
"why": "The law is the per-object ownership and tenant check before data is returned. Violating it hands one user another user's data."
|
|
12
|
+
},
|
|
13
|
+
"command-suggestion-policy": {
|
|
14
|
+
"clause": "authority-bypass",
|
|
15
|
+
"why": "The law is SUGGEST, NEVER INVOKE. Violating it starts a command flow the user never picked."
|
|
16
|
+
},
|
|
17
|
+
"decision-revisit-gate": {
|
|
18
|
+
"clause": "authority-bypass",
|
|
19
|
+
"why": "The law routes a reopened decision to the council by default and to the owner for the reserved set. Violating it executes an owner-reserved transition on the agent's own authority."
|
|
20
|
+
},
|
|
21
|
+
"doc-screenshot-hygiene": {
|
|
22
|
+
"clause": "irreversible-external",
|
|
23
|
+
"why": "The law calls a shipped screenshot with unredacted data an irreversible published egress, in those words."
|
|
24
|
+
},
|
|
25
|
+
"domain-safety-disclaimer": {
|
|
26
|
+
"clause": "authority-bypass",
|
|
27
|
+
"why": "The law refuses diagnosis and dosage outright and makes every advisory draft carry its disclaimer. Violating it issues a professional judgement the agent is not licensed to make."
|
|
28
|
+
},
|
|
29
|
+
"domain-safety-pii": {
|
|
30
|
+
"clause": "security-boundary",
|
|
31
|
+
"why": "The law keeps raw direct identifiers out of drafts, logs and exports. Violating it is the data exposure."
|
|
32
|
+
},
|
|
33
|
+
"domain-safety-retention": {
|
|
34
|
+
"clause": "irreversible-external",
|
|
35
|
+
"why": "The law forbids recommending deletion under audit, litigation or regulatory hold. Violating it destroys records that cannot be recovered."
|
|
36
|
+
},
|
|
37
|
+
"engineering-safety-floor": {
|
|
38
|
+
"clause": "irreversible-external",
|
|
39
|
+
"why": "The law restates the Hard Floor for deploys, production-trunk merges and production data. Every trigger it names is an action this agent cannot undo."
|
|
40
|
+
},
|
|
41
|
+
"evaluator-independence": {
|
|
42
|
+
"clause": "authority-bypass",
|
|
43
|
+
"why": "The law forbids authoring the verdict into an evaluator's prompt. Violating it manufactures the independent review a gate then relies on."
|
|
44
|
+
},
|
|
45
|
+
"fast-path-marker-visibility": {
|
|
46
|
+
"clause": "authority-bypass",
|
|
47
|
+
"why": "The marker is the only signal that a fast path resolved a decision instead of the user. Swallowing it hides the substitution."
|
|
48
|
+
},
|
|
49
|
+
"finance-safety-floor": {
|
|
50
|
+
"clause": "authority-bypass",
|
|
51
|
+
"why": "The law refuses a final invest or raise call. Violating it takes a decision the law assigns to the human."
|
|
52
|
+
},
|
|
53
|
+
"git-history-discipline": {
|
|
54
|
+
"clause": "irreversible-external",
|
|
55
|
+
"why": "The law forbids rewriting published history and dropping commits the session did not author. A force-push over someone else's work is not recoverable from here."
|
|
56
|
+
},
|
|
57
|
+
"image-likeness-and-rights": {
|
|
58
|
+
"clause": "irreversible-external",
|
|
59
|
+
"why": "The law gates a real person's likeness, a trademarked mark and a living artist's style behind explicit rights. The harm lands outside the repository and outlives the render."
|
|
60
|
+
},
|
|
61
|
+
"legal-safety-floor": {
|
|
62
|
+
"clause": "authority-bypass",
|
|
63
|
+
"why": "The law refuses a binding legal conclusion and stops outright at individual-case examination. Violating it performs regulated activity."
|
|
64
|
+
},
|
|
65
|
+
"lethal-trifecta-guard": {
|
|
66
|
+
"clause": "security-boundary",
|
|
67
|
+
"why": "The law forbids shipping private-data access, untrusted ingestion and external comms on one autonomous path. That combination is the exfiltration shape itself."
|
|
68
|
+
},
|
|
69
|
+
"low-impact-corpus-privacy-floor": {
|
|
70
|
+
"clause": "security-boundary",
|
|
71
|
+
"why": "The law is a non-bypassable redaction gate on entries that leave the project repo. It is the last check before an upstream push."
|
|
72
|
+
},
|
|
73
|
+
"question-not-instruction": {
|
|
74
|
+
"clause": "authority-bypass",
|
|
75
|
+
"why": "A question is not authorization to act — the purest authority-bypass clause in the tree."
|
|
76
|
+
},
|
|
77
|
+
"runtime-safety": {
|
|
78
|
+
"clause": "security-boundary",
|
|
79
|
+
"why": "The rule bounds what an `automated` skill may execute and which handlers are allowlisted."
|
|
80
|
+
},
|
|
81
|
+
"secret-vcs-guard": {
|
|
82
|
+
"clause": "security-boundary",
|
|
83
|
+
"why": "The law stops before a credential reaches version control. Once committed it is leaked in every clone, and only rotation undoes it."
|
|
84
|
+
},
|
|
85
|
+
"security-sensitive-stop": {
|
|
86
|
+
"clause": "security-boundary",
|
|
87
|
+
"why": "The law requires a threat pass before the first edit to auth, tenancy, billing, secrets, uploads and public endpoints. It is the gate the other security rules assume ran."
|
|
88
|
+
},
|
|
89
|
+
"session-canary": {
|
|
90
|
+
"clause": "authority-bypass",
|
|
91
|
+
"why": "The honesty clause forbids papering over a dropped canary. Faking continuity removes the user's only signal that the session is degrading, which is their decision to make."
|
|
92
|
+
},
|
|
93
|
+
"settings-ask-protocol": {
|
|
94
|
+
"clause": "authority-bypass",
|
|
95
|
+
"why": "The law calls a silent permissive default a decision taken in the user's name, and forbids it."
|
|
96
|
+
},
|
|
97
|
+
"source-confidentiality": {
|
|
98
|
+
"clause": "security-boundary",
|
|
99
|
+
"why": "The law keeps derivation attribution out of the tracked tree. A disclosure that lands in git history is not withdrawable."
|
|
100
|
+
},
|
|
101
|
+
"strategy-safety-floor": {
|
|
102
|
+
"clause": "authority-bypass",
|
|
103
|
+
"why": "The law refuses a final enter / build / buy / reorg call and names the human decision owner."
|
|
104
|
+
},
|
|
105
|
+
"tool-safety": {
|
|
106
|
+
"clause": "security-boundary",
|
|
107
|
+
"why": "The rule is the deny-by-default tool allowlist and the no-hidden-credentials floor."
|
|
108
|
+
},
|
|
109
|
+
"untrusted-input-defense": {
|
|
110
|
+
"clause": "security-boundary",
|
|
111
|
+
"why": "The law makes fetched, tool, file, RAG and MCP content data and never instructions. Violating it is how an attacker's text becomes the agent's plan."
|
|
112
|
+
},
|
|
113
|
+
"user-interrupt-priority": {
|
|
114
|
+
"clause": "authority-bypass",
|
|
115
|
+
"why": "The law stops the current task on a new instruction and asks before resuming. Silent resume continues work the user withdrew."
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
"no_stub": {
|
|
119
|
+
"autonomous-execution": {
|
|
120
|
+
"clause": "authority-bypass",
|
|
121
|
+
"why": "The Hard Floor and the commit default are authority boundaries.",
|
|
122
|
+
"reason": "No heading matching `Iron Law`: the rule states its floors under `## Hard Floor` and its bound in a fence under `## Validation-loop budget`. Promoting one of those to a law heading is authoring a law, which is a change to what the rule obligates and is out of scope for a projection change. Projects full-bodied until a law section is written deliberately."
|
|
123
|
+
},
|
|
124
|
+
"legal-safety-floor": {
|
|
125
|
+
"clause": "authority-bypass",
|
|
126
|
+
"why": "The law refuses a binding legal conclusion and stops outright at individual-case examination.",
|
|
127
|
+
"reason": "Law section is 2,023 characters, 23 over the hard ceiling, and carries a dated exception in rule-law-ceilings.json. It cannot stand in a stub until the RDG STOP block is reviewed out of the law and into the body beside it."
|
|
128
|
+
},
|
|
129
|
+
"question-not-instruction": {
|
|
130
|
+
"clause": "authority-bypass",
|
|
131
|
+
"why": "A question is not authorization to act — the purest authority-bypass clause in the tree.",
|
|
132
|
+
"reason": "No heading matching `Iron Law`: the rule opens with a bare fence under its title. The fence is the law and promoting it needs a heading, which is a rule edit rather than a projection one."
|
|
133
|
+
},
|
|
134
|
+
"runtime-safety": {
|
|
135
|
+
"clause": "security-boundary",
|
|
136
|
+
"why": "The rule bounds what an `automated` skill may execute and which handlers are allowlisted.",
|
|
137
|
+
"reason": "No heading matching `Iron Law`: the constraints are a bullet list under `## Constraints`. Named by the roadmap's own Context as one of the two sharpest cases in the 35."
|
|
138
|
+
},
|
|
139
|
+
"tool-safety": {
|
|
140
|
+
"clause": "security-boundary",
|
|
141
|
+
"why": "The rule is the deny-by-default tool allowlist and the no-hidden-credentials floor.",
|
|
142
|
+
"reason": "No heading matching `Iron Law`: the floor is stated under `## Constraints` and `## Scoped grants`. Named by the roadmap's own Context as one of the two sharpest cases in the 35."
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
"excluded": {
|
|
146
|
+
"active-remediation": "A spotted issue left unfixed costs quality and rework. Its one genuinely high-consequence branch — a live cross-user exposure — is already `broken-access-control`'s law, which is in the class.",
|
|
147
|
+
"delegation-policy": "Dispatch shape, not authority: it delegates nothing a Hard Floor would stop, and says so.",
|
|
148
|
+
"downstream-changes": "A missed caller is a broken build, which is loud and recoverable.",
|
|
149
|
+
"history-discipline": "Audit coverage is an auditability property. Its privacy interlock points at `domain-safety-pii`, which is in the class.",
|
|
150
|
+
"media-governance-routing": "A routing rule: it surfaces the project-local media policies. The rights obligation itself is `image-likeness-and-rights`, which is in the class.",
|
|
151
|
+
"media-sync-ground-truth": "The spend gate is real but the obligation its law states is a sourcing one — timing and singer come from the transcribed audio. The paid-render confirmation it builds on is `non-destructive-by-default`, a kernel rule that is never thinned.",
|
|
152
|
+
"no-attribution-footers": "An attribution footer is external but editable, so the action is not irreversible.",
|
|
153
|
+
"no-decorative-emojis-in-git-surfaces": "An emoji in a PR title or a commit subject is external but editable, and the fix is an edit rather than a rotation or a retraction. Same reason as no-attribution-footers, one surface over.",
|
|
154
|
+
"no-pr-progress-comments": "A noisy PR thread is a cost, not a boundary, and a comment can be deleted.",
|
|
155
|
+
"playbook-precedence": "Its propose-never-silently-run clause defers to the same floor `non-destructive-by-default` holds; on its own it decides which procedure to follow.",
|
|
156
|
+
"provider-lifecycle-discipline": "Tier declaration and a refuse-and-surface ask. The spend floor it defers to is a kernel rule.",
|
|
157
|
+
"scale-discipline": "An exhausted connection pool is an availability failure, not a security boundary.",
|
|
158
|
+
"senior-engineering-discipline": "The anchor that ROUTES to the invisible controls. The controls themselves are in the class; the anchor is not, or the criterion would admit every rule that mentions security.",
|
|
159
|
+
"think-before-action": "Analysis discipline. Violating it wastes work."
|
|
160
|
+
}
|
|
161
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_comment": "Per-rule law-section and body ceilings (road-to-rule-laws-that-can-stand Phase 1). SHRINK-ONLY on every axis: an id may LEAVE `missing`, never join it; a recorded exception is a ceiling the rule may fall below and never rise above. Raising one to clear a red is the config-weakening move this repo blocks by construction — `--write-baseline` refuses to raise, it only re-records the smaller of old and current. A rule at its exception is not thereby correct, only not worse. Regenerate with `lint_rule_law_section --write-baseline`; never hand-edit the counts, but DO hand-edit `owner`, `review` and `reason` — those are the review contract and the generator only seeds them.",
|
|
3
|
+
"measured_at_commit": "30f7d21f6",
|
|
4
|
+
"missing": [
|
|
5
|
+
"architecture",
|
|
6
|
+
"artifact-drafting-protocol",
|
|
7
|
+
"artifact-engagement-recording",
|
|
8
|
+
"augment-edit-discipline",
|
|
9
|
+
"autonomous-execution",
|
|
10
|
+
"cli-output-handling",
|
|
11
|
+
"commit-conventions",
|
|
12
|
+
"context-hygiene",
|
|
13
|
+
"copilot-routing",
|
|
14
|
+
"devcontainer-routing",
|
|
15
|
+
"docker-commands",
|
|
16
|
+
"external-code-graph-interop",
|
|
17
|
+
"improve-before-implement",
|
|
18
|
+
"laravel-routing",
|
|
19
|
+
"laravel-translations",
|
|
20
|
+
"linked-projects-onboarding-gate",
|
|
21
|
+
"markdown-safe-codeblocks",
|
|
22
|
+
"minimal-safe-diff",
|
|
23
|
+
"missing-tool-handling",
|
|
24
|
+
"model-recommendation",
|
|
25
|
+
"onboarding-gate",
|
|
26
|
+
"php-coding",
|
|
27
|
+
"question-not-instruction",
|
|
28
|
+
"reviewer-awareness",
|
|
29
|
+
"role-mode-adherence",
|
|
30
|
+
"rule-type-governance",
|
|
31
|
+
"runtime-safety",
|
|
32
|
+
"skill-improvement-trigger",
|
|
33
|
+
"skill-quality",
|
|
34
|
+
"slash-command-routing-policy",
|
|
35
|
+
"source-of-truth",
|
|
36
|
+
"symfony-routing",
|
|
37
|
+
"test-first",
|
|
38
|
+
"tool-safety",
|
|
39
|
+
"upstream-proposal"
|
|
40
|
+
],
|
|
41
|
+
"law_exceptions": {
|
|
42
|
+
"legal-safety-floor": {
|
|
43
|
+
"chars": 2023,
|
|
44
|
+
"owner": "agent-config-maintainer",
|
|
45
|
+
"review": "2026-12-01",
|
|
46
|
+
"reason": "Three laws a regulator reads literally (no final legal call, consent gate, council gate) plus the RDG STOP block whose wording is quoted verbatim to the user. At 2023 characters it is 23 over the ceiling, so the review is about whether the STOP block belongs in the law or beside it."
|
|
47
|
+
},
|
|
48
|
+
"preservation-guard": {
|
|
49
|
+
"chars": 2418,
|
|
50
|
+
"owner": "agent-config-maintainer",
|
|
51
|
+
"review": "2026-12-01",
|
|
52
|
+
"reason": "The law IS a checklist: each bullet names a passage class that must survive a transform, and check_condensation reads the same list. Shortening the prose would shorten the contract the gate enforces. Review target: move the reject criteria out and leave the preservation checklist."
|
|
53
|
+
},
|
|
54
|
+
"roadmap-progress-sync": {
|
|
55
|
+
"chars": 5387,
|
|
56
|
+
"owner": "agent-config-maintainer",
|
|
57
|
+
"review": "2026-12-01",
|
|
58
|
+
"reason": "Three separate Iron Laws (dashboard sync, checkbox cadence, no silent archive) plus the preservation test that resolves a deferred item. Splitting them would create three rules with one trigger set; collapsing them would drop an obligation. Review target: move the resolution procedure under Iron Law 3 behind load_context and keep the three laws."
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"body_exceptions": {
|
|
62
|
+
"code-provenance": {
|
|
63
|
+
"chars": 8106,
|
|
64
|
+
"owner": "agent-config-maintainer",
|
|
65
|
+
"review": "2026-12-01",
|
|
66
|
+
"reason": "Two layers (code borrows and the knowledge/harvest layer) each with its own law, plus the no-CI-detector honesty section recording a measured gate decision."
|
|
67
|
+
},
|
|
68
|
+
"context-hygiene": {
|
|
69
|
+
"chars": 8320,
|
|
70
|
+
"owner": "agent-config-maintainer",
|
|
71
|
+
"review": "2026-12-01",
|
|
72
|
+
"reason": "Carries the freshness ladder, the 3-failure rule, loop detection and the 15/25 read-loop rule, each with its own self-check. Already migrated once into context-hygiene-mechanics and re-grew."
|
|
73
|
+
},
|
|
74
|
+
"decision-revisit-gate": {
|
|
75
|
+
"chars": 8566,
|
|
76
|
+
"owner": "agent-config-maintainer",
|
|
77
|
+
"review": "2026-12-01",
|
|
78
|
+
"reason": "The largest rule in the tree. Carries the five-step gate, the two descriptive axes, the owner-reserved table and an honest-enforcement section. Phase 1.4 of road-to-rule-laws-that-can-stand names it as a first mover for the load_context split."
|
|
79
|
+
},
|
|
80
|
+
"design-fidelity": {
|
|
81
|
+
"chars": 8777,
|
|
82
|
+
"owner": "agent-config-maintainer",
|
|
83
|
+
"review": "2026-12-01",
|
|
84
|
+
"reason": "Carries the artefact-maturity axis, the fidelity-mode table and the routing matrix. Phase 1.4 names it as a first mover."
|
|
85
|
+
},
|
|
86
|
+
"roadmap-progress-sync": {
|
|
87
|
+
"chars": 9308,
|
|
88
|
+
"owner": "agent-config-maintainer",
|
|
89
|
+
"review": "2026-12-01",
|
|
90
|
+
"reason": "Three laws plus the deferred-item resolution procedure and the later/PR-gate dispositions. The dispositions are mechanism, not obligation, and are the load_context candidate."
|
|
91
|
+
},
|
|
92
|
+
"settings-ask-protocol": {
|
|
93
|
+
"chars": 8099,
|
|
94
|
+
"owner": "agent-config-maintainer",
|
|
95
|
+
"review": "2026-12-01",
|
|
96
|
+
"reason": "Carries the four slots, the seven keys, the non-interactive rule and the consent-verdict contract. The key inventory is reference material and is the load_context candidate."
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -188,6 +188,21 @@ export interface ClaudePathsPlan {
|
|
|
188
188
|
dropped: { pattern: string; reason: 'unresolved-placeholder' | 'over-budget' | 'mixed-triggers' }[];
|
|
189
189
|
}
|
|
190
190
|
|
|
191
|
+
/**
|
|
192
|
+
* The two trigger keys `derive_trigger_globs` turns into a host glob. Kept
|
|
193
|
+
* beside it deliberately: the day a third path-shaped key is added there, this
|
|
194
|
+
* set is the other half of the same edit, and a reader looking at either one
|
|
195
|
+
* sees the pair.
|
|
196
|
+
*/
|
|
197
|
+
const PATH_SHAPED_TRIGGER_KEYS: ReadonlySet<string> = new Set(['file_pattern', 'path_prefix']);
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Keys on a trigger object that match nothing. `reason:` documents why the
|
|
201
|
+
* trigger exists; counting it would make every annotated path trigger look
|
|
202
|
+
* mixed and scope nothing at all.
|
|
203
|
+
*/
|
|
204
|
+
const NON_MATCHING_TRIGGER_KEYS: ReadonlySet<string> = new Set(['reason']);
|
|
205
|
+
|
|
191
206
|
/**
|
|
192
207
|
* Does this rule declare any trigger that is NOT path-shaped?
|
|
193
208
|
*
|
|
@@ -199,6 +214,18 @@ export interface ClaudePathsPlan {
|
|
|
199
214
|
* rule loads unconditionally. The emitter fed both semantics from one list, so
|
|
200
215
|
* a rule that declared keywords *and* one path glob silently became
|
|
201
216
|
* path-gated-only on Claude.
|
|
217
|
+
*
|
|
218
|
+
* **The test is a negation, not a list of non-path kinds**, and the difference
|
|
219
|
+
* is not stylistic. The predicate used to enumerate `keyword` and `phrase`,
|
|
220
|
+
* which left `command` — a prompt route like any other — uncounted:
|
|
221
|
+
* `roadmap-progress-sync` declares one `path_prefix` and three `command`
|
|
222
|
+
* triggers, so it was emitted with an exclusive `paths:` and its three command
|
|
223
|
+
* routes never fired on this host. A list can only ever be as current as its
|
|
224
|
+
* last edit; the schema's `additionalProperties: false` means a new match key
|
|
225
|
+
* arrives as a deliberate schema change, and until someone teaches
|
|
226
|
+
* `derive_trigger_globs` to make a glob from it, treating it as promptable is
|
|
227
|
+
* the fail-safe reading — the rule stays unconditional rather than silently
|
|
228
|
+
* narrowing to a path it does not have.
|
|
202
229
|
*/
|
|
203
230
|
export function _has_non_path_trigger(meta: Record<string, unknown>): boolean {
|
|
204
231
|
const triggers = meta['triggers'];
|
|
@@ -206,8 +233,21 @@ export function _has_non_path_trigger(meta: Record<string, unknown>): boolean {
|
|
|
206
233
|
for (const t of triggers) {
|
|
207
234
|
if (t === null || typeof t !== 'object' || Array.isArray(t)) continue;
|
|
208
235
|
const obj = t as Record<string, unknown>;
|
|
209
|
-
|
|
210
|
-
|
|
236
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
237
|
+
if (PATH_SHAPED_TRIGGER_KEYS.has(key) || NON_MATCHING_TRIGGER_KEYS.has(key)) continue;
|
|
238
|
+
// A string that is not blank, or ANY non-string value. The schema
|
|
239
|
+
// types all five match keys as strings today, so the second half is
|
|
240
|
+
// for the key that arrives later: a `keyword: ["a","b"]` read as
|
|
241
|
+
// "not a string, so not a trigger" would silently narrow the rule
|
|
242
|
+
// to a path it does not have, which is the exact failure the
|
|
243
|
+
// negation above exists to prevent. Undefined and null are the one
|
|
244
|
+
// shape that means "absent".
|
|
245
|
+
if (typeof value === 'string') {
|
|
246
|
+
if (value.trim() !== '') return true;
|
|
247
|
+
} else if (value !== undefined && value !== null) {
|
|
248
|
+
return true;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
211
251
|
}
|
|
212
252
|
return false;
|
|
213
253
|
}
|
|
@@ -230,8 +270,10 @@ export function _claude_paths_plan(meta: Record<string, unknown>): ClaudePathsPl
|
|
|
230
270
|
const globs: string[] = [];
|
|
231
271
|
const dropped: ClaudePathsPlan['dropped'] = [];
|
|
232
272
|
|
|
233
|
-
// A rule that ALSO declares
|
|
234
|
-
//
|
|
273
|
+
// A rule that ALSO declares a non-path trigger — keyword, phrase, command,
|
|
274
|
+
// or a match key added to the schema later — gets no `paths:` at all, and
|
|
275
|
+
// therefore keeps loading unconditionally on Claude Code. The predicate is
|
|
276
|
+
// a negation of the two path-shaped keys, deliberately: see its docblock.
|
|
235
277
|
//
|
|
236
278
|
// Emitting `paths:` here would narrow the rule to a path match and discard
|
|
237
279
|
// every keyword the author wrote, because this host reads the list as the
|
|
@@ -132,7 +132,7 @@ export function rewriteAndReport(
|
|
|
132
132
|
quiet: boolean,
|
|
133
133
|
info: (m: string) => void,
|
|
134
134
|
warn: (m: string) => void,
|
|
135
|
-
wrappers?: { wrapped: readonly string[]; reserved: readonly string[] },
|
|
135
|
+
wrappers?: { wrapped: readonly string[]; reserved: readonly string[]; foreign?: readonly string[] },
|
|
136
136
|
preserved: ReadonlySet<string> = new Set(),
|
|
137
137
|
): ClaudeRuleRewriteResult {
|
|
138
138
|
const result = rewriteClaudeRules(rulesDir, preserved);
|
|
@@ -157,6 +157,15 @@ export function rewriteAndReport(
|
|
|
157
157
|
'commands remain available',
|
|
158
158
|
);
|
|
159
159
|
}
|
|
160
|
+
if (wrappers.foreign !== undefined && wrappers.foreign.length > 0) {
|
|
161
|
+
// Reported, never removed. The name shadows a host built-in, but
|
|
162
|
+
// this package did not write the file, so deleting it would be
|
|
163
|
+
// taking a neighbour's command away without saying so.
|
|
164
|
+
info(
|
|
165
|
+
` claude-code: kept ${wrappers.foreign.length} neighbour command file(s) whose ` +
|
|
166
|
+
`name is a Claude Code built-in (${wrappers.foreign.join(', ')}); not ours to remove`,
|
|
167
|
+
);
|
|
168
|
+
}
|
|
160
169
|
}
|
|
161
170
|
if (result.rewritten > 0 && !quiet) {
|
|
162
171
|
info(
|
|
@@ -44,6 +44,14 @@ import {
|
|
|
44
44
|
_emit_windsurf_rule,
|
|
45
45
|
strip_frontmatter,
|
|
46
46
|
} from '../scripts/condense.js';
|
|
47
|
+
import {
|
|
48
|
+
WINDSURFRULES_HEADER,
|
|
49
|
+
cleanOwnedOnly,
|
|
50
|
+
keptLine,
|
|
51
|
+
mayWriteRuleFile,
|
|
52
|
+
mayWriteWindsurfRules,
|
|
53
|
+
ownedPaths,
|
|
54
|
+
} from './host_rule_ownership.js';
|
|
47
55
|
|
|
48
56
|
function _ruleFiles(rulesDir: string): string[] {
|
|
49
57
|
return fs
|
|
@@ -60,63 +68,64 @@ function _ruleFiles(rulesDir: string): string[] {
|
|
|
60
68
|
});
|
|
61
69
|
}
|
|
62
70
|
|
|
63
|
-
/** Remove entries not in `valid` (mirror of condense's `_clean_modern_dir`). */
|
|
64
|
-
function _cleanDir(dir: string, valid: ReadonlySet<string>): void {
|
|
65
|
-
let entries: string[];
|
|
66
|
-
try {
|
|
67
|
-
entries = fs.readdirSync(dir);
|
|
68
|
-
} catch {
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
for (const name of entries) {
|
|
72
|
-
if (name === 'README.md' || valid.has(name)) {
|
|
73
|
-
continue;
|
|
74
|
-
}
|
|
75
|
-
const full = path.join(dir, name);
|
|
76
|
-
try {
|
|
77
|
-
if (fs.lstatSync(full).isDirectory()) {
|
|
78
|
-
fs.rmSync(full, { recursive: true, force: true });
|
|
79
|
-
} else {
|
|
80
|
-
fs.unlinkSync(full);
|
|
81
|
-
}
|
|
82
|
-
} catch {
|
|
83
|
-
/* best-effort clean */
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
71
|
export function emitCursor(rulesDir: string, projectRoot: string): number {
|
|
89
72
|
const targetDir = path.join(projectRoot, '.cursor', 'rules');
|
|
90
73
|
const files = _ruleFiles(rulesDir);
|
|
74
|
+
const owned = ownedPaths(projectRoot);
|
|
91
75
|
const valid = new Set<string>();
|
|
76
|
+
let blocked = 0;
|
|
92
77
|
for (const src of files) {
|
|
93
78
|
const name = `${path.basename(src, '.md')}.mdc`;
|
|
94
|
-
|
|
79
|
+
const target = path.join(targetDir, name);
|
|
80
|
+
// Ownership BEFORE the write: a neighbour's file under one of our
|
|
81
|
+
// names would otherwise be destroyed and then skipped by the cleanup
|
|
82
|
+
// pass, which only looks at names this run did not emit.
|
|
83
|
+
if (!mayWriteRuleFile(target, owned)) {
|
|
84
|
+
blocked += 1;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
_emit_cursor_mdc(src, target);
|
|
95
88
|
valid.add(name);
|
|
96
89
|
}
|
|
97
|
-
|
|
90
|
+
const { kept } = cleanOwnedOnly(targetDir, valid, owned);
|
|
91
|
+
const line = keptLine(kept + blocked);
|
|
92
|
+
if (line !== null) process.stdout.write(`cursor: ${line}\n`);
|
|
98
93
|
return files.length;
|
|
99
94
|
}
|
|
100
95
|
|
|
101
96
|
export function emitWindsurf(rulesDir: string, projectRoot: string): number {
|
|
102
97
|
const perRuleDir = path.join(projectRoot, '.windsurf', 'rules');
|
|
103
98
|
const files = _ruleFiles(rulesDir);
|
|
99
|
+
const owned = ownedPaths(projectRoot);
|
|
104
100
|
const valid = new Set<string>();
|
|
101
|
+
let blocked = 0;
|
|
105
102
|
for (const src of files) {
|
|
106
103
|
const name = path.basename(src);
|
|
107
|
-
|
|
104
|
+
const target = path.join(perRuleDir, name);
|
|
105
|
+
if (!mayWriteRuleFile(target, owned)) {
|
|
106
|
+
blocked += 1;
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
_emit_windsurf_rule(src, target);
|
|
108
110
|
valid.add(name);
|
|
109
111
|
}
|
|
110
|
-
|
|
112
|
+
const { kept } = cleanOwnedOnly(perRuleDir, valid, owned);
|
|
113
|
+
const line = keptLine(kept + blocked);
|
|
114
|
+
if (line !== null) process.stdout.write(`windsurf: ${line}\n`);
|
|
111
115
|
|
|
112
116
|
// Concatenated legacy surface — same format as the projection-path
|
|
113
117
|
// generator (condense.generate_windsurfrules), consumer-sourced header.
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
+
const target = path.join(projectRoot, '.windsurfrules');
|
|
119
|
+
if (mayWriteWindsurfRules(target, owned)) {
|
|
120
|
+
const parts = [`${WINDSURFRULES_HEADER}\n`];
|
|
121
|
+
for (const src of files) {
|
|
122
|
+
const content = strip_frontmatter(fs.readFileSync(src, 'utf-8'));
|
|
123
|
+
parts.push(`---\n\n${content.trim()}\n`);
|
|
124
|
+
}
|
|
125
|
+
fs.writeFileSync(target, parts.join('\n') + '\n', 'utf-8');
|
|
126
|
+
} else {
|
|
127
|
+
process.stdout.write('windsurf: kept: 1 neighbour file(s) (.windsurfrules)\n');
|
|
118
128
|
}
|
|
119
|
-
fs.writeFileSync(path.join(projectRoot, '.windsurfrules'), parts.join('\n') + '\n', 'utf-8');
|
|
120
129
|
return files.length;
|
|
121
130
|
}
|
|
122
131
|
|