@event4u/agent-config 14.9.0 → 14.11.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 +384 -0
- 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/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/alerting-doctrine/evals/triggers.json +17 -0
- package/dist/agent-src/skills/async-python-patterns/SKILL.md +1 -1
- 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 +1 -1
- package/dist/agent-src/skills/code-review/SKILL.md +11 -0
- package/dist/agent-src/skills/command-routing/SKILL.md +6 -0
- package/dist/agent-src/skills/condense-memory/SKILL.md +4 -1
- package/dist/agent-src/skills/context-authoring/SKILL.md +1 -1
- package/dist/agent-src/skills/conventional-commits-writing/SKILL.md +4 -1
- 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 +80 -2
- 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/discovery-interview/SKILL.md +1 -1
- package/dist/agent-src/skills/doc-coauthoring/SKILL.md +1 -1
- package/dist/agent-src/skills/docx-authoring/SKILL.md +1 -1
- package/dist/agent-src/skills/editorial-calendar/SKILL.md +1 -1
- package/dist/agent-src/skills/estimate-ticket/SKILL.md +3 -0
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +20 -3
- package/dist/agent-src/skills/fe-design/SKILL.md +74 -41
- package/dist/agent-src/skills/fe-design/evals/triggers.json +65 -53
- 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/github-ci/SKILL.md +1 -1
- 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/evals/triggers.json +17 -0
- package/dist/agent-src/skills/js-library-packaging/scripts/check_package_surface.ts +270 -0
- package/dist/agent-src/skills/judge-artifact-completeness/SKILL.md +1 -1
- package/dist/agent-src/skills/judge-injection-defense/SKILL.md +1 -1
- package/dist/agent-src/skills/laravel-migration/SKILL.md +3 -0
- package/dist/agent-src/skills/laravel-validation/SKILL.md +1 -1
- package/dist/agent-src/skills/learning-to-rule-or-skill/SKILL.md +3 -0
- package/dist/agent-src/skills/legal-intake-triage/SKILL.md +1 -1
- package/dist/agent-src/skills/legal-practice-profile/SKILL.md +1 -1
- 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/messaging-architecture/SKILL.md +1 -1
- package/dist/agent-src/skills/migration-architect/SKILL.md +1 -1
- package/dist/agent-src/skills/module-detect-on-the-fly/SKILL.md +1 -1
- package/dist/agent-src/skills/module-management/SKILL.md +1 -1
- package/dist/agent-src/skills/monorepo-workspace/SKILL.md +149 -0
- package/dist/agent-src/skills/monorepo-workspace/evals/triggers.json +17 -0
- package/dist/agent-src/skills/motion-choreographer/SKILL.md +7 -1
- package/dist/agent-src/skills/multi-tenancy/SKILL.md +4 -0
- package/dist/agent-src/skills/onboarding-program/SKILL.md +1 -1
- package/dist/agent-src/skills/operational-readiness/SKILL.md +184 -0
- package/dist/agent-src/skills/operational-readiness/evals/triggers.json +17 -0
- package/dist/agent-src/skills/override-management/SKILL.md +3 -0
- package/dist/agent-src/skills/perf-feedback-craft/SKILL.md +1 -1
- 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/prompt-engineering-image/SKILL.md +3 -0
- package/dist/agent-src/skills/prompt-optimizer/SKILL.md +1 -1
- package/dist/agent-src/skills/quality-tools/SKILL.md +5 -0
- package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +52 -21
- 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 +3 -3
- 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/SKILL.md +1 -1
- package/dist/agent-src/skills/scene-expander/scene-blueprint.schema.yaml +26 -0
- package/dist/agent-src/skills/secrets-management/SKILL.md +5 -1
- package/dist/agent-src/skills/server-hardening/SKILL.md +159 -0
- package/dist/agent-src/skills/server-hardening/evals/triggers.json +17 -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/spreadsheet-authoring/SKILL.md +3 -0
- package/dist/agent-src/skills/storybook-workshop/SKILL.md +194 -0
- package/dist/agent-src/skills/storybook-workshop/evals/triggers.json +17 -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 +9 -1
- package/dist/agent-src/skills/upstream-contribute/SKILL.md +3 -0
- package/dist/agent-src/skills/using-git-worktrees/SKILL.md +1 -1
- 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/skills/workspace-link/evals/triggers.json +17 -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/uiAudit.js.map +1 -0
- package/dist/cli/commands/uiRender.js +206 -0
- package/dist/cli/commands/uiRender.js.map +1 -0
- package/dist/cli/main.js +22 -1
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/mcp/content.js +64 -1
- package/dist/cli/mcp/content.js.map +1 -1
- package/dist/cli/mcp/dispatch.js +175 -10
- package/dist/cli/mcp/dispatch.js.map +1 -1
- package/dist/cli/registry.js +3 -0
- package/dist/cli/registry.js.map +1 -1
- package/dist/cli-delegate/{chunk-H4VIVD4C.js → chunk-236PNQZK.js} +413 -391
- 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-PLSG6UL5.js → chunk-K4FFODTS.js} +341 -204
- package/dist/cli-delegate/{chunk-YM4GZDJG.js → chunk-L43NCYPB.js} +5 -0
- 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 +380 -145
- 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 +2337 -1436
- package/dist/install/install.mjs +795 -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/lean_projection_mode.js.map +1 -0
- package/dist/scripts/_lib/scoped_projection.js +84 -0
- package/dist/scripts/_lib/scoped_projection.js.map +1 -1
- package/dist/scripts/_lib/ui_surface.js +89 -0
- package/dist/scripts/_lib/ui_surface.js.map +1 -0
- package/dist/scripts/condense.js +6 -10
- package/dist/scripts/condense.js.map +1 -1
- package/dist/scripts/project_thin_rules.js +40 -2
- package/dist/scripts/project_thin_rules.js.map +1 -1
- package/dist/server/schemas/settings.js +3 -0
- package/dist/server/schemas/settings.js.map +1 -1
- package/dist/shared/skillRanking.js +159 -0
- package/dist/shared/skillRanking.js.map +1 -0
- package/docs/contracts/provider-lifecycle.md +47 -18
- package/docs/contracts/settings-classes.md +14 -4
- package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +49 -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/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/llms.txt +50 -39
- package/package.json +1 -1
- 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 +28 -0
- package/src/config/assurance-capability-registry.json +223 -0
- package/src/config/assurance-threshold-budget.json +65 -0
- package/src/config/ci-local-parity.yml +14 -0
- package/src/config/discovery/unassigned-artefacts.yml +2 -0
- package/src/config/dispatch-economy-metrics.json +4 -2
- package/src/config/evaluator-budgets.json +14 -14
- package/src/config/gate-coverage.yml +227 -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 +4 -2
- package/src/config/preamble-payload-budget.json +71 -67
- package/src/config/quorum-attendance-budget.json +12 -4
- 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/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/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/transcript_reads.ts +207 -0
- package/src/scripts/_lib/ui_authority.test.ts +251 -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/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/seating.ts +211 -0
- 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_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_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_pack_passport_reconciliation.ts +274 -0
- 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_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/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/design_slop_rules.test.ts +7 -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/generate_pack_manifests.ts +78 -0
- package/src/scripts/grade_target_readiness.ts +478 -0
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +97 -16
- package/src/scripts/hooks/concern_registry.ts +4 -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/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 +2 -1
- 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_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/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/roadmap_context.ts +778 -0
- package/src/scripts/schemas/fidelity-measurement-sheet.schema.json +169 -0
- package/src/scripts/schemas/pack.schema.json +62 -4
- package/src/scripts/schemas/rule.schema.json +24 -2
- package/src/scripts/schemas/skill.schema.json +41 -2
- package/src/scripts/schemas/ui-authority.schema.json +114 -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/tighten_skill_descriptions.ts +264 -0
- 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 +5 -0
- package/src/shared/skillRanking.ts +183 -0
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Token-sink ranking + re-read measurement over the local transcript store.
|
|
4
|
+
*
|
|
5
|
+
* `road-to-role-scoped-spawn-profiles` Phase 3 Steps 1-3. Phase 3 is declared
|
|
6
|
+
* independent of that roadmap's Phases 0-2 in both directions: it needs no
|
|
7
|
+
* payload capture and it arms nothing.
|
|
8
|
+
*
|
|
9
|
+
* **The denominator is published, deliberately.** Step 2's whole content is
|
|
10
|
+
* that *"a sink's share is only meaningful against the total it was measured
|
|
11
|
+
* from, and the store is one machine's history — the report says so rather
|
|
12
|
+
* than reading as a property of the package."* Every rendered figure is
|
|
13
|
+
* therefore accompanied by the record count, the date range, and the
|
|
14
|
+
* single-store caveat, and {@link Report.provenance} carries that sentence as
|
|
15
|
+
* data so a JSON consumer cannot strip it by taking the numbers only.
|
|
16
|
+
*
|
|
17
|
+
* **Two things this report is NOT.** It is not a cost figure — the weighting
|
|
18
|
+
* is the cost-SHAPED `weightedInputUnits` from `_lib/cc_transcript.ts`, not a
|
|
19
|
+
* price. And the wasted-token column is a `chars / 4` proxy over duplicate
|
|
20
|
+
* `tool_result` bodies (see `_lib/transcript_reads.ts`), because the
|
|
21
|
+
* transcript records no per-tool-result token count; it is named
|
|
22
|
+
* `wasted_tokens_proxy` everywhere so the label travels with the number.
|
|
23
|
+
*
|
|
24
|
+
* Class A: in-process, per-invocation, read-only, no network, no daemon, no
|
|
25
|
+
* writes outside stdout.
|
|
26
|
+
*
|
|
27
|
+
* Usage:
|
|
28
|
+
* ./scripts-run src/scripts/token_sink_report [--format text|json]
|
|
29
|
+
* [--root <path>] [--max-age-days <n>] [--top <n>]
|
|
30
|
+
*/
|
|
31
|
+
import * as path from 'node:path';
|
|
32
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
33
|
+
|
|
34
|
+
import {
|
|
35
|
+
DEFAULT_PROJECTS_ROOT,
|
|
36
|
+
billableInputTokens,
|
|
37
|
+
listTranscriptFiles,
|
|
38
|
+
scanTranscripts,
|
|
39
|
+
weightedInputUnits,
|
|
40
|
+
type TranscriptRecord,
|
|
41
|
+
} from './_lib/cc_transcript.js';
|
|
42
|
+
import { computeRereads, type RereadResult } from './_lib/transcript_reads.js';
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* One token sink: a `bucket/model` pair. The bucket half is what makes the
|
|
46
|
+
* ranking answer the question the roadmap asks — `main` versus `subagent` is
|
|
47
|
+
* the axis a scoping decision acts on — and the model half keeps a cheap
|
|
48
|
+
* worker's traffic from being summed with an expensive orchestrator's.
|
|
49
|
+
*/
|
|
50
|
+
export interface Sink {
|
|
51
|
+
sink: string;
|
|
52
|
+
bucket: string;
|
|
53
|
+
model: string;
|
|
54
|
+
calls: number;
|
|
55
|
+
billable_input: number;
|
|
56
|
+
weighted_input_units: number;
|
|
57
|
+
/** This sink's share of total weighted input units, 0..1. */
|
|
58
|
+
weighted_share: number;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function rankSinks(records: readonly TranscriptRecord[]): Sink[] {
|
|
62
|
+
const acc = new Map<string, Sink>();
|
|
63
|
+
for (const r of records) {
|
|
64
|
+
const key = `${r.bucket}/${r.model}`;
|
|
65
|
+
const row = acc.get(key) ?? {
|
|
66
|
+
sink: key,
|
|
67
|
+
bucket: r.bucket,
|
|
68
|
+
model: r.model,
|
|
69
|
+
calls: 0,
|
|
70
|
+
billable_input: 0,
|
|
71
|
+
weighted_input_units: 0,
|
|
72
|
+
weighted_share: 0,
|
|
73
|
+
};
|
|
74
|
+
row.calls += 1;
|
|
75
|
+
row.billable_input += billableInputTokens(r.usage);
|
|
76
|
+
row.weighted_input_units += weightedInputUnits(r.usage);
|
|
77
|
+
acc.set(key, row);
|
|
78
|
+
}
|
|
79
|
+
const rows = [...acc.values()];
|
|
80
|
+
const total = rows.reduce((s, r) => s + r.weighted_input_units, 0);
|
|
81
|
+
for (const r of rows) {
|
|
82
|
+
r.weighted_share = total > 0 ? r.weighted_input_units / total : 0;
|
|
83
|
+
}
|
|
84
|
+
rows.sort((a, b) => b.weighted_input_units - a.weighted_input_units || a.sink.localeCompare(b.sink));
|
|
85
|
+
return rows;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface Options {
|
|
89
|
+
format: 'text' | 'json';
|
|
90
|
+
root: string;
|
|
91
|
+
maxAgeDays: number;
|
|
92
|
+
top: number;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const DEFAULT_TOP = 15;
|
|
96
|
+
|
|
97
|
+
export function parseArgs(argv: string[]): Options {
|
|
98
|
+
const opts: Options = {
|
|
99
|
+
format: 'text',
|
|
100
|
+
root: DEFAULT_PROJECTS_ROOT,
|
|
101
|
+
maxAgeDays: 90,
|
|
102
|
+
top: DEFAULT_TOP,
|
|
103
|
+
};
|
|
104
|
+
for (let i = 0; i < argv.length; i++) {
|
|
105
|
+
const a = argv[i];
|
|
106
|
+
if (a === undefined) continue;
|
|
107
|
+
if (a === '--format') opts.format = (argv[++i] as Options['format']) ?? opts.format;
|
|
108
|
+
else if (a.startsWith('--format=')) opts.format = a.slice('--format='.length) as Options['format'];
|
|
109
|
+
else if (a === '--root') opts.root = argv[++i] ?? opts.root;
|
|
110
|
+
else if (a.startsWith('--root=')) opts.root = a.slice('--root='.length);
|
|
111
|
+
else if (a === '--max-age-days') opts.maxAgeDays = Number(argv[++i]) || opts.maxAgeDays;
|
|
112
|
+
else if (a.startsWith('--max-age-days=')) opts.maxAgeDays = Number(a.slice('--max-age-days='.length)) || opts.maxAgeDays;
|
|
113
|
+
else if (a === '--top') opts.top = Number(argv[++i]) || opts.top;
|
|
114
|
+
else if (a.startsWith('--top=')) opts.top = Number(a.slice('--top='.length)) || opts.top;
|
|
115
|
+
}
|
|
116
|
+
if (opts.format !== 'text' && opts.format !== 'json') opts.format = 'text';
|
|
117
|
+
return opts;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* The single-store caveat, carried as DATA rather than as rendering. A JSON
|
|
122
|
+
* consumer that keeps `sinks` and drops the prose still keeps this field.
|
|
123
|
+
*/
|
|
124
|
+
export const PROVENANCE =
|
|
125
|
+
'Local-store-derived: computed from one machine\'s ~/.claude/projects transcripts. ' +
|
|
126
|
+
'Every share below is a fact about this store, not a property of the package.';
|
|
127
|
+
|
|
128
|
+
export interface Report {
|
|
129
|
+
schema: 'token-sink-report/v1';
|
|
130
|
+
root: string;
|
|
131
|
+
window_days: number;
|
|
132
|
+
provenance: string;
|
|
133
|
+
total_seen: number;
|
|
134
|
+
deduped_count: number;
|
|
135
|
+
dedup_ratio: number;
|
|
136
|
+
legs_scanned: number;
|
|
137
|
+
date_range: { first: string | null; last: string | null };
|
|
138
|
+
sinks: Sink[];
|
|
139
|
+
rereads: RereadResult;
|
|
140
|
+
wasted_tokens_proxy_note: string;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const PROXY_NOTE =
|
|
144
|
+
'wasted_tokens_proxy is a chars / 4 estimate over duplicate tool_result bodies. ' +
|
|
145
|
+
'The transcript records no per-tool-result token count, so this is a proxy, never a measurement.';
|
|
146
|
+
|
|
147
|
+
export function buildReport(opts: Options): Report {
|
|
148
|
+
const scan = scanTranscripts({ root: opts.root, maxAgeDays: opts.maxAgeDays });
|
|
149
|
+
const files = listTranscriptFiles({ root: opts.root, maxAgeDays: opts.maxAgeDays });
|
|
150
|
+
const rereads = computeRereads(files);
|
|
151
|
+
|
|
152
|
+
const stamps = scan.records
|
|
153
|
+
.map((r) => r.timestamp)
|
|
154
|
+
.filter((t): t is string => typeof t === 'string' && t.length > 0)
|
|
155
|
+
.sort();
|
|
156
|
+
|
|
157
|
+
return {
|
|
158
|
+
schema: 'token-sink-report/v1',
|
|
159
|
+
root: opts.root,
|
|
160
|
+
window_days: opts.maxAgeDays,
|
|
161
|
+
provenance: PROVENANCE,
|
|
162
|
+
total_seen: scan.totalSeen,
|
|
163
|
+
deduped_count: scan.dedupedCount,
|
|
164
|
+
dedup_ratio: scan.dedup_ratio,
|
|
165
|
+
legs_scanned: rereads.legs_scanned,
|
|
166
|
+
date_range: { first: stamps[0] ?? null, last: stamps[stamps.length - 1] ?? null },
|
|
167
|
+
sinks: rankSinks(scan.records),
|
|
168
|
+
rereads,
|
|
169
|
+
wasted_tokens_proxy_note: PROXY_NOTE,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function pct(v: number): string {
|
|
174
|
+
return `${(v * 100).toFixed(1)}%`;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export function renderText(r: Report, top: number = DEFAULT_TOP): string {
|
|
178
|
+
const out: string[] = [];
|
|
179
|
+
out.push('token-sink report · schema token-sink-report/v1');
|
|
180
|
+
out.push('');
|
|
181
|
+
out.push('Denominator (read this before any share below):');
|
|
182
|
+
out.push(` records (deduped) : ${r.deduped_count} of ${r.total_seen} seen (dedup ${pct(r.dedup_ratio)})`);
|
|
183
|
+
out.push(` transcript legs : ${r.legs_scanned}`);
|
|
184
|
+
out.push(` date range : ${r.date_range.first ?? 'n/a'} .. ${r.date_range.last ?? 'n/a'}`);
|
|
185
|
+
out.push(` window : ${r.window_days} days · root ${r.root}`);
|
|
186
|
+
out.push(` provenance : ${r.provenance}`);
|
|
187
|
+
out.push('');
|
|
188
|
+
|
|
189
|
+
if (r.deduped_count === 0) {
|
|
190
|
+
out.push('No records in this store for the given window — nothing to rank.');
|
|
191
|
+
out.push('');
|
|
192
|
+
} else {
|
|
193
|
+
out.push(`Token sinks, ranked by weighted input units (top ${top}):`);
|
|
194
|
+
for (const s of r.sinks.slice(0, top)) {
|
|
195
|
+
out.push(
|
|
196
|
+
` ${s.sink.padEnd(38)} calls=${String(s.calls).padStart(6)} ` +
|
|
197
|
+
`weighted=${s.weighted_input_units.toFixed(0).padStart(12)} share=${pct(s.weighted_share)}`,
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
out.push('');
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
out.push('Re-reads within a single transcript leg:');
|
|
204
|
+
out.push(` reads observed : ${r.rereads.total_reads}`);
|
|
205
|
+
out.push(` duplicate reads : ${r.rereads.duplicate_reads}`);
|
|
206
|
+
out.push(` wasted (proxy) : ${r.rereads.wasted_tokens_proxy} tokens`);
|
|
207
|
+
out.push(` note : ${r.wasted_tokens_proxy_note}`);
|
|
208
|
+
if (r.rereads.files.length === 0) {
|
|
209
|
+
out.push(' no file was read twice inside one leg in this window.');
|
|
210
|
+
} else {
|
|
211
|
+
out.push(` top ${top} by wasted (proxy):`);
|
|
212
|
+
for (const f of r.rereads.files.slice(0, top)) {
|
|
213
|
+
out.push(
|
|
214
|
+
` ${f.file_path}\n reads=${f.total_reads} dup=${f.duplicate_reads} ` +
|
|
215
|
+
`legs_with_reread=${f.legs_with_reread} wasted_proxy=${f.wasted_tokens_proxy}`,
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return out.join('\n');
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export function main(argv: string[] = process.argv.slice(2)): number {
|
|
223
|
+
const opts = parseArgs(argv);
|
|
224
|
+
const report = buildReport(opts);
|
|
225
|
+
if (opts.format === 'json') {
|
|
226
|
+
process.stdout.write(JSON.stringify(report, null, 2) + '\n');
|
|
227
|
+
} else {
|
|
228
|
+
process.stdout.write(renderText(report, opts.top) + '\n');
|
|
229
|
+
}
|
|
230
|
+
return 0;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const _HERE = fileURLToPath(import.meta.url);
|
|
234
|
+
declare const __AGENT_CONFIG_BUNDLE__: boolean | undefined;
|
|
235
|
+
const _bundled = typeof __AGENT_CONFIG_BUNDLE__ !== 'undefined' && __AGENT_CONFIG_BUNDLE__;
|
|
236
|
+
if (!_bundled && process.argv[1] !== undefined) {
|
|
237
|
+
const invokedUrl = pathToFileURL(path.resolve(process.argv[1])).href;
|
|
238
|
+
if (pathToFileURL(_HERE).href === invokedUrl) process.exit(main());
|
|
239
|
+
}
|
|
@@ -338,14 +338,18 @@ interface ParsedArgs {
|
|
|
338
338
|
json: boolean;
|
|
339
339
|
/** `rule` keeps the pinned byte-identical contract; `skill` is additive. */
|
|
340
340
|
scope: 'rule' | 'skill';
|
|
341
|
+
/** `--ratchet`: compare the skill scope against its published baseline. */
|
|
342
|
+
ratchet: boolean;
|
|
341
343
|
}
|
|
342
344
|
|
|
343
345
|
function parse_args(argv: string[]): ParsedArgs {
|
|
344
|
-
const out: ParsedArgs = { json: false, scope: 'rule' };
|
|
346
|
+
const out: ParsedArgs = { json: false, scope: 'rule', ratchet: false };
|
|
345
347
|
for (let i = 0; i < argv.length; i += 1) {
|
|
346
348
|
const a = argv[i]!;
|
|
347
349
|
if (a === '--json') {
|
|
348
350
|
out.json = true;
|
|
351
|
+
} else if (a === '--ratchet') {
|
|
352
|
+
out.ratchet = true;
|
|
349
353
|
} else if (a === '--scope') {
|
|
350
354
|
const v = argv[i + 1];
|
|
351
355
|
if (v !== 'rule' && v !== 'skill') {
|
|
@@ -355,7 +359,9 @@ function parse_args(argv: string[]): ParsedArgs {
|
|
|
355
359
|
out.scope = v;
|
|
356
360
|
i += 1;
|
|
357
361
|
} else if (a === '-h' || a === '--help') {
|
|
358
|
-
process.stdout.write(
|
|
362
|
+
process.stdout.write(
|
|
363
|
+
'usage: trigger_coverage [-h] [--json] [--scope rule|skill] [--ratchet]\n',
|
|
364
|
+
);
|
|
359
365
|
process.exit(0);
|
|
360
366
|
}
|
|
361
367
|
}
|
|
@@ -372,6 +378,113 @@ function parse_args(argv: string[]): ParsedArgs {
|
|
|
372
378
|
* its own change, not against a number invented on the day the instrument
|
|
373
379
|
* shipped.
|
|
374
380
|
*/
|
|
381
|
+
/** The published skill-coverage baseline `--ratchet` compares against. */
|
|
382
|
+
export const SKILL_RATCHET_BASELINE = path.join(
|
|
383
|
+
REPO_ROOT,
|
|
384
|
+
'agents',
|
|
385
|
+
'evidence',
|
|
386
|
+
'metrics',
|
|
387
|
+
'skill-trigger-coverage-baseline.json',
|
|
388
|
+
);
|
|
389
|
+
|
|
390
|
+
export interface SkillRatchetBaseline {
|
|
391
|
+
skills_with_triggers: number;
|
|
392
|
+
activations: number;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/** Read the baseline, or `null` when none is published yet. */
|
|
396
|
+
export function loadSkillRatchetBaseline(file = SKILL_RATCHET_BASELINE): SkillRatchetBaseline | null {
|
|
397
|
+
if (!fs.existsSync(file)) return null;
|
|
398
|
+
try {
|
|
399
|
+
const parsed = JSON.parse(fs.readFileSync(file, 'utf-8')) as Record<string, unknown>;
|
|
400
|
+
const c = parsed['skills_with_triggers'];
|
|
401
|
+
const a = parsed['activations'];
|
|
402
|
+
if (typeof c !== 'number' || typeof a !== 'number') return null;
|
|
403
|
+
return { skills_with_triggers: c, activations: a };
|
|
404
|
+
} catch {
|
|
405
|
+
return null;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
export interface RatchetVerdict {
|
|
410
|
+
ok: boolean;
|
|
411
|
+
lines: string[];
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* The Phase-3.2 ratchet, as a pure function of two readings.
|
|
416
|
+
*
|
|
417
|
+
* TWO directions, and only one of them is a floor. Coverage
|
|
418
|
+
* (`skills_with_triggers`) may only RISE — a tranche that removes triggers is
|
|
419
|
+
* the regression this exists to catch. Activations over the matrix may only
|
|
420
|
+
* FALL OR HOLD — that is the noise ceiling, and it is the half that makes
|
|
421
|
+
* seeding safe rather than merely measurable.
|
|
422
|
+
*
|
|
423
|
+
* A missing baseline is NOT a pass. It is `ok: false` with a line saying to
|
|
424
|
+
* publish one, because a ratchet that silently no-ops when its baseline is gone
|
|
425
|
+
* is the failure mode a ratchet exists to prevent.
|
|
426
|
+
*/
|
|
427
|
+
export function ratchetVerdict(
|
|
428
|
+
current: SkillRatchetBaseline,
|
|
429
|
+
baseline: SkillRatchetBaseline | null,
|
|
430
|
+
): RatchetVerdict {
|
|
431
|
+
if (baseline === null) {
|
|
432
|
+
return {
|
|
433
|
+
ok: false,
|
|
434
|
+
lines: [
|
|
435
|
+
'❌ no published baseline — cannot ratchet.',
|
|
436
|
+
` Publish one: {"skills_with_triggers": ${current.skills_with_triggers}, ` +
|
|
437
|
+
`"activations": ${current.activations}}`,
|
|
438
|
+
` at agents/evidence/metrics/skill-trigger-coverage-baseline.json`,
|
|
439
|
+
],
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
const lines: string[] = [];
|
|
443
|
+
let ok = true;
|
|
444
|
+
if (current.skills_with_triggers < baseline.skills_with_triggers) {
|
|
445
|
+
ok = false;
|
|
446
|
+
lines.push(
|
|
447
|
+
`❌ coverage fell: ${baseline.skills_with_triggers} → ${current.skills_with_triggers} ` +
|
|
448
|
+
'skills declaring triggers. The ratchet only turns one way.',
|
|
449
|
+
);
|
|
450
|
+
} else {
|
|
451
|
+
lines.push(
|
|
452
|
+
`✅ coverage ${baseline.skills_with_triggers} → ${current.skills_with_triggers} ` +
|
|
453
|
+
'skills declaring triggers.',
|
|
454
|
+
);
|
|
455
|
+
}
|
|
456
|
+
if (current.activations > baseline.activations) {
|
|
457
|
+
ok = false;
|
|
458
|
+
lines.push(
|
|
459
|
+
`❌ matrix activations rose: ${baseline.activations} → ${current.activations}. ` +
|
|
460
|
+
'A tranche may raise coverage only without raising noise.',
|
|
461
|
+
);
|
|
462
|
+
} else {
|
|
463
|
+
lines.push(`✅ matrix activations ${baseline.activations} → ${current.activations}.`);
|
|
464
|
+
}
|
|
465
|
+
return { ok, lines };
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
function runSkillRatchetCli(json: boolean): number {
|
|
469
|
+
const report = runSkillScope(loadSkillTriggers(SKILLS_DIR), loadMatrixPrompts(MATRIX_DIR));
|
|
470
|
+
const current = {
|
|
471
|
+
skills_with_triggers: report.skills_with_triggers,
|
|
472
|
+
activations: report.activations,
|
|
473
|
+
};
|
|
474
|
+
const verdict = ratchetVerdict(current, loadSkillRatchetBaseline());
|
|
475
|
+
if (json) {
|
|
476
|
+
process.stdout.write(_jsonDumps({ current, ok: verdict.ok, lines: verdict.lines }) + '\n');
|
|
477
|
+
return verdict.ok ? 0 : 1;
|
|
478
|
+
}
|
|
479
|
+
for (const line of verdict.lines) process.stdout.write(`${line}\n`);
|
|
480
|
+
process.stdout.write(
|
|
481
|
+
verdict.ok
|
|
482
|
+
? '\nskill-trigger ratchet: OK\n'
|
|
483
|
+
: '\nskill-trigger ratchet: FAILED\n',
|
|
484
|
+
);
|
|
485
|
+
return verdict.ok ? 0 : 1;
|
|
486
|
+
}
|
|
487
|
+
|
|
375
488
|
function runSkillScopeCli(json: boolean): number {
|
|
376
489
|
const report = runSkillScope(loadSkillTriggers(SKILLS_DIR), loadMatrixPrompts(MATRIX_DIR));
|
|
377
490
|
if (json) {
|
|
@@ -405,7 +518,13 @@ function runSkillScopeCli(json: boolean): number {
|
|
|
405
518
|
|
|
406
519
|
export function main(argv: string[] | null = null): number {
|
|
407
520
|
const args = parse_args(argv ?? process.argv.slice(2));
|
|
408
|
-
if (args.scope
|
|
521
|
+
if (args.ratchet && args.scope !== 'skill') {
|
|
522
|
+
process.stderr.write('error: --ratchet requires --scope skill\n');
|
|
523
|
+
return 2;
|
|
524
|
+
}
|
|
525
|
+
if (args.scope === 'skill') {
|
|
526
|
+
return args.ratchet ? runSkillRatchetCli(args.json) : runSkillScopeCli(args.json);
|
|
527
|
+
}
|
|
409
528
|
|
|
410
529
|
let isFile = false;
|
|
411
530
|
try {
|
|
@@ -281,9 +281,13 @@ export const TARGETS: ReadonlyArray<[string, ReadonlyArray<[string, string]>]> =
|
|
|
281
281
|
// claim names as its own method.
|
|
282
282
|
['(installs ships )(\\d+)( of )', 'skills_scoped'],
|
|
283
283
|
['( of )(\\d+)( skills \\(untagged core)', 'skills'],
|
|
284
|
-
// "
|
|
285
|
-
//
|
|
286
|
-
|
|
284
|
+
// The "N of M governed rules" position was retired on 2026-08-23:
|
|
285
|
+
// the `enforcement-coverage-resolved` entry no longer restates any
|
|
286
|
+
// enforcement figure, because five hand-written numbers for one
|
|
287
|
+
// property is the defect `check_enforcement_denominator` now reds
|
|
288
|
+
// on. The denominator lives in ONE place — the resolver's own output,
|
|
289
|
+
// projected into docs/proof.md § 4b — so there is no longer a
|
|
290
|
+
// literal here for a generator to keep in sync.
|
|
287
291
|
],
|
|
288
292
|
],
|
|
289
293
|
[
|
|
@@ -872,6 +872,69 @@ export function check_obligation_frequency(
|
|
|
872
872
|
];
|
|
873
873
|
}
|
|
874
874
|
|
|
875
|
+
/**
|
|
876
|
+
* Shape check for a skill's optional `scope:` write-scope declaration.
|
|
877
|
+
*
|
|
878
|
+
* WHAT IT CHECKS, and only this: when `scope:` is present it carries exactly ONE
|
|
879
|
+
* of `verification_command` / `verification_reason`. The `access` enum, the
|
|
880
|
+
* `pattern` shape and the closed key set are `skill.schema.json`'s and are
|
|
881
|
+
* already enforced by {@link validate} — including through `skill_linter`, which
|
|
882
|
+
* calls the same validator. This covers the one constraint JSON Schema cannot
|
|
883
|
+
* express in the subset implemented here: **exactly one of two optional
|
|
884
|
+
* siblings**. `oneOf` / `anyOf` / `not` are not implemented (nor are
|
|
885
|
+
* `minProperties` / `maxProperties`), so a schema-only attempt would be silently
|
|
886
|
+
* inert — which is worse than absent, because it reads as enforced.
|
|
887
|
+
*
|
|
888
|
+
* WHY EXACTLY ONE. Neither branch is a formality. A declaration with NEITHER is a
|
|
889
|
+
* scope claim nobody can check and nobody has excused, which is the pro-forma
|
|
890
|
+
* field the whole shape exists to avoid. A declaration with BOTH reads as
|
|
891
|
+
* "verified, with an excuse attached" — and the excuse is the half a reader would
|
|
892
|
+
* act on, so the pair is strictly less informative than either alone.
|
|
893
|
+
*
|
|
894
|
+
* WHY IT LIVES HERE AND NOT IN `skill_linter.ts`. It was written there and
|
|
895
|
+
* `check_source_size_budget` refused it: `skill_linter.ts` is 4,742 lines, the
|
|
896
|
+
* ratchet sums lines ABOVE 1,500 per file, and 63 added lines were 63 new
|
|
897
|
+
* violations against a shrink-only baseline. Extracting the body to `_lib` still
|
|
898
|
+
* left the import plus the call, i.e. +2, and a ratchet turns one way. This file
|
|
899
|
+
* is 1,120 lines, so the same code costs zero — and it sits beside
|
|
900
|
+
* {@link check_obligation_frequency}, the existing precedent for an
|
|
901
|
+
* artefact-specific check that the generic validator cannot express.
|
|
902
|
+
*
|
|
903
|
+
* WHAT IT DOES NOT CHECK, stated plainly: whether the declared paths are the
|
|
904
|
+
* paths the skill actually writes. Nothing observes a skill's writes, so that
|
|
905
|
+
* half is model-carried and `scope:` is a declaration, not a control.
|
|
906
|
+
*/
|
|
907
|
+
export function check_scope_declaration(data: Record<string, YamlValue>): SchemaError[] {
|
|
908
|
+
const scope = data['scope'];
|
|
909
|
+
if (scope === null || typeof scope !== 'object' || Array.isArray(scope)) return [];
|
|
910
|
+
const keys = scope as Record<string, YamlValue>;
|
|
911
|
+
const hasCommand = typeof keys['verification_command'] === 'string';
|
|
912
|
+
const hasReason = typeof keys['verification_reason'] === 'string';
|
|
913
|
+
if (hasCommand && hasReason) {
|
|
914
|
+
return [
|
|
915
|
+
new SchemaError(
|
|
916
|
+
'$.scope',
|
|
917
|
+
'scope-verification-both',
|
|
918
|
+
'declares BOTH verification_command and verification_reason — exactly one. A reason ' +
|
|
919
|
+
'beside a command reads as a verified claim with an excuse attached, and the excuse ' +
|
|
920
|
+
'is the half a reader would act on.',
|
|
921
|
+
),
|
|
922
|
+
];
|
|
923
|
+
}
|
|
924
|
+
if (!hasCommand && !hasReason) {
|
|
925
|
+
return [
|
|
926
|
+
new SchemaError(
|
|
927
|
+
'$.scope',
|
|
928
|
+
'scope-verification-missing',
|
|
929
|
+
'declares neither verification_command nor verification_reason — exactly one. A scope ' +
|
|
930
|
+
'claim with no command and no stated reason is unfalsifiable, which is the ' +
|
|
931
|
+
'pro-forma field this declaration exists to avoid.',
|
|
932
|
+
),
|
|
933
|
+
];
|
|
934
|
+
}
|
|
935
|
+
return [];
|
|
936
|
+
}
|
|
937
|
+
|
|
875
938
|
// --- CLI entry point -------------------------------------------------------
|
|
876
939
|
|
|
877
940
|
/** Yield `[artefact_type, path]` pairs for all lintable artefacts. */
|
|
@@ -999,6 +1062,9 @@ export function _main(argv: string[]): number {
|
|
|
999
1062
|
if (artefactType === 'rule') {
|
|
1000
1063
|
errors.push(...check_obligation_frequency(p, text, data));
|
|
1001
1064
|
}
|
|
1065
|
+
if (artefactType === 'skill') {
|
|
1066
|
+
errors.push(...check_scope_declaration(data));
|
|
1067
|
+
}
|
|
1002
1068
|
const fatal = errors.filter((e) => e.severity === 'error');
|
|
1003
1069
|
const warnings = errors.filter((e) => e.severity === 'warning');
|
|
1004
1070
|
if (fatal.length > 0) {
|
|
@@ -511,6 +511,11 @@ export const settingsSchema = z.object({
|
|
|
511
511
|
'PreToolUse anti-slop nudge (road-to-anti-slop-detector Phase 3). Default off. When on, runs the lint_design_slop registry against about-to-be-written UI content and WARNS (never blocks) on P0/P1 aesthetic tells (side-stripe, gradient-text, magic z-index, …). Flags are rebuttable via DESIGN.md / design-slop-disable. Anti-loop: a file::rule signature surfaced 3x goes silent. Host-limited convenience layer; the universal gate is the lint_design_slop linter/CI.',
|
|
512
512
|
),
|
|
513
513
|
}).default({}),
|
|
514
|
+
design_pass: z.object({
|
|
515
|
+
enabled: z.boolean().default(false).describe(
|
|
516
|
+
'PostToolUse + stop design pass (road-to-frontend-power E1.1/E1.2/E1.3). Default off. One concern on two slots: on post_tool_use a write to a UI surface delivers the design findings as context and never blocks; on stop the same pass runs over every UI file touched this session, deduped against what the post pass surfaced, and a P0 objective floor (contrast, font size, heading skip, focus) blocks with a continuation. P1-P3 never block. post_tool_use rather than pre_tool_use for two measured reasons: pre_tool_use is declared by three hosts and honoured by one while post_tool_use is declared by six, and _lib/ui_surface.ts is a path predicate, so a pre-write gate cannot fire on the first write of a new surface. A pass that could not fully run reports verification: degraded with a reason rather than passing silently. Does not replace design_slop: two design keys is the honest state until the tiering experiment has a number.',
|
|
517
|
+
),
|
|
518
|
+
}).default({}),
|
|
514
519
|
ui_route_nudge: z.object({
|
|
515
520
|
enabled: z.boolean().default(false).describe(
|
|
516
521
|
'PreToolUse UI-route nudge (road-to-frontend-skill-application Phase 4). Default off. When on, a Write/Edit to a UI surface with no design consultation latched this session WARNS (never blocks) naming the route — run existing-ui-audit, then the fe-design loop. A read or search touching fe-design / existing-ui-audit / design-review / design-intelligence latches consultation and silences it for the session. Anti-loop: at most 2 nudges per session. It does not read the rules: the UI-surface decision comes from _lib/ui_surface.ts and no code parses rule frontmatter, so this runs parallel to the two UI rules rather than consuming their triggers, and a test keeps the sets from drifting. It is a nudge, so their enforced_by: none stays accurate.',
|