@event4u/agent-config 14.10.0 → 14.12.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 +161 -208
- package/README.md +1 -1
- package/dist/agent-src/commands/design.md +88 -0
- package/dist/agent-src/commands/project/analyze.md +47 -0
- package/dist/agent-src/commands/review/changes.md +67 -6
- package/dist/agent-src/commands/roadmap/create.md +49 -0
- package/dist/agent-src/commands/roadmap/next.md +27 -11
- package/dist/agent-src/commands/roadmap/process-full.md +14 -0
- package/dist/agent-src/commands/video/from-script.md +60 -3
- package/dist/agent-src/commands/video/stitch.md +14 -0
- package/dist/agent-src/contexts/communication/rules-auto/guidelines-mechanics.md +1 -0
- package/dist/agent-src/contexts/execution/evidence-discipline.md +26 -0
- package/dist/agent-src/contexts/execution/roadmap-process-loop.md +154 -2
- package/dist/agent-src/rules/active-remediation.md +3 -3
- package/dist/agent-src/rules/code-provenance.md +2 -2
- package/dist/agent-src/rules/context-hygiene.md +13 -33
- package/dist/agent-src/rules/council-availability.md +2 -2
- package/dist/agent-src/rules/decision-revisit-gate.md +3 -1
- package/dist/agent-src/rules/design-fidelity.md +18 -0
- package/dist/agent-src/rules/design-review-after-ui-write.md +2 -2
- package/dist/agent-src/rules/evaluator-independence.md +56 -44
- package/dist/agent-src/rules/fix-what-you-see.md +9 -1
- package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +1 -1
- package/dist/agent-src/rules/minimal-safe-diff.md +14 -20
- package/dist/agent-src/rules/missing-skill-recovery.md +13 -1
- package/dist/agent-src/rules/playbook-precedence.md +105 -0
- package/dist/agent-src/rules/recurring-criticism.md +3 -1
- package/dist/agent-src/rules/roadmap-progress-sync.md +14 -13
- package/dist/agent-src/rules/scale-discipline.md +24 -0
- package/dist/agent-src/rules/security-sensitive-stop.md +2 -2
- package/dist/agent-src/rules/settings-ask-protocol.md +2 -2
- package/dist/agent-src/rules/ui-audit-gate.md +27 -15
- package/dist/agent-src/rules/untrusted-input-defense.md +2 -2
- package/dist/agent-src/skills/accessibility-auditor/SKILL.md +19 -0
- package/dist/agent-src/skills/adr-create/SKILL.md +7 -0
- package/dist/agent-src/skills/agents-md-thin-root/SKILL.md +33 -0
- package/dist/agent-src/skills/ai-council/references/advanced-modes.md +17 -3
- package/dist/agent-src/skills/ai-council/references/output-and-synthesis.md +31 -0
- package/dist/agent-src/skills/ai-council/references/procedure.md +19 -0
- package/dist/agent-src/skills/alerting-doctrine/SKILL.md +225 -0
- package/dist/agent-src/skills/authz-review/SKILL.md +0 -1
- package/dist/agent-src/skills/blast-radius-analyzer/SKILL.md +32 -0
- package/dist/agent-src/skills/brand/SKILL.md +3 -0
- package/dist/agent-src/skills/brand-asset-generation/SKILL.md +3 -0
- package/dist/agent-src/skills/brand-audit/SKILL.md +3 -0
- package/dist/agent-src/skills/brand-identity/SKILL.md +3 -0
- package/dist/agent-src/skills/brand-strategy/SKILL.md +3 -0
- package/dist/agent-src/skills/brand-to-tokens/SKILL.md +3 -0
- package/dist/agent-src/skills/check-refs/SKILL.md +3 -0
- package/dist/agent-src/skills/code-refactoring/SKILL.md +45 -1
- package/dist/agent-src/skills/code-review/SKILL.md +75 -5
- package/dist/agent-src/skills/command-routing/SKILL.md +6 -0
- package/dist/agent-src/skills/command-writing/SKILL.md +35 -0
- package/dist/agent-src/skills/condense-memory/SKILL.md +3 -0
- package/dist/agent-src/skills/context-authoring/SKILL.md +1 -1
- package/dist/agent-src/skills/conventional-commits-writing/SKILL.md +3 -0
- package/dist/agent-src/skills/copilot-agents-optimization/SKILL.md +10 -0
- package/dist/agent-src/skills/corpus-grounding/SKILL.md +3 -0
- package/dist/agent-src/skills/design-intelligence/SKILL.md +3 -0
- package/dist/agent-src/skills/design-intelligence/data/landing.csv +36 -35
- package/dist/agent-src/skills/design-intelligence/data/stacks/threejs.csv +1 -0
- package/dist/agent-src/skills/design-review/SKILL.md +79 -1
- package/dist/agent-src/skills/design-review/references/verification-automation.md +41 -0
- package/dist/agent-src/skills/design-system-capture/SKILL.md +35 -40
- package/dist/agent-src/skills/design-system-capture/references/import-procedure.md +50 -0
- package/dist/agent-src/skills/design-tokens/SKILL.md +3 -0
- package/dist/agent-src/skills/design-variations/SKILL.md +3 -0
- package/dist/agent-src/skills/developer-like-execution/SKILL.md +3 -0
- package/dist/agent-src/skills/estimate-ticket/SKILL.md +3 -0
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +28 -4
- package/dist/agent-src/skills/fe-design/SKILL.md +74 -41
- package/dist/agent-src/skills/fe-design/references/craft-floor.md +52 -0
- package/dist/agent-src/skills/fe-design/references/source-led-port.md +36 -0
- package/dist/agent-src/skills/file-editor/SKILL.md +5 -0
- package/dist/agent-src/skills/finishing-a-development-branch/SKILL.md +2 -2
- package/dist/agent-src/skills/git-workflow/SKILL.md +3 -0
- package/dist/agent-src/skills/html-deck/SKILL.md +3 -0
- package/dist/agent-src/skills/iconography/SKILL.md +3 -0
- package/dist/agent-src/skills/image-editing/SKILL.md +3 -0
- package/dist/agent-src/skills/image-generation/SKILL.md +3 -0
- package/dist/agent-src/skills/image-provider-routing/SKILL.md +3 -0
- package/dist/agent-src/skills/incident-commander/SKILL.md +10 -0
- package/dist/agent-src/skills/js-library-packaging/SKILL.md +173 -0
- package/dist/agent-src/skills/js-library-packaging/scripts/check_package_surface.ts +270 -0
- package/dist/agent-src/skills/laravel-migration/SKILL.md +3 -0
- package/dist/agent-src/skills/learning-to-rule-or-skill/SKILL.md +3 -0
- package/dist/agent-src/skills/lint-skills/SKILL.md +3 -0
- package/dist/agent-src/skills/llm-provider-knowledge/SKILL.md +3 -0
- package/dist/agent-src/skills/logging-monitoring/SKILL.md +234 -51
- package/dist/agent-src/skills/logo-generation/SKILL.md +3 -0
- package/dist/agent-src/skills/md-language-check/SKILL.md +3 -0
- package/dist/agent-src/skills/monorepo-workspace/SKILL.md +149 -0
- package/dist/agent-src/skills/motion-choreographer/SKILL.md +6 -0
- package/dist/agent-src/skills/multi-tenancy/SKILL.md +4 -0
- package/dist/agent-src/skills/operational-readiness/SKILL.md +184 -0
- package/dist/agent-src/skills/override-management/SKILL.md +3 -0
- package/dist/agent-src/skills/persona-improvement/SKILL.md +3 -0
- package/dist/agent-src/skills/pest-testing/SKILL.md +3 -0
- package/dist/agent-src/skills/playbook-authoring/SKILL.md +162 -0
- package/dist/agent-src/skills/playwright-testing/SKILL.md +3 -0
- package/dist/agent-src/skills/privacy-review/SKILL.md +3 -0
- package/dist/agent-src/skills/project-analysis-core/SKILL.md +23 -0
- package/dist/agent-src/skills/prompt-engineering-image/SKILL.md +3 -0
- package/dist/agent-src/skills/quality-tools/SKILL.md +5 -0
- package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +81 -33
- package/dist/agent-src/skills/readme-reviewer/SKILL.md +3 -0
- package/dist/agent-src/skills/readme-writing/SKILL.md +3 -0
- package/dist/agent-src/skills/readme-writing-package/SKILL.md +3 -0
- package/dist/agent-src/skills/receiving-code-review/SKILL.md +2 -2
- package/dist/agent-src/skills/refine-prompt/SKILL.md +3 -0
- package/dist/agent-src/skills/refine-ticket/SKILL.md +3 -0
- package/dist/agent-src/skills/requesting-code-review/SKILL.md +2 -2
- package/dist/agent-src/skills/review-routing/SKILL.md +2 -2
- package/dist/agent-src/skills/roadmap-writing/SKILL.md +23 -41
- package/dist/agent-src/skills/roadmap-writing/references/follow-up-roadmap-shape.md +47 -0
- package/dist/agent-src/skills/rtk-output-filtering/SKILL.md +22 -6
- package/dist/agent-src/skills/runway-cognition/SKILL.md +3 -0
- package/dist/agent-src/skills/scene-expander/scene-blueprint.schema.yaml +26 -0
- package/dist/agent-src/skills/secrets-management/SKILL.md +4 -0
- package/dist/agent-src/skills/server-hardening/SKILL.md +159 -0
- package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +3 -0
- package/dist/agent-src/skills/skill-management/SKILL.md +3 -0
- package/dist/agent-src/skills/skill-reviewer/SKILL.md +3 -0
- package/dist/agent-src/skills/skill-writing/SKILL.md +6 -0
- package/dist/agent-src/skills/skill-writing/references/procedure.md +24 -2
- package/dist/agent-src/skills/spreadsheet-authoring/SKILL.md +3 -0
- package/dist/agent-src/skills/storybook-workshop/SKILL.md +203 -0
- package/dist/agent-src/skills/storybook-workshop/scripts/story_contrast_floor.ts +134 -0
- package/dist/agent-src/skills/subagent-orchestration/SKILL.md +1 -1
- package/dist/agent-src/skills/subagent-orchestration/prompts/README.md +25 -0
- package/dist/agent-src/skills/supply-chain-intake/SKILL.md +12 -0
- package/dist/agent-src/skills/systematic-debugging/SKILL.md +1 -1
- package/dist/agent-src/skills/terraform/SKILL.md +3 -0
- package/dist/agent-src/skills/test-driven-development/SKILL.md +1 -1
- package/dist/agent-src/skills/threat-modeling/SKILL.md +0 -3
- package/dist/agent-src/skills/token-optimizer/SKILL.md +3 -0
- package/dist/agent-src/skills/typography-system/SKILL.md +3 -0
- package/dist/agent-src/skills/ui-component-architect/SKILL.md +17 -1
- package/dist/agent-src/skills/upstream-contribute/SKILL.md +3 -0
- package/dist/agent-src/skills/validate-feature-fit/SKILL.md +3 -0
- package/dist/agent-src/skills/verify-completion-evidence/SKILL.md +2 -2
- package/dist/agent-src/skills/wireframe/SKILL.md +3 -0
- package/dist/agent-src/skills/wireframe/references/story-beat-ledger.schema.json +115 -0
- package/dist/agent-src/skills/workspace-link/SKILL.md +131 -0
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/playbook.md +75 -0
- package/dist/agent-src/templates/roadmaps.md +37 -0
- package/dist/agent-src/templates/scripts/check_playbook_invokes.ts +231 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +24 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +2 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/review.ts +216 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/scaffold.ts +159 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/stack_bundles.ts +73 -4
- package/dist/agent-src/templates/scripts/work_engine/stack/detect.ts +325 -40
- package/dist/cli/commands/uiAudit.js +221 -0
- package/dist/cli/commands/uiRender.js +206 -0
- package/dist/cli/main.js +22 -1
- package/dist/cli/mcp/content.js +64 -1
- package/dist/cli/mcp/dispatch.js +175 -10
- package/dist/cli/registry.js +3 -0
- package/dist/cli-delegate/{chunk-G23AT6GD.js → chunk-DMSZHXZS.js} +57 -1
- package/dist/cli-delegate/{chunk-77GR3VD4.js → chunk-FF7WAFMR.js} +58 -3
- package/dist/cli-delegate/{chunk-YM4GZDJG.js → chunk-JCW7ZLHK.js} +10 -0
- package/dist/cli-delegate/{chunk-H4VIVD4C.js → chunk-JJA2QEWA.js} +413 -391
- package/dist/cli-delegate/{chunk-PLSG6UL5.js → chunk-K4FFODTS.js} +341 -204
- package/dist/cli-delegate/{chunk-B2ERU2VA.js → chunk-WOKWX5PL.js} +1 -1
- package/dist/cli-delegate/cmd_brand_status.js +8 -6
- package/dist/cli-delegate/cmd_conformance.js +3 -3
- package/dist/cli-delegate/cmd_doctor.js +3 -3
- package/dist/cli-delegate/cmd_export.js +4 -4
- package/dist/cli-delegate/cmd_handoff.js +1 -1
- package/dist/cli-delegate/cmd_preflight.js +2 -2
- package/dist/cli-delegate/cmd_prune.js +4 -4
- package/dist/cli-delegate/cmd_session_recycle.js +70 -9
- package/dist/cli-delegate/cmd_settings_migrate.js +4 -4
- package/dist/cli-delegate/cmd_settings_set.js +1 -1
- package/dist/cli-delegate/cmd_sync.js +4 -4
- package/dist/cli-delegate/cmd_uninstall.js +4 -4
- package/dist/cli-delegate/cmd_validate.js +4 -4
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +362 -127
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +4 -4
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +18 -8
- package/dist/discovery/trust-report.md +3 -3
- package/dist/discovery/workspaces.json +16 -6
- package/dist/hooks/dispatch.js +2575 -1472
- package/dist/install/install.mjs +800 -708
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +1685 -1250
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/lean_projection_mode.js +40 -0
- package/dist/scripts/_lib/scoped_projection.js +84 -0
- package/dist/scripts/_lib/ui_surface.js +89 -0
- package/dist/scripts/condense.js +6 -10
- package/dist/scripts/project_thin_rules.js +40 -2
- package/dist/server/schemas/settings.js +6 -0
- package/dist/shared/skillRanking.js +159 -0
- package/docs/contracts/provider-lifecycle.md +47 -18
- package/docs/contracts/settings-classes.md +35 -5
- package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +49 -0
- package/docs/guidelines/agent-infra/downstream-changes-mechanics.md +91 -0
- package/docs/guidelines/agent-infra/evaluator-independence-mechanics.md +92 -0
- package/docs/guidelines/agent-infra/minimal-safe-diff-mechanics.md +45 -1
- package/docs/guidelines/agent-infra/roadmap-deferred-resolution-provenance.md +54 -0
- package/docs/guidelines/code-clarity.md +21 -0
- package/docs/guidelines/design-antipatterns.md +4 -2
- package/docs/guidelines/design-asset-discipline.md +38 -0
- package/docs/guidelines/design-fidelity-mechanics.md +45 -29
- package/docs/guidelines/design-handover-extraction.md +35 -5
- package/docs/guidelines/design-modes.md +41 -1
- package/docs/guidelines/monorepo-antipatterns.md +141 -0
- package/docs/guidelines/redundancy-taxonomy.md +180 -0
- package/llms.txt +50 -39
- package/package.json +6 -2
- package/src/agent-src/templates/scripts/check_playbook_invokes.ts +231 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +24 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +2 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui/review.ts +216 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui/scaffold.ts +159 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui/stack_bundles.ts +73 -4
- package/src/agent-src/templates/scripts/work_engine/stack/detect.ts +325 -40
- package/src/config/agent-settings.template.yml +44 -0
- package/src/config/assurance-capability-registry.json +223 -0
- package/src/config/assurance-threshold-budget.json +65 -0
- package/src/config/budgets.yml +19 -0
- package/src/config/ci-local-parity.yml +29 -0
- package/src/config/discovery/prompt-patterns.yml +56 -0
- package/src/config/discovery/unassigned-artefacts.yml +2 -0
- package/src/config/dispatch-economy-metrics.json +4 -2
- package/src/config/estate-count-budget.json +8 -3
- package/src/config/evaluator-budgets.json +14 -14
- package/src/config/gate-coverage.yml +392 -8
- package/src/config/gate-violation-baselines.json +76 -72
- package/src/config/hook-latency-budget.json +1 -0
- package/src/config/hook-token-budget.json +137 -125
- package/src/config/pack-size-budget.json +39 -10
- package/src/config/preamble-payload-budget.json +97 -71
- package/src/config/quorum-attendance-budget.json +12 -4
- package/src/config/routing-coverage-seed.json +29 -0
- package/src/config/rule-activation-census.json +7 -3
- package/src/config/rule-enforcement-baseline.json +0 -1
- package/src/config/rule-stub-ceilings.json +112 -91
- package/src/config/suggestion-capture.json +28 -0
- package/src/config/surface-matrix.yml +21 -2
- package/src/config/web-launch-readiness.json +188 -0
- package/src/scripts/_cli/cmd_doctor.ts +15 -16
- package/src/scripts/_cli/doctor_install_mode.ts +49 -0
- package/src/scripts/_cli/doctor_overrides.ts +154 -0
- package/src/scripts/_dispatch.bash +17 -0
- package/src/scripts/_lib/as_of.ts +412 -0
- package/src/scripts/_lib/exec_evidence.ts +7 -0
- package/src/scripts/_lib/gate_baseline.ts +150 -1
- package/src/scripts/_lib/hook_settings.ts +33 -0
- package/src/scripts/_lib/host_listing_model.ts +192 -0
- package/src/scripts/_lib/lean_projection_mode.ts +44 -0
- package/src/scripts/_lib/mcp_bridge.ts +199 -0
- package/src/scripts/_lib/review_independence.ts +62 -10
- package/src/scripts/_lib/rule_injection.ts +239 -0
- package/src/scripts/_lib/run_checkpoint.ts +54 -1
- package/src/scripts/_lib/scoped_projection.ts +96 -0
- package/src/scripts/_lib/session_register.ts +44 -2
- package/src/scripts/_lib/skill_catalogue.ts +38 -2
- package/src/scripts/_lib/skill_estate.ts +115 -0
- package/src/scripts/_lib/transcript_reads.ts +207 -0
- package/src/scripts/_lib/ui_authority.ts +343 -0
- package/src/scripts/ai-video/adapters/fal.sh +8 -3
- package/src/scripts/ai-video/adapters/gemini-veo.sh +10 -0
- package/src/scripts/ai-video/adapters/higgsfield.sh +10 -2
- package/src/scripts/ai-video/adapters/kling.sh +10 -0
- package/src/scripts/ai-video/adapters/sora.sh +10 -0
- package/src/scripts/ai-video/lib/calibrate-cost.sh +145 -0
- package/src/scripts/ai-video/lib/model-capabilities/README.md +53 -7
- package/src/scripts/ai-video/lib/model-capabilities/comfyui.json +15 -3
- package/src/scripts/ai-video/lib/model-capabilities/fal.json +36 -6
- package/src/scripts/ai-video/lib/model-capabilities/gemini-veo.json +23 -0
- package/src/scripts/ai-video/lib/model-capabilities/higgsfield.json +23 -0
- package/src/scripts/ai-video/lib/model-capabilities/kling.json +23 -0
- package/src/scripts/ai-video/lib/model-capabilities/musetalk.json +8 -2
- package/src/scripts/ai-video/lib/model-capabilities/replicate.json +36 -6
- package/src/scripts/ai-video/lib/model-capabilities/sora.json +45 -0
- package/src/scripts/ai-video/lib/model-capabilities/syncso.json +8 -2
- package/src/scripts/ai-video/lib/parse-blueprint.sh +52 -5
- package/src/scripts/ai-video/lib/resume-scan.sh +92 -3
- package/src/scripts/ai-video/lib/seam-plan.sh +212 -0
- package/src/scripts/ai-video/smoke-trace.sh +450 -2
- package/src/scripts/ai-video/stitch.sh +191 -10
- package/src/scripts/ai-video/test-pipeline.sh +84 -6
- package/src/scripts/ai_council/argument_exhaustion.ts +130 -0
- package/src/scripts/ai_council/cli_agency_bounds.ts +139 -0
- package/src/scripts/ai_council/cli_least_agency_canary.ts +347 -0
- package/src/scripts/ai_council/clients.ts +3 -2
- package/src/scripts/ai_council/consensus.ts +63 -6
- package/src/scripts/ai_council/events_log.ts +46 -1
- package/src/scripts/ai_council/orchestrator.ts +103 -108
- package/src/scripts/ai_council/orchestrator_results.ts +166 -0
- package/src/scripts/ai_council/prompts.ts +12 -5
- package/src/scripts/ai_council/quorum.ts +82 -1
- package/src/scripts/ai_council/quorum_wiring.ts +82 -5
- package/src/scripts/ai_council/stance_tally.ts +22 -0
- package/src/scripts/bench_hook_latency.ts +62 -0
- package/src/scripts/build_proof.ts +12 -1
- package/src/scripts/capture_skill_catalogue.ts +21 -0
- package/src/scripts/check_always_budget.ts +2 -1
- package/src/scripts/check_augmentignore.ts +2 -1
- package/src/scripts/check_beta_review_markers.ts +2 -1
- package/src/scripts/check_bundle_path_leakage.ts +162 -7
- package/src/scripts/check_command_examples.ts +557 -0
- package/src/scripts/check_composite_arming.ts +364 -0
- package/src/scripts/check_corpus_staleness.ts +2 -1
- package/src/scripts/check_council_pin_staleness.ts +3 -1
- package/src/scripts/check_enforcement_coverage.ts +116 -3
- package/src/scripts/check_enforcement_denominator.ts +365 -0
- package/src/scripts/check_estate_count.ts +122 -3
- package/src/scripts/check_gate_coverage.ts +2 -1
- package/src/scripts/check_hook_bundle_freshness.ts +13 -1
- package/src/scripts/check_knowledge_cards.ts +2 -1
- package/src/scripts/check_knowledge_pages.ts +3 -2
- package/src/scripts/check_memory.ts +2 -1
- package/src/scripts/check_no_automerge_key.ts +287 -0
- package/src/scripts/check_pack_conformance_fixture.ts +565 -0
- package/src/scripts/check_preamble_payload_budget.ts +30 -3
- package/src/scripts/check_proposal.ts +2 -1
- package/src/scripts/check_reach_staleness.ts +2 -1
- package/src/scripts/check_release_adjacent_health.ts +2 -1
- package/src/scripts/check_release_pr_shape.ts +5 -0
- package/src/scripts/check_review_schema.ts +34 -1
- package/src/scripts/check_roadmap_trackable.ts +48 -3
- package/src/scripts/check_routing_coverage.ts +352 -0
- package/src/scripts/check_score_contract.ts +505 -0
- package/src/scripts/check_skill_admissions.ts +514 -0
- package/src/scripts/check_source_size_budget.ts +2 -1
- package/src/scripts/check_standing_payload_delta.ts +505 -0
- package/src/scripts/check_trigger_evals.ts +2 -1
- package/src/scripts/check_web_launch_readiness.ts +705 -0
- package/src/scripts/classify_change_risk.ts +281 -0
- package/src/scripts/compute_skill_tiers.ts +186 -0
- package/src/scripts/condense.ts +8 -13
- package/src/scripts/council_attendance_metrics.ts +183 -0
- package/src/scripts/council_cli.ts +10 -8
- package/src/scripts/council_parse_rate.ts +116 -0
- package/src/scripts/derive_playbooks.ts +406 -0
- package/src/scripts/description_route_check.ts +494 -0
- package/src/scripts/design_slop_rules.ts +56 -2
- package/src/scripts/dispatch_r2_reviewer.ts +16 -0
- package/src/scripts/frontend_corpus_hash.ts +116 -0
- package/src/scripts/grade_target_readiness.ts +478 -0
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +124 -16
- package/src/scripts/hooks/concern_registry.ts +6 -0
- package/src/scripts/hooks/design_pass_hook.ts +356 -0
- package/src/scripts/hooks/rtk_wrap_hook.ts +30 -7
- package/src/scripts/hooks/rule_inject_hook.ts +318 -0
- package/src/scripts/hooks/suggestion_capture_hook.ts +368 -0
- package/src/scripts/hot_context_hook.ts +74 -7
- package/src/scripts/install.ts +40 -89
- package/src/scripts/lint_adapter_tier.ts +663 -0
- package/src/scripts/lint_archived_skills.ts +93 -0
- package/src/scripts/lint_budget_ownership.ts +56 -5
- package/src/scripts/lint_deterministic_time.ts +470 -0
- package/src/scripts/lint_framework_leakage.ts +5 -0
- package/src/scripts/lint_handoffs.ts +525 -1
- package/src/scripts/lint_judge_prompt_expectation.ts +155 -0
- package/src/scripts/lint_marketplace.ts +88 -0
- package/src/scripts/lint_media_policy_linkage.ts +140 -1
- package/src/scripts/lint_one_off_age.ts +6 -1
- package/src/scripts/lint_override_kernel_guard.ts +87 -5
- package/src/scripts/lint_roadmap_complexity.ts +56 -0
- package/src/scripts/lint_rule_enforcement_declaration.ts +24 -7
- package/src/scripts/lint_rule_norm_pin.ts +321 -0
- package/src/scripts/lint_skill_trigger_corpus.ts +349 -0
- package/src/scripts/lint_spawn_payload.ts +42 -5
- package/src/scripts/lint_symptom_intake.ts +2 -1
- package/src/scripts/mcp_parity_smoke.ts +30 -4
- package/src/scripts/mcp_render.ts +66 -1
- package/src/scripts/mcp_tool_fingerprint.ts +241 -0
- package/src/scripts/measure_risk_class_drift.ts +140 -0
- package/src/scripts/measure_skill_ranker_baseline.ts +212 -0
- package/src/scripts/media/lib/adapter-common.sh +211 -1
- package/src/scripts/media/lib/adapter-contract.md +74 -6
- package/src/scripts/model_rule_injection.ts +907 -0
- package/src/scripts/pack_install_smoke.ts +363 -0
- package/src/scripts/pr_conflict_census.ts +187 -0
- package/src/scripts/project_thin_rules.ts +45 -2
- package/src/scripts/release.ts +66 -860
- package/src/scripts/release_drill.ts +59 -3
- package/src/scripts/release_env.ts +298 -0
- package/src/scripts/release_publication.ts +720 -0
- package/src/scripts/report_pack_delta.ts +204 -0
- package/src/scripts/roadmap_context.ts +778 -0
- package/src/scripts/schemas/fidelity-measurement-sheet.schema.json +169 -0
- package/src/scripts/schemas/rule.schema.json +24 -2
- package/src/scripts/schemas/skill.schema.json +39 -0
- package/src/scripts/schemas/ui-authority.schema.json +114 -0
- package/src/scripts/select_analysis_mode.ts +112 -0
- package/src/scripts/session_register_hook.ts +29 -3
- package/src/scripts/sessions_cli.ts +67 -3
- package/src/scripts/skill_tools/score_skill_relevance.ts +36 -53
- package/src/scripts/sync_pr_branch.ts +40 -1
- package/src/scripts/token_sink_report.ts +239 -0
- package/src/scripts/trigger_coverage.ts +122 -3
- package/src/scripts/update_counts.ts +7 -3
- package/src/scripts/validate_frontmatter.ts +66 -0
- package/src/server/schemas/settings.ts +10 -0
- package/src/shared/skillRanking.ts +183 -0
- package/dist/agent-src/skills/accessibility-auditor/evals/evals.json +0 -15
- package/dist/agent-src/skills/agent-security-review/evals/triggers.json +0 -52
- package/dist/agent-src/skills/ai-code-blindspots/evals/triggers.json +0 -52
- package/dist/agent-src/skills/analysis-skill-router/evals/evals.json +0 -13
- package/dist/agent-src/skills/brand/evals/triggers.json +0 -17
- package/dist/agent-src/skills/brand-asset-generation/evals/triggers.json +0 -17
- package/dist/agent-src/skills/brand-audit/evals/triggers.json +0 -17
- package/dist/agent-src/skills/brand-identity/evals/triggers.json +0 -17
- package/dist/agent-src/skills/brand-strategy/evals/triggers.json +0 -17
- package/dist/agent-src/skills/brand-to-tokens/evals/triggers.json +0 -17
- package/dist/agent-src/skills/bug-analyzer/evals/evals.json +0 -13
- package/dist/agent-src/skills/canvas-design/evals/triggers.json +0 -17
- package/dist/agent-src/skills/character-consistency/evals/evals.json +0 -16
- package/dist/agent-src/skills/code-intelligence/evals/triggers.json +0 -52
- package/dist/agent-src/skills/code-review/evals/evals.json +0 -100
- package/dist/agent-src/skills/command-routing/evals/evals.json +0 -14
- package/dist/agent-src/skills/complexity-first-planning/evals/triggers.json +0 -17
- package/dist/agent-src/skills/contract-review/evals/triggers.json +0 -17
- package/dist/agent-src/skills/conventional-commits-writing/evals/evals.json +0 -15
- package/dist/agent-src/skills/corpus-grounding/evals/triggers.json +0 -17
- package/dist/agent-src/skills/dashboard-design/evals/evals.json +0 -16
- package/dist/agent-src/skills/dcf-modeling/evals/domain-truth.json +0 -29
- package/dist/agent-src/skills/dcf-modeling/evals/evals.json +0 -20
- package/dist/agent-src/skills/decision-record/evals/evals.json +0 -20
- package/dist/agent-src/skills/decision-record/evals/triggers.json +0 -87
- package/dist/agent-src/skills/design-intelligence/evals/evals.json +0 -14
- package/dist/agent-src/skills/design-intelligence/evals/triggers.json +0 -17
- package/dist/agent-src/skills/design-system-capture/evals/evals.json +0 -15
- package/dist/agent-src/skills/design-tokens/evals/triggers.json +0 -17
- package/dist/agent-src/skills/design-variations/evals/triggers.json +0 -17
- package/dist/agent-src/skills/developer-like-execution/evals/evals.json +0 -16
- package/dist/agent-src/skills/doc-coauthoring/evals/evals.json +0 -16
- package/dist/agent-src/skills/doc-coauthoring/evals/triggers.json +0 -17
- package/dist/agent-src/skills/docx-authoring/evals/triggers.json +0 -52
- package/dist/agent-src/skills/dpa-review/evals/triggers.json +0 -17
- package/dist/agent-src/skills/editorial-calendar/evals/domain-truth.json +0 -16
- package/dist/agent-src/skills/editorial-calendar/evals/evals.json +0 -16
- package/dist/agent-src/skills/eloquent/evals/triggers.json +0 -17
- package/dist/agent-src/skills/estimate-ticket/evals/evals.json +0 -16
- package/dist/agent-src/skills/estimate-ticket/evals/output-schema.yml +0 -20
- package/dist/agent-src/skills/estimate-ticket/evals/triggers.json +0 -19
- package/dist/agent-src/skills/evaluate-llm-feature/evals/triggers.json +0 -52
- package/dist/agent-src/skills/existing-ui-audit/evals/triggers.json +0 -47
- package/dist/agent-src/skills/experiment-loop/evals/output-schema.yml +0 -27
- package/dist/agent-src/skills/experiment-loop/evals/triggers.json +0 -17
- package/dist/agent-src/skills/fe-design/evals/triggers.json +0 -55
- package/dist/agent-src/skills/forecasting/evals/domain-truth.json +0 -29
- package/dist/agent-src/skills/forecasting/evals/evals.json +0 -20
- package/dist/agent-src/skills/forensics-report/evals/triggers.json +0 -17
- package/dist/agent-src/skills/frontend-render-security/evals/triggers.json +0 -52
- package/dist/agent-src/skills/fundraising-narrative/evals/domain-truth.json +0 -16
- package/dist/agent-src/skills/fundraising-narrative/evals/evals.json +0 -16
- package/dist/agent-src/skills/gated-reach/evals/triggers.json +0 -72
- package/dist/agent-src/skills/github-ci/evals/evals.json +0 -25
- package/dist/agent-src/skills/history-design/evals/triggers.json +0 -17
- package/dist/agent-src/skills/html-deck/evals/triggers.json +0 -17
- package/dist/agent-src/skills/humanizer/evals/strip_fixtures.json +0 -57
- package/dist/agent-src/skills/humanizer/evals/triggers.json +0 -17
- package/dist/agent-src/skills/iconography/evals/triggers.json +0 -17
- package/dist/agent-src/skills/image-analyser/evals/triggers.json +0 -17
- package/dist/agent-src/skills/image-creator/evals/triggers.json +0 -17
- package/dist/agent-src/skills/image-editing/evals/triggers.json +0 -17
- package/dist/agent-src/skills/image-generation/evals/triggers.json +0 -17
- package/dist/agent-src/skills/image-provider-routing/evals/triggers.json +0 -17
- package/dist/agent-src/skills/incident-commander/evals/domain-truth.json +0 -16
- package/dist/agent-src/skills/incident-commander/evals/evals.json +0 -20
- package/dist/agent-src/skills/judge-artifact-completeness/evals/triggers.json +0 -17
- package/dist/agent-src/skills/judge-injection-defense/evals/triggers.json +0 -17
- package/dist/agent-src/skills/judge-synthesis/evals/triggers.json +0 -17
- package/dist/agent-src/skills/launch-readiness/evals/evals.json +0 -21
- package/dist/agent-src/skills/learning-tutor/evals/triggers.json +0 -52
- package/dist/agent-src/skills/legal-intake-triage/evals/triggers.json +0 -17
- package/dist/agent-src/skills/legal-practice-profile/evals/triggers.json +0 -17
- package/dist/agent-src/skills/license-compliance-audit/evals/triggers.json +0 -52
- package/dist/agent-src/skills/license-compliance-borrow-check/evals/triggers.json +0 -52
- package/dist/agent-src/skills/license-compliance-credits/evals/triggers.json +0 -52
- package/dist/agent-src/skills/llm-provider-knowledge/evals/triggers.json +0 -20
- package/dist/agent-src/skills/logging-monitoring/evals/evals.json +0 -16
- package/dist/agent-src/skills/logo-generation/evals/triggers.json +0 -17
- package/dist/agent-src/skills/messaging-architecture/evals/domain-truth.json +0 -16
- package/dist/agent-src/skills/messaging-architecture/evals/evals.json +0 -16
- package/dist/agent-src/skills/nda-triage/evals/triggers.json +0 -17
- package/dist/agent-src/skills/pdf-tools/evals/triggers.json +0 -52
- package/dist/agent-src/skills/perf-feedback-craft/evals/evals.json +0 -16
- package/dist/agent-src/skills/persona-improvement/evals/triggers.json +0 -52
- package/dist/agent-src/skills/php-coder/evals/triggers.json +0 -17
- package/dist/agent-src/skills/prediction-pool-optimizer/evals/triggers.json +0 -21
- package/dist/agent-src/skills/prompt-engineering-image/evals/triggers.json +0 -17
- package/dist/agent-src/skills/prompt-engineering-patterns/evals/evals.json +0 -16
- package/dist/agent-src/skills/prompt-validator/evals/triggers.json +0 -17
- package/dist/agent-src/skills/quality-tools/evals/evals.json +0 -15
- package/dist/agent-src/skills/reasoning-orchestrator/evals/triggers.json +0 -17
- package/dist/agent-src/skills/refine-prompt/evals/evals.json +0 -16
- package/dist/agent-src/skills/refine-ticket/evals/evals.json +0 -16
- package/dist/agent-src/skills/refine-ticket/evals/output-schema.yml +0 -16
- package/dist/agent-src/skills/refine-ticket/evals/triggers.json +0 -17
- package/dist/agent-src/skills/release-comms/evals/evals.json +0 -16
- package/dist/agent-src/skills/rice-prioritization/evals/evals.json +0 -20
- package/dist/agent-src/skills/runway-cognition/evals/domain-truth.json +0 -29
- package/dist/agent-src/skills/runway-cognition/evals/evals.json +0 -20
- package/dist/agent-src/skills/scenario-modeling/evals/domain-truth.json +0 -29
- package/dist/agent-src/skills/scenario-modeling/evals/evals.json +0 -20
- package/dist/agent-src/skills/schema-review/evals/triggers.json +0 -17
- package/dist/agent-src/skills/screenshot-hygiene/evals/triggers.json +0 -52
- package/dist/agent-src/skills/security-maturity-assessment/evals/triggers.json +0 -52
- package/dist/agent-src/skills/skill-writing/evals/triggers.json +0 -17
- package/dist/agent-src/skills/spreadsheet-authoring/evals/triggers.json +0 -47
- package/dist/agent-src/skills/subagent-orchestration/evals/evals.json +0 -60
- package/dist/agent-src/skills/supply-chain-intake/evals/triggers.json +0 -52
- package/dist/agent-src/skills/systematic-debugging/evals/evals.json +0 -20
- package/dist/agent-src/skills/test-case-discovery/evals/triggers.json +0 -52
- package/dist/agent-src/skills/test-driven-development/evals/evals.json +0 -16
- package/dist/agent-src/skills/threat-modeling/evals/evals.json +0 -21
- package/dist/agent-src/skills/typography-system/evals/evals.json +0 -14
- package/dist/agent-src/skills/typography-system/evals/triggers.json +0 -17
- package/dist/agent-src/skills/unit-economics-modeling/evals/domain-truth.json +0 -40
- package/dist/agent-src/skills/unit-economics-modeling/evals/evals.json +0 -24
- package/dist/agent-src/skills/verify-completion-evidence/evals/evals.json +0 -16
- package/dist/agent-src/skills/verify-repair-loop/evals/output-schema.yml +0 -20
- package/dist/agent-src/skills/verify-repair-loop/evals/triggers.json +0 -17
- package/dist/agent-src/skills/vision-articulation/evals/evals.json +0 -16
- package/dist/agent-src/skills/voice-and-tone-design/evals/evals.json +0 -16
- package/dist/agent-src/skills/wireframe/evals/triggers.json +0 -17
- package/dist/agent-src/skills/worktree-lifecycle/evals/evals.json +0 -38
- package/dist/agent-src/skills/worktree-lifecycle/evals/triggers.json +0 -52
- package/dist/cli/agent-config.js.map +0 -1
- package/dist/cli/bash/runBash.js.map +0 -1
- package/dist/cli/commands/commands.js.map +0 -1
- package/dist/cli/commands/config.js.map +0 -1
- package/dist/cli/commands/doctorShell.js.map +0 -1
- package/dist/cli/commands/mcpServer.js.map +0 -1
- package/dist/cli/commands/packs.js.map +0 -1
- package/dist/cli/commands/profiles.js.map +0 -1
- package/dist/cli/commands/recordTriggerEval.js.map +0 -1
- package/dist/cli/commands/rtkDetect.js.map +0 -1
- package/dist/cli/commands/settings.js.map +0 -1
- package/dist/cli/commands/uiServe.js.map +0 -1
- package/dist/cli/commands/versions.js.map +0 -1
- package/dist/cli/commands/workspaces.js.map +0 -1
- package/dist/cli/configRoot.js.map +0 -1
- package/dist/cli/discovery/loadManifest.js.map +0 -1
- package/dist/cli/firstRunNotice.js.map +0 -1
- package/dist/cli/help.js.map +0 -1
- package/dist/cli/initRouting.js.map +0 -1
- package/dist/cli/log/logger.js.map +0 -1
- package/dist/cli/main.js.map +0 -1
- package/dist/cli/mcp/content.js.map +0 -1
- package/dist/cli/mcp/dispatch.js.map +0 -1
- package/dist/cli/mcp/stdio.js.map +0 -1
- package/dist/cli/paths.js.map +0 -1
- package/dist/cli/python/knowledge_ingest.js.map +0 -1
- package/dist/cli/python/workspace_analytics.js.map +0 -1
- package/dist/cli/python/workspace_crypto.js.map +0 -1
- package/dist/cli/python/workspace_documents.js.map +0 -1
- package/dist/cli/python/workspace_drive.js.map +0 -1
- package/dist/cli/python/workspace_drive_health.js.map +0 -1
- package/dist/cli/python/workspace_explain.js.map +0 -1
- package/dist/cli/python/workspace_hosts.js.map +0 -1
- package/dist/cli/python/workspace_inbox.js.map +0 -1
- package/dist/cli/python/workspace_render.js.map +0 -1
- package/dist/cli/python/workspace_roles.js.map +0 -1
- package/dist/cli/python/workspace_secrets.js.map +0 -1
- package/dist/cli/python/workspace_sessions.js.map +0 -1
- package/dist/cli/python/workspace_skills.js.map +0 -1
- package/dist/cli/registry.js.map +0 -1
- package/dist/install/agentSwitchDetection.js.map +0 -1
- package/dist/install/agentSwitchProfile.js.map +0 -1
- package/dist/install/atomic.js.map +0 -1
- package/dist/install/claudePathsPlan.js.map +0 -1
- package/dist/install/conflict.js.map +0 -1
- package/dist/install/detect.js.map +0 -1
- package/dist/install/emit_host_rules_cli.js.map +0 -1
- package/dist/install/globalRuleLayers.js.map +0 -1
- package/dist/install/hostLayerFingerprint.js.map +0 -1
- package/dist/install/partitionEligibility.js.map +0 -1
- package/dist/install/paths.js.map +0 -1
- package/dist/install/plan.js.map +0 -1
- package/dist/install/preflight.js.map +0 -1
- package/dist/install/rtkDetection.js.map +0 -1
- package/dist/install/ruleInScope.js.map +0 -1
- package/dist/install/ruleLayerPartition.js.map +0 -1
- package/dist/install/rule_scope.js.map +0 -1
- package/dist/install/rule_scope_cli.js.map +0 -1
- package/dist/install/selectedTools.js.map +0 -1
- package/dist/install/toolDetection.js.map +0 -1
- package/dist/install/txlog.js.map +0 -1
- package/dist/install/types.js.map +0 -1
- package/dist/install/wizard-plan.js.map +0 -1
- package/dist/install/wizardDismissals.js.map +0 -1
- package/dist/scripts/_lib/agent_settings.js.map +0 -1
- package/dist/scripts/_lib/agent_src.js.map +0 -1
- package/dist/scripts/_lib/claude_builtin_names.js.map +0 -1
- package/dist/scripts/_lib/claude_plugin.js.map +0 -1
- package/dist/scripts/_lib/claude_settings_hooks.js.map +0 -1
- package/dist/scripts/_lib/compile_time_toggles.js.map +0 -1
- package/dist/scripts/_lib/environment_detector.js.map +0 -1
- package/dist/scripts/_lib/host_launch.js.map +0 -1
- package/dist/scripts/_lib/install_layout.js.map +0 -1
- package/dist/scripts/_lib/installed_lock.js.map +0 -1
- package/dist/scripts/_lib/model_tier.js.map +0 -1
- package/dist/scripts/_lib/prune_empty_dirs.js.map +0 -1
- package/dist/scripts/_lib/scoped_projection.js.map +0 -1
- package/dist/scripts/_lib/script_output.js.map +0 -1
- package/dist/scripts/_lib/spawn_env.js.map +0 -1
- package/dist/scripts/_lib/surface_tiers.js.map +0 -1
- package/dist/scripts/_lib/token_count.js.map +0 -1
- package/dist/scripts/_lib/trigger_eval_floors.js.map +0 -1
- package/dist/scripts/_lib/user_global_paths.js.map +0 -1
- package/dist/scripts/ai_council/modes.js.map +0 -1
- package/dist/scripts/ai_council/transport_resolver.js.map +0 -1
- package/dist/scripts/condense.js.map +0 -1
- package/dist/scripts/project_thin_rules.js.map +0 -1
- package/dist/server/app.js.map +0 -1
- package/dist/server/io/atomicMultiWrite.js.map +0 -1
- package/dist/server/io/atomicWrite.js.map +0 -1
- package/dist/server/io/sharedWriteCheck.js.map +0 -1
- package/dist/server/io/substituteTemplate.js.map +0 -1
- package/dist/server/io/yamlIO.js.map +0 -1
- package/dist/server/nicknameResolver.js.map +0 -1
- package/dist/server/port.js.map +0 -1
- package/dist/server/routes/discovery.js.map +0 -1
- package/dist/server/routes/install.js.map +0 -1
- package/dist/server/routes/ping.js.map +0 -1
- package/dist/server/routes/schema.js.map +0 -1
- package/dist/server/routes/settings.js.map +0 -1
- package/dist/server/routes/settingsChanges.js.map +0 -1
- package/dist/server/routes/userMd.js.map +0 -1
- package/dist/server/routes/wizard.js.map +0 -1
- package/dist/server/routes/workspace.js.map +0 -1
- package/dist/server/schemas/settings.js.map +0 -1
- package/dist/server/serverInfo.js.map +0 -1
- package/dist/server/token.js.map +0 -1
- package/dist/server/writeRoot.js.map +0 -1
- package/dist/shared/capabilities.js.map +0 -1
- package/dist/shared/interactiveContext.js.map +0 -1
- package/dist/shared/nicknamePrefill.js.map +0 -1
- package/dist/shared/settingsAsks.js.map +0 -1
- package/dist/shared/settingsCarveOut.js.map +0 -1
- package/dist/shared/settingsClasses.js.map +0 -1
- package/dist/shared/settingsConsent.js.map +0 -1
- package/dist/shared/settingsSurface.js.map +0 -1
- package/dist/shared/userMd/formAdapter.js.map +0 -1
- package/dist/shared/userMd/schema.js.map +0 -1
- package/dist/shared/userMd/utils.js.map +0 -1
- package/dist/ui/assets/index-Cxgy63kz.js.map +0 -1
- package/src/scripts/_lib/adr_frontmatter.test.ts +0 -365
- package/src/scripts/_lib/adversarial_council_gate.test.ts +0 -112
- package/src/scripts/_lib/adversarial_reconcile.test.ts +0 -197
- package/src/scripts/_lib/auto_dispatch.corpus.test.ts +0 -150
- package/src/scripts/_lib/secret_detector.test.ts +0 -108
- package/src/scripts/_lib/secret_detector_adversarial.test.ts +0 -116
- package/src/scripts/_lib/untrusted_content.test.ts +0 -175
- package/src/scripts/check_secret_leak.test.ts +0 -90
- package/src/scripts/design_slop_rules.test.ts +0 -239
- package/src/scripts/self_review_gate.test.ts +0 -296
- package/src/shared/capabilities.test.ts +0 -43
|
@@ -0,0 +1,494 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* `description_route_check` — a routing regression detector on the DESCRIPTION
|
|
4
|
+
* surface, cheap enough to run per PR.
|
|
5
|
+
*
|
|
6
|
+
* `road-to-routing-assurance` Phase 1. Input is the full catalogue (name +
|
|
7
|
+
* description — the production routing condition) plus one prompt; output is
|
|
8
|
+
* the would-load set. Two backends:
|
|
9
|
+
*
|
|
10
|
+
* (a) `dry` — the existing MockRouter shape: no key, no network, no spend.
|
|
11
|
+
* It exercises plumbing, never fidelity.
|
|
12
|
+
* (b) `cached-live` — a real model call keyed on `(catalogue-hash, prompt)`,
|
|
13
|
+
* so an unchanged pair costs zero on the second run. The cache key
|
|
14
|
+
* includes the catalogue hash deliberately: a description edit anywhere
|
|
15
|
+
* changes the routing condition for EVERY prompt, so a prompt-only key
|
|
16
|
+
* would serve a stale answer precisely when the answer changed.
|
|
17
|
+
*
|
|
18
|
+
* ## THE PROXY GAP — a stated limitation, not a caveat (Phase 1.4)
|
|
19
|
+
*
|
|
20
|
+
* This checker asks a model *"which units would you load given this
|
|
21
|
+
* catalogue"*. That is **NOT the host's selection procedure.** The host applies
|
|
22
|
+
* its own truncation, its own ordering, its own system prompt, and — measured
|
|
23
|
+
* on a default install — publishes a budget event saying it stripped every
|
|
24
|
+
* description and dropped hundreds of entries before the model saw the list.
|
|
25
|
+
*
|
|
26
|
+
* So a green run here is evidence that the **description signal** did not
|
|
27
|
+
* regress. It is NEVER evidence that production routing works. The fidelity of
|
|
28
|
+
* this proxy to real sessions is a MEASURED quantity — roadmap step 5.4, over
|
|
29
|
+
* prompts appearing in both the trace corpus and the fixture corpus — and until
|
|
30
|
+
* that measurement exists the gap is unquantified rather than small.
|
|
31
|
+
*
|
|
32
|
+
* ## Fail direction: recall first (Phase 1.3)
|
|
33
|
+
*
|
|
34
|
+
* A **positive that stops loading BLOCKS** — the unit was supposed to be
|
|
35
|
+
* consulted for this prompt and no longer is, which is the defect class this
|
|
36
|
+
* whole roadmap exists for. A **near-miss that starts loading WARNS** — a unit
|
|
37
|
+
* loading when it need not is a token cost, not a missing obligation. The
|
|
38
|
+
* asymmetry is deliberate and matches defect D2's direction: this repository's
|
|
39
|
+
* measured failure is under-delivery, not over-delivery.
|
|
40
|
+
*
|
|
41
|
+
* Exit codes: 0 = no recall breach · 1 = a positive stopped loading · 2 = usage
|
|
42
|
+
* or IO error.
|
|
43
|
+
*/
|
|
44
|
+
import { createHash } from 'node:crypto';
|
|
45
|
+
import * as fs from 'node:fs';
|
|
46
|
+
import * as path from 'node:path';
|
|
47
|
+
import process from 'node:process';
|
|
48
|
+
import { fileURLToPath } from 'node:url';
|
|
49
|
+
|
|
50
|
+
import { GateLedger } from './_lib/gate_ledger.js';
|
|
51
|
+
import { type SkillMeta } from './skill_trigger_eval.js';
|
|
52
|
+
|
|
53
|
+
const HERE = fileURLToPath(import.meta.url);
|
|
54
|
+
const REAL_REPO_ROOT = path.resolve(path.dirname(HERE), '..', '..');
|
|
55
|
+
/** Scan root; the env override exists for the self-test and for fixtures. */
|
|
56
|
+
const REPO_ROOT = process.env['DESCRIPTION_ROUTE_CHECK_ROOT'] ?? REAL_REPO_ROOT;
|
|
57
|
+
|
|
58
|
+
export const CACHE_REL = 'internal/evals/cache/description-route';
|
|
59
|
+
|
|
60
|
+
/** One corpus case: a prompt, and whether the unit must be consulted for it. */
|
|
61
|
+
export interface Case {
|
|
62
|
+
unit: string;
|
|
63
|
+
prompt: string;
|
|
64
|
+
/** `true` = positive (must load) · `false` = near-miss (must not). */
|
|
65
|
+
expect: boolean;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface Backend {
|
|
69
|
+
name: string;
|
|
70
|
+
/** Returns the would-load set for one prompt against one catalogue. */
|
|
71
|
+
route(prompt: string, catalogue: readonly SkillMeta[]): string[];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Stable catalogue fingerprint.
|
|
76
|
+
*
|
|
77
|
+
* Sorted by name before hashing, so a reordering of the source directory — a
|
|
78
|
+
* property of the filesystem, not of the routing condition — does not
|
|
79
|
+
* invalidate every cache entry.
|
|
80
|
+
*/
|
|
81
|
+
export function catalogueHash(catalogue: readonly SkillMeta[]): string {
|
|
82
|
+
const body = [...catalogue]
|
|
83
|
+
.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0))
|
|
84
|
+
.map((c) => `${c.name} ${c.description}`)
|
|
85
|
+
.join('');
|
|
86
|
+
return createHash('sha256').update(body).digest('hex').slice(0, 16);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function cacheKey(catalogue: readonly SkillMeta[], prompt: string): string {
|
|
90
|
+
const p = createHash('sha256').update(prompt).digest('hex').slice(0, 16);
|
|
91
|
+
return `${catalogueHash(catalogue)}-${p}`;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* A backend that answers from disk and calls `inner` only on a miss.
|
|
96
|
+
*
|
|
97
|
+
* `calls` is exposed so a test can assert ZERO calls on a repeat — the verify
|
|
98
|
+
* condition Phase 1.1 states, and the only one that distinguishes a working
|
|
99
|
+
* cache from a cache-shaped no-op.
|
|
100
|
+
*/
|
|
101
|
+
export class CachedBackend implements Backend {
|
|
102
|
+
name: string;
|
|
103
|
+
calls = 0;
|
|
104
|
+
private dir: string;
|
|
105
|
+
private inner: Backend;
|
|
106
|
+
|
|
107
|
+
constructor(inner: Backend, dir: string) {
|
|
108
|
+
this.inner = inner;
|
|
109
|
+
this.dir = dir;
|
|
110
|
+
this.name = `cached(${inner.name})`;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
route(prompt: string, catalogue: readonly SkillMeta[]): string[] {
|
|
114
|
+
const file = path.join(this.dir, `${cacheKey(catalogue, prompt)}.json`);
|
|
115
|
+
try {
|
|
116
|
+
return JSON.parse(fs.readFileSync(file, 'utf-8')) as string[];
|
|
117
|
+
} catch {
|
|
118
|
+
/* miss — fall through to the inner backend */
|
|
119
|
+
}
|
|
120
|
+
this.calls += 1;
|
|
121
|
+
const out = this.inner.route(prompt, catalogue);
|
|
122
|
+
fs.mkdirSync(this.dir, { recursive: true });
|
|
123
|
+
fs.writeFileSync(file, JSON.stringify(out));
|
|
124
|
+
return out;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* The dry backend: substring containment of the unit name in the prompt.
|
|
130
|
+
*
|
|
131
|
+
* Deliberately crude, and it must stay that way. Its job is to prove the
|
|
132
|
+
* plumbing runs with no key and no spend; making it cleverer would invite
|
|
133
|
+
* reading a green dry run as a routing result, which is the exact conflation
|
|
134
|
+
* the proxy-gap section above exists to prevent.
|
|
135
|
+
*/
|
|
136
|
+
export class DryBackend implements Backend {
|
|
137
|
+
name = 'dry';
|
|
138
|
+
route(prompt: string, catalogue: readonly SkillMeta[]): string[] {
|
|
139
|
+
const q = prompt.toLowerCase();
|
|
140
|
+
return catalogue.filter((c) => q.includes(c.name.toLowerCase())).map((c) => c.name);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export type Direction = 'recall' | 'precision';
|
|
145
|
+
|
|
146
|
+
export interface Finding {
|
|
147
|
+
unit: string;
|
|
148
|
+
prompt: string;
|
|
149
|
+
direction: Direction;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export interface Report {
|
|
153
|
+
findings: Finding[];
|
|
154
|
+
cases: number;
|
|
155
|
+
backend: string;
|
|
156
|
+
/** Recall breaches block; precision breaches warn. */
|
|
157
|
+
blocked: number;
|
|
158
|
+
warned: number;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export function evaluate(
|
|
162
|
+
cases: readonly Case[],
|
|
163
|
+
catalogue: readonly SkillMeta[],
|
|
164
|
+
backend: Backend,
|
|
165
|
+
): Report {
|
|
166
|
+
const findings: Finding[] = [];
|
|
167
|
+
for (const c of cases) {
|
|
168
|
+
const loaded = new Set(backend.route(c.prompt, catalogue));
|
|
169
|
+
const hit = loaded.has(c.unit);
|
|
170
|
+
if (c.expect && !hit) {
|
|
171
|
+
findings.push({ unit: c.unit, prompt: c.prompt, direction: 'recall' });
|
|
172
|
+
}
|
|
173
|
+
if (!c.expect && hit) {
|
|
174
|
+
findings.push({ unit: c.unit, prompt: c.prompt, direction: 'precision' });
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return {
|
|
178
|
+
findings,
|
|
179
|
+
cases: cases.length,
|
|
180
|
+
backend: backend.name,
|
|
181
|
+
blocked: findings.filter((f) => f.direction === 'recall').length,
|
|
182
|
+
warned: findings.filter((f) => f.direction === 'precision').length,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export function render(r: Report, write: (s: string) => unknown): number {
|
|
187
|
+
for (const f of r.findings) {
|
|
188
|
+
const tag = f.direction === 'recall' ? 'BLOCK' : 'WARN ';
|
|
189
|
+
const what = f.direction === 'recall' ? 'stopped loading' : 'started loading';
|
|
190
|
+
write(` ${tag} ${f.unit}: ${what} for ${JSON.stringify(f.prompt)}\n`);
|
|
191
|
+
}
|
|
192
|
+
write(
|
|
193
|
+
`description_route_check: ${String(r.cases)} case(s) via ${r.backend} · ` +
|
|
194
|
+
`${String(r.blocked)} recall breach(es) · ${String(r.warned)} precision warning(s)\n`,
|
|
195
|
+
);
|
|
196
|
+
if (r.blocked > 0) {
|
|
197
|
+
write(
|
|
198
|
+
'recall-first: a positive stopped loading, so this blocks. Either the\n' +
|
|
199
|
+
'description regressed or the corpus case is wrong — both are edits, and\n' +
|
|
200
|
+
'neither of them is "lower the expectation".\n',
|
|
201
|
+
);
|
|
202
|
+
return 1;
|
|
203
|
+
}
|
|
204
|
+
write('no recall breach on the description surface.\n');
|
|
205
|
+
return 0;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export function cacheDir(root = REPO_ROOT): string {
|
|
209
|
+
return path.join(root, CACHE_REL);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export { REPO_ROOT as SCAN_ROOT };
|
|
213
|
+
|
|
214
|
+
/* ── Phase 1.2 — diff scoping, inside the existing key boundary ───────────── */
|
|
215
|
+
|
|
216
|
+
export type RunMode = 'advisory' | 'scoped-live';
|
|
217
|
+
|
|
218
|
+
export interface ScopeDecision {
|
|
219
|
+
mode: RunMode;
|
|
220
|
+
/** The units whose description changed; empty for an advisory run. */
|
|
221
|
+
units: string[];
|
|
222
|
+
reason: string;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Does this changed path carry a routable `description`?
|
|
227
|
+
*
|
|
228
|
+
* Skill frontmatter lives in `SKILL.md`; a rule's description lives in the
|
|
229
|
+
* rule file itself. Both source and projection count: the projection is what a
|
|
230
|
+
* host reads, and a projection-only change is exactly the case a source-only
|
|
231
|
+
* filter would miss.
|
|
232
|
+
*/
|
|
233
|
+
export function describesAUnit(file: string): string | null {
|
|
234
|
+
let m = /^(?:src|dist\/agent-src)\/skills\/([^/]+)\/SKILL\.md$/.exec(file);
|
|
235
|
+
if (m) return m[1] ?? null;
|
|
236
|
+
m = /^(?:src|dist\/agent-src)\/rules\/([^/]+)\.md$/.exec(file);
|
|
237
|
+
if (m) return m[1] ?? null;
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Decide whether the scoped live run may happen at all.
|
|
243
|
+
*
|
|
244
|
+
* Live authorization derives exclusively from the key file the canary workflow
|
|
245
|
+
* materializes from repo secrets, with **no env-var fallback**. A fork PR
|
|
246
|
+
* cannot reach that key by construction, so it stays on the advisory path —
|
|
247
|
+
* and this function refuses BEFORE any spend rather than letting the call fail
|
|
248
|
+
* at the router, so the refusal is a decision with a reason rather than an
|
|
249
|
+
* error nobody planned for.
|
|
250
|
+
*/
|
|
251
|
+
export function scopeRun(opts: { isFork: boolean; changedFiles: readonly string[] }): ScopeDecision {
|
|
252
|
+
const units = [...new Set(opts.changedFiles.map(describesAUnit).filter((u): u is string => u !== null))].sort();
|
|
253
|
+
if (opts.isFork) {
|
|
254
|
+
return {
|
|
255
|
+
mode: 'advisory',
|
|
256
|
+
units: [],
|
|
257
|
+
reason: 'fork PR — the key file is unreachable by construction, so live cannot run',
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
if (units.length === 0) {
|
|
261
|
+
return {
|
|
262
|
+
mode: 'advisory',
|
|
263
|
+
units: [],
|
|
264
|
+
reason: 'no description surface in the diff — nothing to regress',
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
return {
|
|
268
|
+
mode: 'scoped-live',
|
|
269
|
+
units,
|
|
270
|
+
reason: `${String(units.length)} unit(s) with a changed description`,
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/** Keep only the cases belonging to the units the diff actually touched. */
|
|
275
|
+
export function scopeCases(cases: readonly Case[], units: readonly string[]): Case[] {
|
|
276
|
+
const want = new Set(units);
|
|
277
|
+
return cases.filter((c) => want.has(c.unit));
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/* ── Corpus loading — one reader over BOTH existing shapes ────────────────── */
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Load every corpus case, from both surfaces, into one flat list.
|
|
284
|
+
*
|
|
285
|
+
* Two shapes exist and neither is rewritten: `tests/eval/routing-matrix/*.yaml`
|
|
286
|
+
* (rules — `positives` / `near_misses`) and `src/skills/<n>/evals/triggers.json`
|
|
287
|
+
* (skills — `queries[].trigger`). Normalising them here rather than migrating
|
|
288
|
+
* one to the other keeps the substring matcher's corpus untouched, which Phase
|
|
289
|
+
* 2.1 requires explicitly: this reuses the corpus DISCIPLINE, not the matcher.
|
|
290
|
+
*/
|
|
291
|
+
export function loadCases(root = REPO_ROOT): Case[] {
|
|
292
|
+
const out: Case[] = [];
|
|
293
|
+
const mdir = path.join(root, 'tests', 'eval', 'routing-matrix');
|
|
294
|
+
let matrixFiles: string[] = [];
|
|
295
|
+
try {
|
|
296
|
+
matrixFiles = fs.readdirSync(mdir).filter((f) => /\.ya?ml$/.test(f));
|
|
297
|
+
} catch {
|
|
298
|
+
matrixFiles = [];
|
|
299
|
+
}
|
|
300
|
+
for (const f of matrixFiles) {
|
|
301
|
+
const unit = f.replace(/\.ya?ml$/, '');
|
|
302
|
+
const text = fs.readFileSync(path.join(mdir, f), 'utf-8');
|
|
303
|
+
// Deliberately a line scan rather than a YAML parse: the only shape
|
|
304
|
+
// this reads is `- prompt: "..."` under one of two keys, and adding a
|
|
305
|
+
// parser dependency here would make the loader fail on YAML this gate
|
|
306
|
+
// has no opinion about.
|
|
307
|
+
let bucket: boolean | null = null;
|
|
308
|
+
for (const line of text.split('\n')) {
|
|
309
|
+
if (/^positives:/.test(line)) bucket = true;
|
|
310
|
+
else if (/^near_misses:/.test(line)) bucket = false;
|
|
311
|
+
else if (/^[a-z_]+:/.test(line)) bucket = null;
|
|
312
|
+
const m = /^\s*-\s*prompt:\s*(.+)$/.exec(line);
|
|
313
|
+
if (m && bucket !== null) {
|
|
314
|
+
out.push({ unit, prompt: unquote(m[1] ?? ''), expect: bucket });
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
const sdir = path.join(root, 'src', 'skills');
|
|
319
|
+
let skillDirs: fs.Dirent[] = [];
|
|
320
|
+
try {
|
|
321
|
+
skillDirs = fs.readdirSync(sdir, { withFileTypes: true });
|
|
322
|
+
} catch {
|
|
323
|
+
skillDirs = [];
|
|
324
|
+
}
|
|
325
|
+
for (const d of skillDirs) {
|
|
326
|
+
if (!d.isDirectory()) continue;
|
|
327
|
+
const f = path.join(sdir, d.name, 'evals', 'triggers.json');
|
|
328
|
+
if (!fs.existsSync(f)) continue;
|
|
329
|
+
out.push(...readTriggersFile(d.name, f));
|
|
330
|
+
}
|
|
331
|
+
return out;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Read one skill trigger file, in EITHER of the two shapes that exist.
|
|
336
|
+
*
|
|
337
|
+
* 74 files use `queries: [{q, trigger}]`; 2 use `should_trigger` /
|
|
338
|
+
* `should_not_trigger` string arrays. A reader that knew only the majority
|
|
339
|
+
* shape returned ZERO cases for the other two while `check_routing_coverage`
|
|
340
|
+
* counted them as covered — the file exists, so the ratio said yes and the
|
|
341
|
+
* corpus said nothing. That is exactly the silent no-op this repository keeps
|
|
342
|
+
* finding, and it is the reason both shapes are read here rather than one
|
|
343
|
+
* being called the format.
|
|
344
|
+
*/
|
|
345
|
+
export function readTriggersFile(unit: string, file: string): Case[] {
|
|
346
|
+
const doc = JSON.parse(fs.readFileSync(file, 'utf-8')) as {
|
|
347
|
+
queries?: { q?: string; trigger?: boolean }[];
|
|
348
|
+
should_trigger?: string[];
|
|
349
|
+
should_not_trigger?: string[];
|
|
350
|
+
};
|
|
351
|
+
const out: Case[] = [];
|
|
352
|
+
for (const q of doc.queries ?? []) {
|
|
353
|
+
if (typeof q.q === 'string' && typeof q.trigger === 'boolean') {
|
|
354
|
+
out.push({ unit, prompt: q.q, expect: q.trigger });
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
for (const q of doc.should_trigger ?? []) {
|
|
358
|
+
if (typeof q === 'string') out.push({ unit, prompt: q, expect: true });
|
|
359
|
+
}
|
|
360
|
+
for (const q of doc.should_not_trigger ?? []) {
|
|
361
|
+
if (typeof q === 'string') out.push({ unit, prompt: q, expect: false });
|
|
362
|
+
}
|
|
363
|
+
return out;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
function unquote(s: string): string {
|
|
367
|
+
const t = s.trim();
|
|
368
|
+
if ((t.startsWith('"') && t.endsWith('"')) || (t.startsWith("'") && t.endsWith("'"))) {
|
|
369
|
+
return t.slice(1, -1);
|
|
370
|
+
}
|
|
371
|
+
return t;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* The catalogue is name + description — the production routing condition.
|
|
376
|
+
*
|
|
377
|
+
* Read from the PROJECTION (`dist/agent-src/`), not from `src/`, because that
|
|
378
|
+
* is the tree a host actually loads. Reading `src/` would measure a surface no
|
|
379
|
+
* host sees, and the two can diverge for exactly one revision at a time.
|
|
380
|
+
*
|
|
381
|
+
* The catalogue is the WHOLE estate even when the diff scope is one unit: the
|
|
382
|
+
* routing condition is competitive, so a description is only judgeable against
|
|
383
|
+
* the 400-odd it competes with. Scoping the CASES is the cost control; scoping
|
|
384
|
+
* the catalogue would change what is being measured.
|
|
385
|
+
*/
|
|
386
|
+
export function loadCatalogue(root = REPO_ROOT): SkillMeta[] {
|
|
387
|
+
const out: SkillMeta[] = [];
|
|
388
|
+
const push = (name: string, file: string): void => {
|
|
389
|
+
let text: string;
|
|
390
|
+
try {
|
|
391
|
+
text = fs.readFileSync(file, 'utf-8');
|
|
392
|
+
} catch {
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
const m = /^description:\s*(.+)$/m.exec(text.split('---')[1] ?? '');
|
|
396
|
+
out.push({ name, description: m ? unquote(m[1] ?? '') : '' });
|
|
397
|
+
};
|
|
398
|
+
const sdir = path.join(root, 'dist', 'agent-src', 'skills');
|
|
399
|
+
try {
|
|
400
|
+
for (const d of fs.readdirSync(sdir, { withFileTypes: true })) {
|
|
401
|
+
if (d.isDirectory()) push(d.name, path.join(sdir, d.name, 'SKILL.md'));
|
|
402
|
+
}
|
|
403
|
+
} catch {
|
|
404
|
+
/* no projection in this tree — the caller sees an empty catalogue */
|
|
405
|
+
}
|
|
406
|
+
const rdir = path.join(root, 'dist', 'agent-src', 'rules');
|
|
407
|
+
try {
|
|
408
|
+
for (const f of fs.readdirSync(rdir)) {
|
|
409
|
+
if (f.endsWith('.md')) push(f.replace(/\.md$/, ''), path.join(rdir, f));
|
|
410
|
+
}
|
|
411
|
+
} catch {
|
|
412
|
+
/* same */
|
|
413
|
+
}
|
|
414
|
+
return out;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/* ── CLI ──────────────────────────────────────────────────────────────────── */
|
|
418
|
+
|
|
419
|
+
function flagValue(argv: readonly string[], name: string): string | null {
|
|
420
|
+
const i = argv.indexOf(name);
|
|
421
|
+
return i >= 0 && i + 1 < argv.length ? (argv[i + 1] ?? null) : null;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
export function main(argv: string[] = process.argv.slice(2), root = REPO_ROOT): number {
|
|
425
|
+
const write = process.stdout.write.bind(process.stdout);
|
|
426
|
+
const listFile = flagValue(argv, '--changed-files');
|
|
427
|
+
let changed: string[] = [];
|
|
428
|
+
if (listFile !== null) {
|
|
429
|
+
try {
|
|
430
|
+
changed = fs
|
|
431
|
+
.readFileSync(listFile, 'utf-8')
|
|
432
|
+
.split('\n')
|
|
433
|
+
.map((s) => s.trim())
|
|
434
|
+
.filter((s) => s !== '');
|
|
435
|
+
} catch {
|
|
436
|
+
process.stderr.write(`--changed-files: cannot read ${listFile}\n`);
|
|
437
|
+
return 2;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
const decision = scopeRun({ isFork: argv.includes('--fork'), changedFiles: changed });
|
|
441
|
+
write(`scope: ${decision.mode} — ${decision.reason}\n`);
|
|
442
|
+
if (decision.mode === 'advisory') {
|
|
443
|
+
// Not a pass and not a skip-with-a-shrug: the advisory path is the
|
|
444
|
+
// SHIPPED behaviour for this class of diff, and saying so is what keeps
|
|
445
|
+
// a green run from reading as coverage it does not have.
|
|
446
|
+
write('advisory path unchanged; no scoped run, no spend.\n');
|
|
447
|
+
return 0;
|
|
448
|
+
}
|
|
449
|
+
const all = loadCases(root);
|
|
450
|
+
const cases = scopeCases(all, decision.units);
|
|
451
|
+
if (cases.length === 0) {
|
|
452
|
+
write(
|
|
453
|
+
`no corpus case exists for ${decision.units.join(', ')} — the description ` +
|
|
454
|
+
'changed on a unit nothing covers. That is a corpus gap, reported rather ' +
|
|
455
|
+
'than passed over; the 0.3 ratchet is what makes closing it durable.\n',
|
|
456
|
+
);
|
|
457
|
+
return 0;
|
|
458
|
+
}
|
|
459
|
+
const catalogue = loadCatalogue(root);
|
|
460
|
+
const dry = argv.includes('--dry');
|
|
461
|
+
const inner: Backend = new DryBackend();
|
|
462
|
+
const backend = dry ? inner : new CachedBackend(inner, path.join(root, CACHE_REL));
|
|
463
|
+
const report = evaluate(cases, catalogue, backend);
|
|
464
|
+
// The ledger's target is the UNIT, not the individual case: a unit is what
|
|
465
|
+
// the diff scoped in, so a per-case ledger would report rows nobody chose
|
|
466
|
+
// to include while hiding which unit actually regressed.
|
|
467
|
+
const ledger = new GateLedger('description_route_check');
|
|
468
|
+
ledger.plan(decision.units);
|
|
469
|
+
for (const u of decision.units) {
|
|
470
|
+
const own = report.findings.filter((f) => f.unit === u && f.direction === 'recall');
|
|
471
|
+
if (own.length === 0) ledger.complete(u);
|
|
472
|
+
else ledger.fail(u, `${String(own.length)} positive(s) stopped loading`);
|
|
473
|
+
}
|
|
474
|
+
ledger.report(write);
|
|
475
|
+
const code = render(report, write);
|
|
476
|
+
if (dry) {
|
|
477
|
+
// The dry backend is a NAME-substring matcher over a catalogue whose
|
|
478
|
+
// signal is the DESCRIPTION, so it misses almost every real prompt by
|
|
479
|
+
// construction. Its verdict is therefore not a verdict: `--dry` proves
|
|
480
|
+
// the plumbing runs with no key and no spend, and nothing else.
|
|
481
|
+
// Returning its exit code would make every description edit red for a
|
|
482
|
+
// reason that has nothing to do with the description.
|
|
483
|
+
write(
|
|
484
|
+
'dry backend: findings above are PLUMBING output, not a routing result. ' +
|
|
485
|
+
'Exit forced to 0.\n',
|
|
486
|
+
);
|
|
487
|
+
return 0;
|
|
488
|
+
}
|
|
489
|
+
return code;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
if (path.resolve(process.argv[1] ?? '') === path.resolve(HERE)) {
|
|
493
|
+
process.exit(main());
|
|
494
|
+
}
|
|
@@ -175,6 +175,35 @@ const BUZZWORDS = [
|
|
|
175
175
|
"leverage",
|
|
176
176
|
];
|
|
177
177
|
|
|
178
|
+
/**
|
|
179
|
+
* Stock render subjects — the default thing an image or 3D model becomes when
|
|
180
|
+
* nobody decided what it should be about.
|
|
181
|
+
*
|
|
182
|
+
* Same mechanism as `BUZZWORDS` (CP2), applied to art direction instead of
|
|
183
|
+
* prose: each entry names a *visual* that carries no subject matter. The
|
|
184
|
+
* delete-test is the same one — swap the phrase for the product's actual
|
|
185
|
+
* subject and the brief says more, which is the proof it said nothing.
|
|
186
|
+
*
|
|
187
|
+
* On the `copy` engine deliberately. A CSS engine cannot see subject matter:
|
|
188
|
+
* `transform: translateZ()` looks identical whether it moves a product or a
|
|
189
|
+
* glowing orb. The only detectable surface is the brief's own wording.
|
|
190
|
+
*/
|
|
191
|
+
const STOCK_RENDER_SUBJECTS = [
|
|
192
|
+
"floating abstract shapes",
|
|
193
|
+
"abstract floating shapes",
|
|
194
|
+
"gradient mesh",
|
|
195
|
+
"glowing orb",
|
|
196
|
+
"glowing orbs",
|
|
197
|
+
"floating particles",
|
|
198
|
+
"particle field",
|
|
199
|
+
"abstract 3d shape",
|
|
200
|
+
"abstract 3d shapes",
|
|
201
|
+
"futuristic hud",
|
|
202
|
+
"digital landscape",
|
|
203
|
+
"flowing ribbons",
|
|
204
|
+
"liquid metal blob",
|
|
205
|
+
];
|
|
206
|
+
|
|
178
207
|
// ---------------------------------------------------------------------------
|
|
179
208
|
// The registry
|
|
180
209
|
// ---------------------------------------------------------------------------
|
|
@@ -314,9 +343,15 @@ export const SLOP_RULES: SlopRule[] = [
|
|
|
314
343
|
catalogId: "T7",
|
|
315
344
|
severity: "P2",
|
|
316
345
|
engines: ["css"],
|
|
317
|
-
description: "Default AI font (Inter/Roboto/DM Sans/Geist/Space Grotesk/Instrument Serif) without a
|
|
346
|
+
description: "Default AI font (Inter/Roboto/DM Sans/Geist/Space Grotesk/Instrument Serif) without a stated reason",
|
|
347
|
+
// Register-scoped by the catalog, NOT by this matcher: a CSS text pass carries
|
|
348
|
+
// no register signal, so the scope lives in the rebuttal rather than in the
|
|
349
|
+
// gate. `design-modes.md` sanctions a single reliable family in the PRODUCT
|
|
350
|
+
// register, which makes "product register" a complete reason on its own — the
|
|
351
|
+
// message names it so a product surface knows the rebuttal without reading two
|
|
352
|
+
// guidelines. P2 is a rebuttable presumption (see the header), never a block.
|
|
318
353
|
message:
|
|
319
|
-
"This is a default AI-coding-tool font pick. Declare it
|
|
354
|
+
"This is a default AI-coding-tool font pick. Declare it with a reason (T7) — in the product register, \"single reliable family\" IS the reason; state it in DESIGN.md or the surface brief.",
|
|
320
355
|
gated: (ctx) => DEFAULT_FONTS.some((f) => ctx.has(f)),
|
|
321
356
|
detect: ({ lines }) =>
|
|
322
357
|
lines.flatMap((l, i) => {
|
|
@@ -416,6 +451,25 @@ export const SLOP_RULES: SlopRule[] = [
|
|
|
416
451
|
return [];
|
|
417
452
|
},
|
|
418
453
|
},
|
|
454
|
+
{
|
|
455
|
+
id: "slop-cp6-generic-art-direction",
|
|
456
|
+
catalogId: "CP6",
|
|
457
|
+
severity: "P2",
|
|
458
|
+
engines: ["copy"],
|
|
459
|
+
description: "Stock render subject named in a brief instead of the product's own subject matter",
|
|
460
|
+
message:
|
|
461
|
+
"This names a default visual, not a subject — swap it for what the product " +
|
|
462
|
+
"actually shows and the brief says more (CP6).",
|
|
463
|
+
detect: ({ content, ext }) => {
|
|
464
|
+
const text = visibleText(content, ext);
|
|
465
|
+
const lower = text.toLowerCase();
|
|
466
|
+
const hits = STOCK_RENDER_SUBJECTS.filter((s) => lower.includes(s));
|
|
467
|
+
if (hits.length === 0) {
|
|
468
|
+
return [];
|
|
469
|
+
}
|
|
470
|
+
return [{ line: 1, snippet: hits.slice(0, 3).join(", ") }];
|
|
471
|
+
},
|
|
472
|
+
},
|
|
419
473
|
{
|
|
420
474
|
id: "slop-cp5-emoji-ui",
|
|
421
475
|
catalogId: "CP5",
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
* (bad ref, unreadable file, crash).
|
|
40
40
|
*/
|
|
41
41
|
|
|
42
|
+
import { independenceFields } from './_lib/review_independence.js';
|
|
42
43
|
import { execFileSync } from 'node:child_process';
|
|
43
44
|
import { createHash } from 'node:crypto';
|
|
44
45
|
import * as fs from 'node:fs';
|
|
@@ -872,6 +873,21 @@ function findingsSkeleton(args: {
|
|
|
872
873
|
return [
|
|
873
874
|
`# Findings: ${args.slug}`,
|
|
874
875
|
`<!-- completion-review: v1 | reviewed: ${args.reviewedDate} | scope: ${args.scopeHash} | diff: ${args.headSha} | reviewer: r2-fresh-subagent-${args.slug} | prompt_hash: ${args.promptHash} -->`,
|
|
876
|
+
// SECOND PRODUCER of the independence record — step 2.2 of
|
|
877
|
+
// road-to-review-independence. Until this line, `self_review_gate.ts` was the
|
|
878
|
+
// only producer, which is why `check_review_schema` reported `scanned: 1`: a
|
|
879
|
+
// schema gate with one producer checks that one producer agrees with itself.
|
|
880
|
+
//
|
|
881
|
+
// The values are derived, never chosen. `single-member` because this dispatch
|
|
882
|
+
// has exactly one reviewer; `fresh` because a fresh subagent is what this file
|
|
883
|
+
// dispatches and is the property the whole artifact exists to carry (the
|
|
884
|
+
// `reviewer:` field above already says so in prose). Both axes go in, and the
|
|
885
|
+
// derived pair follows: single-member + fresh is `provisional` / `single-pass`.
|
|
886
|
+
//
|
|
887
|
+
// Recording `provisional` on a fresh reviewer is not a downgrade — it is the
|
|
888
|
+
// honest reading. One reviewer is one reviewer, however uncontaminated; the
|
|
889
|
+
// family axis is what `accepted` needs and one member cannot supply it.
|
|
890
|
+
`<!-- ${JSON.stringify({ 'review-independence': independenceFields([`r2-fresh-subagent-${args.slug}`], 'fresh') })} -->`,
|
|
875
891
|
// Set at CREATION, never inferred later: an inferred type reads filename
|
|
876
892
|
// and location, which are exactly the signals that already fail to
|
|
877
893
|
// distinguish an input from a binding. This artifact binds a scope from
|