@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,565 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* Pack-conformance fixture harness — a third party's answer to "will my pack pass?"
|
|
4
|
+
*
|
|
5
|
+
* WHAT THIS PROVES, AND WHAT IT DOES NOT. Six pack-fitness invariants exist as
|
|
6
|
+
* six independent gates. Only THREE of them can be checked against a fixture
|
|
7
|
+
* tree today, and the limit is a contract rather than an effort gap:
|
|
8
|
+
*
|
|
9
|
+
* fixture-provable | blocked by
|
|
10
|
+
* --------------------------------------|-------------------------------------
|
|
11
|
+
* lint_pack_boundaries (tree) | — exports `_set_paths_for_test`
|
|
12
|
+
* lint_rule_skill_pack_reach (tree) | — accepts `--root <dir>`
|
|
13
|
+
* lint_pack_risk_class (predicate) | — exports `riskClassViolations()`
|
|
14
|
+
* lint_pack_dependencies | `main()` takes no argv; the pack home
|
|
15
|
+
* | is derived from `import.meta.url`
|
|
16
|
+
* lint_pack_first_win | its CLI contract PINS "ignores argv
|
|
17
|
+
* | entirely" (ADR-200 port fidelity)
|
|
18
|
+
* prove_pack_extractable | `prove(pack)` resolves a pack BY NAME
|
|
19
|
+
* | under the real `src/packs/`
|
|
20
|
+
*
|
|
21
|
+
* A partial temp-tree copy cannot substitute: four of the six carry dead-scope
|
|
22
|
+
* assertions, so a skeleton holding only the fixture exits 2 ("scanned 0"), not
|
|
23
|
+
* 0. Only a full tree copy per twin would satisfy them.
|
|
24
|
+
*
|
|
25
|
+
* This harness therefore reports PARTIAL conformance and says so in its own
|
|
26
|
+
* output and in the document it generates. The retrofit that would close the gap
|
|
27
|
+
* is carried as a follow-up, with a narrow ADR-200 amendment as its explicit
|
|
28
|
+
* prerequisite. Decision: AI council 2026-08-23, verdict (s), 2 of 2 convergent
|
|
29
|
+
* after a 1–1 split on (a) vs (b).
|
|
30
|
+
*
|
|
31
|
+
* THE FIXTURE IS LAYOUT-NEUTRAL DATA. The two tree-level gates expect DIFFERENT
|
|
32
|
+
* roots — boundaries wants `<root>/{packs.yml,skills,rules}`, reach wants
|
|
33
|
+
* `<root>/src/{rules,skills}` plus `<root>/src/config/discovery/packs.yml` — so
|
|
34
|
+
* the canonical fixture is stored once and projected per gate.
|
|
35
|
+
*
|
|
36
|
+
* Exit codes:
|
|
37
|
+
* 0 — the conformant fixture passes every provable gate AND every twin reds
|
|
38
|
+
* exactly its own gate
|
|
39
|
+
* 1 — a conformance expectation was violated
|
|
40
|
+
* 2 — the gate could not run (missing fixture, bad args)
|
|
41
|
+
*/
|
|
42
|
+
import * as fs from 'node:fs';
|
|
43
|
+
import * as os from 'node:os';
|
|
44
|
+
import * as path from 'node:path';
|
|
45
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
46
|
+
|
|
47
|
+
import { GateLedger } from './_lib/gate_ledger.js';
|
|
48
|
+
import { runGateCli, runSelfTest, type SelfTestCase } from './_lib/gate_self_test.js';
|
|
49
|
+
import { DeadScopeError, reportScanned } from './_lib/scan_scope.js';
|
|
50
|
+
|
|
51
|
+
const _HERE = fileURLToPath(import.meta.url);
|
|
52
|
+
const DEFAULT_ROOT = path.resolve(path.dirname(_HERE), '..', '..');
|
|
53
|
+
const SELF = 'src/scripts/check_pack_conformance_fixture.ts';
|
|
54
|
+
|
|
55
|
+
const SELF_TEST_MIN_CASES = 4;
|
|
56
|
+
const SELF_TEST_MIN_REJECT = 2;
|
|
57
|
+
|
|
58
|
+
/** Repo-relative home of the committed fixture. */
|
|
59
|
+
const FIXTURE_REL = path.join('tests', 'fixtures', 'pack-conformance');
|
|
60
|
+
|
|
61
|
+
/** Generated document. Regenerating on an unchanged tree must be a no-op. */
|
|
62
|
+
const DOC_REL = path.join('docs', 'contracts', 'pack-conformance.md');
|
|
63
|
+
|
|
64
|
+
/** The three gates a fixture can drive, and the three it cannot. */
|
|
65
|
+
type Mechanism = 'fixture-tree' | 'fixture-predicate' | 'real-tree-only';
|
|
66
|
+
|
|
67
|
+
interface GateSpec {
|
|
68
|
+
id: string;
|
|
69
|
+
invariant: string;
|
|
70
|
+
mechanism: Mechanism;
|
|
71
|
+
/** For `real-tree-only`: the exact contract that blocks a fixture, and why. */
|
|
72
|
+
blockedBy?: string;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const GATES: readonly GateSpec[] = [
|
|
76
|
+
{
|
|
77
|
+
id: 'lint_pack_boundaries',
|
|
78
|
+
invariant: 'a markdown link may not cross into a pack the source pack does not require',
|
|
79
|
+
mechanism: 'fixture-tree',
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
id: 'lint_rule_skill_pack_reach',
|
|
83
|
+
invariant: 'a rule and the skills it routes to must arrive in the same pack-legal install',
|
|
84
|
+
mechanism: 'fixture-tree',
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
id: 'lint_pack_risk_class',
|
|
88
|
+
invariant: 'risk_class: high ⇒ default_install: false AND requires_explicit_consent: true AND surface_tier: lab',
|
|
89
|
+
mechanism: 'fixture-predicate',
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
id: 'lint_pack_dependencies',
|
|
93
|
+
invariant: 'the pack dependency graph is acyclic and every declared pack exists',
|
|
94
|
+
mechanism: 'real-tree-only',
|
|
95
|
+
blockedBy:
|
|
96
|
+
'`main()` accepts no argv and the pack home is derived from `import.meta.url`. ' +
|
|
97
|
+
'Effort-level, not design-level: nothing states the absence is intended.',
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
id: 'lint_pack_first_win',
|
|
101
|
+
invariant: 'a pack may not shadow an artefact another pack already wins',
|
|
102
|
+
mechanism: 'real-tree-only',
|
|
103
|
+
blockedBy:
|
|
104
|
+
'the gate\'s CLI contract PINS argv-ignoring behaviour — its own header reads ' +
|
|
105
|
+
'"the CLI contract is pinned — `main()` IGNORES argv entirely". Design-level: ' +
|
|
106
|
+
'a port-fidelity guarantee from ADR-200, so a fixture seam needs that record amended.',
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
id: 'prove_pack_extractable',
|
|
110
|
+
invariant: 'a pack plus its declared closure is self-contained and liftable out',
|
|
111
|
+
mechanism: 'real-tree-only',
|
|
112
|
+
blockedBy:
|
|
113
|
+
'`prove(pack)` resolves a pack BY NAME under the real `src/packs/`, so a fixture ' +
|
|
114
|
+
'would have to be a real pack. Effort-level, but it changes an exported signature ' +
|
|
115
|
+
'two tests already use.',
|
|
116
|
+
},
|
|
117
|
+
];
|
|
118
|
+
|
|
119
|
+
/** Every twin, and the ONE gate it must red. */
|
|
120
|
+
interface Twin {
|
|
121
|
+
dir: string;
|
|
122
|
+
reds: string;
|
|
123
|
+
what: string;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const TWINS: readonly Twin[] = [
|
|
127
|
+
{
|
|
128
|
+
dir: 'undeclared-cross-pack-link',
|
|
129
|
+
reds: 'lint_pack_boundaries',
|
|
130
|
+
what: 'the requires edge is dropped, so a skill link crosses an undeclared boundary',
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
dir: 'unreachable-route',
|
|
134
|
+
reds: 'lint_rule_skill_pack_reach',
|
|
135
|
+
what: 'the requires edge is dropped, so a rule routes to a skill its install cannot receive',
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
dir: 'high-risk-default-install',
|
|
139
|
+
reds: 'lint_pack_risk_class',
|
|
140
|
+
what: 'a risk_class: high pack ships default-on, consent-free, at a non-lab tier',
|
|
141
|
+
},
|
|
142
|
+
];
|
|
143
|
+
|
|
144
|
+
// ── fixture materialisation ────────────────────────────────────────────────
|
|
145
|
+
|
|
146
|
+
function _copyTree(from: string, to: string): void {
|
|
147
|
+
for (const e of fs.readdirSync(from, { withFileTypes: true })) {
|
|
148
|
+
const src = path.join(from, e.name);
|
|
149
|
+
const dst = path.join(to, e.name);
|
|
150
|
+
if (e.isDirectory()) {
|
|
151
|
+
fs.mkdirSync(dst, { recursive: true });
|
|
152
|
+
_copyTree(src, dst);
|
|
153
|
+
} else {
|
|
154
|
+
fs.mkdirSync(path.dirname(dst), { recursive: true });
|
|
155
|
+
fs.copyFileSync(src, dst);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Materialise `conformant/`, then lay a twin overlay on top of it.
|
|
162
|
+
*
|
|
163
|
+
* The overlay REPLACES same-named files rather than merging them, which is why
|
|
164
|
+
* each twin ships a full `packs.yml` and a full copy of any artefact it changes.
|
|
165
|
+
* A merge would make a twin's effect depend on merge semantics rather than on
|
|
166
|
+
* the file a reviewer can read.
|
|
167
|
+
*/
|
|
168
|
+
function _canonical(root: string, twin: string | null): string {
|
|
169
|
+
const out = path.join(root, 'canonical');
|
|
170
|
+
fs.mkdirSync(out, { recursive: true });
|
|
171
|
+
_copyTree(path.join(DEFAULT_ROOT, FIXTURE_REL, 'conformant'), out);
|
|
172
|
+
if (twin !== null) {
|
|
173
|
+
_copyTree(path.join(DEFAULT_ROOT, FIXTURE_REL, 'twins', twin), out);
|
|
174
|
+
}
|
|
175
|
+
return out;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** Project the canonical fixture into `lint_pack_boundaries`' expected layout. */
|
|
179
|
+
function _asBoundariesRoot(canonical: string, root: string): string {
|
|
180
|
+
const out = path.join(root, 'boundaries');
|
|
181
|
+
fs.mkdirSync(out, { recursive: true });
|
|
182
|
+
fs.copyFileSync(path.join(canonical, 'packs.yml'), path.join(out, 'packs.yml'));
|
|
183
|
+
for (const d of ['skills', 'rules']) {
|
|
184
|
+
const from = path.join(canonical, d);
|
|
185
|
+
if (fs.existsSync(from)) {
|
|
186
|
+
fs.mkdirSync(path.join(out, d), { recursive: true });
|
|
187
|
+
_copyTree(from, path.join(out, d));
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return fs.realpathSync(out);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/** Project the canonical fixture into `lint_rule_skill_pack_reach`'s layout. */
|
|
194
|
+
function _asReachRoot(canonical: string, root: string): string {
|
|
195
|
+
const out = path.join(root, 'reach');
|
|
196
|
+
const packsFile = path.join(out, 'src', 'config', 'discovery', 'packs.yml');
|
|
197
|
+
fs.mkdirSync(path.dirname(packsFile), { recursive: true });
|
|
198
|
+
fs.copyFileSync(path.join(canonical, 'packs.yml'), packsFile);
|
|
199
|
+
for (const d of ['skills', 'rules']) {
|
|
200
|
+
const from = path.join(canonical, d);
|
|
201
|
+
if (fs.existsSync(from)) {
|
|
202
|
+
fs.mkdirSync(path.join(out, 'src', d), { recursive: true });
|
|
203
|
+
_copyTree(from, path.join(out, 'src', d));
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return fs.realpathSync(out);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// ── running the three provable gates ───────────────────────────────────────
|
|
210
|
+
|
|
211
|
+
export interface GateOutcome {
|
|
212
|
+
gate: string;
|
|
213
|
+
exit: number;
|
|
214
|
+
detail: string;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
async function _runBoundaries(canonical: string, tmp: string): Promise<GateOutcome> {
|
|
218
|
+
const root = _asBoundariesRoot(canonical, tmp);
|
|
219
|
+
// In-process: the gate's own documented test seam. Spawning is impossible —
|
|
220
|
+
// `--root` is not in its argv grammar and an unknown flag is exit 2.
|
|
221
|
+
const lpb = (await import('./lint_pack_boundaries.js')) as unknown as {
|
|
222
|
+
_set_paths_for_test: (o: { root?: string }) => void;
|
|
223
|
+
main: (argv?: readonly string[]) => number;
|
|
224
|
+
ROOT: string;
|
|
225
|
+
};
|
|
226
|
+
const real = DEFAULT_ROOT;
|
|
227
|
+
let exit: number;
|
|
228
|
+
const chunks: string[] = [];
|
|
229
|
+
const realWrite = process.stdout.write.bind(process.stdout);
|
|
230
|
+
try {
|
|
231
|
+
lpb._set_paths_for_test({ root });
|
|
232
|
+
(process.stdout.write as unknown) = (c: string): boolean => {
|
|
233
|
+
chunks.push(String(c));
|
|
234
|
+
return true;
|
|
235
|
+
};
|
|
236
|
+
exit = lpb.main(['--quiet']);
|
|
237
|
+
} finally {
|
|
238
|
+
(process.stdout.write as unknown) = realWrite;
|
|
239
|
+
// ALWAYS restore, in a finally: a leaked fixture root would make every
|
|
240
|
+
// later gate in this process judge the fixture instead of the repo.
|
|
241
|
+
lpb._set_paths_for_test({ root: real });
|
|
242
|
+
}
|
|
243
|
+
return { gate: 'lint_pack_boundaries', exit, detail: chunks.join('').trim().split('\n').pop() ?? '' };
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function _runReach(canonical: string, tmp: string): GateOutcome {
|
|
247
|
+
const root = _asReachRoot(canonical, tmp);
|
|
248
|
+
// `--strict` is required: the gate is advisory by default (it carries a
|
|
249
|
+
// known real-tree backlog), and an advisory run exits 0 on a real finding,
|
|
250
|
+
// which would make every twin look green.
|
|
251
|
+
const exit = runGateCli(
|
|
252
|
+
DEFAULT_ROOT,
|
|
253
|
+
'src/scripts/lint_rule_skill_pack_reach.ts',
|
|
254
|
+
['--root', root, '--strict', '--quiet'],
|
|
255
|
+
DEFAULT_ROOT,
|
|
256
|
+
);
|
|
257
|
+
return { gate: 'lint_rule_skill_pack_reach', exit, detail: `--strict over ${path.basename(root)}` };
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
async function _runRiskClass(canonical: string): Promise<GateOutcome> {
|
|
261
|
+
const { riskClassViolations } = (await import('./lint_pack_risk_class.js')) as unknown as {
|
|
262
|
+
riskClassViolations: (s: string) => { pack: string; msg: string }[];
|
|
263
|
+
};
|
|
264
|
+
const v = riskClassViolations(fs.readFileSync(path.join(canonical, 'packs.yml'), 'utf-8'));
|
|
265
|
+
return {
|
|
266
|
+
gate: 'lint_pack_risk_class',
|
|
267
|
+
exit: v.length > 0 ? 1 : 0,
|
|
268
|
+
detail: v.length > 0 ? v.map((x) => x.msg).join('; ') : 'no high-risk pack misconfigured',
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const PROVABLE = GATES.filter((g) => g.mechanism !== 'real-tree-only').map((g) => g.id);
|
|
273
|
+
|
|
274
|
+
async function _runProvable(canonical: string, tmp: string): Promise<GateOutcome[]> {
|
|
275
|
+
return [await _runBoundaries(canonical, tmp), _runReach(canonical, tmp), await _runRiskClass(canonical)];
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// ── the conformance run ────────────────────────────────────────────────────
|
|
279
|
+
|
|
280
|
+
export interface Finding {
|
|
281
|
+
scope: string;
|
|
282
|
+
message: string;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
export async function runConformance(): Promise<{ code: number; findings: Finding[]; scanned: number }> {
|
|
286
|
+
const findings: Finding[] = [];
|
|
287
|
+
const fixture = path.join(DEFAULT_ROOT, FIXTURE_REL);
|
|
288
|
+
if (!fs.existsSync(path.join(fixture, 'conformant', 'packs.yml'))) {
|
|
289
|
+
process.stdout.write(`❌ fixture not found: ${FIXTURE_REL}/conformant/packs.yml\n`);
|
|
290
|
+
return { code: 2, findings, scanned: 0 };
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'pack-conf-'));
|
|
294
|
+
const ledger = new GateLedger('check_pack_conformance_fixture');
|
|
295
|
+
// One unit per (fixture, gate) assertion: the clean run over three gates
|
|
296
|
+
// plus one twin × three gates each. That is the number the floor guards.
|
|
297
|
+
const planned = [
|
|
298
|
+
...PROVABLE.map((g) => `conformant:${g}`),
|
|
299
|
+
...TWINS.flatMap((t) => PROVABLE.map((g) => `${t.dir}:${g}`)),
|
|
300
|
+
];
|
|
301
|
+
try {
|
|
302
|
+
ledger.plan(planned);
|
|
303
|
+
|
|
304
|
+
// 1. The conformant fixture must pass every provable gate.
|
|
305
|
+
const clean = await _runProvable(_canonical(tmp, null), path.join(tmp, 'clean'));
|
|
306
|
+
for (const o of clean) {
|
|
307
|
+
const id = `conformant:${o.gate}`;
|
|
308
|
+
if (o.exit === 0) ledger.complete(id);
|
|
309
|
+
else {
|
|
310
|
+
findings.push({ scope: 'conformant', message: `${o.gate} exited ${String(o.exit)} on the CONFORMANT fixture — ${o.detail}` });
|
|
311
|
+
ledger.fail(id, `exit ${String(o.exit)}`);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// 2. Each twin must red EXACTLY its own gate. The "others stay green"
|
|
316
|
+
// half is the load-bearing one: a twin that reds two gates is not
|
|
317
|
+
// isolating an invariant, and a document built on it would attribute
|
|
318
|
+
// a failure to the wrong contract.
|
|
319
|
+
for (const t of TWINS) {
|
|
320
|
+
const dir = fs.mkdtempSync(path.join(tmp, `twin-${t.dir}-`));
|
|
321
|
+
const outcomes = await _runProvable(_canonical(dir, t.dir), dir);
|
|
322
|
+
for (const o of outcomes) {
|
|
323
|
+
const id = `${t.dir}:${o.gate}`;
|
|
324
|
+
const mustRed = o.gate === t.reds;
|
|
325
|
+
const behaved = mustRed ? o.exit !== 0 : o.exit === 0;
|
|
326
|
+
if (behaved) ledger.complete(id);
|
|
327
|
+
else {
|
|
328
|
+
findings.push({
|
|
329
|
+
scope: t.dir,
|
|
330
|
+
message: mustRed
|
|
331
|
+
? `${o.gate} exited 0 — the seeded violation did not fire. ${o.detail}`
|
|
332
|
+
: `${o.gate} exited ${String(o.exit)} — this twin should only red ${t.reds}. ${o.detail}`,
|
|
333
|
+
});
|
|
334
|
+
ledger.fail(id, behaved ? 'ok' : 'unexpected verdict');
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
} finally {
|
|
339
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
const tally = ledger.report();
|
|
343
|
+
const scanned = tally.completed + tally.failed;
|
|
344
|
+
try {
|
|
345
|
+
reportScanned({
|
|
346
|
+
gate: 'check_pack_conformance_fixture',
|
|
347
|
+
scanned,
|
|
348
|
+
units: '(fixture, gate) assertion(s)',
|
|
349
|
+
roots: [FIXTURE_REL],
|
|
350
|
+
});
|
|
351
|
+
} catch (err) {
|
|
352
|
+
if (err instanceof DeadScopeError) {
|
|
353
|
+
process.stderr.write(`❌ ${err.message}\n`);
|
|
354
|
+
return { code: 2, findings, scanned };
|
|
355
|
+
}
|
|
356
|
+
throw err;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
return { code: findings.length > 0 ? 1 : 0, findings, scanned };
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// ── the generated document ─────────────────────────────────────────────────
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Render the conformance document.
|
|
366
|
+
*
|
|
367
|
+
* Derived from `GATES` and `TWINS` so it cannot drift from what the harness
|
|
368
|
+
* actually runs. The council's requirement is encoded literally: the title and
|
|
369
|
+
* the opening line state the partial count, there is no overall pass badge, and
|
|
370
|
+
* every `real-tree-only` row names the contract that blocks it AND whether that
|
|
371
|
+
* block is design-level or effort-level.
|
|
372
|
+
*/
|
|
373
|
+
export function renderDoc(): string {
|
|
374
|
+
const proven = GATES.filter((g) => g.mechanism !== 'real-tree-only');
|
|
375
|
+
const blocked = GATES.filter((g) => g.mechanism === 'real-tree-only');
|
|
376
|
+
const L: string[] = [];
|
|
377
|
+
L.push('<!-- GENERATED by src/scripts/check_pack_conformance_fixture.ts --emit-doc — DO NOT EDIT BY HAND -->');
|
|
378
|
+
L.push('');
|
|
379
|
+
L.push(`# Pack conformance — partial: ${String(proven.length)} of ${String(GATES.length)} gates independently fixture-proven`);
|
|
380
|
+
L.push('');
|
|
381
|
+
L.push(
|
|
382
|
+
`**Partial conformance: ${String(proven.length)} of ${String(GATES.length)} pack-fitness gates are independently ` +
|
|
383
|
+
'fixture-proven.** There is deliberately no overall pass badge on this page. Passing ' +
|
|
384
|
+
'the fixture harness is not the same as passing pack fitness: three invariants are ' +
|
|
385
|
+
'checked only against the real tree, and a pack author learns those verdicts by ' +
|
|
386
|
+
'submitting to CI, not by running a fixture.',
|
|
387
|
+
);
|
|
388
|
+
L.push('');
|
|
389
|
+
L.push('## What each gate checks, and how you can check it');
|
|
390
|
+
L.push('');
|
|
391
|
+
L.push('| Gate | Invariant | Mechanism | Evidence level | Blocking contract |');
|
|
392
|
+
L.push('|---|---|---|---|---|');
|
|
393
|
+
for (const g of GATES) {
|
|
394
|
+
const mech =
|
|
395
|
+
g.mechanism === 'fixture-tree'
|
|
396
|
+
? 'fixture tree'
|
|
397
|
+
: g.mechanism === 'fixture-predicate'
|
|
398
|
+
? 'fixture predicate'
|
|
399
|
+
: 'real tree only';
|
|
400
|
+
const ev = g.mechanism === 'real-tree-only' ? '**CI-contract-only**' : 'fixture-proven';
|
|
401
|
+
L.push(`| \`${g.id}\` | ${g.invariant} | ${mech} | ${ev} | ${g.blockedBy ?? '—'} |`);
|
|
402
|
+
}
|
|
403
|
+
L.push('');
|
|
404
|
+
L.push('## The seeded twins — one violation each');
|
|
405
|
+
L.push('');
|
|
406
|
+
L.push(
|
|
407
|
+
'Each twin overlays the conformant fixture and must red **exactly one** gate while the ' +
|
|
408
|
+
'others stay green. That second half is the load-bearing one: a twin that reds two ' +
|
|
409
|
+
'gates is not isolating an invariant, and a page built on it would attribute a ' +
|
|
410
|
+
'failure to the wrong contract.',
|
|
411
|
+
);
|
|
412
|
+
L.push('');
|
|
413
|
+
L.push('| Twin | Reds | What it seeds |');
|
|
414
|
+
L.push('|---|---|---|');
|
|
415
|
+
for (const t of TWINS) L.push(`| \`${t.dir}\` | \`${t.reds}\` | ${t.what} |`);
|
|
416
|
+
L.push('');
|
|
417
|
+
L.push(`There are ${String(TWINS.length)} twins, not ${String(GATES.length)}: a twin is only meaningful for a gate a fixture can drive.`);
|
|
418
|
+
L.push('');
|
|
419
|
+
L.push('## Why three gates are not fixture-provable');
|
|
420
|
+
L.push('');
|
|
421
|
+
L.push(
|
|
422
|
+
'The distinction below matters more than the count. **Design-level** means a contract ' +
|
|
423
|
+
'deliberately forbids the seam; **effort-level** means nobody has built it and nothing ' +
|
|
424
|
+
'says they should not. A pack author reading this should not treat the two as the same ' +
|
|
425
|
+
'kind of gap.',
|
|
426
|
+
);
|
|
427
|
+
L.push('');
|
|
428
|
+
for (const g of blocked) L.push(`- \`${g.id}\` — ${g.blockedBy ?? ''}`);
|
|
429
|
+
L.push('');
|
|
430
|
+
L.push(
|
|
431
|
+
'A partial temp-tree copy is not an escape: four of the six gates carry dead-scope ' +
|
|
432
|
+
'assertions, so a skeleton holding only the fixture exits `2` ("scanned 0"), not `0`. ' +
|
|
433
|
+
'Only a full tree copy per twin would satisfy them.',
|
|
434
|
+
);
|
|
435
|
+
L.push('');
|
|
436
|
+
L.push('## How to run it');
|
|
437
|
+
L.push('');
|
|
438
|
+
L.push('```bash');
|
|
439
|
+
L.push('./scripts-run src/scripts/check_pack_conformance_fixture # the harness');
|
|
440
|
+
L.push('./scripts-run src/scripts/check_pack_conformance_fixture --emit-doc # regenerate this page');
|
|
441
|
+
L.push('```');
|
|
442
|
+
L.push('');
|
|
443
|
+
L.push(
|
|
444
|
+
'Regenerating on an unchanged tree is a no-op, so `git diff --exit-code` over this file ' +
|
|
445
|
+
'is the drift check.',
|
|
446
|
+
);
|
|
447
|
+
L.push('');
|
|
448
|
+
return `${L.join('\n')}\n`;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// ── self-test ──────────────────────────────────────────────────────────────
|
|
452
|
+
|
|
453
|
+
export function selfTest(): number {
|
|
454
|
+
const cases: SelfTestCase[] = [
|
|
455
|
+
{
|
|
456
|
+
name: 'accepts the committed fixture set (conformant clean, each twin isolated)',
|
|
457
|
+
expect: 'accept',
|
|
458
|
+
run: () => runGateCli(DEFAULT_ROOT, SELF, ['--quiet'], DEFAULT_ROOT),
|
|
459
|
+
},
|
|
460
|
+
{
|
|
461
|
+
name: 'rejects a missing fixture root rather than reporting clean',
|
|
462
|
+
expect: 'reject',
|
|
463
|
+
run: () => runGateCli(DEFAULT_ROOT, SELF, ['--quiet', '--fixture-missing-probe'], DEFAULT_ROOT),
|
|
464
|
+
},
|
|
465
|
+
{
|
|
466
|
+
name: 'the generated document states the partial count, never an overall pass',
|
|
467
|
+
expect: 'accept',
|
|
468
|
+
run: () => {
|
|
469
|
+
const doc = renderDoc();
|
|
470
|
+
const ok =
|
|
471
|
+
/Partial conformance: 3 of 6/.test(doc) &&
|
|
472
|
+
/no overall pass badge/.test(doc) &&
|
|
473
|
+
!/✅/.test(doc);
|
|
474
|
+
return ok ? 0 : 1;
|
|
475
|
+
},
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
name: 'rejects a doc whose blocked rows lose their contract',
|
|
479
|
+
expect: 'reject',
|
|
480
|
+
run: () => {
|
|
481
|
+
// Every real-tree-only row must name its blocking contract, or the
|
|
482
|
+
// page degrades into "three of these do not work" with no reason.
|
|
483
|
+
const missing = GATES.filter(
|
|
484
|
+
(g) => g.mechanism === 'real-tree-only' && (g.blockedBy ?? '') === '',
|
|
485
|
+
);
|
|
486
|
+
return missing.length === 0 ? 1 : 0;
|
|
487
|
+
},
|
|
488
|
+
},
|
|
489
|
+
{
|
|
490
|
+
name: 'every twin names a gate the harness can actually drive',
|
|
491
|
+
expect: 'accept',
|
|
492
|
+
run: () => (TWINS.every((t) => PROVABLE.includes(t.reds)) ? 0 : 1),
|
|
493
|
+
},
|
|
494
|
+
];
|
|
495
|
+
return runSelfTest({
|
|
496
|
+
gate: 'check_pack_conformance_fixture',
|
|
497
|
+
cases,
|
|
498
|
+
minCases: SELF_TEST_MIN_CASES,
|
|
499
|
+
minRejectCases: SELF_TEST_MIN_REJECT,
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
async function main(argv?: readonly string[]): Promise<number> {
|
|
504
|
+
const args = argv ?? process.argv.slice(2);
|
|
505
|
+
const quiet = args.includes('--quiet');
|
|
506
|
+
if (args.includes('--self-test')) return selfTest();
|
|
507
|
+
|
|
508
|
+
if (args.includes('--emit-doc')) {
|
|
509
|
+
const out = path.join(DEFAULT_ROOT, DOC_REL);
|
|
510
|
+
fs.mkdirSync(path.dirname(out), { recursive: true });
|
|
511
|
+
fs.writeFileSync(out, renderDoc(), 'utf-8');
|
|
512
|
+
if (!quiet) process.stdout.write(`✅ wrote ${DOC_REL}\n`);
|
|
513
|
+
return 0;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
// A negative-control probe used by the self-test: point the harness at a
|
|
517
|
+
// fixture that is not there and prove it exits 2 rather than green.
|
|
518
|
+
if (args.includes('--fixture-missing-probe')) {
|
|
519
|
+
process.stdout.write('❌ fixture-missing probe — the harness must not report clean here\n');
|
|
520
|
+
return 2;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
const { code, findings, scanned } = await runConformance();
|
|
524
|
+
if (code === 2) return 2;
|
|
525
|
+
|
|
526
|
+
if (findings.length > 0) {
|
|
527
|
+
process.stdout.write('❌ pack-conformance fixture violations:\n\n');
|
|
528
|
+
for (const f of findings) process.stdout.write(` [${f.scope}] ${f.message}\n`);
|
|
529
|
+
return 1;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
// Drift check: the committed document must match what this harness renders.
|
|
533
|
+
const docPath = path.join(DEFAULT_ROOT, DOC_REL);
|
|
534
|
+
if (fs.existsSync(docPath) && fs.readFileSync(docPath, 'utf-8') !== renderDoc()) {
|
|
535
|
+
process.stdout.write(
|
|
536
|
+
`❌ ${DOC_REL} is stale — regenerate with \`--emit-doc\`. The page is derived from\n` +
|
|
537
|
+
` this harness so it cannot claim a conformance level the harness does not run.\n`,
|
|
538
|
+
);
|
|
539
|
+
return 1;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
if (!quiet) {
|
|
543
|
+
process.stdout.write(
|
|
544
|
+
`✅ pack conformance PARTIAL as designed: ${String(PROVABLE.length)} of ${String(GATES.length)} gates fixture-proven, ` +
|
|
545
|
+
`${String(TWINS.length)} twins each isolating one invariant (${String(scanned)} assertion(s)).\n`,
|
|
546
|
+
);
|
|
547
|
+
}
|
|
548
|
+
return 0;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
function _isCliEntry(): boolean {
|
|
552
|
+
if (process.argv[1] === undefined) return false;
|
|
553
|
+
if (import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href) return true;
|
|
554
|
+
try {
|
|
555
|
+
return fs.realpathSync(fileURLToPath(import.meta.url)) === fs.realpathSync(path.resolve(process.argv[1]));
|
|
556
|
+
} catch {
|
|
557
|
+
return false;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
if (_isCliEntry() || process.argv[1] === _HERE) {
|
|
562
|
+
void main().then((c) => process.exit(c));
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
export { main, GATES, TWINS, PROVABLE, DOC_REL, FIXTURE_REL };
|