@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,365 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* CI gate: exactly one enforcement denominator is quotable, and it comes from
|
|
4
|
+
* the resolver.
|
|
5
|
+
*
|
|
6
|
+
* WHY. Measured on 2026-08-23, the tree published **five** figures for one
|
|
7
|
+
* property — how many governed rules declare no enforcement backstop.
|
|
8
|
+
* `docs/proof.md` carried **86** in one place and **89** in another (two
|
|
9
|
+
* different frames quoted under one heading); a frontmatter-strict grep of
|
|
10
|
+
* `src/rules/` returned **87**; an any-line grep returned **82**; and a
|
|
11
|
+
* hand-written ledger entry at `docs/CLAIMS.md:203` carried its own snapshot.
|
|
12
|
+
* A reader had no way to tell which was the answer, and correcting any single
|
|
13
|
+
* figure would have left the plurality intact.
|
|
14
|
+
*
|
|
15
|
+
* `check_enforcement_coverage` is the only citable source: it RESOLVES rather
|
|
16
|
+
* than counts (a declared validator no workflow reaches is `unwired`, not
|
|
17
|
+
* covered) and it publishes its denominator with the frame that produced it.
|
|
18
|
+
* `docs/proof.md` § 4b projects that output. This gate is what stops a sixth
|
|
19
|
+
* number appearing — a sixth number would be the defect, not the fix.
|
|
20
|
+
*
|
|
21
|
+
* THE CONTRACT. In the scanned corpus, a line stating an enforcement count is a
|
|
22
|
+
* finding, full stop. Not "a wrong one" — the gate deliberately does NOT compare
|
|
23
|
+
* values against the resolver, because a hand-written figure that happens to be
|
|
24
|
+
* right today is the mechanism by which the plurality returned every previous
|
|
25
|
+
* time. The remedy is to cite the generated projection or the resolver's own
|
|
26
|
+
* output instead of restating a number.
|
|
27
|
+
*
|
|
28
|
+
* SCOPE, and why each exclusion is not a loophole:
|
|
29
|
+
* · `docs/**` plus `README.md` — the published surfaces. `agents/` is
|
|
30
|
+
* excluded wholesale because an evidence artefact records a measurement
|
|
31
|
+
* taken at a stated time, which is its job; freezing those would forbid
|
|
32
|
+
* measurement itself.
|
|
33
|
+
* · `docs/decisions/` — an ADR is a dated record of what was true when the
|
|
34
|
+
* decision was made. Rewriting one to today's number destroys the record.
|
|
35
|
+
* · `docs/archive/` — shipped changelogs, immutable by construction.
|
|
36
|
+
* · Any file whose head declares `GENERATED by` — that IS the resolver's
|
|
37
|
+
* projection, which is the sanctioned home for the number.
|
|
38
|
+
*
|
|
39
|
+
* Escape hatch: `<!-- enforcement-count-ok: <reason> -->` on the line, reason
|
|
40
|
+
* mandatory. A bare marker stays a finding.
|
|
41
|
+
*
|
|
42
|
+
* Exit codes:
|
|
43
|
+
* 0 — no hand-written enforcement count in the published corpus
|
|
44
|
+
* 1 — at least one (or a marker with no reason)
|
|
45
|
+
* 2 — the gate could not run (dead scan scope, bad args)
|
|
46
|
+
*/
|
|
47
|
+
import * as fs from 'node:fs';
|
|
48
|
+
import * as os from 'node:os';
|
|
49
|
+
import * as path from 'node:path';
|
|
50
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
51
|
+
|
|
52
|
+
import { GateLedger, LedgerUsageError } from './_lib/gate_ledger.js';
|
|
53
|
+
import { runGateCli, runSelfTest, type SelfTestCase } from './_lib/gate_self_test.js';
|
|
54
|
+
import { DeadScopeError, reportScanned } from './_lib/scan_scope.js';
|
|
55
|
+
|
|
56
|
+
const _HERE = fileURLToPath(import.meta.url);
|
|
57
|
+
const DEFAULT_ROOT = path.join(path.dirname(_HERE), '..', '..');
|
|
58
|
+
const SELF = 'src/scripts/check_enforcement_denominator.ts';
|
|
59
|
+
|
|
60
|
+
const SELF_TEST_MIN_CASES = 7;
|
|
61
|
+
const SELF_TEST_MIN_REJECT = 3;
|
|
62
|
+
|
|
63
|
+
/** Roots walked, repo-relative. */
|
|
64
|
+
const SCAN_ROOTS = ['docs', 'README.md'] as const;
|
|
65
|
+
|
|
66
|
+
/** Repo-relative prefixes excluded — see the docstring for why each is not a loophole. */
|
|
67
|
+
const EXCLUDED_PREFIXES = ['docs/decisions/', 'docs/archive/'] as const;
|
|
68
|
+
|
|
69
|
+
/** A file declaring this in its first few lines is the resolver's own projection. */
|
|
70
|
+
const GENERATED_MARKER = 'GENERATED by';
|
|
71
|
+
const GENERATED_HEAD_LINES = 5;
|
|
72
|
+
|
|
73
|
+
/** Same-line exemption; the reason after the colon must be non-empty. */
|
|
74
|
+
const MARKER = 'enforcement-count-ok:';
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* A line is a candidate only when it talks about enforcement AND carries a
|
|
78
|
+
* rule-count shape. Both halves are load-bearing: the keyword alone matches
|
|
79
|
+
* every prose mention of a backstop, and the shape alone matches "2 rules" in a
|
|
80
|
+
* concepts page, which is not this property at all.
|
|
81
|
+
*/
|
|
82
|
+
const ENFORCEMENT_KEYWORDS =
|
|
83
|
+
/undeclared|enforced_by|enforcement coverage|carry a backstop|backstop that fails/;
|
|
84
|
+
|
|
85
|
+
const COUNT_SHAPES: readonly RegExp[] = [
|
|
86
|
+
/\b\d+\s+of\s+\d+\s+(?:governed\s+)?rules?\b/,
|
|
87
|
+
/\b\d+\s+(?:governed\s+)?rules?\b/,
|
|
88
|
+
/\b\d+\s+undeclared\b/,
|
|
89
|
+
/\bundeclared\s+\d+\b/,
|
|
90
|
+
];
|
|
91
|
+
|
|
92
|
+
export interface Finding {
|
|
93
|
+
file: string;
|
|
94
|
+
line: number;
|
|
95
|
+
excerpt: string;
|
|
96
|
+
/** `raw` — an unmarked count. `bare-marker` — a marker with no reason. */
|
|
97
|
+
kind: 'raw' | 'bare-marker';
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function markerOn(line: string): 'none' | 'bare' | 'reasoned' {
|
|
101
|
+
const at = line.indexOf(MARKER);
|
|
102
|
+
if (at < 0) return 'none';
|
|
103
|
+
const tail = line.slice(at + MARKER.length).replace(/-->\s*$/, '').trim();
|
|
104
|
+
return tail === '' ? 'bare' : 'reasoned';
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function scanText(relPath: string, text: string): Finding[] {
|
|
108
|
+
const out: Finding[] = [];
|
|
109
|
+
const lines = text.split('\n');
|
|
110
|
+
for (let i = 0; i < lines.length; i += 1) {
|
|
111
|
+
const line = lines[i] ?? '';
|
|
112
|
+
if (!ENFORCEMENT_KEYWORDS.test(line)) continue;
|
|
113
|
+
if (!COUNT_SHAPES.some((re) => re.test(line))) continue;
|
|
114
|
+
const marker = markerOn(line);
|
|
115
|
+
if (marker === 'reasoned') continue;
|
|
116
|
+
out.push({
|
|
117
|
+
file: relPath,
|
|
118
|
+
line: i + 1,
|
|
119
|
+
excerpt: line.trim().slice(0, 120),
|
|
120
|
+
kind: marker === 'bare' ? 'bare-marker' : 'raw',
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
return out;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** `true` when the file declares itself generated — i.e. it IS the projection. */
|
|
127
|
+
export function isGenerated(text: string): boolean {
|
|
128
|
+
return text.split('\n', GENERATED_HEAD_LINES).join('\n').includes(GENERATED_MARKER);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** Every markdown file in scope, repo-relative, sorted. */
|
|
132
|
+
export function corpus(root: string): string[] {
|
|
133
|
+
const out: string[] = [];
|
|
134
|
+
const walk = (rel: string): void => {
|
|
135
|
+
const abs = path.join(root, rel);
|
|
136
|
+
let st: fs.Stats;
|
|
137
|
+
try {
|
|
138
|
+
st = fs.statSync(abs);
|
|
139
|
+
} catch {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
if (st.isFile()) {
|
|
143
|
+
if (!rel.endsWith('.md')) return;
|
|
144
|
+
if (EXCLUDED_PREFIXES.some((p) => rel.startsWith(p))) return;
|
|
145
|
+
out.push(rel);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
if (!st.isDirectory()) return;
|
|
149
|
+
for (const name of fs.readdirSync(abs).sort()) walk(path.posix.join(rel, name));
|
|
150
|
+
};
|
|
151
|
+
for (const r of SCAN_ROOTS) walk(r);
|
|
152
|
+
return out.sort();
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export function check(root: string): { code: number; findings: Finding[]; scanned: number } {
|
|
156
|
+
const files = corpus(root);
|
|
157
|
+
const findings: Finding[] = [];
|
|
158
|
+
const ledger = new GateLedger('check_enforcement_denominator');
|
|
159
|
+
|
|
160
|
+
try {
|
|
161
|
+
reportScanned({
|
|
162
|
+
gate: 'check_enforcement_denominator',
|
|
163
|
+
scanned: files.length,
|
|
164
|
+
units: 'published markdown file(s)',
|
|
165
|
+
roots: [...SCAN_ROOTS],
|
|
166
|
+
});
|
|
167
|
+
} catch (err) {
|
|
168
|
+
if (err instanceof DeadScopeError) {
|
|
169
|
+
process.stderr.write(`❌ ${err.message}\n`);
|
|
170
|
+
return { code: 2, findings, scanned: files.length };
|
|
171
|
+
}
|
|
172
|
+
throw err;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
try {
|
|
176
|
+
ledger.plan(files);
|
|
177
|
+
for (const rel of files) {
|
|
178
|
+
const text = fs.readFileSync(path.join(root, rel), 'utf-8');
|
|
179
|
+
if (isGenerated(text)) {
|
|
180
|
+
ledger.complete(rel);
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
const found = scanText(rel, text);
|
|
184
|
+
if (found.length > 0) {
|
|
185
|
+
findings.push(...found);
|
|
186
|
+
ledger.fail(rel, `${String(found.length)} hand-written enforcement count(s)`);
|
|
187
|
+
} else {
|
|
188
|
+
ledger.complete(rel);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
} catch (err) {
|
|
192
|
+
if (err instanceof LedgerUsageError) {
|
|
193
|
+
process.stderr.write(`❌ ${err.message}\n`);
|
|
194
|
+
return { code: 2, findings, scanned: files.length };
|
|
195
|
+
}
|
|
196
|
+
throw err;
|
|
197
|
+
}
|
|
198
|
+
ledger.report();
|
|
199
|
+
|
|
200
|
+
return { code: findings.length > 0 ? 1 : 0, findings, scanned: files.length };
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/* ------------------------------------------------------------------ *
|
|
204
|
+
* Self-test
|
|
205
|
+
* ------------------------------------------------------------------ */
|
|
206
|
+
|
|
207
|
+
function fixtureRoot(files: Record<string, string>): string {
|
|
208
|
+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'enf-denom-'));
|
|
209
|
+
for (const [rel, body] of Object.entries(files)) {
|
|
210
|
+
const abs = path.join(dir, rel);
|
|
211
|
+
fs.mkdirSync(path.dirname(abs), { recursive: true });
|
|
212
|
+
fs.writeFileSync(abs, body);
|
|
213
|
+
}
|
|
214
|
+
return dir;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export function selfTest(): number {
|
|
218
|
+
const made: string[] = [];
|
|
219
|
+
const run = (files: Record<string, string>): number => {
|
|
220
|
+
const d = fixtureRoot(files);
|
|
221
|
+
made.push(d);
|
|
222
|
+
return runGateCli(DEFAULT_ROOT, SELF, ['--quiet', '--root', d], DEFAULT_ROOT);
|
|
223
|
+
};
|
|
224
|
+
const CLEAN = '# Docs\n\nNothing about counts here.\n';
|
|
225
|
+
|
|
226
|
+
const cases: SelfTestCase[] = [
|
|
227
|
+
{
|
|
228
|
+
name: 'rejects a hand-written "N of M governed rules … backstop" figure',
|
|
229
|
+
expect: 'reject',
|
|
230
|
+
run: () =>
|
|
231
|
+
run({
|
|
232
|
+
'docs/a.md': '15 of 120 governed rules carry a backstop that fails a CI build.\n',
|
|
233
|
+
}),
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
name: 'rejects a hand-written undeclared count',
|
|
237
|
+
expect: 'reject',
|
|
238
|
+
run: () => run({ 'docs/a.md': 'Today 86 rules are undeclared.\n' }),
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
name: 'rejects the same figure in README.md',
|
|
242
|
+
expect: 'reject',
|
|
243
|
+
run: () => run({ 'README.md': '86 undeclared rules have no enforced_by.\n' }),
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
name: 'rejects a marker with no reason',
|
|
247
|
+
expect: 'reject',
|
|
248
|
+
run: () =>
|
|
249
|
+
run({
|
|
250
|
+
'docs/a.md': `86 rules are undeclared. <!-- ${MARKER} -->\n`,
|
|
251
|
+
}),
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
name: 'accepts a marker carrying a reason',
|
|
255
|
+
expect: 'accept',
|
|
256
|
+
run: () =>
|
|
257
|
+
run({
|
|
258
|
+
'docs/a.md': `86 rules are undeclared. <!-- ${MARKER} historical, dated in place -->\n`,
|
|
259
|
+
}),
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
name: "accepts the resolver's own generated projection",
|
|
263
|
+
expect: 'accept',
|
|
264
|
+
run: () =>
|
|
265
|
+
run({
|
|
266
|
+
'docs/proof.md':
|
|
267
|
+
`<!-- ${GENERATED_MARKER} src/scripts/build_proof.ts -->\n\n` +
|
|
268
|
+
'120 rules · 15 blocking · 86 undeclared (no enforced_by yet).\n',
|
|
269
|
+
}),
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
name: 'accepts a dated ADR record (docs/decisions/ is excluded)',
|
|
273
|
+
expect: 'accept',
|
|
274
|
+
run: () =>
|
|
275
|
+
run({
|
|
276
|
+
'docs/a.md': CLEAN,
|
|
277
|
+
'docs/decisions/ADR-001-x.md': '86 rules were undeclared on 2026-08-12.\n',
|
|
278
|
+
}),
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
name: 'accepts a rule count with no enforcement sense ("2 rules" in a concepts page)',
|
|
282
|
+
expect: 'accept',
|
|
283
|
+
run: () => run({ 'docs/a.md': 'The kernel splits into 2 rules and a router.\n' }),
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
name: 'rejects a moved scan root rather than reporting clean (exit 2)',
|
|
287
|
+
expect: 'reject',
|
|
288
|
+
run: () =>
|
|
289
|
+
runGateCli(
|
|
290
|
+
DEFAULT_ROOT,
|
|
291
|
+
SELF,
|
|
292
|
+
['--quiet', '--root', path.join(DEFAULT_ROOT, 'no-such-root')],
|
|
293
|
+
DEFAULT_ROOT,
|
|
294
|
+
),
|
|
295
|
+
},
|
|
296
|
+
];
|
|
297
|
+
|
|
298
|
+
try {
|
|
299
|
+
return runSelfTest({
|
|
300
|
+
gate: 'check_enforcement_denominator',
|
|
301
|
+
cases,
|
|
302
|
+
minCases: SELF_TEST_MIN_CASES,
|
|
303
|
+
minRejectCases: SELF_TEST_MIN_REJECT,
|
|
304
|
+
});
|
|
305
|
+
} finally {
|
|
306
|
+
for (const d of made) fs.rmSync(d, { recursive: true, force: true });
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
export function main(argv?: readonly string[]): number {
|
|
311
|
+
const args = argv ?? process.argv.slice(2);
|
|
312
|
+
if (args.includes('--self-test')) return selfTest();
|
|
313
|
+
const quiet = args.includes('--quiet');
|
|
314
|
+
const rootIdx = args.indexOf('--root');
|
|
315
|
+
const root = rootIdx >= 0 ? (args[rootIdx + 1] ?? DEFAULT_ROOT) : DEFAULT_ROOT;
|
|
316
|
+
|
|
317
|
+
const { code, findings, scanned } = check(root);
|
|
318
|
+
if (code === 2) return 2;
|
|
319
|
+
|
|
320
|
+
if (findings.length > 0) {
|
|
321
|
+
process.stdout.write('❌ hand-written enforcement count(s) in a published doc:\n\n');
|
|
322
|
+
for (const f of findings) {
|
|
323
|
+
const why =
|
|
324
|
+
f.kind === 'bare-marker' ? `\`${MARKER}\` with no reason` : 'hand-written count';
|
|
325
|
+
process.stdout.write(` ${f.file}:${String(f.line)} — ${why}\n ${f.excerpt}\n`);
|
|
326
|
+
}
|
|
327
|
+
process.stdout.write(
|
|
328
|
+
'\nExactly one enforcement denominator is quotable, and it comes from\n' +
|
|
329
|
+
'`check_enforcement_coverage` — which resolves rather than counts, and prints\n' +
|
|
330
|
+
'its denominator with the frame that produced it. `docs/proof.md` § 4b projects\n' +
|
|
331
|
+
'that output; cite the projection instead of restating a number. A figure that\n' +
|
|
332
|
+
'is right today is how the plurality returned every previous time.\n' +
|
|
333
|
+
`If the number is a dated record rather than a live claim, say so on the line:\n` +
|
|
334
|
+
` <!-- ${MARKER} <reason> -->\n`,
|
|
335
|
+
);
|
|
336
|
+
return 1;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
if (!quiet) {
|
|
340
|
+
process.stdout.write(
|
|
341
|
+
`✅ one citable enforcement denominator: ${String(scanned)} published doc(s) restate none of it.\n`,
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
return 0;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
function _isCliEntry(): boolean {
|
|
348
|
+
if (process.argv[1] === undefined) return false;
|
|
349
|
+
const argvUrl = pathToFileURL(path.resolve(process.argv[1])).href;
|
|
350
|
+
if (import.meta.url === argvUrl) return true;
|
|
351
|
+
try {
|
|
352
|
+
return (
|
|
353
|
+
fs.realpathSync(fileURLToPath(import.meta.url)) ===
|
|
354
|
+
fs.realpathSync(path.resolve(process.argv[1]))
|
|
355
|
+
);
|
|
356
|
+
} catch {
|
|
357
|
+
return false;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
if (_isCliEntry() || process.argv[1] === _HERE) {
|
|
362
|
+
process.exit(main());
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
export { SCAN_ROOTS, EXCLUDED_PREFIXES, MARKER };
|
|
@@ -49,6 +49,7 @@ import process from 'node:process';
|
|
|
49
49
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
50
50
|
|
|
51
51
|
import * as yaml from 'js-yaml';
|
|
52
|
+
import { asOf } from './_lib/as_of.js';
|
|
52
53
|
import { checkRatchet } from './_lib/gate_baseline.js';
|
|
53
54
|
import { GateLedger, type GateSkipReason } from './_lib/gate_ledger.js';
|
|
54
55
|
import { runCountedProbe } from './_lib/counted_probe.js';
|
|
@@ -979,7 +980,7 @@ function run_canary_mode(specs: readonly GateSpec[], argv: readonly string[]): n
|
|
|
979
980
|
process.stdout.write(` ❌ DISAGREEMENT [${d.kind}] ${d.gate}: ${d.detail}\n`);
|
|
980
981
|
}
|
|
981
982
|
|
|
982
|
-
const cycleId = `gate-surface-${
|
|
983
|
+
const cycleId = `gate-surface-${asOf().toISOString().slice(0, 10)}`;
|
|
983
984
|
const li = argv.indexOf('--ledger');
|
|
984
985
|
if (li >= 0 && argv[li + 1] !== undefined) {
|
|
985
986
|
const out = path.resolve(REPO_ROOT, argv[li + 1] as string);
|
|
@@ -28,6 +28,18 @@
|
|
|
28
28
|
* A hook fix that cannot reach the agent that wrote it is indistinguishable
|
|
29
29
|
* from no fix, and nothing said so. This gate says so.
|
|
30
30
|
*
|
|
31
|
+
* WHAT IT DOES NOT DO — ORDERING IS NOT EQUIVALENCE. This gate compares
|
|
32
|
+
* mtimes, so `touch dist/hooks/dispatch.js` makes every source look older and
|
|
33
|
+
* this gate green while the executing bytes are stale. Demonstrated on this tree
|
|
34
|
+
* rather than argued (2026-08-23): a one-constant edit to
|
|
35
|
+
* `block_unauthorized_git.ts` plus a `touch` on the bundle left THIS gate at
|
|
36
|
+
* exit 0 while `check_hook_bundle_content` exited 1 with executing
|
|
37
|
+
* `sha256 ce21579b7c14` against rebuilt `ac83e2f51118` — identical byte count,
|
|
38
|
+
* different bytes. That is why the success line below says "ordering" and names
|
|
39
|
+
* the digest gate instead of claiming freshness outright, and why preflight runs
|
|
40
|
+
* the two together (`taskfiles/ci-fast.yml`). The content comparison is NOT
|
|
41
|
+
* duplicated here: one home per invariant.
|
|
42
|
+
*
|
|
31
43
|
* WHAT IT DOES NOT DO: it never builds. Building into a live hook path is a
|
|
32
44
|
* documented hazard in this repo (an esbuild run that overwrites the
|
|
33
45
|
* dispatcher a running hook is executing can wedge the tool loop), so the
|
|
@@ -169,7 +181,7 @@ export function main(argv: string[] = process.argv.slice(2)): number {
|
|
|
169
181
|
if (r.stale.length === 0) {
|
|
170
182
|
if (!quiet) {
|
|
171
183
|
process.stdout.write(
|
|
172
|
-
`✅ OK hook bundle: fresh (built ${stamp(r.bundleMtimeMs)}, ${String(r.checked)} bundled source(s) checked)\n`,
|
|
184
|
+
`✅ OK hook bundle: ordering fresh (built ${stamp(r.bundleMtimeMs)}, ${String(r.checked)} bundled source(s) checked) — byte-equivalence is check_hook_bundle_content's\n`,
|
|
173
185
|
);
|
|
174
186
|
}
|
|
175
187
|
return 0;
|
|
@@ -37,6 +37,7 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
|
37
37
|
// tolerantly (try/except → None) so the project-local linter still runs if the
|
|
38
38
|
// _lib package layout shifts; the TS twins always exist, so a static import is
|
|
39
39
|
// byte-faithful for behaviour (the only observable effect is the --global path).
|
|
40
|
+
import { asOf } from './_lib/as_of.js';
|
|
40
41
|
import * as _kg from './_lib/knowledge_global.js';
|
|
41
42
|
import * as _kgr from './_lib/knowledge_global_redaction.js';
|
|
42
43
|
import { assertScanned } from './_lib/scan_scope.js';
|
|
@@ -485,7 +486,7 @@ function _maxDate(parsed: PyDate[]): PyDate {
|
|
|
485
486
|
}
|
|
486
487
|
|
|
487
488
|
function _todayUtcDate(): PyDate {
|
|
488
|
-
const now =
|
|
489
|
+
const now = asOf();
|
|
489
490
|
return { year: now.getUTCFullYear(), month: now.getUTCMonth() + 1, day: now.getUTCDate() };
|
|
490
491
|
}
|
|
491
492
|
|
|
@@ -29,6 +29,7 @@ import process from 'node:process';
|
|
|
29
29
|
import { fileURLToPath } from 'node:url';
|
|
30
30
|
import YAML from 'yaml';
|
|
31
31
|
|
|
32
|
+
import { asOf } from './_lib/as_of.js';
|
|
32
33
|
import { assertScanned } from './_lib/scan_scope.js';
|
|
33
34
|
|
|
34
35
|
const PROG = 'check_knowledge_pages.ts';
|
|
@@ -72,7 +73,7 @@ function bodyLineCount(body: string): number {
|
|
|
72
73
|
}
|
|
73
74
|
|
|
74
75
|
/** Lint a single page's already-read content. Pure — no filesystem access — for direct unit testing. */
|
|
75
|
-
export function lintPage(relPath: string, content: string, today: Date =
|
|
76
|
+
export function lintPage(relPath: string, content: string, today: Date = asOf()): Warning[] {
|
|
76
77
|
const warnings: Warning[] = [];
|
|
77
78
|
const fm = readFrontmatter(content);
|
|
78
79
|
|
|
@@ -145,7 +146,7 @@ function countPages(knowledgeRoot: string): number {
|
|
|
145
146
|
);
|
|
146
147
|
}
|
|
147
148
|
|
|
148
|
-
export function lintAll(knowledgeRoot: string, today: Date =
|
|
149
|
+
export function lintAll(knowledgeRoot: string, today: Date = asOf()): Warning[] {
|
|
149
150
|
const warnings: Warning[] = [];
|
|
150
151
|
for (const dir of TYPED_DIRS) {
|
|
151
152
|
const scanDir = path.join(knowledgeRoot, dir);
|
|
@@ -53,6 +53,7 @@ import process from 'node:process';
|
|
|
53
53
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
54
54
|
import YAML, { parseDocument } from 'yaml';
|
|
55
55
|
|
|
56
|
+
import { asOf } from './_lib/as_of.js';
|
|
56
57
|
import { assertScanned, DeadScopeError } from './_lib/scan_scope.js';
|
|
57
58
|
|
|
58
59
|
type Severity = 'error' | 'warning' | 'info';
|
|
@@ -276,7 +277,7 @@ function _dateDiffDays(today: PyDate, lv: PyDate): number {
|
|
|
276
277
|
}
|
|
277
278
|
|
|
278
279
|
function _today(): PyDate {
|
|
279
|
-
const now =
|
|
280
|
+
const now = asOf();
|
|
280
281
|
return new PyDate(now.getFullYear(), now.getMonth() + 1, now.getDate());
|
|
281
282
|
}
|
|
282
283
|
|