@event4u/agent-config 14.12.0 → 14.14.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 +118 -155
- package/CONTRIBUTING.md +38 -0
- package/CREDITS.md +135 -0
- package/NOTICE +13 -0
- package/README.md +8 -6
- package/dist/agent-src/commands/analyze/inbox.md +145 -2
- package/dist/agent-src/commands/feature/dev.md +7 -2
- package/dist/agent-src/commands/ghostwriter/write.md +5 -1
- package/dist/agent-src/commands/implement-ticket.md +1 -1
- package/dist/agent-src/commands/mission/upgrade.md +1 -1
- package/dist/agent-src/commands/orchestrate.md +2 -2
- package/dist/agent-src/commands/post-as/me.md +5 -1
- package/dist/agent-src/commands/pr/merge.md +19 -6
- package/dist/agent-src/commands/roadmap/process-full.md +19 -5
- package/dist/agent-src/commands/tdd/red.md +12 -2
- package/dist/agent-src/commands/work.md +1 -1
- package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +40 -0
- package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +5 -2
- package/dist/agent-src/contexts/execution/autonomy-mechanics.md +21 -0
- package/dist/agent-src/contexts/execution/orchestration-telemetry.md +1 -0
- package/dist/agent-src/contexts/execution/subagent-response-contract.md +40 -0
- package/dist/agent-src/contexts/execution/subagent-steering.md +13 -1
- package/dist/agent-src/contexts/execution/terminal-states.md +96 -0
- package/dist/agent-src/rules/artifact-drafting-protocol.md +1 -1
- package/dist/agent-src/rules/broken-access-control.md +4 -0
- package/dist/agent-src/rules/code-comment-discipline.md +6 -0
- package/dist/agent-src/rules/code-provenance.md +4 -0
- package/dist/agent-src/rules/design-fidelity.md +1 -1
- package/dist/agent-src/rules/domain-safety-pii.md +4 -0
- package/dist/agent-src/rules/domain-safety-retention.md +4 -0
- package/dist/agent-src/rules/engineering-safety-floor.md +2 -0
- package/dist/agent-src/rules/external-code-graph-interop.md +14 -12
- package/dist/agent-src/rules/improve-before-implement.md +6 -8
- package/dist/agent-src/rules/laravel-routing.md +1 -1
- package/dist/agent-src/rules/lethal-trifecta-guard.md +4 -0
- package/dist/agent-src/rules/secret-vcs-guard.md +2 -0
- package/dist/agent-src/rules/security-sensitive-stop.md +2 -0
- package/dist/agent-src/rules/source-confidentiality.md +12 -34
- package/dist/agent-src/rules/symfony-routing.md +1 -1
- package/dist/agent-src/rules/token-efficiency.md +14 -0
- package/dist/agent-src/rules/tool-safety.md +4 -0
- package/dist/agent-src/rules/untrusted-input-defense.md +4 -0
- package/dist/agent-src/scripts/archive_completed_roadmaps.ts +252 -8
- package/dist/agent-src/scripts/guarded_baseline.ts +343 -0
- package/dist/agent-src/scripts/roadmap_set_step.ts +253 -0
- package/dist/agent-src/scripts/stub_queue.ts +82 -0
- package/dist/agent-src/scripts/stubs_due.ts +516 -0
- package/dist/agent-src/scripts/ticket_bundles.ts +84 -0
- package/dist/agent-src/scripts/update_roadmap_progress.ts +16 -12
- package/dist/agent-src/skills/brand-asset-generation/SKILL.md +17 -4
- package/dist/agent-src/skills/brand-audit/SKILL.md +33 -0
- package/dist/agent-src/skills/code-intelligence/SKILL.md +57 -0
- package/dist/agent-src/skills/database/SKILL.md +8 -0
- package/dist/agent-src/skills/dependency-upgrade/SKILL.md +27 -0
- package/dist/agent-src/skills/design-review/SKILL.md +1 -1
- package/dist/agent-src/skills/doc-coauthoring/SKILL.md +1 -1
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +17 -1
- package/dist/agent-src/skills/feature-planning/SKILL.md +9 -2
- package/dist/agent-src/skills/frontend-render-security/SKILL.md +44 -0
- package/dist/agent-src/skills/git-workflow/SKILL.md +1 -1
- package/dist/agent-src/skills/js-library-packaging/scripts/check_package_surface.ts +38 -4
- package/dist/agent-src/skills/judge-artifact-completeness/rubrics/ticket-quality-score.json +2 -2
- package/dist/agent-src/skills/laravel/SKILL.md +35 -0
- package/dist/agent-src/skills/laravel-migration/SKILL.md +57 -3
- package/dist/agent-src/skills/monorepo-workspace/SKILL.md +26 -0
- package/dist/agent-src/skills/playbook-authoring/SKILL.md +28 -1
- package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +1 -1
- package/dist/agent-src/skills/skill-writing/references/procedure.md +5 -5
- package/dist/agent-src/skills/sql-writing/SKILL.md +7 -1
- package/dist/agent-src/skills/standards-from-config/SKILL.md +27 -4
- package/dist/agent-src/skills/supply-chain-intake/SKILL.md +11 -4
- package/dist/agent-src/skills/symfony-workflow/SKILL.md +35 -0
- package/dist/agent-src/skills/test-case-discovery/SKILL.md +85 -0
- package/dist/agent-src/skills/test-driven-development/SKILL.md +33 -9
- package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
- package/dist/agent-src/skills/testing-anti-patterns/process-anti-patterns.md +37 -0
- package/dist/agent-src/skills/ui-component-architect/SKILL.md +45 -2
- package/dist/agent-src/skills/upstream-contribute/SKILL.md +38 -1
- package/dist/agent-src/skills/verify-repair-loop/SKILL.md +9 -4
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/roadmaps.md +97 -3
- package/dist/agent-src/templates/scripts/check_memory.ts +258 -17
- package/dist/agent-src/templates/scripts/check_memory_proposal.ts +9 -3
- package/dist/agent-src/templates/scripts/memory_lookup.ts +86 -0
- package/dist/agent-src/templates/scripts/memory_signal.ts +44 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/implement.ts +90 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/index.ts +11 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/test.ts +23 -1
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +10 -1
- package/dist/agent-src/templates/scripts/work_engine/directives/mixed/stitch.ts +5 -1
- package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +102 -14
- package/dist/cli/commands/uiAudit.js +124 -5
- package/dist/cli/registry.js +2 -0
- package/dist/cli-delegate/{chunk-HYWSRNUX.js → chunk-2DK2VJWG.js} +3 -3
- package/dist/cli-delegate/{chunk-JCW7ZLHK.js → chunk-4FS4WRXP.js} +5 -0
- package/dist/cli-delegate/{chunk-OMIVVCG2.js → chunk-A4QJ6ENT.js} +24 -0
- package/dist/cli-delegate/{chunk-JJA2QEWA.js → chunk-AKJGUQNO.js} +466 -285
- package/dist/cli-delegate/{chunk-E46KPN6K.js → chunk-BTWUYDGN.js} +424 -363
- package/dist/cli-delegate/{chunk-K4FFODTS.js → chunk-ILMUPLGW.js} +1227 -316
- package/dist/cli-delegate/{chunk-FF7WAFMR.js → chunk-KPBWFOPZ.js} +5 -1
- package/dist/cli-delegate/cmd_adr_effective.js +102 -0
- package/dist/cli-delegate/cmd_conformance.js +80 -11
- package/dist/cli-delegate/cmd_doctor.js +3 -3
- package/dist/cli-delegate/cmd_export.js +3 -2
- package/dist/cli-delegate/cmd_fleet.js +2 -2
- 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 +3 -2
- package/dist/cli-delegate/cmd_settings_get.js +1 -1
- package/dist/cli-delegate/cmd_settings_migrate.js +3 -2
- package/dist/cli-delegate/cmd_settings_set.js +2 -2
- package/dist/cli-delegate/cmd_sync.js +3 -2
- package/dist/cli-delegate/cmd_uninstall.js +3 -2
- package/dist/cli-delegate/cmd_validate.js +3 -2
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +58 -58
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +1 -1
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +2 -2
- package/dist/discovery/trust-report.md +1 -1
- package/dist/discovery/workspaces.json +2 -2
- package/dist/hooks/dispatch.js +2900 -1049
- package/dist/install/claudeRuleRewrite.js +254 -0
- package/dist/install/detect.js +29 -16
- package/dist/install/detect_php_shape.js +159 -0
- package/dist/install/install.mjs +634 -428
- package/dist/mcp/awesome-mcp-servers.row.md +1 -1
- package/dist/mcp/mcp-cloudflare-catalogue.json +1 -1
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +3 -3
- package/dist/mcp/server.mjs +4895 -2627
- package/dist/server/schemas/settings.js +3 -0
- package/dist/ui/assets/index-D0jaCRPM.js +29 -0
- package/dist/ui/index.html +1 -1
- package/docs/MIGRATION.md +1 -1
- package/docs/THIRD-PARTY-NOTICES.md +25 -0
- package/docs/contracts/provider-lifecycle.md +1 -1
- package/docs/contracts/settings-classes.md +10 -4
- package/docs/guidelines/agent-infra/5w2h-analysis.md +3 -3
- package/docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md +1 -0
- package/docs/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md +58 -3
- package/docs/guidelines/agent-infra/ask-when-uncertain-demos.md +2 -2
- package/docs/guidelines/agent-infra/asking-and-brevity-examples.md +3 -3
- package/docs/guidelines/agent-infra/break-glass-usage.md +7 -7
- package/docs/guidelines/agent-infra/carve-out-predicates.md +3 -3
- package/docs/guidelines/agent-infra/comparison-matrix.md +1 -1
- package/docs/guidelines/agent-infra/critical-thinking.md +4 -4
- package/docs/guidelines/agent-infra/direct-answers-demos.md +2 -2
- package/docs/guidelines/agent-infra/domain-eval-anti-pattern.md +1 -1
- package/docs/guidelines/agent-infra/engineering-memory-data-format.md +3 -3
- package/docs/guidelines/agent-infra/existence-question-verdicts.md +80 -0
- package/docs/guidelines/agent-infra/first-principles.md +2 -2
- package/docs/guidelines/agent-infra/framework-neutrality-patterns.md +2 -2
- package/docs/guidelines/agent-infra/guarded-baseline.md +39 -0
- package/docs/guidelines/agent-infra/inversion-thinking.md +5 -5
- package/docs/guidelines/agent-infra/language-and-tone-examples.md +1 -1
- package/docs/guidelines/agent-infra/layered-settings.md +10 -10
- package/docs/guidelines/agent-infra/memory-access.md +1 -1
- package/docs/guidelines/agent-infra/mental-models.md +3 -3
- package/docs/guidelines/agent-infra/reuse-verdict-mechanics.md +71 -0
- package/docs/guidelines/agent-infra/review-routing-data-format.md +7 -7
- package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +13 -7
- package/docs/guidelines/agent-infra/role-contracts.md +2 -2
- package/docs/guidelines/agent-infra/role-mode-router.md +3 -3
- package/docs/guidelines/agent-infra/rule-type-governance.md +2 -2
- package/docs/guidelines/agent-infra/scqa-framework.md +5 -5
- package/docs/guidelines/agent-infra/self-improvement-pipeline.md +6 -6
- package/docs/guidelines/agent-infra/simplicity-and-goal-demos.md +2 -2
- package/docs/guidelines/agent-infra/six-hats.md +3 -3
- package/docs/guidelines/agent-infra/skill-quality-checklist.md +6 -6
- package/docs/guidelines/agent-infra/source-confidentiality-mechanics.md +109 -0
- package/docs/guidelines/agent-infra/systems-thinking.md +1 -1
- package/docs/guidelines/agent-infra/verify-before-complete-demos.md +2 -2
- package/docs/guidelines/augment-portability-patterns.md +6 -4
- package/docs/guidelines/code-clarity.md +18 -0
- package/docs/guidelines/component-oriented-and-oop-development.md +3 -2
- package/docs/guidelines/cross-role-handoff.md +2 -2
- package/docs/guidelines/design-fidelity-mechanics.md +1 -1
- package/docs/guidelines/docs/readme-size-and-splitting.md +3 -3
- package/docs/guidelines/php/database.md +90 -7
- package/docs/guidelines/prompt-templates.md +7 -7
- package/llms.txt +2 -2
- package/package.json +5 -2
- package/src/agent-src/scripts/archive_completed_roadmaps.ts +252 -8
- package/src/agent-src/scripts/guarded_baseline.ts +343 -0
- package/src/agent-src/scripts/roadmap_set_step.ts +253 -0
- package/src/agent-src/scripts/stub_queue.ts +82 -0
- package/src/agent-src/scripts/stubs_due.ts +516 -0
- package/src/agent-src/scripts/ticket_bundles.ts +84 -0
- package/src/agent-src/scripts/update_roadmap_progress.ts +16 -12
- package/src/agent-src/templates/scripts/check_memory.ts +258 -17
- package/src/agent-src/templates/scripts/check_memory_proposal.ts +9 -3
- package/src/agent-src/templates/scripts/memory_lookup.ts +86 -0
- package/src/agent-src/templates/scripts/memory_signal.ts +44 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/implement.ts +90 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/index.ts +11 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/test.ts +23 -1
- package/src/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +10 -1
- package/src/agent-src/templates/scripts/work_engine/directives/mixed/stitch.ts +5 -1
- package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +102 -14
- package/src/config/agent-settings.template.yml +32 -3
- package/src/config/assurance-capability-registry.json +21 -9
- package/src/config/canonical-terms.yml +119 -0
- package/src/config/capability-native-outcome-bars.json +81 -0
- package/src/config/ci-local-parity.yml +80 -0
- package/src/config/drafting-channels.yml +43 -0
- package/src/config/estate-count-budget.json +57 -36
- package/src/config/evaluator-budgets.json +14 -14
- package/src/config/gate-coverage.yml +729 -63
- package/src/config/gate-reachability-exemptions.json +21 -0
- package/src/config/gate-violation-baselines.json +42 -19
- package/src/config/harness-evolution-budget.json +25 -0
- package/src/config/lapsed-beta-baseline.json +96 -0
- package/src/config/memory-twin-verdicts.yml +129 -0
- package/src/config/metric-registry.yml +124 -0
- package/src/config/pack-size-budget.json +16 -15
- package/src/config/preamble-payload-budget.json +12 -4
- package/src/config/profiles/balanced.ini +27 -0
- package/src/config/profiles/full.ini +27 -0
- package/src/config/profiles/minimal.ini +27 -0
- package/src/config/publish-surface.json +9 -2
- package/src/config/routing-coverage-seed.json +16 -2
- package/src/config/rule-stub-ceilings.json +133 -112
- package/src/config/turnaround-budget.json +66 -0
- package/src/install/claudeRuleRewrite.ts +288 -0
- package/src/install/detect.ts +60 -17
- package/src/install/detect_php_shape.ts +191 -0
- package/src/scripts/_cli/cmd_doctor.ts +27 -112
- package/src/scripts/_dispatch.bash +23 -0
- package/src/scripts/_lib/activation_ladder.ts +255 -0
- package/src/scripts/_lib/activation_receipt_producer.ts +341 -0
- package/src/scripts/_lib/activation_states.ts +88 -0
- package/src/scripts/_lib/adherence_detectors.ts +143 -0
- package/src/scripts/_lib/adr_frontmatter.ts +26 -0
- package/src/scripts/_lib/arith_claims.ts +181 -0
- package/src/scripts/_lib/arm_ranking.ts +62 -0
- package/src/scripts/_lib/asset_delivery_ledger.ts +303 -0
- package/src/scripts/_lib/audit_field_provenance.ts +54 -0
- package/src/scripts/_lib/auto_dispatch.ts +32 -3
- package/src/scripts/_lib/bench_ab_size_claim.ts +98 -4
- package/src/scripts/_lib/benchmark_cache_fields.ts +158 -0
- package/src/scripts/_lib/candidate_pair_delta.ts +349 -0
- package/src/scripts/_lib/candidate_proposer.ts +402 -0
- package/src/scripts/_lib/candidate_record.ts +601 -0
- package/src/scripts/_lib/capture_rate.ts +319 -0
- package/src/scripts/_lib/carrier_status.ts +118 -0
- package/src/scripts/_lib/cascade_stage_enumeration.ts +92 -0
- package/src/scripts/_lib/collector_denominator.ts +771 -0
- package/src/scripts/_lib/collector_record.ts +340 -0
- package/src/scripts/_lib/collector_store.ts +664 -0
- package/src/scripts/_lib/collector_supervision.ts +827 -0
- package/src/scripts/_lib/concern_estate.ts +77 -0
- package/src/scripts/_lib/config_chain.ts +477 -0
- package/src/scripts/_lib/config_cost.ts +209 -0
- package/src/scripts/_lib/corpus_manifest.ts +726 -0
- package/src/scripts/_lib/council_settings_block.ts +6 -0
- package/src/scripts/_lib/curator_ops.ts +172 -0
- package/src/scripts/_lib/delivery_arm_experiment.ts +282 -0
- package/src/scripts/_lib/delivery_criticality.ts +126 -0
- package/src/scripts/_lib/doctor_runtime_checks.ts +70 -0
- package/src/scripts/_lib/empty_cycles.ts +88 -0
- package/src/scripts/_lib/estate_carrier_cases.ts +72 -0
- package/src/scripts/_lib/eval_publication.ts +354 -0
- package/src/scripts/_lib/evaluation_cascade.ts +452 -0
- package/src/scripts/_lib/evaluation_vector.ts +283 -0
- package/src/scripts/_lib/evaluator_promotion.ts +225 -0
- package/src/scripts/_lib/evidence_basis.ts +118 -0
- package/src/scripts/_lib/evolution_roi.ts +562 -0
- package/src/scripts/_lib/exec_evidence.ts +8 -0
- package/src/scripts/_lib/experience_card.ts +272 -0
- package/src/scripts/_lib/experience_report.ts +151 -0
- package/src/scripts/_lib/experiment_freeze.ts +112 -0
- package/src/scripts/_lib/generated_by.ts +66 -0
- package/src/scripts/_lib/harness_evolution_guards.ts +239 -0
- package/src/scripts/_lib/hook_effect_probe.ts +141 -0
- package/src/scripts/_lib/host_denominator.ts +687 -0
- package/src/scripts/_lib/host_projection_reach.ts +157 -0
- package/src/scripts/_lib/ignored_blocker.ts +148 -0
- package/src/scripts/_lib/install_reach_checks.ts +495 -0
- package/src/scripts/_lib/json_duplicate_keys.ts +150 -0
- package/src/scripts/_lib/judge_hygiene.ts +228 -0
- package/src/scripts/_lib/legacy_boundary_map.ts +228 -0
- package/src/scripts/_lib/lexical_shortlist.ts +215 -0
- package/src/scripts/_lib/llm_candidate_proposer.ts +461 -0
- package/src/scripts/_lib/llm_proposer_transport.ts +153 -0
- package/src/scripts/_lib/loop_guards.ts +299 -0
- package/src/scripts/_lib/loss_class.ts +129 -0
- package/src/scripts/_lib/machine_wake.ts +51 -0
- package/src/scripts/_lib/md_prose_lines.ts +177 -0
- package/src/scripts/_lib/minimality_tiebreak.ts +168 -0
- package/src/scripts/_lib/one_resolver_invariant.ts +449 -0
- package/src/scripts/_lib/orchestration_record.ts +253 -5
- package/src/scripts/_lib/outcome_envelope.ts +227 -0
- package/src/scripts/_lib/outcome_vocabularies.ts +125 -0
- package/src/scripts/_lib/paired_stats.ts +245 -0
- package/src/scripts/_lib/paired_verdict.ts +226 -0
- package/src/scripts/_lib/pathology_archive.ts +393 -0
- package/src/scripts/_lib/prefix_stable_surfaces.ts +123 -0
- package/src/scripts/_lib/privacy_class.ts +47 -0
- package/src/scripts/_lib/promotion_capability.ts +315 -0
- package/src/scripts/_lib/promotion_evidence.ts +414 -0
- package/src/scripts/_lib/promotion_review.ts +294 -0
- package/src/scripts/_lib/prompt_shape.ts +92 -0
- package/src/scripts/_lib/regression_neighbourhood.ts +259 -0
- package/src/scripts/_lib/release_highlights.ts +70 -1
- package/src/scripts/_lib/release_material.ts +125 -2
- package/src/scripts/_lib/repeated_failure.ts +105 -0
- package/src/scripts/_lib/repo_root.ts +111 -0
- package/src/scripts/_lib/review_skipped_record.ts +37 -0
- package/src/scripts/_lib/role_split.ts +338 -0
- package/src/scripts/_lib/routing_corpus.ts +307 -0
- package/src/scripts/_lib/routing_index_input.ts +104 -0
- package/src/scripts/_lib/rule_injection.ts +22 -1
- package/src/scripts/_lib/runtime_journal.ts +1499 -0
- package/src/scripts/_lib/runtime_wiring_checks.ts +430 -0
- package/src/scripts/_lib/semantic_noop.ts +167 -0
- package/src/scripts/_lib/skill_catalogue.ts +11 -1
- package/src/scripts/_lib/source_digest.ts +200 -0
- package/src/scripts/_lib/source_redact.ts +260 -0
- package/src/scripts/_lib/source_shape.ts +502 -0
- package/src/scripts/_lib/source_snapshot_dedup.ts +199 -0
- package/src/scripts/_lib/strip_comments.d.mts +8 -0
- package/src/scripts/_lib/strip_comments.mjs +65 -0
- package/src/scripts/_lib/test_red_state.ts +154 -0
- package/src/scripts/_lib/trigger_shift.ts +144 -0
- package/src/scripts/_lib/untrusted_content.ts +82 -7
- package/src/scripts/activation_receipt.ts +258 -0
- package/src/scripts/adoption_report.ts +1 -1
- package/src/scripts/adr/evidence_census.ts +1 -1
- package/src/scripts/adr/regenerate_index.ts +26 -2
- package/src/scripts/adr_cite_check.ts +164 -1
- package/src/scripts/ai_council/blind_review.ts +11 -1
- package/src/scripts/ai_council/clients.ts +4 -0
- package/src/scripts/ai_council/config.ts +3 -0
- package/src/scripts/ai_council/consensus.ts +28 -8
- package/src/scripts/ai_council/consensus_round.ts +226 -0
- package/src/scripts/ai_council/cross_exam.ts +128 -0
- package/src/scripts/ai_council/disagreement_signal.ts +338 -0
- package/src/scripts/ai_council/explain_route.ts +157 -0
- package/src/scripts/ai_council/information_gain.ts +293 -0
- package/src/scripts/ai_council/inline_findings.ts +340 -0
- package/src/scripts/ai_council/judge_position_bias.ts +197 -0
- package/src/scripts/ai_council/leakage_corpus.ts +385 -0
- package/src/scripts/ai_council/leakage_patterns.ts +453 -0
- package/src/scripts/ai_council/minority_retention.ts +171 -0
- package/src/scripts/ai_council/orchestrator.ts +16 -203
- package/src/scripts/ai_council/orchestrator_results.ts +23 -3
- package/src/scripts/ai_council/pricing.ts +106 -0
- package/src/scripts/ai_council/prompts.ts +74 -7
- package/src/scripts/ai_council/provider_leakage_bench.ts +327 -0
- package/src/scripts/ai_council/py_format.ts +14 -3
- package/src/scripts/ai_council/recouncil_guard.ts +293 -0
- package/src/scripts/ai_council/recouncil_savings.ts +299 -0
- package/src/scripts/ai_council/replay_route.ts +223 -0
- package/src/scripts/ai_council/response_record.ts +50 -0
- package/src/scripts/ai_council/reviewer_assignment.ts +279 -0
- package/src/scripts/ai_council/routing_training_row.ts +197 -0
- package/src/scripts/ai_council/synthesis_strategy.ts +159 -0
- package/src/scripts/ai_council/topology_bench_manifest.ts +860 -0
- package/src/scripts/ai_council/topology_vocabulary.ts +175 -0
- package/src/scripts/asset_delivery_ledger.ts +157 -0
- package/src/scripts/attest_artifact.ts +193 -0
- package/src/scripts/audit_auto_rules.ts +2 -1
- package/src/scripts/audit_command_surface.ts +1 -1
- package/src/scripts/audit_mcp_tools.ts +2 -2
- package/src/scripts/audit_skill_overlap_allowlist.json +6 -1
- package/src/scripts/audit_user_type_axis.ts +2 -1
- package/src/scripts/bench_ab_clone.ts +215 -10
- package/src/scripts/bench_ab_integrity.ts +119 -5
- package/src/scripts/bench_ab_v2_stats.ts +40 -213
- package/src/scripts/build_archive_index.ts +1 -1
- package/src/scripts/build_linear_digest.ts +1 -1
- package/src/scripts/build_proof.ts +11 -4
- package/src/scripts/build_rule_trigger_matrix.ts +1 -1
- package/src/scripts/build_source_digests.ts +157 -0
- package/src/scripts/cache_realization_report.ts +103 -0
- package/src/scripts/check_adr_frontmatter.ts +131 -10
- package/src/scripts/check_benchmark_report_fields.ts +207 -0
- package/src/scripts/check_beta_review_markers.ts +235 -6
- package/src/scripts/check_bundle_path_leakage.ts +34 -1
- package/src/scripts/check_claims.ts +576 -6
- package/src/scripts/check_composite_arming.ts +35 -0
- package/src/scripts/check_concern_admissions.ts +365 -0
- package/src/scripts/check_enforcement_coverage.ts +28 -0
- package/src/scripts/check_estate_count.ts +347 -25
- package/src/scripts/check_gate_reachability.ts +383 -0
- package/src/scripts/check_host_loadability.ts +104 -0
- package/src/scripts/check_loss_class_declared.ts +308 -0
- package/src/scripts/check_md_language.ts +15 -98
- package/src/scripts/check_memory_proposal.ts +18 -11
- package/src/scripts/check_no_currency_in_cost_surfaces.ts +225 -0
- package/src/scripts/check_no_external_sources.ts +281 -6
- package/src/scripts/check_pack_conformance_fixture.ts +11 -1
- package/src/scripts/check_pack_size.ts +59 -2
- package/src/scripts/check_preamble_payload_budget.ts +114 -3
- package/src/scripts/check_prefix_stable_mutation.ts +372 -0
- package/src/scripts/check_publish_surface.ts +10 -1
- package/src/scripts/check_references.ts +24 -1
- package/src/scripts/check_release_highlights.ts +96 -13
- package/src/scripts/check_roadmap_trackable.ts +17 -2
- package/src/scripts/check_rule_evidence_declaration.ts +316 -0
- package/src/scripts/check_rule_projection_integrity.ts +14 -4
- package/src/scripts/check_score_contract.ts +26 -3
- package/src/scripts/check_static_parity.ts +285 -0
- package/src/scripts/check_supervision_claim_atomicity.ts +498 -0
- package/src/scripts/check_suppression_hygiene.ts +15 -0
- package/src/scripts/ci_settle.ts +39 -2
- package/src/scripts/code_graph/build.ts +60 -3
- package/src/scripts/code_graph/extract.ts +44 -0
- package/src/scripts/code_graph/types.ts +24 -0
- package/src/scripts/collector_daemon.ts +714 -0
- package/src/scripts/config_cost_report.ts +302 -0
- package/src/scripts/consumer_matrix.ts +74 -1
- package/src/scripts/corpus_manifest.ts +235 -0
- package/src/scripts/cost/budget.mjs +10 -3
- package/src/scripts/cost/track.mjs +10 -3
- package/src/scripts/council_cli.ts +37 -54
- package/src/scripts/dispatch_r2_reviewer.ts +46 -5
- package/src/scripts/evolution_lab.ts +1153 -0
- package/src/scripts/external_sources_denylist.json +5 -18
- package/src/scripts/extract_audit_patterns.ts +21 -0
- package/src/scripts/fold_intake.ts +12 -1
- package/src/scripts/gen_discovery_baseline.ts +1 -1
- package/src/scripts/generate_capabilities_index.ts +12 -5
- package/src/scripts/generate_capability_matrix.ts +3 -3
- package/src/scripts/generate_command_flows.ts +2 -2
- package/src/scripts/generate_cookbook.ts +2 -2
- package/src/scripts/generate_index.ts +8 -1
- package/src/scripts/generate_knowledge_index.ts +2 -1
- package/src/scripts/generate_ownership_matrix.ts +2 -1
- package/src/scripts/generate_pack_manifests.ts +10 -2
- package/src/scripts/generate_role_experiences_catalog.ts +2 -2
- package/src/scripts/generate_settings_reference.ts +1 -1
- package/src/scripts/git_authorization_hook.ts +22 -1
- package/src/scripts/grade_target_readiness.ts +48 -5
- package/src/scripts/hook_effect_doctor.ts +261 -0
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +125 -16
- package/src/scripts/hooks/block_speaking_inbox_dir.ts +271 -0
- package/src/scripts/hooks/block_unauthorized_git.ts +18 -0
- package/src/scripts/hooks/comment_discipline_hook.ts +146 -0
- package/src/scripts/hooks/concern_registry.ts +6 -0
- package/src/scripts/hooks/dispatch_hook.ts +32 -0
- package/src/scripts/hooks/journal_record_hook.ts +345 -0
- package/src/scripts/hooks/prepush_metadata_sources.sh +110 -0
- package/src/scripts/hooks/run_continuation_hook.ts +44 -9
- package/src/scripts/hooks/shims/install.sh +61 -0
- package/src/scripts/hooks/shims/php +101 -0
- package/src/scripts/hooks/suggestion_capture_hook.ts +10 -0
- package/src/scripts/hooks/turn_end_gate_hook.ts +9 -1
- package/src/scripts/hot_context_hook.ts +16 -0
- package/src/scripts/install-hooks.sh +20 -5
- package/src/scripts/install.ts +17 -35
- package/src/scripts/inventory_frontmatter.ts +2 -1
- package/src/scripts/language_mirror_hook.ts +14 -2
- package/src/scripts/lint_adr_sweep_routing.ts +12 -0
- package/src/scripts/lint_canonical_terms.ts +604 -0
- package/src/scripts/lint_carrier_integrity.ts +820 -0
- package/src/scripts/lint_code_comments.ts +643 -0
- package/src/scripts/lint_composition_review.ts +619 -0
- package/src/scripts/lint_consolidation_lineage.ts +666 -0
- package/src/scripts/lint_eval_specs.ts +593 -0
- package/src/scripts/lint_hook_manifest.ts +19 -0
- package/src/scripts/lint_host_portability.ts +373 -0
- package/src/scripts/lint_judge_prompt_expectation.ts +27 -1
- package/src/scripts/lint_memory_twin_parity.ts +335 -0
- package/src/scripts/lint_metric_consumers.ts +355 -0
- package/src/scripts/lint_plan_risk_register.ts +39 -19
- package/src/scripts/lint_promotion_paths.ts +779 -0
- package/src/scripts/lint_skill_descriptions.ts +18 -1
- package/src/scripts/lint_skill_frontmatter_safety.ts +58 -0
- package/src/scripts/lint_skill_link_reach.ts +252 -0
- package/src/scripts/lint_skill_trigger_corpus.ts +426 -23
- package/src/scripts/lint_ticket_buildable.ts +17 -1
- package/src/scripts/llm_propose.ts +256 -0
- package/src/scripts/mcp_server/consumer_tool_catalog.json +1 -1
- package/src/scripts/mcp_server/tool_catalog_source.ts +1 -1
- package/src/scripts/measure_delivery_sets.ts +361 -0
- package/src/scripts/measure_docs_dead_links.ts +348 -0
- package/src/scripts/measure_host_capture.ts +461 -0
- package/src/scripts/measure_routing_signal.ts +307 -0
- package/src/scripts/migration_status.ts +3 -3
- package/src/scripts/model_rule_injection.ts +76 -0
- package/src/scripts/orchestration_record.ts +14 -0
- package/src/scripts/preamble_byte_census.ts +139 -10
- package/src/scripts/prepack-check.mjs +4 -1
- package/src/scripts/probe_council_retention.ts +495 -0
- package/src/scripts/probe_turnaround.ts +384 -0
- package/src/scripts/probe_unblocked_ask.ts +279 -0
- package/src/scripts/release.ts +21 -37
- package/src/scripts/release_drill.ts +143 -0
- package/src/scripts/release_env.ts +35 -0
- package/src/scripts/release_publication.ts +84 -0
- package/src/scripts/render_benchmark_md.ts +1 -1
- package/src/scripts/rule_activation_census.ts +70 -9
- package/src/scripts/rule_backlinks.ts +1 -1
- package/src/scripts/run_lifecycle_suite.ts +208 -0
- package/src/scripts/run_skill_evals.ts +40 -0
- package/src/scripts/schemas/delivery-manifest.schema.json +43 -0
- package/src/scripts/schemas/drafting-channels.schema.json +43 -0
- package/src/scripts/schemas/evals.schema.json +24 -1
- package/src/scripts/schemas/rule.schema.json +52 -1
- package/src/scripts/schemas/skill.schema.json +17 -2
- package/src/scripts/skill_overlap.ts +7 -1
- package/src/scripts/skill_tools/run_block_d_eval.ts +8 -1
- package/src/scripts/skill_tools/score_skill_relevance.ts +84 -3
- package/src/scripts/skill_tools/suggest_skill_for_task.ts +8 -1
- package/src/scripts/skill_usage_report.ts +2 -1
- package/src/scripts/stubs_due.ts +211 -0
- package/src/scripts/sweep_source_surfaces.ts +678 -0
- package/src/scripts/sync_pr_branch.ts +3 -3
- package/src/scripts/trigger_eval_grandfather.json +202 -222
- package/src/scripts/utilization_report.ts +22 -2
- package/src/server/schemas/settings.ts +5 -0
- package/src/templates/marketing-copy.yml +1 -1
- package/dist/ui/assets/index-Cxgy63kz.js +0 -26
|
@@ -15,17 +15,17 @@
|
|
|
15
15
|
# THE CONTRACT (three rules, each from a real failure)
|
|
16
16
|
# ----------------------------------------------------
|
|
17
17
|
# 1. MACHINE-READABLE COUNT. Every listed gate emits exactly one line
|
|
18
|
-
# `scanned: <N>` (stdout or stderr), N =
|
|
18
|
+
# `scanned: <N>` (stdout or stderr), N = artifacts it actually inspected. The
|
|
19
19
|
# guard never parses a gate's human output — that would make the guard itself
|
|
20
20
|
# fragile, and a fragile guard is the thing being replaced.
|
|
21
21
|
#
|
|
22
22
|
# 2. CI-IDENTICAL INVOCATION. `argv` MUST match how CI/Taskfile calls the gate.
|
|
23
23
|
# A bare probe produced a false alarm during the sweep: `skill_linter` looked
|
|
24
24
|
# blind when called with no arguments, but CI passes `--all` and it scans 429
|
|
25
|
-
#
|
|
25
|
+
# artifacts. The guard must reproduce the real call or it invents defects.
|
|
26
26
|
#
|
|
27
27
|
# 3. BASELINE, NOT `> 0`. `min_scanned` is a floor, not a zero-check. A gate that
|
|
28
|
-
# drops from 428
|
|
28
|
+
# drops from 428 artifacts to 3 is as broken as one that drops to 0, and `> 0`
|
|
29
29
|
# cannot see it. Set the floor below the true corpus (room for legitimate
|
|
30
30
|
# deletions) but far above a collapse.
|
|
31
31
|
#
|
|
@@ -40,17 +40,79 @@
|
|
|
40
40
|
# visible, or it repeats the sin it exists to catch.
|
|
41
41
|
# canary optional mutation recipe (Phase 7) — see CANARY below
|
|
42
42
|
#
|
|
43
|
-
# COVERAGE — THE HONEST DENOMINATOR (re-measured 2026-08-
|
|
43
|
+
# COVERAGE — THE HONEST DENOMINATOR (re-measured 2026-08-28)
|
|
44
44
|
# ----------------------------------------------------------
|
|
45
|
-
#
|
|
45
|
+
# 306 `lint_*` / `check_*` / `audit_*` scripts live under `src/scripts/`
|
|
46
46
|
# (the count is computed, not asserted — `check_gate_coverage.count_gate_scripts`,
|
|
47
|
-
# re-run on the tree carrying these rows,
|
|
48
|
-
#
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
#
|
|
52
|
-
#
|
|
53
|
-
# carry a floor,
|
|
47
|
+
# re-run on the tree carrying these rows, which now include the four gates the
|
|
48
|
+
# two runtime-cost roadmaps add: check_prefix_stable_mutation,
|
|
49
|
+
# check_loss_class_declared, check_benchmark_report_fields, and
|
|
50
|
+
# check_no_currency_in_cost_surfaces).
|
|
51
|
+
# **78 of them emit the machine-readable `scanned: <N>` line under their
|
|
52
|
+
# CI-identical argv, and 75 of those 78 are listed below.** The manifest is
|
|
53
|
+
# complete for every gate that can carry a floor, covering ~25 % of the population.
|
|
54
|
+
#
|
|
55
|
+
# RECOUNTED 2026-08-31, on the change that adds `lint_promotion_paths` — and the
|
|
56
|
+
# 2026-08-30 block above was already stale when this row landed, in BOTH numbers
|
|
57
|
+
# rather than only in the one this change moves. Recomputed on this tree:
|
|
58
|
+
# `count_gate_scripts()` returns **310** and `grep -c '^ - id:'` returns **81**
|
|
59
|
+
# (80 before this row), so 81/310 = 26.1 %. The script count rose without any
|
|
60
|
+
# recount, which is the drift the blocks below keep describing; it is recorded
|
|
61
|
+
# here rather than folded into the 2026-08-30 prose, because that block is a
|
|
62
|
+
# measurement of a tree that no longer exists.
|
|
63
|
+
#
|
|
64
|
+
# RECOUNTED ON A MERGE, 2026-08-30 — the fifth time, and the same shape as the
|
|
65
|
+
# 2026-08-26 blocks below: two sides each correct for their own tree (~24 % from
|
|
66
|
+
# the branch, ~25 % from main) meeting in one number. Recomputed rather than
|
|
67
|
+
# picked: `count_gate_scripts()` returns **306** and `grep -c '^ - id:'`
|
|
68
|
+
# returns **76** on the merged tree, so 76/306 = 24.8 % and main's side is the
|
|
69
|
+
# right one — arrived at by arithmetic, not by taking theirs.
|
|
70
|
+
#
|
|
71
|
+
# RECOUNTED ON A MERGE, 2026-08-26 — the fourth time this file has met the case
|
|
72
|
+
# the 2026-08-24 block below describes, and this one left TWO STACKED claim
|
|
73
|
+
# blocks rather than a conflict inside one number: 295/68 from this branch and
|
|
74
|
+
# 296/67 from main, each correct for its own tree. Collapsed to one recomputed
|
|
75
|
+
# block rather than reconciled by hand: `count_gate_scripts()` returns **296**
|
|
76
|
+
# and `grep -c '^ - id:'` returns **66** on the merged tree.
|
|
77
|
+
#
|
|
78
|
+
# 66 + 3 unlisted emitters (`lint_evidence_artifacts`, `adr_cite_check`,
|
|
79
|
+
# `check_new_adr_evidence`) = 69.
|
|
80
|
+
#
|
|
81
|
+
# RECOUNTED ON A MERGE, 2026-08-26, and the merge left TWO stacked header claims
|
|
82
|
+
# rather than a conflict inside one number — each branch had recounted correctly
|
|
83
|
+
# for its own tree, and keeping both sides produced a page asserting 294/62 and
|
|
84
|
+
# 295/64 four lines apart. Collapsed to one recomputed block: `count_gate_scripts()`
|
|
85
|
+
# returns **295** and `grep -c '^ - id:'` returns **64** on the merged tree.
|
|
86
|
+
#
|
|
87
|
+
# A paragraph that briefly stood here claimed the emitter total "cannot be
|
|
88
|
+
# derived by grep" and dropped it. That was true of the method it tried and
|
|
89
|
+
# wrong as a conclusion — every LISTED row is an emitter by construction (a row
|
|
90
|
+
# that did not emit could carry no floor) and the same three emitters remain
|
|
91
|
+
# deliberately unlisted, so 64 + 3 = 67. The figure is arithmetic over this
|
|
92
|
+
# file, not a grep over `src/scripts/`, and it is restored rather than left
|
|
93
|
+
# absent.
|
|
94
|
+
#
|
|
95
|
+
# RECOUNTED ON A MERGE, 2026-08-26 — the case the 2026-08-24 block below was
|
|
96
|
+
# written for, arriving again. Two branches each added one row and each recorded
|
|
97
|
+
# a correct population line for its own tree, so the merge put 293 and 294 side
|
|
98
|
+
# by side; after the merge both gates exist, so either figure describes a tree
|
|
99
|
+
# that no longer does. Recomputed on the merged tree rather than reconciled by
|
|
100
|
+
# hand: `count_gate_scripts()` returns **294** and `grep -c '^ - id:'` returns
|
|
101
|
+
# **63**.
|
|
102
|
+
#
|
|
103
|
+
# The emitter total moves with the listed count for the reason the 2026-08-25
|
|
104
|
+
# paragraph already states: every LISTED row is an emitter, because a row that
|
|
105
|
+
# did not emit could carry no floor, and the same three emitters remain
|
|
106
|
+
# deliberately unlisted (`lint_evidence_artifacts`, `adr_cite_check`,
|
|
107
|
+
# `check_new_adr_evidence`). 63 + 3 = 66.
|
|
108
|
+
#
|
|
109
|
+
# RECOUNTED on 2026-08-26 while adding `lint_canonical_terms`
|
|
110
|
+
# (road-to-canonical-terms 2.3). Recomputed, not adjusted — the two commands in
|
|
111
|
+
# the 2026-08-24 block below were re-run on this tree and returned 293 and 61.
|
|
112
|
+
# The population moved by TWO while one row was added, which is why the prose was
|
|
113
|
+
# not incremented by hand: a second gate script had arrived since the last count
|
|
114
|
+
# without a manifest row, and hand-arithmetic would have recorded 292 and been
|
|
115
|
+
# wrong in a way nobody could see.
|
|
54
116
|
#
|
|
55
117
|
# `description_route_check` is counted in the POPULATION and deliberately NOT
|
|
56
118
|
# listed: it is diff-scoped, so its natural reading on most trees is zero cases,
|
|
@@ -306,10 +368,56 @@
|
|
|
306
368
|
# in-place edit would need byte-exact restoration of a tracked file, and a canary
|
|
307
369
|
# that can corrupt the tree violates the never-ships rule it inherits. The
|
|
308
370
|
# consequence is a real gap — a gate whose only possible violation is a
|
|
309
|
-
# modification of an existing tracked
|
|
371
|
+
# modification of an existing tracked artifact (`check_condensation`, whose
|
|
310
372
|
# contract is `dist == rewrite(src)`; `check_ci_local_parity`, whose corpus is
|
|
311
373
|
# workflow files) carries no recipe and is reported UNPROVEN, never green.
|
|
312
374
|
gates:
|
|
375
|
+
- id: lint_metric_consumers
|
|
376
|
+
argv: ["--quiet"]
|
|
377
|
+
min_scanned: 5
|
|
378
|
+
corpus: "entries in src/config/metric-registry.yml (7 at the time of writing). The floor is 5, not 1: the registry's failure shape is a scan that reads a truncated or renamed file, and a single surviving entry would still pass a `> 0` check while the other six went unchecked."
|
|
379
|
+
status: enforced
|
|
380
|
+
no_canary_reason: >-
|
|
381
|
+
A create-only canary cannot express this gate's violation. The corpus is
|
|
382
|
+
the `metrics:` list inside ONE tracked file, so a planted file lands in no
|
|
383
|
+
row; every violation it can have is a MODIFICATION — a field emptied, a
|
|
384
|
+
field replaced with boilerplate, an id duplicated. Same class as
|
|
385
|
+
`check_no_automerge_key` and `lint_memory_twin_parity`. Discrimination is
|
|
386
|
+
proven instead by the gate's own `--self-test`: 7 cases, 6 rejecting,
|
|
387
|
+
each driving the real CLI against a throwaway registry.
|
|
388
|
+
note: >
|
|
389
|
+
road-to-experience-loop-broadening step 0.3. Refuses a metric that does
|
|
390
|
+
not name its consumer, the decision it feeds, and what fails without it.
|
|
391
|
+
The third field is the falsifiable one: the first two are answerable for a
|
|
392
|
+
metric nobody needs, and if the honest answer to "what fails without it"
|
|
393
|
+
is nothing, the entry cannot be written. HONEST LIMIT, stated in the
|
|
394
|
+
gate's own docstring: it checks SHAPE, not truth — it makes the omission
|
|
395
|
+
impossible, not the answer correct, because telling a real consumer from a
|
|
396
|
+
plausible sentence is a review judgement no parser has.
|
|
397
|
+
- id: lint_consolidation_lineage
|
|
398
|
+
argv: []
|
|
399
|
+
min_scanned: 0
|
|
400
|
+
corpus: "every agents/roadmaps/*.md, counted as FILES rather than as declarations. THE FLOOR WAS RETIRED ON 2026-08-30 AND REPLACED WITH AN ENUMERATION ASSERTION IN THE LINTER ITSELF (AI council, anthropic + openai, convergent on option b). It sat at 5 over a population under deliberate drawdown to ZERO, so it went red the day the drain succeeded — 6 active roadmaps to 4 in one afternoon — and the only available move was lowering the number again, a treadmill ending at a floor of 0, which is no floor. What guards the scope now is `lint_consolidation_lineage` refusing outright when a declared root is missing, is not a directory, or cannot be enumerated; that check lives in the PRODUCTION linter rather than here on purpose, because an independent existsSync in this gate would observe a directory without proving the linter enumerated it. Honest limit, named rather than implied: it catches a missing or renamed root, not a glob narrowed to match nothing, not enumeration in the wrong working directory, and not roadmaps moved into nested directories the walk no longer traverses. Today none of them carries a `consolidates:` field, so the finding count is legitimately zero while the scanned count is not — that split is the point: a declaration-count floor would be a zero-check wearing a ratchet's name, and would go green the moment the scan root moved. The floor sits at 5 rather than near the present 12 because the active estate is under deliberate drawdown (one-in-one-out plus an explicit drain), so a falling count is expected work rather than a collapse; below 5 the estate would be smaller than any point in its recorded history. NO CANARY, deliberately: the council decision that admitted this gate (2026-08-27, 2/2 convergent, E1=b/E2=report) fixed it in REPORT mode, so it exits 0 on findings by design and a planted violation could not turn it red. Its ability to go red is proven instead by `--self-test`, which the same decision required: six declaration spellings must parse identically, all four finding types must fire, and a complete folder must stay silent."
|
|
401
|
+
status: enforced
|
|
402
|
+
no_canary_reason: "A report-mode gate cannot be turned red by a planted file. The council decision that admitted this gate (2026-08-27, 2/2 convergent, E1=b/E2=report) fixed it in report mode deliberately: the four measured failures come from a high-noise drafting context and do not establish precision on the tracked estate, so blocking is earned by tracked-scope evidence rather than assumed. A canary here would either be planted and ignored (proving nothing) or force `--strict` into CI, which would decide E2 by wiring instead of by evidence. The negative control is `--self-test` instead, required by the same decision and stronger than a single planted file: six declaration spellings must parse to an identical parent set, all four finding types must fire, and a complete folder must stay silent — the third arm being what stops a checker that returned every code unconditionally from passing the second. Revisit together with E2: when the tracked half is promoted to blocking, it owes a canary."
|
|
403
|
+
- id: lint_carrier_integrity
|
|
404
|
+
argv: []
|
|
405
|
+
min_scanned: 600
|
|
406
|
+
corpus: "every roadmap file under agents/roadmaps/archive/ and agents/roadmaps/skipped/ — 656 at the time of writing, and the count only rises because archival is one-way. The floor sits at 600 rather than near 656 because a reading below it means the walk lost a directory, not that roadmaps were un-archived. The walk direction is the design: a `[~]` carry is validated once, when the parent is archived, by a sweep that then never looks at the pair again, so the receiver can be deleted afterwards with nothing going red. Starting from the archived parent — which names its destination by slug and which nothing rewrites — makes whole-file deletion detectable on the first pass, with no registry to maintain. TWO CLASSES, and the split decides the tier: `broken-destination` (deleted, renamed, re-parented, skipped, or archived with open steps) is a HARD failure at zero with no baseline, because every member had a recorded home and lost it; `unannotated` (a bare `[~]` with no annotation at all) is ratcheted at 243 in gate-violation-baselines.json, all of it predating the annotation contract by up to three months."
|
|
407
|
+
status: enforced
|
|
408
|
+
canary:
|
|
409
|
+
class: contract-violation
|
|
410
|
+
path: agents/roadmaps/archive/zz-canary-carrier-integrity.md
|
|
411
|
+
content: |
|
|
412
|
+
---
|
|
413
|
+
complexity: bounded
|
|
414
|
+
---
|
|
415
|
+
# Canary planted by check_gate_coverage --canary; never ships.
|
|
416
|
+
|
|
417
|
+
## Phase 1 — a phase
|
|
418
|
+
|
|
419
|
+
- [~] **1.1 A step carried to a receiver that does not exist.**
|
|
420
|
+
<!-- deferred-resolution: carried-to=road-to-zz-canary-receiver-that-does-not-exist -->
|
|
313
421
|
- id: lint_skill_trigger_corpus
|
|
314
422
|
argv: []
|
|
315
423
|
min_scanned: 70
|
|
@@ -406,7 +514,7 @@ gates:
|
|
|
406
514
|
per-class red observation lives in the gate's own `--self-test` (9 cases,
|
|
407
515
|
6 rejecting), which proves every class discriminates over a synthetic
|
|
408
516
|
payload with no pack run. Two of the four cannot be planted through the
|
|
409
|
-
register at all: `compiled-test-
|
|
517
|
+
register at all: `compiled-test-artifact` is excluded from the payload by
|
|
410
518
|
the `files[]` negations that fixed it, so a plant never ships and never
|
|
411
519
|
reds, and `source-map` needs 121 files in a BUILT tree.
|
|
412
520
|
|
|
@@ -461,7 +569,7 @@ gates:
|
|
|
461
569
|
corpus: "the npm pack payload (2,686 in an unbuilt worktree on 2026-08-22), read to classify each .npmignore pattern against what actually shipped"
|
|
462
570
|
status: enforced
|
|
463
571
|
no_canary_reason: >-
|
|
464
|
-
the violation is a MODIFICATION, not a creation: this gate reds when package.json `files[]` or `.npmignore` changes and the committed
|
|
572
|
+
the violation is a MODIFICATION, not a creation: this gate reds when package.json `files[]` or `.npmignore` changes and the committed artifact does not, and the canary contract is create-only. A planted FILE cannot move either surface — the closest it gets is changing the payload-derived shadowed set, which is informational and deliberately excluded from the drift verdict, so a plant would leave the gate green and be reported as dead. Discrimination is proven by the gate's own `--self-test` (8 cases, 5 rejecting) over the pattern matcher, and end to end by hand: editing `files[]` alone exits 1, regenerating exits 0, editing `.npmignore` alone exits 1, restoring exits 0.
|
|
465
573
|
|
|
466
574
|
- id: check_pack_passport_reconciliation
|
|
467
575
|
argv: []
|
|
@@ -821,7 +929,7 @@ gates:
|
|
|
821
929
|
- id: check_no_roadmap_refs
|
|
822
930
|
argv: []
|
|
823
931
|
min_scanned: 700
|
|
824
|
-
corpus: "stable
|
|
932
|
+
corpus: "stable artifacts across src/{rules,skills,agent-src/*} + docs/ + agents/settings/contexts (872 at baseline)"
|
|
825
933
|
status: enforced
|
|
826
934
|
canary:
|
|
827
935
|
class: stale-reference
|
|
@@ -829,7 +937,7 @@ gates:
|
|
|
829
937
|
content: |
|
|
830
938
|
---
|
|
831
939
|
type: auto
|
|
832
|
-
description: "Planted canary rule linking a stable
|
|
940
|
+
description: "Planted canary rule linking a stable artifact into the transient roadmap tree."
|
|
833
941
|
---
|
|
834
942
|
|
|
835
943
|
See [the plan](../../agents/roadmaps/road-to-nowhere.md) — the exact
|
|
@@ -837,7 +945,7 @@ gates:
|
|
|
837
945
|
note: >
|
|
838
946
|
Retargeted 2026-07-29 from the ADR-051-emptied tree. It had been enforcing the
|
|
839
947
|
no-roadmap-references rule for docs/ only while the rule + skill layer went
|
|
840
|
-
unscanned — 0 -> 872
|
|
948
|
+
unscanned — 0 -> 872 artifacts. No violation had slipped through (verified),
|
|
841
949
|
so this closed a latent gap, not a live breach.
|
|
842
950
|
|
|
843
951
|
- id: check_context_paths
|
|
@@ -921,7 +1029,7 @@ gates:
|
|
|
921
1029
|
silent-green found in the same sweep — the per-pack lint matrix, whose path was
|
|
922
1030
|
a double ADR-051 casualty and which exited 0 on an empty match across 17 CI
|
|
923
1031
|
shards — is NOT listed here because it was deleted rather than repaired
|
|
924
|
-
(skill_linter --all already covers all 429
|
|
1032
|
+
(skill_linter --all already covers all 429 artifacts in 0.5s).
|
|
925
1033
|
|
|
926
1034
|
|
|
927
1035
|
# ── Registered 2026-08-02 (road-to-renewal-foundation Phase 1) ───────────
|
|
@@ -965,7 +1073,7 @@ gates:
|
|
|
965
1073
|
corpus: "src/rules + src/skills + src/agent-src/commands + docs/guidelines .md (533 at baseline)"
|
|
966
1074
|
status: enforced
|
|
967
1075
|
no_canary_reason: >-
|
|
968
|
-
thresholds are computed across the whole corpus; a single planted
|
|
1076
|
+
thresholds are computed across the whole corpus; a single planted artifact has no population to exceed.
|
|
969
1077
|
note: >
|
|
970
1078
|
A collapse below the floor would mean the gate stopped reading the tree
|
|
971
1079
|
that states extraction thresholds, so a bare or diverging threshold
|
|
@@ -1071,10 +1179,45 @@ gates:
|
|
|
1071
1179
|
or if a drop to 0 is ever traced to a scanner defect rather than to an
|
|
1072
1180
|
empty corpus.
|
|
1073
1181
|
|
|
1182
|
+
- id: check_gate_reachability
|
|
1183
|
+
script: src/scripts/check_gate_reachability.ts
|
|
1184
|
+
min_scanned: 10
|
|
1185
|
+
corpus: "exemption rows in src/config/gate-reachability-exemptions.json PLUS the gate-shaped task targets reachable from neither `task ci`'s transitive closure nor any workflow. Reachability is measured three ways, not two: a workflow may call `task <name>` OR the script directly, and conflating those overstated the hole 39 -> 22 on this tree."
|
|
1186
|
+
status: enforced
|
|
1187
|
+
no_canary_reason: "The negative control is the gate's own --self-test, run in CI: 4 cases, 2 rejecting, covering BOTH directions — an unreachable target with no row, and a row naming a target that is reachable. It builds throwaway task trees rather than touching this one, which is strictly better than a planted canary here: a canary would mean adding a real unreachable gate target to taskfiles/ and removing it again, and a forgotten one is the exact defect this gate exists to catch."
|
|
1188
|
+
|
|
1189
|
+
# road-to-retired-claims-stay-retired 2.3. The gate was NOT in this manifest
|
|
1190
|
+
# before that roadmap widened it: it asserted its scope with plain
|
|
1191
|
+
# `assertScanned` and published no machine-readable count, so
|
|
1192
|
+
# check_gate_coverage could not see it at all. Widening it to read the
|
|
1193
|
+
# publish-surface set is exactly the moment that becomes indefensible — a
|
|
1194
|
+
# gate that now decides what may ship on npm should not be the one gate
|
|
1195
|
+
# nobody counts.
|
|
1196
|
+
- id: check_claims
|
|
1197
|
+
argv: []
|
|
1198
|
+
min_scanned: 60
|
|
1199
|
+
corpus: "ledger entries in docs/CLAIMS.md (97 at registration: 59 backed, 30 unbacked, 8 closed). The gate's SECOND root, the five files in `PUBLISH_SURFACES`, is not summed into this count — ledger entries and files are different units and a sum of the two is a number nobody can re-derive. That root is guarded by `assertWatchlistResolves` inside the gate, which fires when every publish surface has vanished while a retired phrasing is still registered."
|
|
1200
|
+
status: enforced
|
|
1201
|
+
no_canary_reason: "The gate carries its own `--self-test` (5 cases, 3 rejecting) — so this row is an adopter, not an exemption; the reason field states why a PLANTED canary is additionally unavailable. Beyond the self-test the negative controls are the 30 mechanism tests in tests/scripts/check_claims.test.ts (17) and tests/scripts/check_claims_retired_phrasings.test.ts (13), each building a throwaway tree and running the real script in it. Twenty-one assert a REJECTION, and one publishes the LITERAL historical string (`zero runtime daemon`) that shipped in package.json and .github/about.yml while claim:no-runtime-daemon was already withdrawn. A planted canary here would mean committing a retired phrasing to a real publish surface and removing it again, and a forgotten one is precisely the defect this gate exists to catch."
|
|
1202
|
+
|
|
1203
|
+
- id: check_rule_evidence_declaration
|
|
1204
|
+
argv: []
|
|
1205
|
+
min_scanned: 10
|
|
1206
|
+
corpus: "the ten security / safety-floor rules named in the gate's own SCOPE constant. The floor equals the scope on purpose, unlike every other row here: the corpus is not discovered, it is DECLARED, so a count below it means a row was deleted rather than that the tree shrank. Widening the obligation means adding a row to SCOPE, which raises both numbers together."
|
|
1207
|
+
status: enforced
|
|
1208
|
+
no_canary_reason: "The gate carries its own `--self-test` (6 cases, 4 rejecting), each building a throwaway src/rules/ tree and running the real gate against it — a missing block, a valueless key, and BOTH directions of the conditional rule: an external-source block missing `normative_level` or `verified_on` must reject, and an `own-analysis` block carrying neither must ACCEPT. That pair is the load-bearing one, because a gate enforcing more than the schema would reject a rule the schema accepts. A planted canary cannot express any of them: the violation is a MODIFICATION of one of ten tracked rule files, and a newly created file lands outside the declared scope by construction. Same class as check_no_automerge_key and check_score_contract."
|
|
1209
|
+
|
|
1210
|
+
- id: check_concern_admissions
|
|
1211
|
+
script: src/scripts/check_concern_admissions.ts
|
|
1212
|
+
min_scanned: 0
|
|
1213
|
+
corpus: "agents/decisions/concern-admissions.jsonl rows PLUS the concerns added since the base ref (a SET DIFFERENCE over ids in src/scripts/hook_manifest.yaml, because a concern is a key inside one file rather than a file of its own). Ships at 0: the 55 pre-existing concerns are grandfathered by that forward-only scope, so the first row arrives with the first new concern, and a MALFORMED ledger is a separate hard error in readLedger() rather than an empty read."
|
|
1214
|
+
status: enforced
|
|
1215
|
+
no_canary_reason: "The negative control is the gate's own --self-test, which is stronger than a single planted canary and is run in CI: 6 cases, 3 of them rejecting, covering a concern added with no row, a row with a blank answer, and a rejected row naming a live concern — plus two ACCEPT cases that pin the grandfathering, so a gate that started failing everything would not pass either. A planted canary in the real ledger would additionally have to be removed again, and a forgotten one is a false rejection row in a decision record."
|
|
1216
|
+
|
|
1074
1217
|
- id: check_estate_count
|
|
1075
1218
|
argv: []
|
|
1076
1219
|
min_scanned: 20
|
|
1077
|
-
corpus: "active + parked roadmap files (81 at baseline: 38 active, 43 in later/)"
|
|
1220
|
+
corpus: "active + parked roadmap files (81 at baseline: 38 active, 43 in later/), plus src/scripts/hook_manifest.yaml for the concern axis — a single file read with `git show` at the base ref rather than a third materialised subtree"
|
|
1078
1221
|
status: enforced
|
|
1079
1222
|
canary:
|
|
1080
1223
|
class: contract-violation
|
|
@@ -1099,17 +1242,45 @@ gates:
|
|
|
1099
1242
|
cannot survive a collapse: at that point the gate's own `reportScanned`
|
|
1100
1243
|
fires first. (Set to 50 in the first version, corrected on an R2 finding.)
|
|
1101
1244
|
|
|
1245
|
+
- id: check_static_parity
|
|
1246
|
+
argv: ["--quiet"]
|
|
1247
|
+
min_scanned: 20
|
|
1248
|
+
corpus: "test files that spell the dispatcher module name, discovered by grep over tests/ and src/. The count is deliberately not written here — it moves with the suite, and four different figures for it appeared across the rounds of this change (R2 round-5 finding 12). The floor is 20, not 1: this gate's silent-failure shape is a discovery COLLAPSE — a grep that stops matching would run two suites of one file each and report them identical, which is the 'gate that scans nothing exits green' case in its most convincing disguise."
|
|
1249
|
+
status: enforced
|
|
1250
|
+
no_canary_reason: >-
|
|
1251
|
+
No plantable violation: the gate's finding is a DIVERGENCE between two
|
|
1252
|
+
whole-suite runs, not a pattern in a file. Planting one would mean making
|
|
1253
|
+
the collector behave differently under the two runs, i.e. writing the bug
|
|
1254
|
+
it exists to detect.
|
|
1255
|
+
note: >
|
|
1256
|
+
road-to-supervised-telemetry-collector step 4.2 (AC-7). Runs the
|
|
1257
|
+
dispatcher-reaching suite twice — collector present-but-off, then aliased
|
|
1258
|
+
away entirely — and compares per-test verdicts rather than declaring each
|
|
1259
|
+
run green. Two green runs are not the assertion; a test that silently
|
|
1260
|
+
turns from `passed` to `skipped` keeps both suites green and only the
|
|
1261
|
+
per-test comparison sees it.
|
|
1262
|
+
|
|
1263
|
+
SELF-TEST EXEMPT, with the reason rather than the omission: a
|
|
1264
|
+
`--self-test` here would have to spawn two full vitest runs over a fixture
|
|
1265
|
+
repository, minutes per invocation, to prove a comparator that is already
|
|
1266
|
+
unit-tested with a REJECTING case —
|
|
1267
|
+
`tests/scripts/check_static_parity.test.ts` drives `compare()` through the
|
|
1268
|
+
`passed → skipped` divergence a length-only check would miss, plus both
|
|
1269
|
+
only-in-one-run directions. The discrimination is proven; what is skipped
|
|
1270
|
+
is proving it a second time through the slowest possible harness. The
|
|
1271
|
+
marker the self-test ratchet reads lives in the gate's own source, beside
|
|
1272
|
+
`main` — this note explains it; that line is what is counted.
|
|
1102
1273
|
- id: check_completion_review
|
|
1103
1274
|
argv: ["--advisory", "--base", "origin/main"]
|
|
1104
1275
|
min_scanned: 1
|
|
1105
|
-
corpus: "findings
|
|
1276
|
+
corpus: "findings artifacts under agents/evidence/reviews/ + the current-diff evaluation (1 at baseline — the evaluation itself; artifact count grows with gated PRs)"
|
|
1106
1277
|
status: enforced
|
|
1107
1278
|
no_canary_reason: >-
|
|
1108
1279
|
git-dependent: it evaluates the current diff against a base ref.
|
|
1109
1280
|
note: >
|
|
1110
1281
|
Gate R2 (docs/contracts/plan-review-gates.md § 2). HONEST LIMIT, stated
|
|
1111
1282
|
because a floor that cannot fail is exactly the false green this file
|
|
1112
|
-
exists to prevent: scanned =
|
|
1283
|
+
exists to prevent: scanned = artifacts inspected + 1 for the diff
|
|
1113
1284
|
evaluation, so on any run that REACHES the count `min_scanned: 1` cannot
|
|
1114
1285
|
trip. It is not unreachable in principle — a moved reviews root exits
|
|
1115
1286
|
before the inventory and reports `scanned: 0`, which the guard does read —
|
|
@@ -1141,7 +1312,7 @@ gates:
|
|
|
1141
1312
|
deleted, so a drop to 7 means the reviews root moved or the naming
|
|
1142
1313
|
convention drifted — not that the work went clean. That is precisely the
|
|
1143
1314
|
case rule 3 exists for. The gate reads the FROZEN records because R2
|
|
1144
|
-
selects only
|
|
1315
|
+
selects only artifacts in the CURRENT review scope, so a superseded round
|
|
1145
1316
|
renamed out of the `*.findings.md` glob is read by nothing at all — two
|
|
1146
1317
|
findings sat recorded as `open` in this repo's own corpus for a day
|
|
1147
1318
|
through exactly that gap.
|
|
@@ -1184,15 +1355,15 @@ gates:
|
|
|
1184
1355
|
collision gate across four roots at once; one planted name collides with nothing.
|
|
1185
1356
|
note: >
|
|
1186
1357
|
Counts NAMES, not files — the scan-scope census counts files under the same
|
|
1187
|
-
roots, so the two
|
|
1358
|
+
roots, so the two artifacts legitimately report different numbers here.
|
|
1188
1359
|
|
|
1189
1360
|
- id: lint_artefact_frontmatter
|
|
1190
1361
|
argv: ["--quiet"]
|
|
1191
1362
|
min_scanned: 540
|
|
1192
|
-
corpus: "
|
|
1363
|
+
corpus: "artifacts carrying frontmatter across the discovery roots (619 at baseline)"
|
|
1193
1364
|
status: enforced
|
|
1194
1365
|
no_canary_reason: >-
|
|
1195
|
-
a planted
|
|
1366
|
+
a planted artifact is judged, but the gate reports adoption across the discovery roots, so the number rather than a red is the output.
|
|
1196
1367
|
|
|
1197
1368
|
- id: audit_skill_overlap
|
|
1198
1369
|
argv: ["--quiet", "--print-table", "--strict"]
|
|
@@ -1410,7 +1581,7 @@ gates:
|
|
|
1410
1581
|
note: >
|
|
1411
1582
|
The plant needs a slug that already carries a `prompt_hash` but no committed
|
|
1412
1583
|
package — a brand-new `zz-canary` slug is skipped, not caught, because an
|
|
1413
|
-
|
|
1584
|
+
artifact without a package is deliberately out of scope. `zcs-closure` is a
|
|
1414
1585
|
closed round, so it will not gain a real package and the plant cannot
|
|
1415
1586
|
collide with one. The two planted failures the roadmap asked for (a one-byte
|
|
1416
1587
|
prompt edit, a pre-loaded verdict) are pinned in
|
|
@@ -1469,7 +1640,7 @@ gates:
|
|
|
1469
1640
|
That case is the gate's own subject, so it is pinned by a test fixture
|
|
1470
1641
|
too (`a table that parses to zero rows reds rather than exiting green`).
|
|
1471
1642
|
No `canary:` recipe: this gate's only violation shape is a MODIFICATION of
|
|
1472
|
-
a tracked
|
|
1643
|
+
a tracked artifact (`docs/MIGRATION.md`), and the canary contract is
|
|
1473
1644
|
create-only, so it reports UNPROVEN rather than green. Discrimination is
|
|
1474
1645
|
proven instead by paired fixtures in
|
|
1475
1646
|
`tests/scripts/lint_scheduled_deprecations.test.ts`, verified by mutation:
|
|
@@ -1600,7 +1771,7 @@ gates:
|
|
|
1600
1771
|
# cmd_settings_check), forcing them into the ledger contract and reddening
|
|
1601
1772
|
# the completeness ratchet for work nobody asked for;
|
|
1602
1773
|
# - renaming the script to `check_adr_citations.ts` is the convention-conform
|
|
1603
|
-
# answer and touches 26 files, including archived review
|
|
1774
|
+
# answer and touches 26 files, including archived review artifacts and a
|
|
1604
1775
|
# committed diff.patch that must not be rewritten;
|
|
1605
1776
|
# - manifest-driven classification is explicitly rejected by
|
|
1606
1777
|
# gate_population.ts's own header (a new gate lands before anyone
|
|
@@ -1623,7 +1794,7 @@ gates:
|
|
|
1623
1794
|
the gate correctly stays green. Measured on a previous attempt, where the
|
|
1624
1795
|
gate was then mis-reported as dead. Same class as `check_condensation` and
|
|
1625
1796
|
`check_ci_local_parity` — the only possible violation is a modification of
|
|
1626
|
-
an existing tracked
|
|
1797
|
+
an existing tracked artifact. The red is proven instead by the committed
|
|
1627
1798
|
violating fixture `tests/fixtures/automerge-key/` plus two recorded
|
|
1628
1799
|
sabotage probes in `tests/scripts/check_no_automerge_key.test.ts`.
|
|
1629
1800
|
note: >
|
|
@@ -1632,7 +1803,7 @@ gates:
|
|
|
1632
1803
|
lands OUTSIDE the corpus and the gate correctly stays green — measured on a
|
|
1633
1804
|
previous attempt at this gate, where it was then mis-reported as dead. The
|
|
1634
1805
|
only violation this gate can have is a modification of an existing tracked
|
|
1635
|
-
|
|
1806
|
+
artifact, which is the same class as `check_condensation` and
|
|
1636
1807
|
`check_ci_local_parity`, and the CANARY section above already states that
|
|
1637
1808
|
such a gate carries no recipe and is reported UNPROVEN rather than green.
|
|
1638
1809
|
|
|
@@ -1750,42 +1921,54 @@ gates:
|
|
|
1750
1921
|
ADR whose dated record must not be rewritten, and a bare rule count with no
|
|
1751
1922
|
enforcement sense ("2 rules" in a concepts page) which must not be a finding.
|
|
1752
1923
|
|
|
1924
|
+
- id: check_supervision_claim_atomicity
|
|
1925
|
+
argv: []
|
|
1926
|
+
min_scanned: 6
|
|
1927
|
+
corpus: "public surfaces a reader lands on — README.md plus seven docs/ pages (8 at baseline, 2026-08-27); the floor is 6 so a page being renamed does not silently shrink the scan to nothing"
|
|
1928
|
+
status: enforced
|
|
1929
|
+
no_canary_reason: >-
|
|
1930
|
+
A create-only canary cannot express this gate's violation. The corpus is a
|
|
1931
|
+
committed CONSTANT (`PUBLIC_SURFACES`), so a planted file lands in no row —
|
|
1932
|
+
the eight rows exist whatever the filesystem holds. The violation is a
|
|
1933
|
+
present-tense supervision claim appearing INSIDE one of those tracked
|
|
1934
|
+
pages, which is a modification. Same class as `check_score_contract`,
|
|
1935
|
+
`check_no_automerge_key` and `check_condensation`.
|
|
1936
|
+
Discrimination is proven instead by the gate's own `--self-test`, which is
|
|
1937
|
+
the step that created it: road-to-runtime-governance-flip 3.4 required
|
|
1938
|
+
seeded negatives to be OBSERVED red, not asserted. **7/7, 5 rejecting**,
|
|
1939
|
+
each building a throwaway git repo so the revision check is real and each
|
|
1940
|
+
driving the real CLI. The rejecting cases: no evidence at all; an emptied
|
|
1941
|
+
suite whose cases all skipped; a result recorded against a different
|
|
1942
|
+
revision; a suite that did not exercise real processes; and a non-integer
|
|
1943
|
+
case count. Two accepting controls: sufficient evidence lets the claim
|
|
1944
|
+
through, and a DENIAL of supervision needs no evidence at all.
|
|
1945
|
+
The refusals are separate because a suite that ran on a parent commit, one
|
|
1946
|
+
that skipped everything, and one that mocked the process layer are three
|
|
1947
|
+
different lies, and a file-presence check catches none of them.
|
|
1948
|
+
**Grown from 4/4 by a neutral council review of the code**, which found the
|
|
1949
|
+
docstring advertising a mocked-process negative the case list did not
|
|
1950
|
+
contain, and — worse — that the pattern matched `is NOT supervised`, so the
|
|
1951
|
+
gate would have refused a truthful denial. Both are closed with regression
|
|
1952
|
+
cases; the second is the `denial` accepting control above.
|
|
1753
1953
|
- id: check_score_contract
|
|
1754
1954
|
argv: ["--quiet"]
|
|
1755
1955
|
min_scanned: 20
|
|
1756
1956
|
corpus: "rows in `agents/evidence/ac-capability-scorecard.yaml` — one per rubric category recoverable from the tracked tree (23 at baseline, 2026-08-24)"
|
|
1757
1957
|
status: enforced
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
recovered_category_count: 1
|
|
1773
|
-
missing_category_count: 31
|
|
1774
|
-
manifest_version: baseline_v1
|
|
1775
|
-
recovery_source: agents/roadmaps/road-to-ten-across-the-board.md
|
|
1776
|
-
excluded_from_manifest: []
|
|
1777
|
-
categories:
|
|
1778
|
-
- category: release-integrity
|
|
1779
|
-
baseline: 9.2
|
|
1780
|
-
claim: "canary"
|
|
1781
|
-
closing_path: "canary"
|
|
1782
|
-
mechanism_evidence: ["src/scripts/check_score_contract.ts"]
|
|
1783
|
-
adoption_evidence: ["src/scripts/check_score_contract.ts"]
|
|
1784
|
-
negative_control_evidence: []
|
|
1785
|
-
production_window: src/scripts/check_score_contract.ts
|
|
1786
|
-
outcome_evidence: ["src/scripts/check_score_contract.ts"]
|
|
1787
|
-
non_regression_evidence: ["src/scripts/check_score_contract.ts"]
|
|
1788
|
-
status: ten
|
|
1958
|
+
no_canary_reason: >-
|
|
1959
|
+
Create-only canary cannot reach this corpus. Measured 2026-08-26: the row
|
|
1960
|
+
declared one, and `check_gate_coverage --canary` reported the gate DEAD —
|
|
1961
|
+
it stayed green over the plant. The gate is not dead; the recipe was
|
|
1962
|
+
unreachable. `check_score_contract` reads ONE file (`DEFAULT_REL`, or
|
|
1963
|
+
`--file`), so a newly created `ac-capability-scorecard-zz-canary.yaml`
|
|
1964
|
+
sits outside the corpus by construction and the gate correctly ignores it.
|
|
1965
|
+
Same class as `check_no_automerge_key` and `check_condensation`: the only
|
|
1966
|
+
violation this gate can have is a MODIFICATION of the one tracked
|
|
1967
|
+
scorecard, which a create-only canary cannot express. Discrimination is
|
|
1968
|
+
proven instead by the gate's own `--self-test` (8 cases, 6 of them
|
|
1969
|
+
pointing at the committed twins under `tests/fixtures/score-contract/twins/`)
|
|
1970
|
+
and by `tests/scripts/check_score_contract.test.ts`, which asserts each
|
|
1971
|
+
twin reds on exactly one finding CODE rather than merely on a non-zero exit.
|
|
1789
1972
|
note: >
|
|
1790
1973
|
The floor is 20 against a live corpus of 23, and the gap is deliberately
|
|
1791
1974
|
narrow because this corpus does not grow by ordinary work: a row is added
|
|
@@ -1805,3 +1988,486 @@ gates:
|
|
|
1805
1988
|
`tests/scripts/check_score_contract.test.ts` asserts each reds on exactly
|
|
1806
1989
|
one finding CODE — not merely on a non-zero exit, which would let a twin
|
|
1807
1990
|
keep passing while testing the wrong defect.
|
|
1991
|
+
- id: check_beta_review_markers
|
|
1992
|
+
argv: []
|
|
1993
|
+
min_scanned: 100
|
|
1994
|
+
corpus: "every `stability: beta` contract under docs/contracts/ — 121 at the time this row landed. The floor sits at 100 because the beta population shrinks as contracts promote to stable, so a slow decline is expected and a drop below 100 is a scan-root collapse rather than a promotion wave."
|
|
1995
|
+
status: enforced
|
|
1996
|
+
canary:
|
|
1997
|
+
class: contract-violation
|
|
1998
|
+
path: docs/contracts/zz-canary-beta-lapse.md
|
|
1999
|
+
content: |
|
|
2000
|
+
---
|
|
2001
|
+
stability: beta
|
|
2002
|
+
keep-beta-until: 2026-01-01
|
|
2003
|
+
---
|
|
2004
|
+
|
|
2005
|
+
# ZZ canary — a beta contract whose review deadline lapsed
|
|
2006
|
+
|
|
2007
|
+
Planted by `check_gate_coverage --canary`; never ships. The date is far
|
|
2008
|
+
in the past, so this is a FRESH lapse rather than one inside the frozen
|
|
2009
|
+
2026-08-25 baseline — the distinction is the whole point of the gate,
|
|
2010
|
+
because an inherited lapse warns and a new one must fail.
|
|
2011
|
+
- id: lint_canonical_terms
|
|
2012
|
+
argv: []
|
|
2013
|
+
min_scanned: 1200
|
|
2014
|
+
corpus: "every markdown file under src/ and docs/, tracked and untracked. 1,577 exist in the shipped tree; the floor sits at 1,200 so a legitimate documentation prune cannot red it while a scan-root collapse still can. Untracked files are IN the corpus deliberately — the canary below is create-only by contract, so a tracked-only listing would leave the gate green on its own canary."
|
|
2015
|
+
status: enforced
|
|
2016
|
+
canary:
|
|
2017
|
+
class: contract-violation
|
|
2018
|
+
path: src/skills/zz-canary-canonical-terms/SKILL.md
|
|
2019
|
+
content: |
|
|
2020
|
+
---
|
|
2021
|
+
name: zz-canary-canonical-terms
|
|
2022
|
+
description: Canary planted by check_gate_coverage --canary; never ships.
|
|
2023
|
+
---
|
|
2024
|
+
|
|
2025
|
+
# Canary
|
|
2026
|
+
|
|
2027
|
+
This sentence describes the observed behaviour of an artifact, in prose,
|
|
2028
|
+
outside any fence — two non-canonical spellings the house dialect
|
|
2029
|
+
recorded in `src/config/canonical-terms.yml` decided against. The gate
|
|
2030
|
+
must red on it, because a ratchet that cannot see a NEW occurrence is a
|
|
2031
|
+
ratchet that only records history.
|
|
2032
|
+
- id: lint_host_portability
|
|
2033
|
+
argv: []
|
|
2034
|
+
min_scanned: 600
|
|
2035
|
+
corpus: "every .md under src/skills, src/agent-src, src/domains and src/subagents — 717 today. The floor sits at 600 because the artifact estate only grows by ordinary work and a reading below it means a scan root moved, not that 117 artifacts were deleted."
|
|
2036
|
+
status: enforced
|
|
2037
|
+
canary:
|
|
2038
|
+
class: contract-violation
|
|
2039
|
+
path: src/skills/zz-canary-host-portability/SKILL.md
|
|
2040
|
+
content: |
|
|
2041
|
+
---
|
|
2042
|
+
name: zz-canary-host-portability
|
|
2043
|
+
description: Canary planted by check_gate_coverage --canary; never ships.
|
|
2044
|
+
execution:
|
|
2045
|
+
type: assisted
|
|
2046
|
+
handler: internal
|
|
2047
|
+
allowed_tools: ["FileWriterTool"]
|
|
2048
|
+
---
|
|
2049
|
+
|
|
2050
|
+
# Canary
|
|
2051
|
+
|
|
2052
|
+
The grant above names a tool no host in this tree is known to honour. A
|
|
2053
|
+
loader IGNORES an unrecognised key, so this artifact reads as restricted
|
|
2054
|
+
and is not — which is the whole defect class the gate exists to refuse.
|
|
2055
|
+
- id: check_host_loadability
|
|
2056
|
+
argv: ["--reach", "--root", "."]
|
|
2057
|
+
min_scanned: 6
|
|
2058
|
+
corpus: "the six host surfaces in HOST_SURFACES (claude-code, cursor, cline, windsurf, gemini-cli, copilot). The floor is the full set rather than a fraction: the surface list is a committed constant, so a reading below 6 means a row was dropped from the constant, never that a projection is legitimately smaller. An ABSENT host tool is a ledger SKIP with its detection signal named, not a missing row."
|
|
2059
|
+
status: enforced
|
|
2060
|
+
no_canary_reason: "Create-only canary cannot reach this corpus, and the reason is structural rather than incidental. The corpus is a committed CONSTANT (HOST_SURFACES in _lib/host_projection_reach.ts), so a planted FILE lands in no row: the six rows exist whatever the filesystem holds. The violation this gate can have is an installed host tool whose projection directory is EMPTY \u2014 a state a create-only plant is the opposite of. Discrimination is proven instead by the measurement itself, which reports 6/6 present and projecting with per-host artifact counts (claude-code 13, cursor 228, cline 14, windsurf 215, gemini-cli 1, copilot 1); a dead projection reads as `empty-projection` and a missing tool as `skipped-tool-absent`, and those two verdicts being DIFFERENT is the whole point of the mode."
|
|
2061
|
+
argv_note: "The `--reach` argv, not the default. The default mode checks that two projections PARSE and emits no coverage line; reach accounts for every host surface and is the mode that carries a corpus. Registered on the argv that emits, per this manifest\u0027s own CI-identical-argv rule \u2014 and note that `--reach` is declared LOCAL-ONLY in ci-local-parity.yml, because a CI runner has no host tool installed and every row would resolve `skipped-tool-absent`, which is the empty-scope false green this manifest exists to refuse."
|
|
2062
|
+
- id: lint_eval_specs
|
|
2063
|
+
argv: []
|
|
2064
|
+
min_scanned: 120
|
|
2065
|
+
corpus: "every eval specification under src/skills/*/evals/, src/domains/*/evals/ and src/agent-src/commands/evals/ — 175 at the time this row landed. The floor sits at 120 because the corpus grows as skills gain evals and shrinks only when a skill is archived; a drop below 120 is a scan-root collapse rather than a pruning wave."
|
|
2066
|
+
status: enforced
|
|
2067
|
+
canary:
|
|
2068
|
+
class: contract-violation
|
|
2069
|
+
path: src/skills/zz-canary-eval-specs/evals/evals.json
|
|
2070
|
+
content: |
|
|
2071
|
+
{
|
|
2072
|
+
"skill": "zz-canary-eval-specs",
|
|
2073
|
+
"scenarios": [
|
|
2074
|
+
{ "id": "x", "prompt": "planted by check_gate_coverage --canary; never ships", "assertions": [{ "kind": "tool-choice" }] }
|
|
2075
|
+
]
|
|
2076
|
+
}
|
|
2077
|
+
- id: lint_memory_twin_parity
|
|
2078
|
+
argv: []
|
|
2079
|
+
min_scanned: 7
|
|
2080
|
+
corpus: "the twins declared in src/config/memory-twin-verdicts.yml — 7 today. The floor is the exact count rather than a lower bound: this list does not grow by ordinary work (a twin is added only when a script is duplicated into the template tree, which is a deliberate act), and a DROP means a verdict was deleted rather than earned. A new twin raises the floor in the same commit."
|
|
2081
|
+
status: enforced
|
|
2082
|
+
no_canary_reason: >-
|
|
2083
|
+
Create-only canary cannot reach this corpus. The gate's population is the
|
|
2084
|
+
`twins:` list inside one tracked config file, and every violation it can
|
|
2085
|
+
have is a MODIFICATION — a twin drifting, a verdict deleted, a ceiling
|
|
2086
|
+
exceeded. A newly created file lands outside the list by construction and
|
|
2087
|
+
the gate correctly ignores it. Same class as `check_no_automerge_key`,
|
|
2088
|
+
`check_condensation` and `check_ci_local_parity`. Discrimination is proven
|
|
2089
|
+
instead by the gate's own `--self-test`: 5 cases, 3 rejecting, including
|
|
2090
|
+
the two states the roadmap's verify clause names by hand — a one-line
|
|
2091
|
+
behavioural divergence must RED, and a comment-only divergence must stay
|
|
2092
|
+
GREEN.
|
|
2093
|
+
- id: lint_skill_link_reach
|
|
2094
|
+
argv: []
|
|
2095
|
+
min_scanned: 200
|
|
2096
|
+
corpus: "every skill directory under dist/agent-src/skills — the tree the installer deploys. 299 at the time this row landed, and the floor sits at 200 because the delivered set shrinks when a skill is archived and a scoped projection can legitimately deliver fewer, while a reading below 200 means the projection is broken rather than smaller."
|
|
2097
|
+
status: enforced
|
|
2098
|
+
canary:
|
|
2099
|
+
class: contract-violation
|
|
2100
|
+
path: dist/agent-src/skills/zz-canary-link-reach/SKILL.md
|
|
2101
|
+
content: |
|
|
2102
|
+
---
|
|
2103
|
+
name: zz-canary-link-reach
|
|
2104
|
+
description: Canary planted by check_gate_coverage --canary; never ships.
|
|
2105
|
+
---
|
|
2106
|
+
|
|
2107
|
+
# Canary
|
|
2108
|
+
|
|
2109
|
+
This body links to [a skill that is not delivered](../zz-canary-absent-target/SKILL.md).
|
|
2110
|
+
The gate must red on it: a consumer following that link gets a 404, and a
|
|
2111
|
+
link checker that reads only `src/` cannot see the difference between a
|
|
2112
|
+
missing file and a file that exists but did not ship.
|
|
2113
|
+
- id: lint_composition_review
|
|
2114
|
+
argv: []
|
|
2115
|
+
min_scanned: 380
|
|
2116
|
+
corpus: "the skill + rule corpus — every src/skills/*/SKILL.md and src/rules/*.md (419 at baseline: 299 skills + 120 rules)"
|
|
2117
|
+
status: enforced
|
|
2118
|
+
canary:
|
|
2119
|
+
class: contract-violation
|
|
2120
|
+
path: src/rules/__canary_composition_review__.md
|
|
2121
|
+
content: |
|
|
2122
|
+
---
|
|
2123
|
+
name: __canary_composition_review__
|
|
2124
|
+
composition_review:
|
|
2125
|
+
- candidate: rule:this-rule-does-not-exist
|
|
2126
|
+
disposition: create_separate
|
|
2127
|
+
rationale: a canary record naming an incumbent that is not in the tree
|
|
2128
|
+
---
|
|
2129
|
+
|
|
2130
|
+
# canary
|
|
2131
|
+
note: >
|
|
2132
|
+
road-to-composition-before-creation Phase 4.1. Two halves with different
|
|
2133
|
+
teeth, on purpose. The STRUCTURAL half is hard: a present record whose
|
|
2134
|
+
candidate resolves to nothing, whose `none`/`none_found` pair disagrees,
|
|
2135
|
+
whose disposition is off-enum, which repeats a candidate, which is empty,
|
|
2136
|
+
or which uses a YAML block scalar, exits 1. The PRESENCE half is advisory
|
|
2137
|
+
and exits 0: an artifact added without a record is reported by path and
|
|
2138
|
+
never blocks. Flipping that to a block needs a false-positive rate from at
|
|
2139
|
+
least one release of advisory operation, which the roadmap records as not
|
|
2140
|
+
yet measured and does not pre-authorise.
|
|
2141
|
+
|
|
2142
|
+
WHAT IT CERTIFIES, narrowed after an independent review (2 seats, both
|
|
2143
|
+
raising it): REFERENTIAL CONSISTENCY, never that a search happened. An
|
|
2144
|
+
author can name any existing artifact, write `create_separate` and a
|
|
2145
|
+
sixteen-character rationale, and pass. The earlier wording here said a
|
|
2146
|
+
record pointing at a non-existent incumbent "reads as evidence of a search
|
|
2147
|
+
that cannot have happened", which reads as a claim about the search — it is
|
|
2148
|
+
not one, and the module docstring makes the same narrowing. What the hard
|
|
2149
|
+
half buys is that a record cannot point at nothing; whether it points at
|
|
2150
|
+
the RIGHT thing is a reviewer's judgement, and the roadmap's own Risk 1 is
|
|
2151
|
+
that the field becomes a pro-forma line.
|
|
2152
|
+
|
|
2153
|
+
DISCRIMINATION is carried by `--self-test` (8 cases, 5 rejecting), not by
|
|
2154
|
+
the canary. The canary is one create-only recipe by design and exercises
|
|
2155
|
+
the unresolvable-candidate door only; the other five hard doors and the
|
|
2156
|
+
advisory path are covered by the self-test and by
|
|
2157
|
+
tests/scripts/lint_composition_review.test.ts, including a real-git
|
|
2158
|
+
fixture for the untracked-addition union.
|
|
2159
|
+
|
|
2160
|
+
COMPATIBILITY: this is a new HARD whole-corpus gate, so a pre-existing
|
|
2161
|
+
malformed record anywhere in the tree would fail every later PR. Measured
|
|
2162
|
+
at landing: 419 artifacts scanned, 0 records malformed, because zero
|
|
2163
|
+
artifacts carry the field at all — the hard half can only fire on a record
|
|
2164
|
+
that EXISTS, so a corpus with none cannot fail it. The first record written
|
|
2165
|
+
is the first thing that can.
|
|
2166
|
+
|
|
2167
|
+
`{{.QUIET_FLAG}}` in the taskfile against `argv: []` here: `--quiet`
|
|
2168
|
+
suppresses per-finding lines only. Verified — `scanned: 419` and the exit
|
|
2169
|
+
code are byte-identical with and without it, so the coverage measurement
|
|
2170
|
+
and the CI invocation cannot diverge.
|
|
2171
|
+
|
|
2172
|
+
The floor is 380 against a live 419 — room for real deletions, far above
|
|
2173
|
+
a collapse. The corpus is the whole estate rather than the diff precisely
|
|
2174
|
+
so the floor can be honest: `lint_evidence_artifacts` declines
|
|
2175
|
+
registration here because a diff-scoped gate legitimately scans 0, and
|
|
2176
|
+
this gate narrows to the diff only for the advisory half.
|
|
2177
|
+
|
|
2178
|
+
- id: check_prefix_stable_mutation
|
|
2179
|
+
argv: []
|
|
2180
|
+
min_scanned: 35
|
|
2181
|
+
corpus: "hook-manifest concerns bound on at least one mid-session slot, whose script exists (45 at baseline, across 45 mid-session concerns)"
|
|
2182
|
+
status: enforced
|
|
2183
|
+
canary:
|
|
2184
|
+
class: contract-violation
|
|
2185
|
+
path: src/scripts/__canary_prefix_stable__.ts
|
|
2186
|
+
content: |
|
|
2187
|
+
// A canary hook that writes a prefix-stable surface mid-session.
|
|
2188
|
+
// The gate reads the MANIFEST, so this file alone cannot trip it —
|
|
2189
|
+
// which is why DISCRIMINATION is carried by --self-test, not here.
|
|
2190
|
+
import * as fs from 'node:fs';
|
|
2191
|
+
fs.writeFileSync('dist/agent-src/rules/__canary__.md', 'x');
|
|
2192
|
+
note: >
|
|
2193
|
+
road-to-runtime-context-floors step 1.2 — the RUNTIME half of prefix
|
|
2194
|
+
stability. `check_kernel_prefix_stability` guards the kernel prefix at
|
|
2195
|
+
authoring time against a committed snapshot, and `_lib/payload_hash_drift`
|
|
2196
|
+
measures churn after the fact from an audit ledger; neither can see a hook
|
|
2197
|
+
rewriting a prefix-stable surface DURING a session, which invalidates the
|
|
2198
|
+
prompt cache for the rest of it.
|
|
2199
|
+
|
|
2200
|
+
THE SURFACE LIST IS LOADED, NOT RESTATED. Both this gate and
|
|
2201
|
+
`check_preamble_payload_budget` import `PREFIX_STABLE_SURFACES` from
|
|
2202
|
+
`_lib/prefix_stable_surfaces.ts`. That refactor is part of the same change:
|
|
2203
|
+
the budget gate previously stated its three roots twice inside its own
|
|
2204
|
+
file, and a third statement here would be the drift shape this repository
|
|
2205
|
+
already pays for elsewhere.
|
|
2206
|
+
|
|
2207
|
+
DISCRIMINATION is carried by `--self-test` (7 cases, 2 rejecting), NOT by
|
|
2208
|
+
the canary. The gate's corpus is the hook manifest, so a planted script
|
|
2209
|
+
that no manifest binds is invisible to it by construction — the canary
|
|
2210
|
+
above documents the violating SHAPE for a reader and is honestly not the
|
|
2211
|
+
discriminator. The self-test plants a manifest as well as a script, which
|
|
2212
|
+
is what actually proves the red path: a fixture concern on `post_tool_use`
|
|
2213
|
+
writing `dist/agent-src/rules/` fails, and the same concern with
|
|
2214
|
+
`re_arm: pre_compact` passes.
|
|
2215
|
+
|
|
2216
|
+
FAIL-CLOSED on an undecidable target, per the council that resolved
|
|
2217
|
+
`which-surfaces-are-prefix-stable` (2026-08-28, 2/2): a write whose target
|
|
2218
|
+
is computed at runtime, in a file that ALSO carries a literal resolving
|
|
2219
|
+
into a declared surface, fails. Narrow on purpose — a dynamic write in a
|
|
2220
|
+
file with no such literal is not reported, because a gate that flagged
|
|
2221
|
+
every dynamic write in every hook is one nobody can keep green.
|
|
2222
|
+
|
|
2223
|
+
The floor is 35 against a live 45: room for real concern deletions, far
|
|
2224
|
+
above a collapse. `{{.QUIET_FLAG}}` against `argv: []` is safe here —
|
|
2225
|
+
`--quiet` suppresses only the success line, and `scanned:` is emitted
|
|
2226
|
+
outside that guard.
|
|
2227
|
+
|
|
2228
|
+
- id: check_loss_class_declared
|
|
2229
|
+
argv: []
|
|
2230
|
+
min_scanned: 45
|
|
2231
|
+
corpus: "every hook-manifest concern whose script exists (53 at baseline); of those, the model-facing lossy subset is the gated population"
|
|
2232
|
+
status: enforced
|
|
2233
|
+
canary:
|
|
2234
|
+
class: contract-violation
|
|
2235
|
+
path: src/scripts/__canary_loss_class__.ts
|
|
2236
|
+
content: |
|
|
2237
|
+
// A model-facing lossy transform with no loss_class declaration.
|
|
2238
|
+
// As with the sibling gate, the manifest is the corpus, so the
|
|
2239
|
+
// discriminator is --self-test rather than this plant.
|
|
2240
|
+
const WORD_CAP = 400;
|
|
2241
|
+
export function run() {
|
|
2242
|
+
return { context: redactLines(body).slice(0, WORD_CAP).join('\n') };
|
|
2243
|
+
}
|
|
2244
|
+
note: >
|
|
2245
|
+
road-to-runtime-context-floors step 3.2. Strictness was decided, not
|
|
2246
|
+
assumed: council 2026-08-28 (2/2 convergent) resolved
|
|
2247
|
+
`how-strict-the-loss-class-lint-is` as option (b) — FAIL on transforms
|
|
2248
|
+
whose output reaches the model, WARN elsewhere. Option (a) (fail
|
|
2249
|
+
everywhere in `src/`) buys a first-run backlog whose usual answer is a
|
|
2250
|
+
broad allowlist, which this repository has measured emptying a gate;
|
|
2251
|
+
option (c) (warn everywhere, ratchet later) is the shape this repository
|
|
2252
|
+
has measurably never ratcheted. Both seats added the refinement adopted
|
|
2253
|
+
here: unknown reachability is classified as model-reaching.
|
|
2254
|
+
|
|
2255
|
+
MEASURED AT LANDING: **1** module qualifies — `hot_context_hook`, which is
|
|
2256
|
+
exactly the `ephemeral-lossy` exemplar `docs/contracts/loss-classes.md`
|
|
2257
|
+
classifies. A gated population of one is the honest state of this tree,
|
|
2258
|
+
not a broken detector, and it is why the floor below is set on the SCANNED
|
|
2259
|
+
corpus (53 hook scripts) rather than on the gated subset.
|
|
2260
|
+
|
|
2261
|
+
THE DETECTOR READS CODE, NOT PROSE. Its first cut matched `truncat` inside
|
|
2262
|
+
three docblocks that describe truncation without performing any and
|
|
2263
|
+
reported a corpus of four; three of those four were comments. Comments are
|
|
2264
|
+
stripped before matching, and one self-test case pins that direction
|
|
2265
|
+
("prose about truncation is not truncation"), because a gate that fires on
|
|
2266
|
+
writing about a defect is how a real corpus of one becomes a pro-forma
|
|
2267
|
+
corpus of four.
|
|
2268
|
+
|
|
2269
|
+
DISCRIMINATION: `--self-test`, 8 cases, 3 rejecting — including the two
|
|
2270
|
+
that matter beyond "missing declaration": a `recoverable-lossy` with no
|
|
2271
|
+
`loss_recovery` locator (without it the class is indistinguishable from
|
|
2272
|
+
`ephemeral-lossy`) and a misspelled class name.
|
|
2273
|
+
|
|
2274
|
+
- id: check_benchmark_report_fields
|
|
2275
|
+
argv: []
|
|
2276
|
+
min_scanned: 4
|
|
2277
|
+
corpus: "committed benchmark reports under internal/bench/reports/ that announce a schema_version and a corpus/selection block (6 at baseline)"
|
|
2278
|
+
status: enforced
|
|
2279
|
+
canary:
|
|
2280
|
+
class: contract-violation
|
|
2281
|
+
path: internal/bench/reports/__canary_missing_cache__.json
|
|
2282
|
+
content: |
|
|
2283
|
+
{
|
|
2284
|
+
"schema_version": 1,
|
|
2285
|
+
"corpus": { "id": "__canary__" },
|
|
2286
|
+
"selection": { "top_k": 3 }
|
|
2287
|
+
}
|
|
2288
|
+
note: >
|
|
2289
|
+
road-to-runtime-context-floors step 4.1. `cache.read_write_ratio` and
|
|
2290
|
+
`cache.stable_prefix_share` are REQUIRED fields; a report that cannot
|
|
2291
|
+
compute one emits `{ unavailable: "<reason>" }` rather than omitting the
|
|
2292
|
+
key or emitting a zero. A blank reads as "no cache activity" and a zero
|
|
2293
|
+
reads as "the worst possible ratio" — both are claims, and neither is the
|
|
2294
|
+
claim "this was not measured".
|
|
2295
|
+
|
|
2296
|
+
The canary IS the discriminator here, unlike its two siblings: this gate's
|
|
2297
|
+
corpus is a directory of files, so a planted report is genuinely in scope
|
|
2298
|
+
and a create-only plant exercises the real red path. `--self-test` adds 7
|
|
2299
|
+
cases (5 rejecting) covering the forms a plant cannot reach — a blank
|
|
2300
|
+
`unavailable` reason, and a share above 1.
|
|
2301
|
+
|
|
2302
|
+
COMPATIBILITY: six committed reports predate the requirement, and all six
|
|
2303
|
+
were backfilled in the landing change with a stated reason rather than a
|
|
2304
|
+
fabricated number — additively, 48 insertions and 0 deletions, so no
|
|
2305
|
+
historical measurement moved.
|
|
2306
|
+
|
|
2307
|
+
The floor is 4 against a live 6. `allowEmpty` is declared
|
|
2308
|
+
(`OPTIONAL_INPUT:`) because benchmark reports are run artefacts rather
|
|
2309
|
+
than source and a checkout may legitimately carry none; the floor applies
|
|
2310
|
+
whenever any are present.
|
|
2311
|
+
|
|
2312
|
+
- id: check_no_currency_in_cost_surfaces
|
|
2313
|
+
argv: []
|
|
2314
|
+
min_scanned: 4
|
|
2315
|
+
corpus: "the four cost surfaces road-to-delivered-cost-truth built (4 at baseline) — a named watchlist, not a tree walk"
|
|
2316
|
+
status: enforced
|
|
2317
|
+
canary:
|
|
2318
|
+
class: contract-violation
|
|
2319
|
+
path: src/scripts/__canary_currency__.ts
|
|
2320
|
+
content: |
|
|
2321
|
+
// A planted file is NOT in this gate's corpus by construction — the
|
|
2322
|
+
// watchlist is four named files. Discrimination is --self-test's job.
|
|
2323
|
+
out.push(`total: $42`);
|
|
2324
|
+
note: >
|
|
2325
|
+
road-to-delivered-cost-truth AC-7. The suite does not know a consumer's
|
|
2326
|
+
contract — subscription, per-token, committed spend, a reseller rate — so
|
|
2327
|
+
any monetary figure it printed would be extrapolated from a rate it
|
|
2328
|
+
invented. That is worse than no number, because it is actionable and wrong,
|
|
2329
|
+
and it is exactly the thing someone reasonably adds back later on the
|
|
2330
|
+
grounds that a cost report should show cost.
|
|
2331
|
+
|
|
2332
|
+
SCOPE IS A NAMED LIST, NOT A PATTERN, and that is the load-bearing choice.
|
|
2333
|
+
`cache_realization_report` legitimately carries a `cost_usd` block for
|
|
2334
|
+
back-compat with downstream consumers; a gate sweeping `src/scripts/*cost*`
|
|
2335
|
+
would fail on it and be neutered with an allowlist inside a release. The
|
|
2336
|
+
watchlist is asserted by `assertWatchlistResolves`, so a renamed surface is
|
|
2337
|
+
a dead scope (exit 2) rather than a silent pass.
|
|
2338
|
+
|
|
2339
|
+
THE DETECTOR TOOK TWO CORRECTIONS, BOTH FROM ITS OWN SELF-TEST, and both
|
|
2340
|
+
are pinned as accepting cases so a future widening cannot reintroduce them:
|
|
2341
|
+
a bare `$` substring matches TEMPLATE INTERPOLATION (`${value}`), and
|
|
2342
|
+
excluding `${` alone still matched a REGEX END ANCHOR (`/\.md$/`). The
|
|
2343
|
+
shipped pattern is positive rather than subtractive — a currency `$` is
|
|
2344
|
+
followed by a digit or by an interpolated amount — because a gate whose
|
|
2345
|
+
first real run produces dozens of false positives gets an allowlist within
|
|
2346
|
+
a release and then guards nothing.
|
|
2347
|
+
|
|
2348
|
+
DISCRIMINATION: `--self-test`, 9 cases, 4 rejecting. The canary above
|
|
2349
|
+
documents the violating shape for a reader and is honestly NOT the
|
|
2350
|
+
discriminator, because a created file lands outside a four-name watchlist.
|
|
2351
|
+
|
|
2352
|
+
- id: lint_promotion_paths
|
|
2353
|
+
argv: ["--quiet"]
|
|
2354
|
+
min_scanned: 1800
|
|
2355
|
+
corpus: "every .ts file under src/ and tests/ (2812 at baseline). The floor is 1800, not 1: this gate's failure shape is a walk that stops at a renamed root or a skip-list that grows, and a partial walk certifies exactly the coverage it did not perform."
|
|
2356
|
+
status: enforced
|
|
2357
|
+
canary:
|
|
2358
|
+
class: contract-violation
|
|
2359
|
+
path: src/scripts/__canary_promotion_bypass__.ts
|
|
2360
|
+
content: |
|
|
2361
|
+
import { parseCandidateRecord } from './_lib/candidate_record.js';
|
|
2362
|
+
const promoted = { ...parseCandidateRecord, lifecycle: 'promoted' };
|
|
2363
|
+
fs.writeFileSync(path.join(REPO_ROOT, 'src', 'rules', 'x.md'), promoted);
|
|
2364
|
+
note: >
|
|
2365
|
+
road-to-harness-promotion-bridge — discharge route 1 of the carried
|
|
2366
|
+
blocking condition. The condition covers "a verb, a state transition into
|
|
2367
|
+
`promoted`, or any write into `src/` derived from a candidate", and the AI
|
|
2368
|
+
council of 2026-08-31 ruled it NOT DISCHARGED because only the first two
|
|
2369
|
+
were gated. This gate inventories all three limbs across the whole
|
|
2370
|
+
authored tree and fails when a promotion-capable write bypasses the single
|
|
2371
|
+
guarded capability in `src/scripts/_lib/promotion_capability.ts`.
|
|
2372
|
+
|
|
2373
|
+
THE CAPABILITY IS UNOBTAINABLE WHILE `blocker: merge-authority` IS OPEN,
|
|
2374
|
+
and R0 proves that by CALLING it rather than by reading it — a text match
|
|
2375
|
+
would pass over a refusal edited into a no-op. Sensitivity of R0 was
|
|
2376
|
+
observed: neutralising the refusal makes the gate red with
|
|
2377
|
+
"capability obtainable while the blocker is open".
|
|
2378
|
+
|
|
2379
|
+
ANTI-VACUITY IS THE POINT, not a bonus. The condition's own text says a
|
|
2380
|
+
check over a population of zero discharges nothing, so three floors are
|
|
2381
|
+
asserted separately — 400 files, 4 candidate-derived modules, 10
|
|
2382
|
+
filesystem-write sites inside them — each via `assertScanned`, each exiting
|
|
2383
|
+
2 rather than green. Live values at baseline: 2812 / 16 / 66.
|
|
2384
|
+
|
|
2385
|
+
THE CANARY IS A GENUINE DISCRIMINATOR here: the corpus is a tree walk, so
|
|
2386
|
+
a planted file is in scope and a create-only plant exercises the real red
|
|
2387
|
+
path on all three limbs at once. `--self-test` adds 15 cases (9 rejecting)
|
|
2388
|
+
covering the forms a single plant cannot reach — the interface-declaration
|
|
2389
|
+
accepting pole, a two-argument `assertTransition`, a candidate-derived
|
|
2390
|
+
write into a CLONE's `src/` (out of scope: a clone is a candidate's own
|
|
2391
|
+
sandbox, already gated by `bench_ab_integrity`'s allowed-delta-path check),
|
|
2392
|
+
a candidate-derived READ of `src/`, and prose in a block comment.
|
|
2393
|
+
|
|
2394
|
+
TWO DEFECTS WERE FOUND BY RUNNING IT, both pinned as cases: a substitution
|
|
2395
|
+
that rewrote identifiers INSIDE string literals (`cand` in `'ac-cand-'`),
|
|
2396
|
+
and an expansion that DESTROYED the `REPO_ROOT` token the rule keys on
|
|
2397
|
+
because `REPO_ROOT` is itself a `const`. The first produced a false
|
|
2398
|
+
positive on a tmpdir removal; the second silently dropped the R3 half of a
|
|
2399
|
+
planted three-limb bypass, which is the failure direction that matters.
|
|
2400
|
+
|
|
2401
|
+
- id: lint_code_comments
|
|
2402
|
+
argv: ["--base", "origin/main"]
|
|
2403
|
+
min_scanned: 0
|
|
2404
|
+
corpus: >
|
|
2405
|
+
the source files a change touches, measured against the base ref — a DIFF,
|
|
2406
|
+
not a tree walk. The floor is 0 deliberately: a docs-only or config-only
|
|
2407
|
+
change legitimately carries no source file, and a floor above 0 would red
|
|
2408
|
+
exactly those commits. The scan-scope failure this class exists to catch
|
|
2409
|
+
cannot occur here, because there is no committed path list that can go
|
|
2410
|
+
stale — the root is `git diff`, and git answers for its own range.
|
|
2411
|
+
status: enforced
|
|
2412
|
+
canary:
|
|
2413
|
+
class: contract-violation
|
|
2414
|
+
path: src/scripts/__canary_comment_discipline__.ts
|
|
2415
|
+
content: |
|
|
2416
|
+
// Hier stehen nur die Werte, die Bedeutung tragen und nicht mehr.
|
|
2417
|
+
export const canary = 1;
|
|
2418
|
+
note: >
|
|
2419
|
+
The carrier `code-comment-discipline` never had, and the one the "Code
|
|
2420
|
+
comments English" clause of `language-and-tone` claimed via a `.md`-only
|
|
2421
|
+
validator (`check_md_language.ts:175` rejects every other path).
|
|
2422
|
+
|
|
2423
|
+
THE CANARY IS A GENUINE DISCRIMINATOR: the corpus is a diff, a newly
|
|
2424
|
+
created file is in it by construction, and the planted content trips the
|
|
2425
|
+
`de-comment` class on two function words with no umlaut — the
|
|
2426
|
+
transliterated form the real incident was written in, not the easy case.
|
|
2427
|
+
|
|
2428
|
+
DISCRIMINATION IS ALSO PINNED BY FIXTURE, in both directions, because a
|
|
2429
|
+
language heuristic is only usable if its near-misses are known:
|
|
2430
|
+
`tests/scripts/lint_code_comments.test.ts` asserts silence on an umlauted
|
|
2431
|
+
proper name, a non-ASCII sample value inside a code span, a `Ü2` step
|
|
2432
|
+
label, and a German user quotation spanning two comment lines — the four
|
|
2433
|
+
shapes this repository's own hooks actually contain. Measured over 402
|
|
2434
|
+
source files here: zero findings. Measured over the 45 changed files of
|
|
2435
|
+
the consumer repository that prompted the gate: 530.
|
|
2436
|
+
|
|
2437
|
+
SENSITIVITY WAS OBSERVED, not assumed: neutralising the German predicate
|
|
2438
|
+
turns 4 of the 20 table cases red and restoring it turns them green. (The
|
|
2439
|
+
earlier wording said "4 of the 22" and described the inline vitest corpus
|
|
2440
|
+
that the fixture-table refactor replaced; a completion review caught the
|
|
2441
|
+
stale denominator.)
|
|
2442
|
+
|
|
2443
|
+
THE GATE ALSO CARRIES ITS OWN `--self-test` (20 cases, 11 rejecting),
|
|
2444
|
+
which drives the real binary rather than the imported classifier — argv
|
|
2445
|
+
parsing, scan-scope assertion and exit codes included. It does NOT reach a
|
|
2446
|
+
consumer checkout, and the earlier claim that it did was withdrawn after a
|
|
2447
|
+
completion review: `runGateCli` spawns `<repoRoot>/node_modules/.bin/tsx`
|
|
2448
|
+
and both `tsx` and `vitest` are devDependencies, `dist/scripts/` carries no
|
|
2449
|
+
compiled twin, and `scripts-run` is not in `files[]` — so where the suite
|
|
2450
|
+
is absent the self-test cannot run either, and where it runs the suite is
|
|
2451
|
+
present. What it buys is real and narrower: it exercises the CLI half that
|
|
2452
|
+
the vitest file cannot reach, and CI runs the gate only in diff mode,
|
|
2453
|
+
which exits 0 on an empty diff. It is ONE table, not a second corpus: the cases
|
|
2454
|
+
live in `COMMENT_CASES`, exported by the gate, and the vitest file
|
|
2455
|
+
enumerates the same export against `scanText` while the self-test
|
|
2456
|
+
enumerates it against the CLI. A second table over one classifier would
|
|
2457
|
+
drift, and the copy nobody runs locally drifts first. Floors are set at
|
|
2458
|
+
16/8 against a real 20/11, so deleting a case to reach green fails and a
|
|
2459
|
+
deliberate shrink shows up as a floor edit in the diff. Sensitivity
|
|
2460
|
+
re-observed on the self-test the same way: neutralising the German
|
|
2461
|
+
predicate turns exactly 4 of the 11 rejecting cases red (the three
|
|
2462
|
+
German-comment shapes and the reasonless escape) while the report and
|
|
2463
|
+
provenance cases stay green, and restoring it returns 20/20. The block-comment
|
|
2464
|
+
continuation and JSX cases arrived with the two blind spots fixed on
|
|
2465
|
+
`origin/main` and were folded into the same table on merge, so both surfaces
|
|
2466
|
+
cover them rather than the vitest file alone.
|
|
2467
|
+
|
|
2468
|
+
NOTE ON THE ADOPTION RATCHET, stated because the number does not move:
|
|
2469
|
+
`gate-self-test:registered-non-adopters` counts manifest rows that are
|
|
2470
|
+
`enforced` AND carry `min_scanned >= 1`. This row's floor is 0 for the
|
|
2471
|
+
reason the corpus field gives, so it was never in that population and
|
|
2472
|
+
the count stays at 24 either side of this change. The self-test is
|
|
2473
|
+
therefore adopted on its merits rather than to clear a ratchet.
|