@event4u/agent-config 9.9.0 → 9.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/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +212 -194
- package/README.md +13 -16
- package/agents/templates/.ai-council.yml.example +481 -0
- package/agents/templates/.ai-video.xml.example +247 -0
- package/dist/agent-src/commands/agent-status.md +12 -11
- package/dist/agent-src/commands/agents/user/accept.md +115 -30
- package/dist/agent-src/commands/agents/user/delete.md +147 -0
- package/dist/agent-src/commands/agents/user/review.md +65 -28
- package/dist/agent-src/commands/agents/user/show.md +82 -29
- package/dist/agent-src/commands/agents/user/update.md +2 -2
- package/dist/agent-src/commands/agents/user.md +16 -3
- package/dist/agent-src/commands/check-current-md.md +0 -10
- package/dist/agent-src/commands/condense.md +28 -97
- package/dist/agent-src/commands/cost/report.md +7 -0
- package/dist/agent-src/commands/fix/portability.md +0 -8
- package/dist/agent-src/commands/fix/refs.md +0 -8
- package/dist/agent-src/commands/humanize.md +2 -2
- package/dist/agent-src/commands/jira-ticket.md +1 -1
- package/dist/agent-src/commands/memory/load.md +11 -0
- package/dist/agent-src/commands/optimize/skills.md +1 -1
- package/dist/agent-src/commands/pr/create.md +4 -4
- package/dist/agent-src/commands/profile/show.md +3 -3
- package/dist/agent-src/commands/rule-compliance-audit.md +5 -4
- package/dist/agent-src/commands/security-audit-config.md +1 -1
- package/dist/agent-src/commands/sync/gitignore/fix.md +1 -1
- package/dist/agent-src/commands/tdd.md +21 -0
- package/dist/agent-src/commands/team/delegate.md +2 -2
- package/dist/agent-src/commands/team-knowledge/bootstrap.md +9 -8
- package/dist/agent-src/commands/team-knowledge/consolidate.md +8 -7
- package/dist/agent-src/commands/team.md +4 -1
- package/dist/agent-src/commands/upstream-contribute.md +0 -1
- package/dist/agent-src/contexts/authority/commit-mechanics.md +7 -0
- package/dist/agent-src/contexts/authority/destructive-mechanics.md +16 -0
- package/dist/agent-src/contexts/authority/scope-mechanics.md +61 -0
- package/dist/agent-src/contexts/communication/rules-auto/reply-close-mechanics.md +20 -18
- package/dist/agent-src/contexts/communication/rules-auto/skill-quality-mechanics.md +1 -1
- package/dist/agent-src/contexts/communication/rules-auto/slash-command-routing-policy-mechanics.md +1 -1
- package/dist/agent-src/contexts/communication/rules-auto/source-of-truth-mechanics.md +9 -10
- package/dist/agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +1 -1
- package/dist/agent-src/contexts/communication/rules-auto/user-interaction-mechanics.md +11 -0
- package/dist/agent-src/contexts/contracts/artifact-engagement-flow.md +26 -15
- package/dist/agent-src/contexts/contracts/command-suggestion-flow.md +3 -0
- package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +67 -37
- package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +1 -1
- package/dist/agent-src/contexts/execution/autonomy-examples.md +1 -1
- package/dist/agent-src/contexts/execution/autonomy-mechanics.md +7 -6
- package/dist/agent-src/contexts/execution/evidence-discipline.md +92 -77
- package/dist/agent-src/contexts/execution/orchestration-benchmark-gate.md +22 -21
- package/dist/agent-src/contexts/execution/orchestration-telemetry.md +24 -0
- package/dist/agent-src/contexts/execution/project-intelligence.md +122 -103
- package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +23 -21
- package/dist/agent-src/contexts/execution/subagent-response-contract.md +5 -5
- package/dist/agent-src/contexts/execution/subagent-routing.md +11 -0
- package/dist/agent-src/contexts/execution/subagent-spawn-contract.md +13 -13
- package/dist/agent-src/contexts/execution/subagent-steering.md +36 -34
- package/dist/agent-src/contexts/execution/toolchain-resolver.md +1 -1
- package/dist/agent-src/contexts/execution/user-memory-channels.md +189 -0
- package/dist/agent-src/contexts/execution/verification-mechanics.md +9 -0
- package/dist/agent-src/contexts/model-recommendations.md +3 -2
- package/dist/agent-src/contexts/subagent-configuration.md +3 -3
- package/dist/agent-src/ghostwriter/README.md +2 -2
- package/dist/agent-src/packs/README.md +1 -1
- package/dist/agent-src/personas/README.md +5 -5
- package/dist/agent-src/personas/_template-specialist/persona.md +3 -3
- package/dist/agent-src/personas/backend-architect.md +24 -23
- package/dist/agent-src/personas/eloquent-tamer.md +30 -30
- package/dist/agent-src/personas/frontend-engineer.md +30 -30
- package/dist/agent-src/personas/product-owner.md +41 -38
- package/dist/agent-src/personas/qa.md +13 -13
- package/dist/agent-src/personas/security-engineer.md +22 -22
- package/dist/agent-src/presets/README.md +3 -3
- package/dist/agent-src/profiles/README.md +3 -3
- package/dist/agent-src/rules/active-remediation.md +2 -2
- package/dist/agent-src/rules/artifact-engagement-recording.md +4 -4
- package/dist/agent-src/rules/ask-when-uncertain.md +0 -4
- package/dist/agent-src/rules/augment-edit-discipline.md +1 -1
- package/dist/agent-src/rules/broken-access-control.md +4 -4
- package/dist/agent-src/rules/code-comment-discipline.md +1 -1
- package/dist/agent-src/rules/code-provenance.md +2 -2
- package/dist/agent-src/rules/commit-policy.md +4 -9
- package/dist/agent-src/rules/communication-through-line.md +5 -5
- package/dist/agent-src/rules/decision-revisit-gate.md +1 -1
- package/dist/agent-src/rules/design-fidelity.md +1 -1
- package/dist/agent-src/rules/doc-screenshot-hygiene.md +1 -1
- package/dist/agent-src/rules/domain-adoption-policy.md +1 -1
- package/dist/agent-src/rules/domain-safety-pii.md +1 -1
- package/dist/agent-src/rules/external-code-graph-interop.md +1 -1
- package/dist/agent-src/rules/fast-path-marker-visibility.md +43 -7
- package/dist/agent-src/rules/finance-safety-floor.md +1 -1
- package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +3 -3
- package/dist/agent-src/rules/history-discipline.md +1 -1
- package/dist/agent-src/rules/legal-safety-floor.md +1 -1
- package/dist/agent-src/rules/lethal-trifecta-guard.md +5 -5
- package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +10 -8
- package/dist/agent-src/rules/media-governance-routing.md +13 -13
- package/dist/agent-src/rules/media-sync-ground-truth.md +29 -11
- package/dist/agent-src/rules/no-cheap-questions.md +7 -7
- package/dist/agent-src/rules/no-decorative-emojis-in-git-surfaces.md +29 -18
- package/dist/agent-src/rules/non-destructive-by-default.md +5 -23
- package/dist/agent-src/rules/onboarding-gate.md +14 -4
- package/dist/agent-src/rules/persona-governance.md +2 -2
- package/dist/agent-src/rules/prefer-enums-over-literals.md +9 -9
- package/dist/agent-src/rules/preservation-guard.md +10 -2
- package/dist/agent-src/rules/question-not-instruction.md +1 -1
- package/dist/agent-src/rules/roadmap-progress-sync.md +6 -6
- package/dist/agent-src/rules/rule-type-governance.md +1 -1
- package/dist/agent-src/rules/scale-discipline.md +1 -1
- package/dist/agent-src/rules/scope-control.md +1 -1
- package/dist/agent-src/rules/secret-vcs-guard.md +1 -1
- package/dist/agent-src/rules/security-sensitive-stop.md +17 -11
- package/dist/agent-src/rules/senior-engineering-discipline.md +17 -17
- package/dist/agent-src/rules/session-canary.md +1 -1
- package/dist/agent-src/rules/skill-quality.md +1 -1
- package/dist/agent-src/rules/source-confidentiality.md +21 -19
- package/dist/agent-src/rules/source-of-truth.md +6 -5
- package/dist/agent-src/rules/spreadsheet-source-quality.md +2 -2
- package/dist/agent-src/rules/strategy-safety-floor.md +1 -1
- package/dist/agent-src/rules/think-before-action.md +5 -5
- package/dist/agent-src/rules/token-budget-discipline.md +5 -3
- package/dist/agent-src/rules/token-efficiency.md +2 -2
- package/dist/agent-src/rules/untrusted-input-defense.md +4 -4
- package/dist/agent-src/rules/user-interaction.md +12 -0
- package/dist/agent-src/rules/verify-before-complete.md +4 -24
- package/dist/agent-src/skills/adversarial-review/SKILL.md +2 -2
- package/dist/agent-src/skills/agent-security-review/SKILL.md +52 -45
- package/dist/agent-src/skills/agents-md-thin-root/SKILL.md +2 -2
- package/dist/agent-src/skills/ai-code-blindspots/SKILL.md +20 -20
- package/dist/agent-src/skills/ai-council/SKILL.md +185 -128
- package/dist/agent-src/skills/analysis-skill-router/SKILL.md +3 -3
- package/dist/agent-src/skills/api-endpoint/SKILL.md +2 -2
- package/dist/agent-src/skills/artisan-commands/SKILL.md +2 -2
- package/dist/agent-src/skills/async-python-patterns/SKILL.md +8 -7
- package/dist/agent-src/skills/authz-review/SKILL.md +16 -15
- package/dist/agent-src/skills/aws-infrastructure/SKILL.md +5 -5
- package/dist/agent-src/skills/blade-ui/SKILL.md +1 -1
- package/dist/agent-src/skills/bug-analyzer/SKILL.md +30 -12
- package/dist/agent-src/skills/code-intelligence/SKILL.md +0 -1
- package/dist/agent-src/skills/code-intelligence/evals/triggers.json +52 -0
- package/dist/agent-src/skills/code-review/SKILL.md +6 -6
- package/dist/agent-src/skills/command-routing/SKILL.md +5 -4
- package/dist/agent-src/skills/composer-packages/SKILL.md +2 -2
- package/dist/agent-src/skills/condense-memory/SKILL.md +43 -41
- package/dist/agent-src/skills/context-document/SKILL.md +23 -21
- package/dist/agent-src/skills/copilot-config/SKILL.md +6 -1
- package/dist/agent-src/skills/decision-record/SKILL.md +20 -18
- package/dist/agent-src/skills/design-intelligence/SKILL.md +4 -4
- package/dist/agent-src/skills/design-review/SKILL.md +15 -14
- package/dist/agent-src/skills/design-system-capture/reference/design-system-json.md +28 -25
- package/dist/agent-src/skills/devcontainer/SKILL.md +2 -2
- package/dist/agent-src/skills/docker/SKILL.md +1 -1
- package/dist/agent-src/skills/docx-authoring/evals/triggers.json +52 -0
- package/dist/agent-src/skills/emit-tickets/SKILL.md +2 -2
- package/dist/agent-src/skills/error-handling-patterns/SKILL.md +1 -1
- package/dist/agent-src/skills/estimate-ticket/SKILL.md +2 -2
- package/dist/agent-src/skills/evaluate-llm-feature/SKILL.md +0 -1
- package/dist/agent-src/skills/evaluate-llm-feature/evals/triggers.json +52 -0
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +21 -7
- package/dist/agent-src/skills/fe-design/SKILL.md +10 -0
- package/dist/agent-src/skills/feature-planning/SKILL.md +2 -2
- package/dist/agent-src/skills/finishing-a-development-branch/SKILL.md +3 -3
- package/dist/agent-src/skills/flux/SKILL.md +1 -1
- package/dist/agent-src/skills/frontend-render-security/SKILL.md +13 -13
- package/dist/agent-src/skills/git-workflow/SKILL.md +33 -33
- package/dist/agent-src/skills/grafana/SKILL.md +5 -0
- package/dist/agent-src/skills/humanizer/SKILL.md +83 -66
- package/dist/agent-src/skills/humanizer/data/patterns.md +14 -14
- package/dist/agent-src/skills/humanizer/references/anti-aiisms.md +4 -4
- package/dist/agent-src/skills/judge-artifact-completeness/SKILL.md +82 -37
- package/dist/agent-src/skills/judge-bug-hunter/SKILL.md +17 -5
- package/dist/agent-src/skills/judge-injection-defense/SKILL.md +63 -25
- package/dist/agent-src/skills/judge-security-auditor/SKILL.md +2 -0
- package/dist/agent-src/skills/judge-synthesis/SKILL.md +72 -28
- package/dist/agent-src/skills/laravel-horizon/SKILL.md +5 -0
- package/dist/agent-src/skills/laravel-mail/SKILL.md +5 -4
- package/dist/agent-src/skills/laravel-middleware/SKILL.md +5 -4
- package/dist/agent-src/skills/laravel-notifications/SKILL.md +10 -9
- package/dist/agent-src/skills/laravel-pennant/SKILL.md +1 -1
- package/dist/agent-src/skills/laravel-pulse/SKILL.md +9 -8
- package/dist/agent-src/skills/laravel-reverb/SKILL.md +6 -5
- package/dist/agent-src/skills/laravel-scheduling/SKILL.md +6 -1
- package/dist/agent-src/skills/laravel-validation/SKILL.md +12 -0
- package/dist/agent-src/skills/launch-readiness/SKILL.md +1 -1
- package/dist/agent-src/skills/learning-to-rule-or-skill/SKILL.md +7 -7
- package/dist/agent-src/skills/learning-tutor/SKILL.md +44 -43
- package/dist/agent-src/skills/learning-tutor/evals/triggers.json +52 -0
- package/dist/agent-src/skills/license-compliance-audit/SKILL.md +7 -7
- package/dist/agent-src/skills/license-compliance-borrow-check/SKILL.md +3 -3
- package/dist/agent-src/skills/license-compliance-credits/SKILL.md +4 -4
- package/dist/agent-src/skills/llm-provider-knowledge/SKILL.md +0 -1
- package/dist/agent-src/skills/memory-consolidation/SKILL.md +69 -64
- package/dist/agent-src/skills/motion-choreographer/SKILL.md +6 -6
- package/dist/agent-src/skills/pdf-tools/evals/triggers.json +52 -0
- package/dist/agent-src/skills/performance-analysis/SKILL.md +7 -3
- package/dist/agent-src/skills/persona-improvement/SKILL.md +0 -2
- package/dist/agent-src/skills/persona-improvement/evals/triggers.json +52 -0
- package/dist/agent-src/skills/php-coder/SKILL.md +10 -0
- package/dist/agent-src/skills/prediction-pool-optimizer/SKILL.md +129 -120
- package/dist/agent-src/skills/prediction-pool-optimizer/reference/ev-fixtures.md +36 -35
- package/dist/agent-src/skills/prediction-pool-optimizer/reference/odds-and-bonus.md +45 -41
- package/dist/agent-src/skills/project-analysis-core/SKILL.md +4 -4
- package/dist/agent-src/skills/project-analysis-hypothesis-driven/SKILL.md +3 -3
- package/dist/agent-src/skills/project-analysis-react/SKILL.md +1 -1
- package/dist/agent-src/skills/project-analysis-symfony/SKILL.md +1 -1
- package/dist/agent-src/skills/project-analysis-zend-laminas/SKILL.md +2 -2
- package/dist/agent-src/skills/prompt-engineering-patterns/SKILL.md +1 -1
- package/dist/agent-src/skills/prompt-validator/SKILL.md +39 -39
- package/dist/agent-src/skills/quality-tools/SKILL.md +15 -15
- package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +55 -19
- package/dist/agent-src/skills/react-shadcn-ui/reference/registry.md +29 -27
- package/dist/agent-src/skills/readme-writing-package/SKILL.md +2 -2
- package/dist/agent-src/skills/reasoning-orchestrator/SKILL.md +25 -25
- package/dist/agent-src/skills/recursive-verification/SKILL.md +6 -5
- package/dist/agent-src/skills/refine-prompt/SKILL.md +1 -1
- package/dist/agent-src/skills/refine-ticket/SKILL.md +20 -2
- package/dist/agent-src/skills/repomix-packer/SKILL.md +1 -1
- package/dist/agent-src/skills/requesting-code-review/SKILL.md +2 -2
- package/dist/agent-src/skills/roadmap-management/SKILL.md +80 -66
- package/dist/agent-src/skills/roadmap-writing/SKILL.md +84 -77
- package/dist/agent-src/skills/rule-refactor/SKILL.md +1 -1
- package/dist/agent-src/skills/screenshot-hygiene/evals/triggers.json +52 -0
- package/dist/agent-src/skills/security-audit/SKILL.md +26 -9
- package/dist/agent-src/skills/security-maturity-assessment/SKILL.md +38 -16
- package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +14 -11
- package/dist/agent-src/skills/skill-writing/SKILL.md +9 -8
- package/dist/agent-src/skills/song-to-script/SKILL.md +93 -85
- package/dist/agent-src/skills/sql-writing/SKILL.md +2 -2
- package/dist/agent-src/skills/stakeholder-tradeoff/SKILL.md +4 -3
- package/dist/agent-src/skills/standards-from-config/SKILL.md +61 -43
- package/dist/agent-src/skills/subagent-orchestration/SKILL.md +22 -8
- package/dist/agent-src/skills/subagent-orchestration/prompts/README.md +28 -2
- package/dist/agent-src/skills/supply-chain-intake/SKILL.md +13 -13
- package/dist/agent-src/skills/systematic-debugging/SKILL.md +22 -21
- package/dist/agent-src/skills/tailwind-engineer/SKILL.md +1 -1
- package/dist/agent-src/skills/technical-specification/SKILL.md +5 -0
- package/dist/agent-src/skills/terraform/SKILL.md +2 -2
- package/dist/agent-src/skills/terragrunt/SKILL.md +8 -8
- package/dist/agent-src/skills/testing-anti-patterns/process-anti-patterns.md +1 -1
- package/dist/agent-src/skills/threat-modeling/SKILL.md +19 -13
- package/dist/agent-src/skills/universal-project-analysis/SKILL.md +1 -1
- package/dist/agent-src/skills/upstream-contribute/SKILL.md +0 -1
- package/dist/agent-src/skills/using-git-worktrees/SKILL.md +9 -9
- package/dist/agent-src/skills/validate-feature-fit/SKILL.md +3 -1
- package/dist/agent-src/skills/verify-completion-evidence/SKILL.md +4 -6
- package/dist/agent-src/skills/verify-repair-loop/SKILL.md +67 -61
- package/dist/agent-src/skills/video-director/SKILL.md +7 -7
- package/dist/agent-src/skills/worktree-lifecycle/SKILL.md +3 -3
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/contexts/knowledge-pages.md +47 -45
- package/dist/agent-src/templates/contexts/lesson-card.md +2 -2
- package/dist/agent-src/templates/contexts/tenant-boundaries.md +2 -2
- package/dist/agent-src/templates/contexts.md +1 -1
- package/dist/agent-src/templates/features.md +1 -1
- package/dist/agent-src/templates/roadmaps.md +125 -116
- package/dist/agent-src/templates/rule.md +2 -1
- package/dist/agent-src/templates/scripts/pr_risk_review.ts +0 -0
- package/dist/agent-src/templates/scripts/telemetry/aggregator.ts +0 -0
- package/dist/agent-src/templates/scripts/tier_usage_report.ts +2 -2
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +30 -30
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/design.ts +88 -33
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +22 -2
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/review.ts +21 -2
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/stack_bundles.ts +179 -0
- package/dist/agent-src/templates/scripts/work_engine/stack/detect.ts +155 -4
- package/dist/agent-src/templates/scripts/work_engine/state.ts +21 -4
- package/dist/agent-src/user-types/README.md +8 -8
- package/dist/agent-src/user-types/galabau-field-crew.md +34 -33
- package/dist/agent-src/user-types/metalworking-shop.md +35 -34
- package/dist/agent-src/user-types/truck-driver.md +22 -20
- package/dist/cli/initRouting.js +74 -11
- package/dist/cli/initRouting.js.map +1 -1
- package/dist/cli/main.js +14 -3
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/python/workspace_roles.js +2 -2
- package/dist/cli/python/workspace_roles.js.map +1 -1
- package/dist/cli-delegate/chunk-4SV3XGFA.js +6910 -0
- package/dist/cli-delegate/chunk-736JCWLM.js +1104 -0
- package/dist/cli-delegate/chunk-7DSAMZFU.js +356 -0
- package/dist/cli-delegate/chunk-7HQ52DHU.js +74 -0
- package/dist/cli-delegate/chunk-BJGXZNPM.js +266 -0
- package/dist/cli-delegate/chunk-FTAISGDQ.js +117 -0
- package/dist/cli-delegate/chunk-GME3Q44L.js +82 -0
- package/dist/cli-delegate/chunk-GRRPEPRN.js +336 -0
- package/dist/cli-delegate/chunk-HJ6DAJHR.js +502 -0
- package/dist/cli-delegate/chunk-IR7P7JWA.js +872 -0
- package/dist/cli-delegate/chunk-J55WI3RR.js +47 -0
- package/dist/cli-delegate/chunk-MCJYCQPF.js +35 -0
- package/dist/cli-delegate/chunk-NDJLNC6Q.js +169 -0
- package/dist/cli-delegate/chunk-OMIVVCG2.js +26 -0
- package/dist/cli-delegate/chunk-OY53J6II.js +7336 -0
- package/dist/cli-delegate/chunk-RDGRHAAB.js +259 -0
- package/dist/cli-delegate/chunk-TFG57JJM.js +1969 -0
- package/dist/cli-delegate/chunk-XX6TOPD7.js +715 -0
- package/dist/cli-delegate/chunk-YMFO6FDN.js +10603 -0
- package/dist/cli-delegate/cmd_analyze_session.js +294 -0
- package/dist/cli-delegate/cmd_conformance.js +646 -0
- package/dist/cli-delegate/cmd_converge.js +326 -0
- package/dist/cli-delegate/cmd_doctor.js +144 -0
- package/dist/cli-delegate/cmd_explain.js +2508 -0
- package/dist/cli-delegate/cmd_export.js +296 -0
- package/dist/cli-delegate/cmd_fleet.js +332 -0
- package/dist/cli-delegate/cmd_memory_get.js +3878 -0
- package/dist/cli-delegate/cmd_migrate.js +11 -0
- package/dist/cli-delegate/cmd_preflight.js +270 -0
- package/dist/cli-delegate/cmd_prune.js +444 -0
- package/dist/cli-delegate/cmd_refresh.js +28 -0
- package/dist/cli-delegate/cmd_settings_check.js +574 -0
- package/dist/cli-delegate/cmd_settings_migrate.js +223 -0
- package/dist/cli-delegate/cmd_sync.js +264 -0
- package/dist/cli-delegate/cmd_uninstall.js +656 -0
- package/dist/cli-delegate/cmd_update.js +425 -0
- package/dist/cli-delegate/cmd_upgrade.js +444 -0
- package/dist/cli-delegate/cmd_validate.js +305 -0
- package/dist/cli-delegate/cmd_versions.js +370 -0
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +100 -67
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +4 -4
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +16 -10
- package/dist/discovery/trust-report.md +2 -2
- package/dist/discovery/workspaces.json +7 -5
- package/dist/hooks/dispatch.js +186 -12
- package/dist/install/emit_host_rules_cli.js +2 -1
- package/dist/install/emit_host_rules_cli.js.map +1 -1
- package/dist/install/install.mjs +418 -378
- package/dist/install/rule_scope.js +5 -1
- package/dist/install/rule_scope.js.map +1 -1
- package/dist/install/toolDetection.js +40 -12
- package/dist/install/toolDetection.js.map +1 -1
- package/dist/install/wizard-plan.js +2 -2
- package/dist/install/wizard-plan.js.map +1 -1
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +2194 -1003
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/compile_time_toggles.js +48 -0
- package/dist/scripts/_lib/compile_time_toggles.js.map +1 -0
- package/dist/scripts/condense.js +234 -217
- package/dist/scripts/condense.js.map +1 -1
- package/dist/server/schemas/settings.js +4 -0
- package/dist/server/schemas/settings.js.map +1 -1
- package/dist/shared/userMd/utils.js +30 -0
- package/dist/shared/userMd/utils.js.map +1 -1
- package/dist/ui/assets/index-BpSQt5vm.js.map +1 -1
- package/docs/guidelines/agent-infra/api-cost-levers.md +56 -5
- package/docs/guidelines/agent-infra/simplicity-and-goal-demos.md +93 -33
- package/package.json +4 -2
- package/src/agent-src/templates/scripts/pr_risk_review.ts +0 -0
- package/src/agent-src/templates/scripts/telemetry/aggregator.ts +0 -0
- package/src/agent-src/templates/scripts/tier_usage_report.ts +2 -2
- package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +30 -30
- package/src/agent-src/templates/scripts/work_engine/directives/ui/design.ts +88 -33
- package/src/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +22 -2
- package/src/agent-src/templates/scripts/work_engine/directives/ui/review.ts +21 -2
- package/src/agent-src/templates/scripts/work_engine/directives/ui/stack_bundles.ts +179 -0
- package/src/agent-src/templates/scripts/work_engine/stack/detect.ts +155 -4
- package/src/agent-src/templates/scripts/work_engine/state.ts +21 -4
- package/src/config/agent-settings.template.yml +32 -2
- package/src/config/ci-local-parity.yml +142 -0
- package/src/config/discovery/packs.yml +7 -0
- package/src/config/evaluator-budgets.json +1 -1
- package/src/config/gate-coverage.yml +127 -0
- package/src/config/pack-size-budget.json +27 -0
- package/src/config/preamble-payload-budget.json +44 -0
- package/src/install/emit_host_rules_cli.ts +2 -1
- package/src/install/rule_scope.ts +5 -1
- package/src/install/toolDetection.ts +39 -8
- package/src/install/wizard-plan.ts +2 -2
- package/src/scripts/_cli/cmd_conformance.ts +2 -1
- package/src/scripts/_cli/cmd_converge.ts +2 -1
- package/src/scripts/_cli/cmd_doctor.ts +292 -15
- package/src/scripts/_cli/cmd_export.ts +2 -1
- package/src/scripts/_cli/cmd_fleet.ts +2 -1
- package/src/scripts/_cli/cmd_migrate.ts +2 -1
- package/src/scripts/_cli/cmd_preflight.ts +2 -1
- package/src/scripts/_cli/cmd_refresh.ts +2 -1
- package/src/scripts/_cli/cmd_update.ts +2 -1
- package/src/scripts/_cli/cmd_upgrade.ts +2 -1
- package/src/scripts/_cli/cmd_versions.ts +2 -1
- package/src/scripts/_cli/detection_report.ts +480 -0
- package/src/scripts/_dispatch.bash +52 -14
- package/src/scripts/_lib/agent_user_profile.ts +381 -0
- package/src/scripts/_lib/agents_overlay.ts +9 -0
- package/src/scripts/_lib/anchor_eval.ts +311 -0
- package/src/scripts/_lib/cc_transcript.ts +316 -0
- package/src/scripts/_lib/changelog_eras.ts +103 -9
- package/src/scripts/_lib/compile_time_toggles.ts +79 -0
- package/src/scripts/_lib/confusables.ts +101 -0
- package/src/scripts/_lib/duplicate_scope_census.ts +77 -0
- package/src/scripts/_lib/environment_detector.ts +441 -0
- package/src/scripts/_lib/managed_agents_folder.ts +181 -0
- package/src/scripts/_lib/package_root.ts +72 -0
- package/src/scripts/_lib/payload_hash_drift.ts +126 -0
- package/src/scripts/_lib/preservation_migration.ts +291 -0
- package/src/scripts/_lib/retrieval_sanitize.ts +166 -2
- package/src/scripts/_lib/scan_scope.ts +115 -0
- package/src/scripts/_lib/user_global_memory_audit.ts +187 -0
- package/src/scripts/_lib/user_global_observations.ts +830 -0
- package/src/scripts/_lib/user_global_revocations.ts +110 -0
- package/src/scripts/_lib/user_memory_gate_counters.ts +291 -0
- package/src/scripts/ai_council/blind_review.ts +0 -0
- package/src/scripts/ai_council/budget_guard.ts +90 -11
- package/src/scripts/ai_council/bundler.ts +2 -2
- package/src/scripts/ai_council/clients.ts +59 -3
- package/src/scripts/ai_council/config.ts +53 -7
- package/src/scripts/ai_council/modes.ts +68 -2
- package/src/scripts/ai_council/orchestrator.ts +54 -9
- package/src/scripts/ai_council/transport_resolver.ts +331 -0
- package/src/scripts/ai_team/team_dispatch.ts +17 -6
- package/src/scripts/anchor_eval_falsify.ts +198 -0
- package/src/scripts/anchor_scoring_run.ts +239 -0
- package/src/scripts/annotate_discovery.ts +1 -65
- package/src/scripts/bench_quality_run.ts +168 -4
- package/src/scripts/cache_realization_report.ts +782 -0
- package/src/scripts/check_artefact_count_messaging.ts +5 -1
- package/src/scripts/check_augment_description_cap.ts +15 -4
- package/src/scripts/check_bundle_path_leakage.ts +10 -4
- package/src/scripts/check_ci_local_parity.ts +317 -0
- package/src/scripts/check_condensation.ts +96 -191
- package/src/scripts/check_context_paths.ts +38 -9
- package/src/scripts/check_dependency_floors.ts +153 -0
- package/src/scripts/check_gate_coverage.ts +299 -0
- package/src/scripts/check_iron_law_prominence.ts +22 -1
- package/src/scripts/check_kernel_prefix_stability.ts +0 -0
- package/src/scripts/check_no_new_legacy_path.ts +16 -6
- package/src/scripts/check_no_roadmap_refs.ts +22 -9
- package/src/scripts/check_originality_freshness.ts +167 -0
- package/src/scripts/check_pack_size.ts +188 -0
- package/src/scripts/check_preamble_payload_budget.ts +130 -0
- package/src/scripts/check_proposal.ts +0 -0
- package/src/scripts/check_references.ts +0 -1
- package/src/scripts/check_safety_floor_untouched.ts +171 -24
- package/src/scripts/check_site_links.ts +62 -3
- package/src/scripts/ci_status.ts +0 -0
- package/src/scripts/cluster_near_miss_patterns.ts +0 -0
- package/src/scripts/code_graph/build.ts +0 -0
- package/src/scripts/command_suggester/types.ts +0 -0
- package/src/scripts/compile_router.ts +10 -14
- package/src/scripts/condense.sh +3 -4
- package/src/scripts/condense.ts +247 -228
- package/src/scripts/cost/track.mjs +168 -33
- package/src/scripts/cost_summary.ts +33 -1
- package/src/scripts/council_cli.ts +51 -5
- package/src/scripts/discovery_graph.ts +0 -0
- package/src/scripts/encoding_corpus.ts +500 -0
- package/src/scripts/encoding_corpus_report.ts +216 -0
- package/src/scripts/evaluator_umbrella.sh +34 -1
- package/src/scripts/generate_index.ts +19 -2
- package/src/scripts/install-hooks.sh +2 -2
- package/src/scripts/learning_sidecar.ts +0 -0
- package/src/scripts/lint_confusables.ts +10 -72
- package/src/scripts/lint_eval_fixture_citations.ts +113 -0
- package/src/scripts/lint_featured_skills.ts +0 -0
- package/src/scripts/lint_hidden_unicode.ts +208 -0
- package/src/scripts/lint_load_context.ts +17 -5
- package/src/scripts/lint_new_skill_gate.ts +9 -3
- package/src/scripts/lint_no_python_twin_rationale.ts +17 -2
- package/src/scripts/lint_originality.ts +1 -1
- package/src/scripts/lint_skill_originality.ts +1 -1
- package/src/scripts/lint_ticket_buildable.ts +1 -1
- package/src/scripts/lint_ui_stack_bundles.ts +170 -0
- package/src/scripts/mcp_server/tools.ts +4 -4
- package/src/scripts/measure_scope_dedup.ts +224 -0
- package/src/scripts/memory_lookup.ts +0 -0
- package/src/scripts/mine_session.ts +98 -0
- package/src/scripts/orchestration_payload_hash_drift.ts +145 -0
- package/src/scripts/preamble_byte_census.ts +574 -0
- package/src/scripts/probe_skill_registration.ts +2 -2
- package/src/scripts/redact_hook_capture.ts +13 -0
- package/src/scripts/release.ts +65 -10
- package/src/scripts/router_telemetry.ts +1 -1
- package/src/scripts/second_brain_retrieval.ts +14 -4
- package/src/scripts/skill_linter.ts +5 -0
- package/src/scripts/surface-tiers.yml +2 -0
- package/src/scripts/validate_pack_yaml.ts +0 -0
- package/src/server/schemas/settings.ts +8 -0
- package/src/shared/userMd/utils.ts +31 -0
- package/dist/agent-src/rules/telegraph-speak.md +0 -87
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* Meta-gate: verify that the repo's gates actually inspect something.
|
|
4
|
+
*
|
|
5
|
+
* A gate that scans nothing exits 0 and certifies coverage that does not exist.
|
|
6
|
+
* That is strictly worse than having no gate, because the green is believed. On
|
|
7
|
+
* 2026-07-29 a sweep found three such gates in CI, each pointing at a tree
|
|
8
|
+
* emptied by the ADR-051 flat-`src/` migration; one of them printed the literal
|
|
9
|
+
* count `0` in its own output for as long as it was broken.
|
|
10
|
+
*
|
|
11
|
+
* This guard reads `src/config/gate-coverage.yml`, runs each listed gate with the
|
|
12
|
+
* CI-identical arguments declared there, reads the `scanned: <N>` line the gate
|
|
13
|
+
* emits, and fails when N falls below the declared floor.
|
|
14
|
+
*
|
|
15
|
+
* Three design rules, each traceable to a concrete failure — see the manifest
|
|
16
|
+
* header for the full rationale:
|
|
17
|
+
* 1. Gates emit a machine-readable count; the guard never parses human output.
|
|
18
|
+
* 2. Invocations mirror CI exactly (a bare probe produced a false alarm during
|
|
19
|
+
* the sweep).
|
|
20
|
+
* 3. The check is a baseline floor, not `> 0` (428 → 3 is also a collapse).
|
|
21
|
+
*
|
|
22
|
+
* Self-honesty: this guard must not become the thing it catches. It fails when
|
|
23
|
+
* the manifest is empty or unreadable, and it REPORTS `pending` gates (listed but
|
|
24
|
+
* not yet emitting a count) instead of skipping them silently.
|
|
25
|
+
*
|
|
26
|
+
* CLI:
|
|
27
|
+
* ./scripts-run src/scripts/check_gate_coverage # enforce
|
|
28
|
+
* ./scripts-run src/scripts/check_gate_coverage --list # show the manifest
|
|
29
|
+
* ./scripts-run src/scripts/check_gate_coverage --format json
|
|
30
|
+
*
|
|
31
|
+
* Exit codes: 0 all enforced gates cleared their floor · 1 a gate is blind,
|
|
32
|
+
* collapsed, or silent · 2 the manifest itself is missing/empty/malformed.
|
|
33
|
+
*/
|
|
34
|
+
import { spawnSync } from 'node:child_process';
|
|
35
|
+
import * as fs from 'node:fs';
|
|
36
|
+
import * as path from 'node:path';
|
|
37
|
+
import process from 'node:process';
|
|
38
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
39
|
+
|
|
40
|
+
import yaml from 'js-yaml';
|
|
41
|
+
|
|
42
|
+
const _HERE = fileURLToPath(import.meta.url);
|
|
43
|
+
const REPO_ROOT = path.resolve(path.dirname(_HERE), '..', '..');
|
|
44
|
+
const MANIFEST = path.join(REPO_ROOT, 'src/config/gate-coverage.yml');
|
|
45
|
+
|
|
46
|
+
/** The one line a gate must emit. Deliberately narrow: no format guessing. */
|
|
47
|
+
const SCANNED_RE = /^\s*scanned:\s*(\d+)\s*$/m;
|
|
48
|
+
|
|
49
|
+
export interface GateSpec {
|
|
50
|
+
id: string;
|
|
51
|
+
argv: string[];
|
|
52
|
+
min_scanned: number;
|
|
53
|
+
corpus: string;
|
|
54
|
+
status: 'enforced' | 'pending';
|
|
55
|
+
/**
|
|
56
|
+
* Exit code meaning "my prerequisite is absent, so I inspected nothing" — e.g.
|
|
57
|
+
* check_site_links exits 2 when the site is unbuilt or stale. Without this the
|
|
58
|
+
* guard reads that as `silent` and fails, which would make it red on every machine
|
|
59
|
+
* lacking a build artefact: a gate that blocks for an environmental reason teaches
|
|
60
|
+
* people to ignore it, which is worse than no gate. Reported as `unavailable`
|
|
61
|
+
* rather than skipped, so the partial coverage stays visible — the same reason
|
|
62
|
+
* `pending` is reported instead of hidden.
|
|
63
|
+
*/
|
|
64
|
+
unavailable_exit?: number;
|
|
65
|
+
note?: string;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export type Verdict = 'ok' | 'below_floor' | 'silent' | 'crashed' | 'pending' | 'unavailable';
|
|
69
|
+
|
|
70
|
+
export interface GateResult {
|
|
71
|
+
id: string;
|
|
72
|
+
status: GateSpec['status'];
|
|
73
|
+
verdict: Verdict;
|
|
74
|
+
scanned: number | null;
|
|
75
|
+
min_scanned: number;
|
|
76
|
+
message: string;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function _require_int(v: unknown, id: string, i: number): number {
|
|
80
|
+
const n = Number(v);
|
|
81
|
+
if (!Number.isInteger(n)) {
|
|
82
|
+
throw new Error(`gates[${String(i)}] (${id}): unavailable_exit must be an integer exit code`);
|
|
83
|
+
}
|
|
84
|
+
return n;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Parse + validate the manifest. Throws on anything that would make the guard
|
|
88
|
+
* silently vacuous — an empty gate list is a hard error, not an empty pass. */
|
|
89
|
+
export function load_manifest(file = MANIFEST): GateSpec[] {
|
|
90
|
+
if (!fs.existsSync(file)) {
|
|
91
|
+
throw new Error(`manifest not found: ${path.relative(REPO_ROOT, file)}`);
|
|
92
|
+
}
|
|
93
|
+
const doc = yaml.load(fs.readFileSync(file, 'utf-8')) as { gates?: unknown[] };
|
|
94
|
+
const raw = Array.isArray(doc?.gates) ? doc.gates : [];
|
|
95
|
+
if (raw.length === 0) {
|
|
96
|
+
throw new Error('manifest declares zero gates — a coverage guard over an empty set is vacuous');
|
|
97
|
+
}
|
|
98
|
+
return raw.map((entry, i) => {
|
|
99
|
+
const e = entry as Record<string, unknown>;
|
|
100
|
+
const id = String(e['id'] ?? '');
|
|
101
|
+
if (id === '') throw new Error(`gates[${i}]: missing id`);
|
|
102
|
+
const min = Number(e['min_scanned']);
|
|
103
|
+
if (!Number.isInteger(min) || min < 0) {
|
|
104
|
+
throw new Error(`gates[${i}] (${id}): min_scanned must be a non-negative integer`);
|
|
105
|
+
}
|
|
106
|
+
const status = String(e['status'] ?? 'enforced');
|
|
107
|
+
if (status !== 'enforced' && status !== 'pending') {
|
|
108
|
+
throw new Error(`gates[${i}] (${id}): status must be 'enforced' or 'pending'`);
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
id,
|
|
112
|
+
argv: Array.isArray(e['argv']) ? e['argv'].map(String) : [],
|
|
113
|
+
min_scanned: min,
|
|
114
|
+
corpus: String(e['corpus'] ?? ''),
|
|
115
|
+
status,
|
|
116
|
+
...(e['unavailable_exit'] === undefined
|
|
117
|
+
? {}
|
|
118
|
+
: { unavailable_exit: _require_int(e['unavailable_exit'], id, i) }),
|
|
119
|
+
...(e['note'] === undefined ? {} : { note: String(e['note']) }),
|
|
120
|
+
};
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** Extract the contract line. Returns null when the gate emitted no count. */
|
|
125
|
+
export function parse_scanned(output: string): number | null {
|
|
126
|
+
const m = SCANNED_RE.exec(output);
|
|
127
|
+
return m === null ? null : Number(m[1]);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** Classify one gate's run against its declared floor. Pure — testable without
|
|
131
|
+
* spawning anything. */
|
|
132
|
+
export function classify(
|
|
133
|
+
spec: GateSpec,
|
|
134
|
+
scanned: number | null,
|
|
135
|
+
crashed: boolean,
|
|
136
|
+
exit_code?: number | null,
|
|
137
|
+
): GateResult {
|
|
138
|
+
const base = { id: spec.id, status: spec.status, scanned, min_scanned: spec.min_scanned };
|
|
139
|
+
if (spec.status === 'pending') {
|
|
140
|
+
return {
|
|
141
|
+
...base,
|
|
142
|
+
verdict: 'pending',
|
|
143
|
+
message:
|
|
144
|
+
scanned === null
|
|
145
|
+
? `not yet emitting 'scanned:' — listed as pending, NOT enforced (coverage gap is visible, not hidden)`
|
|
146
|
+
: `reports ${String(scanned)}; floor ${String(spec.min_scanned)} not enforced while pending`,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
if (crashed) {
|
|
150
|
+
return { ...base, verdict: 'crashed', message: 'gate could not be executed' };
|
|
151
|
+
}
|
|
152
|
+
if (
|
|
153
|
+
spec.unavailable_exit !== undefined &&
|
|
154
|
+
exit_code !== undefined &&
|
|
155
|
+
exit_code !== null &&
|
|
156
|
+
exit_code === spec.unavailable_exit
|
|
157
|
+
) {
|
|
158
|
+
return {
|
|
159
|
+
...base,
|
|
160
|
+
verdict: 'unavailable',
|
|
161
|
+
message:
|
|
162
|
+
`exited ${String(exit_code)} — prerequisite absent, nothing inspected. ` +
|
|
163
|
+
`Coverage unverified here; CI is where this gate has its inputs`,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
if (scanned === null) {
|
|
167
|
+
return {
|
|
168
|
+
...base,
|
|
169
|
+
verdict: 'silent',
|
|
170
|
+
message: `emitted no 'scanned: <N>' line — an enforced gate must report what it inspected`,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
if (scanned < spec.min_scanned) {
|
|
174
|
+
return {
|
|
175
|
+
...base,
|
|
176
|
+
verdict: 'below_floor',
|
|
177
|
+
message:
|
|
178
|
+
`scanned ${String(scanned)}, floor ${String(spec.min_scanned)} (${spec.corpus}) — ` +
|
|
179
|
+
`a gate inspecting this little cannot certify the corpus`,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
return { ...base, verdict: 'ok', message: `scanned ${String(scanned)} ≥ ${String(spec.min_scanned)}` };
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function run_gate(spec: GateSpec): { scanned: number | null; crashed: boolean; exit_code: number | null } {
|
|
186
|
+
const runner = path.join(REPO_ROOT, 'scripts-run');
|
|
187
|
+
const r = spawnSync(runner, [`src/scripts/${spec.id}`, ...spec.argv], {
|
|
188
|
+
cwd: REPO_ROOT,
|
|
189
|
+
encoding: 'utf8',
|
|
190
|
+
});
|
|
191
|
+
if (r.error !== undefined || r.status === null) return { scanned: null, crashed: true, exit_code: null };
|
|
192
|
+
// A gate may legitimately exit non-zero (it found real violations) and still
|
|
193
|
+
// have scanned plenty — coverage and verdict are different questions.
|
|
194
|
+
return { scanned: parse_scanned(`${r.stdout}\n${r.stderr}`), crashed: false, exit_code: r.status };
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const ICON: Record<Verdict, string> = {
|
|
198
|
+
ok: '✅',
|
|
199
|
+
below_floor: '❌',
|
|
200
|
+
silent: '❌',
|
|
201
|
+
crashed: '❌',
|
|
202
|
+
pending: '⚠️',
|
|
203
|
+
unavailable: '⚠️',
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
export function main(argv: readonly string[]): number {
|
|
207
|
+
const wantJson = argv.includes('--format') && argv[argv.indexOf('--format') + 1] === 'json';
|
|
208
|
+
const listOnly = argv.includes('--list');
|
|
209
|
+
|
|
210
|
+
let specs: GateSpec[];
|
|
211
|
+
try {
|
|
212
|
+
specs = load_manifest();
|
|
213
|
+
} catch (e) {
|
|
214
|
+
process.stderr.write(`❌ gate-coverage manifest: ${(e as Error).message}\n`);
|
|
215
|
+
return 2;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (listOnly) {
|
|
219
|
+
for (const s of specs) {
|
|
220
|
+
process.stdout.write(
|
|
221
|
+
` ${s.status === 'enforced' ? '[enforced]' : '[pending] '} ${s.id} ` +
|
|
222
|
+
`argv=[${s.argv.join(' ')}] floor=${String(s.min_scanned)}\n`,
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
process.stdout.write(`scanned: ${String(specs.length)}\n`);
|
|
226
|
+
return 0;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const results = specs.map((s) => {
|
|
230
|
+
if (spec_is_pending(s)) {
|
|
231
|
+
const { scanned, crashed } = probe_pending(s);
|
|
232
|
+
return classify(s, scanned, crashed);
|
|
233
|
+
}
|
|
234
|
+
const { scanned, crashed, exit_code } = run_gate(s);
|
|
235
|
+
return classify(s, scanned, crashed, exit_code);
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
if (wantJson) {
|
|
239
|
+
process.stdout.write(`${JSON.stringify({ generated_by: 'check_gate_coverage', results }, null, 2)}\n`);
|
|
240
|
+
} else {
|
|
241
|
+
for (const r of results) {
|
|
242
|
+
process.stdout.write(` ${ICON[r.verdict]} ${r.id}: ${r.message}\n`);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const failed = results.filter((r) => r.verdict === 'below_floor' || r.verdict === 'silent' || r.verdict === 'crashed');
|
|
247
|
+
const pending = results.filter((r) => r.verdict === 'pending');
|
|
248
|
+
const unavailable = results.filter((r) => r.verdict === 'unavailable');
|
|
249
|
+
|
|
250
|
+
// The guard reports its OWN coverage. Hiding a pending gate behind a green
|
|
251
|
+
// summary is exactly the failure mode this file exists to prevent.
|
|
252
|
+
process.stdout.write(
|
|
253
|
+
`\nscanned: ${String(results.length)}\n` +
|
|
254
|
+
` enforced ${String(results.length - pending.length)} · pending ${String(pending.length)} · ` +
|
|
255
|
+
`unavailable ${String(unavailable.length)} · failing ${String(failed.length)}\n`,
|
|
256
|
+
);
|
|
257
|
+
if (unavailable.length > 0) {
|
|
258
|
+
process.stdout.write(
|
|
259
|
+
`⚠️ ${String(unavailable.length)} gate(s) could not run here (prerequisite absent) — ` +
|
|
260
|
+
`their coverage is unverified locally, not proven.\n`,
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
if (pending.length > 0) {
|
|
264
|
+
process.stdout.write(
|
|
265
|
+
`⚠️ ${String(pending.length)} gate(s) are listed but NOT enforced — this guard's coverage is partial by declaration.\n`,
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
if (failed.length > 0) {
|
|
269
|
+
process.stdout.write(`❌ ${String(failed.length)} gate(s) failed the coverage floor.\n`);
|
|
270
|
+
return 1;
|
|
271
|
+
}
|
|
272
|
+
process.stdout.write('✅ every enforced gate cleared its coverage floor.\n');
|
|
273
|
+
return 0;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
function spec_is_pending(s: GateSpec): boolean {
|
|
277
|
+
return s.status === 'pending';
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/** Pending gates are still probed (so the report shows what they currently do),
|
|
281
|
+
* but their count never fails the build. */
|
|
282
|
+
function probe_pending(s: GateSpec): { scanned: number | null; crashed: boolean } {
|
|
283
|
+
return run_gate(s);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
function _isCliEntry(): boolean {
|
|
287
|
+
if (process.argv[1] === undefined) return false;
|
|
288
|
+
const argvUrl = pathToFileURL(path.resolve(process.argv[1])).href;
|
|
289
|
+
if (argvUrl === import.meta.url) return true;
|
|
290
|
+
try {
|
|
291
|
+
return pathToFileURL(fs.realpathSync(path.resolve(process.argv[1]))).href === import.meta.url;
|
|
292
|
+
} catch {
|
|
293
|
+
return false;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (_isCliEntry()) {
|
|
298
|
+
process.exit(main(process.argv.slice(2)));
|
|
299
|
+
}
|
|
@@ -28,6 +28,8 @@ import * as fs from 'node:fs';
|
|
|
28
28
|
import * as path from 'node:path';
|
|
29
29
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
30
30
|
|
|
31
|
+
import { assertScanned } from './_lib/scan_scope.js';
|
|
32
|
+
|
|
31
33
|
const HEADING_RE = /^(#{1,6})\s+(.+?)\s*$/;
|
|
32
34
|
const IRON_LAW_RE = /\biron\s+laws?\b/i;
|
|
33
35
|
const FENCE_RE = /^\s*```/;
|
|
@@ -247,7 +249,11 @@ function parse_args(argv: readonly string[]): Args {
|
|
|
247
249
|
i++;
|
|
248
250
|
}
|
|
249
251
|
return {
|
|
250
|
-
|
|
252
|
+
// ADR-051 moved rule authoring to `src/rules`. Until 2026-07-29 this
|
|
253
|
+
// default still named the retired container, so both CI call sites
|
|
254
|
+
// (consistency.yml + ci-fast.yml) resolved 0 targets and printed
|
|
255
|
+
// "✅ Iron Law prominence clean (0 file(s) scanned)" forever.
|
|
256
|
+
paths: paths.length ? paths : ['src/rules'],
|
|
251
257
|
format,
|
|
252
258
|
quiet,
|
|
253
259
|
};
|
|
@@ -257,6 +263,21 @@ export function main(argv?: readonly string[]): number {
|
|
|
257
263
|
const args = parse_args(argv ?? process.argv.slice(2));
|
|
258
264
|
|
|
259
265
|
const targets = _resolve_targets(args.paths);
|
|
266
|
+
|
|
267
|
+
// Scope assertion: 0 targets means the root moved, not that the tree is
|
|
268
|
+
// clean. Without this the gate reported success while reading nothing.
|
|
269
|
+
try {
|
|
270
|
+
assertScanned({
|
|
271
|
+
gate: 'check_iron_law_prominence',
|
|
272
|
+
scanned: targets.length,
|
|
273
|
+
units: 'rule file(s)',
|
|
274
|
+
roots: args.paths,
|
|
275
|
+
});
|
|
276
|
+
} catch (exc) {
|
|
277
|
+
process.stderr.write(`❌ ${exc instanceof Error ? exc.message : String(exc)}\n`);
|
|
278
|
+
return 2;
|
|
279
|
+
}
|
|
280
|
+
|
|
260
281
|
const all_violations: Violation[] = [];
|
|
261
282
|
for (const p of targets) {
|
|
262
283
|
if (!_exists(p)) {
|
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env tsx
|
|
2
2
|
/**
|
|
3
|
-
* Regression guard: no NEW
|
|
3
|
+
* Regression guard: no NEW dead-root references in `src/` or `tests/`.
|
|
4
4
|
*
|
|
5
5
|
* Ported from the retired Python `src/scripts/check_no_new_legacy_path.py` (ADR-200,
|
|
6
6
|
* Phase 4 / Wave 4c). The CLI contract is pinned — `--base`
|
|
@@ -104,12 +104,22 @@ function find_offenders(diffText: string, twinCheck: TwinCheck = _is_faithful_tw
|
|
|
104
104
|
continue;
|
|
105
105
|
}
|
|
106
106
|
if (line.startsWith('+') && !line.startsWith('+++')) {
|
|
107
|
-
// src
|
|
108
|
-
// only added lines under
|
|
109
|
-
// faithful TS twins) count.
|
|
107
|
+
// Scoped to src/ + tests/: a full diff (e.g. `gh pr diff`) carries
|
|
108
|
+
// every path; only added lines under those roots (minus the exempt
|
|
109
|
+
// detectors and faithful TS twins) count.
|
|
110
|
+
//
|
|
111
|
+
// tests/ added 2026-07-29. Four separate tests were found pinning the
|
|
112
|
+
// dead root — two via fixture paths, one via a `resolve_entry`
|
|
113
|
+
// expectation, one asserting that a missing root exits 0 — and each
|
|
114
|
+
// kept a gate's blindness green because test and implementation agreed
|
|
115
|
+
// on a tree reality had abandoned. A FULL-tree lint over tests/ is the
|
|
116
|
+
// wrong shape (44 files / 213 hits, most of them legitimate: the
|
|
117
|
+
// legacy detectors' own tests, validator_ignore substrings, and
|
|
118
|
+
// synthetic fixtures under tmpdir()). Diff-scoping is what makes this
|
|
119
|
+
// tractable — existing debt stays, growth stops, no allowlist.
|
|
110
120
|
if (
|
|
111
121
|
curFile &&
|
|
112
|
-
curFile.startsWith('src/') &&
|
|
122
|
+
(curFile.startsWith('src/') || curFile.startsWith('tests/')) &&
|
|
113
123
|
!EXEMPT.has(curFile) &&
|
|
114
124
|
line.includes(LEGACY) &&
|
|
115
125
|
!twinCheck(curFile)
|
|
@@ -135,7 +145,7 @@ function main(): number {
|
|
|
135
145
|
// additions (robust locally and where the working tree is the branch tip).
|
|
136
146
|
let proc: ReturnType<typeof spawnSync>;
|
|
137
147
|
try {
|
|
138
|
-
proc = spawnSync('git', ['diff', base, '--', 'src/'], {
|
|
148
|
+
proc = spawnSync('git', ['diff', base, '--', 'src/', 'tests/'], {
|
|
139
149
|
encoding: 'utf-8',
|
|
140
150
|
});
|
|
141
151
|
} catch (exc) {
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* `agents/roadmaps/skipped/`). Forbidden: specific `*.md` files inside those
|
|
19
19
|
* directories.
|
|
20
20
|
*
|
|
21
|
-
* Contract:
|
|
21
|
+
* Contract: src/rules/no-roadmap-references.md
|
|
22
22
|
*
|
|
23
23
|
* Exit codes: 0 = clean, 1 = violations, 3 = internal error.
|
|
24
24
|
*/
|
|
@@ -34,13 +34,20 @@ const ROOT = path.resolve(path.dirname(_HERE), '..', '..');
|
|
|
34
34
|
|
|
35
35
|
// Stable artefact trees — every `*.md` below MUST be free of roadmap-file
|
|
36
36
|
// citations. Directory mentions stay allowed (the regex below excludes them).
|
|
37
|
+
// Retargeted 2026-07-29: these six pointed at the pre-relocation source tree,
|
|
38
|
+
// emptied by the ADR-051 flat-`src/` migration. The gate kept enforcing the rule
|
|
39
|
+
// for `docs/` while the rule + skill layer — the layer `no-roadmap-references` is
|
|
40
|
+
// actually about — went unscanned, and reported green. No violation had slipped
|
|
41
|
+
// through yet (verified), so this closes a latent gap rather than a live breach.
|
|
42
|
+
// (Phrased without the dead path literal on purpose: `check_no_new_legacy_path`
|
|
43
|
+
// guards against those accumulating, and this comment tripped it.)
|
|
37
44
|
const STABLE_TREES = [
|
|
38
|
-
'
|
|
39
|
-
'
|
|
40
|
-
'
|
|
41
|
-
'
|
|
42
|
-
'
|
|
43
|
-
'
|
|
45
|
+
'src/rules',
|
|
46
|
+
'src/skills',
|
|
47
|
+
'src/agent-src/commands',
|
|
48
|
+
'src/agent-src/contexts',
|
|
49
|
+
'src/agent-src/templates',
|
|
50
|
+
'src/agent-src/personas',
|
|
44
51
|
'agents/settings/contexts',
|
|
45
52
|
'docs/guidelines',
|
|
46
53
|
'docs/contracts',
|
|
@@ -69,7 +76,7 @@ const ROADMAP_FILE_RE =
|
|
|
69
76
|
// documentation purposes — the rule itself, the companion CI script docs,
|
|
70
77
|
// and the contract doc that names the rule.
|
|
71
78
|
const SELF_DOCUMENTING_ALLOWLIST: ReadonlySet<string> = new Set([
|
|
72
|
-
'
|
|
79
|
+
'src/rules/no-roadmap-references.md',
|
|
73
80
|
'docs/guidelines/agent-infra/no-roadmap-references.md',
|
|
74
81
|
]);
|
|
75
82
|
|
|
@@ -172,9 +179,15 @@ function _collect_targets(root: string): string[] {
|
|
|
172
179
|
|
|
173
180
|
function scan(root: string): Violation[] {
|
|
174
181
|
const out: Violation[] = [];
|
|
182
|
+
let scanned = 0;
|
|
175
183
|
for (const p of _collect_targets(root)) {
|
|
184
|
+
scanned += 1;
|
|
176
185
|
out.push(..._scan_file(p, root));
|
|
177
186
|
}
|
|
187
|
+
// Gate-coverage contract (src/config/gate-coverage.yml): report what was
|
|
188
|
+
// actually inspected, so a future dead root fails `check_gate_coverage`
|
|
189
|
+
// instead of printing a green "no violations" over an empty set.
|
|
190
|
+
process.stdout.write(`scanned: ${String(scanned)}\n`);
|
|
178
191
|
return out;
|
|
179
192
|
}
|
|
180
193
|
|
|
@@ -190,7 +203,7 @@ function format_text(violations: Violation[]): string {
|
|
|
190
203
|
}
|
|
191
204
|
lines.push(
|
|
192
205
|
'\nPromote the durable conclusion to agents/settings/contexts/ and cite that ' +
|
|
193
|
-
'instead. See
|
|
206
|
+
'instead. See src/rules/no-roadmap-references.md.',
|
|
194
207
|
);
|
|
195
208
|
return lines.join('\n');
|
|
196
209
|
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* Freshness check for the committed originality report.
|
|
4
|
+
*
|
|
5
|
+
* `agents/reports/originality.{json,md}` is a committed artefact that nothing
|
|
6
|
+
* regenerates on a schedule, and the report itself "blocks NOTHING on its own" —
|
|
7
|
+
* so it can drift silently. It did: on 2026-07-31 the committed copy read 507
|
|
8
|
+
* artifacts while the identical corpus produced 508, meaning it predated an
|
|
9
|
+
* artefact and nobody noticed.
|
|
10
|
+
*
|
|
11
|
+
* This check regenerates the report, compares it against the committed bytes,
|
|
12
|
+
* restores the committed bytes either way, and **always exits 0**. Warning, not
|
|
13
|
+
* a gate — the report's non-blocking character is deliberate, and turning a
|
|
14
|
+
* stale doc into a red build would be a worse trade than a visible warning.
|
|
15
|
+
*
|
|
16
|
+
* Restoring is what keeps it safe to run inside a pipeline: the working tree is
|
|
17
|
+
* byte-identical afterwards, so no later step sees a spurious diff.
|
|
18
|
+
*/
|
|
19
|
+
import * as fs from 'node:fs';
|
|
20
|
+
import * as path from 'node:path';
|
|
21
|
+
|
|
22
|
+
import { main as runOriginality } from './lint_originality.js';
|
|
23
|
+
|
|
24
|
+
const REPO_ROOT = path.resolve(path.dirname(new URL(import.meta.url).pathname), '..', '..');
|
|
25
|
+
export const REPORTS = [
|
|
26
|
+
path.join(REPO_ROOT, 'agents', 'reports', 'originality.json'),
|
|
27
|
+
path.join(REPO_ROOT, 'agents', 'reports', 'originality.md'),
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
/** `null` for a report that is not committed yet — absence is not drift. */
|
|
31
|
+
function snapshot(files: readonly string[]): Map<string, Buffer | null> {
|
|
32
|
+
const out = new Map<string, Buffer | null>();
|
|
33
|
+
for (const f of files) {
|
|
34
|
+
try {
|
|
35
|
+
out.set(f, fs.readFileSync(f));
|
|
36
|
+
} catch {
|
|
37
|
+
out.set(f, null);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return out;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Put the committed bytes back. Best-effort per file and never throwing: this
|
|
45
|
+
* check runs inside pipelines, so a restore failure (read-only mount, a
|
|
46
|
+
* concurrent writer) must not become the exception that fails the build for an
|
|
47
|
+
* advisory. A file it could not restore is named loudly instead — that is the
|
|
48
|
+
* one case where the tree is left dirty, and the reader has to know.
|
|
49
|
+
*/
|
|
50
|
+
function restore(before: Map<string, Buffer | null>): void {
|
|
51
|
+
for (const [f, buf] of before) {
|
|
52
|
+
try {
|
|
53
|
+
if (buf === null) {
|
|
54
|
+
fs.rmSync(f, { force: true });
|
|
55
|
+
} else {
|
|
56
|
+
fs.writeFileSync(f, buf);
|
|
57
|
+
}
|
|
58
|
+
} catch (err) {
|
|
59
|
+
const why = err instanceof Error ? err.message : String(err);
|
|
60
|
+
process.stdout.write(
|
|
61
|
+
`⚠️ could not restore ${f} after the freshness sweep: ${why}\n` +
|
|
62
|
+
' The working tree now holds a REGENERATED report. Restore it with\n' +
|
|
63
|
+
` \`git checkout -- ${f}\` if that was not intended.\n`,
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Default regeneration: the real sweep, which writes into `REPORTS`. */
|
|
70
|
+
function regenerateReports(): void {
|
|
71
|
+
runOriginality(['--quiet']);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* `regenerate` is injectable for one reason: a test that exercised the drift
|
|
76
|
+
* path against the real reports would have to write a stale version into a
|
|
77
|
+
* TRACKED file, and vitest runs suites in parallel — any sibling test asserting
|
|
78
|
+
* "the working tree is clean" would see that transient write and fail. (It did:
|
|
79
|
+
* `backfill_model_tier`'s dry-run purity check caught exactly that.) With the
|
|
80
|
+
* hook, drift and restore behaviour is provable entirely in temp space, and the
|
|
81
|
+
* real wiring stays covered by the fresh-path test, which is tree-neutral
|
|
82
|
+
* because rewriting identical bytes is invisible to git.
|
|
83
|
+
*/
|
|
84
|
+
export function checkFreshness(
|
|
85
|
+
files: readonly string[] = REPORTS,
|
|
86
|
+
regenerate: () => void = regenerateReports,
|
|
87
|
+
): {
|
|
88
|
+
drifted: string[];
|
|
89
|
+
missing: string[];
|
|
90
|
+
} {
|
|
91
|
+
const before = snapshot(files);
|
|
92
|
+
try {
|
|
93
|
+
regenerate();
|
|
94
|
+
} catch {
|
|
95
|
+
// A sweep that cannot run is not a drift signal; leave the tree as found.
|
|
96
|
+
restore(before);
|
|
97
|
+
return { drifted: [], missing: [] };
|
|
98
|
+
}
|
|
99
|
+
const drifted: string[] = [];
|
|
100
|
+
const missing: string[] = [];
|
|
101
|
+
for (const [f, buf] of before) {
|
|
102
|
+
let now: Buffer | null;
|
|
103
|
+
try {
|
|
104
|
+
now = fs.readFileSync(f);
|
|
105
|
+
} catch {
|
|
106
|
+
now = null;
|
|
107
|
+
}
|
|
108
|
+
if (buf === null) {
|
|
109
|
+
if (now !== null) missing.push(f);
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
if (now === null || !now.equals(buf)) drifted.push(f);
|
|
113
|
+
}
|
|
114
|
+
restore(before);
|
|
115
|
+
return { drifted, missing };
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* LOCAL-ONLY, established empirically. On a CI runner the sweep produced
|
|
120
|
+
* different bytes than the committed report even with a byte-identical corpus
|
|
121
|
+
* (verified: 508 members on both this branch and `main`, report fresh locally,
|
|
122
|
+
* both files reported stale in `Node Tests`). Something in the CI environment
|
|
123
|
+
* moves the output, and chasing it would mean designing a reproducibility gate
|
|
124
|
+
* for a report that "blocks nothing on its own" — a bad trade for a warning.
|
|
125
|
+
*
|
|
126
|
+
* So this stays a developer-side surface. A freshness warning that fires on
|
|
127
|
+
* every PR regardless of staleness is exactly the never-turns-off warning this
|
|
128
|
+
* check was written to remove.
|
|
129
|
+
*/
|
|
130
|
+
export function main(): number {
|
|
131
|
+
if (process.env['CI'] !== undefined && process.env['CI'] !== '') {
|
|
132
|
+
process.stdout.write(
|
|
133
|
+
'ℹ️ originality freshness: skipped on CI — the sweep is not byte-reproducible\n' +
|
|
134
|
+
' across environments, so a CI warning here would fire regardless of\n' +
|
|
135
|
+
' staleness. Run it locally before quoting the report numbers.\n',
|
|
136
|
+
);
|
|
137
|
+
return 0;
|
|
138
|
+
}
|
|
139
|
+
const { drifted, missing } = checkFreshness();
|
|
140
|
+
const rel = (f: string): string => path.relative(REPO_ROOT, f);
|
|
141
|
+
|
|
142
|
+
if (missing.length > 0) {
|
|
143
|
+
process.stdout.write(
|
|
144
|
+
`⚠️ originality report is not committed yet: ${missing.map(rel).join(', ')}\n` +
|
|
145
|
+
' Run `./scripts-run src/scripts/lint_originality` and commit the result.\n',
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
if (drifted.length === 0 && missing.length === 0) {
|
|
149
|
+
process.stdout.write('✅ originality report is fresh.\n');
|
|
150
|
+
return 0;
|
|
151
|
+
}
|
|
152
|
+
if (drifted.length > 0) {
|
|
153
|
+
process.stdout.write(
|
|
154
|
+
`⚠️ originality report is STALE: ${drifted.map(rel).join(', ')}\n` +
|
|
155
|
+
' Regenerating from the current corpus produces different bytes, so the\n' +
|
|
156
|
+
' committed numbers describe an older corpus. Not a build failure — this\n' +
|
|
157
|
+
' report blocks nothing on its own — but the counts should not be quoted\n' +
|
|
158
|
+
' until refreshed: `./scripts-run src/scripts/lint_originality`.\n',
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
// Always 0: this is a warning surface by design.
|
|
162
|
+
return 0;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (process.argv[1] !== undefined && import.meta.url === `file://${process.argv[1]}`) {
|
|
166
|
+
process.exit(main());
|
|
167
|
+
}
|