@event4u/agent-config 14.12.0 → 14.13.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 +234 -0
- 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 +109 -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-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 +247 -3
- package/dist/agent-src/scripts/guarded_baseline.ts +328 -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 +400 -0
- package/dist/agent-src/scripts/ticket_bundles.ts +84 -0
- package/dist/agent-src/scripts/update_roadmap_progress.ts +8 -4
- 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 +42 -10
- 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 +57 -57
- 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 +1836 -712
- 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 +4818 -2645
- 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/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 +247 -3
- package/src/agent-src/scripts/guarded_baseline.ts +328 -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 +400 -0
- package/src/agent-src/scripts/ticket_bundles.ts +84 -0
- package/src/agent-src/scripts/update_roadmap_progress.ts +8 -4
- 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 +38 -36
- package/src/config/evaluator-budgets.json +14 -14
- package/src/config/gate-coverage.yml +579 -63
- package/src/config/gate-reachability-exemptions.json +21 -0
- package/src/config/gate-violation-baselines.json +37 -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 +8 -8
- 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 +126 -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 +27 -0
- package/src/scripts/_lib/activation_ladder.ts +211 -0
- package/src/scripts/_lib/activation_states.ts +88 -0
- package/src/scripts/_lib/adherence_detectors.ts +143 -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_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/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/council_settings_block.ts +6 -0
- package/src/scripts/_lib/curator_ops.ts +172 -0
- package/src/scripts/_lib/delivery_arm_experiment.ts +266 -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/eval_publication.ts +354 -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/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 +229 -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/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/prefix_stable_surfaces.ts +123 -0
- package/src/scripts/_lib/privacy_class.ts +47 -0
- package/src/scripts/_lib/regression_neighbourhood.ts +259 -0
- 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/runtime_journal.ts +1499 -0
- package/src/scripts/_lib/runtime_wiring_checks.ts +430 -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/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/disagreement_signal.ts +338 -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/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/response_record.ts +50 -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 +126 -0
- 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 +142 -1
- 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_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/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 +980 -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 +98 -11
- 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/concern_registry.ts +4 -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/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/lint_adr_sweep_routing.ts +12 -0
- package/src/scripts/lint_canonical_terms.ts +604 -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_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/mcp_server/consumer_tool_catalog.json +1 -1
- package/src/scripts/mcp_server/tool_catalog_source.ts +1 -1
- package/src/scripts/measure_docs_dead_links.ts +348 -0
- package/src/scripts/measure_host_capture.ts +461 -0
- package/src/scripts/migration_status.ts +3 -3
- package/src/scripts/model_rule_injection.ts +60 -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_turnaround.ts +384 -0
- package/src/scripts/probe_unblocked_ask.ts +279 -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,70 @@
|
|
|
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 ON A MERGE, 2026-08-30 — the fifth time, and the same shape as the
|
|
56
|
+
# 2026-08-26 blocks below: two sides each correct for their own tree (~24 % from
|
|
57
|
+
# the branch, ~25 % from main) meeting in one number. Recomputed rather than
|
|
58
|
+
# picked: `count_gate_scripts()` returns **306** and `grep -c '^ - id:'`
|
|
59
|
+
# returns **76** on the merged tree, so 76/306 = 24.8 % and main's side is the
|
|
60
|
+
# right one — arrived at by arithmetic, not by taking theirs.
|
|
61
|
+
#
|
|
62
|
+
# RECOUNTED ON A MERGE, 2026-08-26 — the fourth time this file has met the case
|
|
63
|
+
# the 2026-08-24 block below describes, and this one left TWO STACKED claim
|
|
64
|
+
# blocks rather than a conflict inside one number: 295/68 from this branch and
|
|
65
|
+
# 296/67 from main, each correct for its own tree. Collapsed to one recomputed
|
|
66
|
+
# block rather than reconciled by hand: `count_gate_scripts()` returns **296**
|
|
67
|
+
# and `grep -c '^ - id:'` returns **66** on the merged tree.
|
|
68
|
+
#
|
|
69
|
+
# 66 + 3 unlisted emitters (`lint_evidence_artifacts`, `adr_cite_check`,
|
|
70
|
+
# `check_new_adr_evidence`) = 69.
|
|
71
|
+
#
|
|
72
|
+
# RECOUNTED ON A MERGE, 2026-08-26, and the merge left TWO stacked header claims
|
|
73
|
+
# rather than a conflict inside one number — each branch had recounted correctly
|
|
74
|
+
# for its own tree, and keeping both sides produced a page asserting 294/62 and
|
|
75
|
+
# 295/64 four lines apart. Collapsed to one recomputed block: `count_gate_scripts()`
|
|
76
|
+
# returns **295** and `grep -c '^ - id:'` returns **64** on the merged tree.
|
|
77
|
+
#
|
|
78
|
+
# A paragraph that briefly stood here claimed the emitter total "cannot be
|
|
79
|
+
# derived by grep" and dropped it. That was true of the method it tried and
|
|
80
|
+
# wrong as a conclusion — every LISTED row is an emitter by construction (a row
|
|
81
|
+
# that did not emit could carry no floor) and the same three emitters remain
|
|
82
|
+
# deliberately unlisted, so 64 + 3 = 67. The figure is arithmetic over this
|
|
83
|
+
# file, not a grep over `src/scripts/`, and it is restored rather than left
|
|
84
|
+
# absent.
|
|
85
|
+
#
|
|
86
|
+
# RECOUNTED ON A MERGE, 2026-08-26 — the case the 2026-08-24 block below was
|
|
87
|
+
# written for, arriving again. Two branches each added one row and each recorded
|
|
88
|
+
# a correct population line for its own tree, so the merge put 293 and 294 side
|
|
89
|
+
# by side; after the merge both gates exist, so either figure describes a tree
|
|
90
|
+
# that no longer does. Recomputed on the merged tree rather than reconciled by
|
|
91
|
+
# hand: `count_gate_scripts()` returns **294** and `grep -c '^ - id:'` returns
|
|
92
|
+
# **63**.
|
|
93
|
+
#
|
|
94
|
+
# The emitter total moves with the listed count for the reason the 2026-08-25
|
|
95
|
+
# paragraph already states: every LISTED row is an emitter, because a row that
|
|
96
|
+
# did not emit could carry no floor, and the same three emitters remain
|
|
97
|
+
# deliberately unlisted (`lint_evidence_artifacts`, `adr_cite_check`,
|
|
98
|
+
# `check_new_adr_evidence`). 63 + 3 = 66.
|
|
99
|
+
#
|
|
100
|
+
# RECOUNTED on 2026-08-26 while adding `lint_canonical_terms`
|
|
101
|
+
# (road-to-canonical-terms 2.3). Recomputed, not adjusted — the two commands in
|
|
102
|
+
# the 2026-08-24 block below were re-run on this tree and returned 293 and 61.
|
|
103
|
+
# The population moved by TWO while one row was added, which is why the prose was
|
|
104
|
+
# not incremented by hand: a second gate script had arrived since the last count
|
|
105
|
+
# without a manifest row, and hand-arithmetic would have recorded 292 and been
|
|
106
|
+
# wrong in a way nobody could see.
|
|
54
107
|
#
|
|
55
108
|
# `description_route_check` is counted in the POPULATION and deliberately NOT
|
|
56
109
|
# listed: it is diff-scoped, so its natural reading on most trees is zero cases,
|
|
@@ -306,10 +359,38 @@
|
|
|
306
359
|
# in-place edit would need byte-exact restoration of a tracked file, and a canary
|
|
307
360
|
# that can corrupt the tree violates the never-ships rule it inherits. The
|
|
308
361
|
# consequence is a real gap — a gate whose only possible violation is a
|
|
309
|
-
# modification of an existing tracked
|
|
362
|
+
# modification of an existing tracked artifact (`check_condensation`, whose
|
|
310
363
|
# contract is `dist == rewrite(src)`; `check_ci_local_parity`, whose corpus is
|
|
311
364
|
# workflow files) carries no recipe and is reported UNPROVEN, never green.
|
|
312
365
|
gates:
|
|
366
|
+
- id: lint_metric_consumers
|
|
367
|
+
argv: ["--quiet"]
|
|
368
|
+
min_scanned: 5
|
|
369
|
+
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."
|
|
370
|
+
status: enforced
|
|
371
|
+
no_canary_reason: >-
|
|
372
|
+
A create-only canary cannot express this gate's violation. The corpus is
|
|
373
|
+
the `metrics:` list inside ONE tracked file, so a planted file lands in no
|
|
374
|
+
row; every violation it can have is a MODIFICATION — a field emptied, a
|
|
375
|
+
field replaced with boilerplate, an id duplicated. Same class as
|
|
376
|
+
`check_no_automerge_key` and `lint_memory_twin_parity`. Discrimination is
|
|
377
|
+
proven instead by the gate's own `--self-test`: 7 cases, 6 rejecting,
|
|
378
|
+
each driving the real CLI against a throwaway registry.
|
|
379
|
+
note: >
|
|
380
|
+
road-to-experience-loop-broadening step 0.3. Refuses a metric that does
|
|
381
|
+
not name its consumer, the decision it feeds, and what fails without it.
|
|
382
|
+
The third field is the falsifiable one: the first two are answerable for a
|
|
383
|
+
metric nobody needs, and if the honest answer to "what fails without it"
|
|
384
|
+
is nothing, the entry cannot be written. HONEST LIMIT, stated in the
|
|
385
|
+
gate's own docstring: it checks SHAPE, not truth — it makes the omission
|
|
386
|
+
impossible, not the answer correct, because telling a real consumer from a
|
|
387
|
+
plausible sentence is a review judgement no parser has.
|
|
388
|
+
- id: lint_consolidation_lineage
|
|
389
|
+
argv: []
|
|
390
|
+
min_scanned: 0
|
|
391
|
+
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."
|
|
392
|
+
status: enforced
|
|
393
|
+
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."
|
|
313
394
|
- id: lint_skill_trigger_corpus
|
|
314
395
|
argv: []
|
|
315
396
|
min_scanned: 70
|
|
@@ -406,7 +487,7 @@ gates:
|
|
|
406
487
|
per-class red observation lives in the gate's own `--self-test` (9 cases,
|
|
407
488
|
6 rejecting), which proves every class discriminates over a synthetic
|
|
408
489
|
payload with no pack run. Two of the four cannot be planted through the
|
|
409
|
-
register at all: `compiled-test-
|
|
490
|
+
register at all: `compiled-test-artifact` is excluded from the payload by
|
|
410
491
|
the `files[]` negations that fixed it, so a plant never ships and never
|
|
411
492
|
reds, and `source-map` needs 121 files in a BUILT tree.
|
|
412
493
|
|
|
@@ -461,7 +542,7 @@ gates:
|
|
|
461
542
|
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
543
|
status: enforced
|
|
463
544
|
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
|
|
545
|
+
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
546
|
|
|
466
547
|
- id: check_pack_passport_reconciliation
|
|
467
548
|
argv: []
|
|
@@ -821,7 +902,7 @@ gates:
|
|
|
821
902
|
- id: check_no_roadmap_refs
|
|
822
903
|
argv: []
|
|
823
904
|
min_scanned: 700
|
|
824
|
-
corpus: "stable
|
|
905
|
+
corpus: "stable artifacts across src/{rules,skills,agent-src/*} + docs/ + agents/settings/contexts (872 at baseline)"
|
|
825
906
|
status: enforced
|
|
826
907
|
canary:
|
|
827
908
|
class: stale-reference
|
|
@@ -829,7 +910,7 @@ gates:
|
|
|
829
910
|
content: |
|
|
830
911
|
---
|
|
831
912
|
type: auto
|
|
832
|
-
description: "Planted canary rule linking a stable
|
|
913
|
+
description: "Planted canary rule linking a stable artifact into the transient roadmap tree."
|
|
833
914
|
---
|
|
834
915
|
|
|
835
916
|
See [the plan](../../agents/roadmaps/road-to-nowhere.md) — the exact
|
|
@@ -837,7 +918,7 @@ gates:
|
|
|
837
918
|
note: >
|
|
838
919
|
Retargeted 2026-07-29 from the ADR-051-emptied tree. It had been enforcing the
|
|
839
920
|
no-roadmap-references rule for docs/ only while the rule + skill layer went
|
|
840
|
-
unscanned — 0 -> 872
|
|
921
|
+
unscanned — 0 -> 872 artifacts. No violation had slipped through (verified),
|
|
841
922
|
so this closed a latent gap, not a live breach.
|
|
842
923
|
|
|
843
924
|
- id: check_context_paths
|
|
@@ -921,7 +1002,7 @@ gates:
|
|
|
921
1002
|
silent-green found in the same sweep — the per-pack lint matrix, whose path was
|
|
922
1003
|
a double ADR-051 casualty and which exited 0 on an empty match across 17 CI
|
|
923
1004
|
shards — is NOT listed here because it was deleted rather than repaired
|
|
924
|
-
(skill_linter --all already covers all 429
|
|
1005
|
+
(skill_linter --all already covers all 429 artifacts in 0.5s).
|
|
925
1006
|
|
|
926
1007
|
|
|
927
1008
|
# ── Registered 2026-08-02 (road-to-renewal-foundation Phase 1) ───────────
|
|
@@ -965,7 +1046,7 @@ gates:
|
|
|
965
1046
|
corpus: "src/rules + src/skills + src/agent-src/commands + docs/guidelines .md (533 at baseline)"
|
|
966
1047
|
status: enforced
|
|
967
1048
|
no_canary_reason: >-
|
|
968
|
-
thresholds are computed across the whole corpus; a single planted
|
|
1049
|
+
thresholds are computed across the whole corpus; a single planted artifact has no population to exceed.
|
|
969
1050
|
note: >
|
|
970
1051
|
A collapse below the floor would mean the gate stopped reading the tree
|
|
971
1052
|
that states extraction thresholds, so a bare or diverging threshold
|
|
@@ -1071,10 +1152,45 @@ gates:
|
|
|
1071
1152
|
or if a drop to 0 is ever traced to a scanner defect rather than to an
|
|
1072
1153
|
empty corpus.
|
|
1073
1154
|
|
|
1155
|
+
- id: check_gate_reachability
|
|
1156
|
+
script: src/scripts/check_gate_reachability.ts
|
|
1157
|
+
min_scanned: 10
|
|
1158
|
+
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."
|
|
1159
|
+
status: enforced
|
|
1160
|
+
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."
|
|
1161
|
+
|
|
1162
|
+
# road-to-retired-claims-stay-retired 2.3. The gate was NOT in this manifest
|
|
1163
|
+
# before that roadmap widened it: it asserted its scope with plain
|
|
1164
|
+
# `assertScanned` and published no machine-readable count, so
|
|
1165
|
+
# check_gate_coverage could not see it at all. Widening it to read the
|
|
1166
|
+
# publish-surface set is exactly the moment that becomes indefensible — a
|
|
1167
|
+
# gate that now decides what may ship on npm should not be the one gate
|
|
1168
|
+
# nobody counts.
|
|
1169
|
+
- id: check_claims
|
|
1170
|
+
argv: []
|
|
1171
|
+
min_scanned: 60
|
|
1172
|
+
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."
|
|
1173
|
+
status: enforced
|
|
1174
|
+
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."
|
|
1175
|
+
|
|
1176
|
+
- id: check_rule_evidence_declaration
|
|
1177
|
+
argv: []
|
|
1178
|
+
min_scanned: 10
|
|
1179
|
+
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."
|
|
1180
|
+
status: enforced
|
|
1181
|
+
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."
|
|
1182
|
+
|
|
1183
|
+
- id: check_concern_admissions
|
|
1184
|
+
script: src/scripts/check_concern_admissions.ts
|
|
1185
|
+
min_scanned: 0
|
|
1186
|
+
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."
|
|
1187
|
+
status: enforced
|
|
1188
|
+
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."
|
|
1189
|
+
|
|
1074
1190
|
- id: check_estate_count
|
|
1075
1191
|
argv: []
|
|
1076
1192
|
min_scanned: 20
|
|
1077
|
-
corpus: "active + parked roadmap files (81 at baseline: 38 active, 43 in later/)"
|
|
1193
|
+
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
1194
|
status: enforced
|
|
1079
1195
|
canary:
|
|
1080
1196
|
class: contract-violation
|
|
@@ -1099,17 +1215,45 @@ gates:
|
|
|
1099
1215
|
cannot survive a collapse: at that point the gate's own `reportScanned`
|
|
1100
1216
|
fires first. (Set to 50 in the first version, corrected on an R2 finding.)
|
|
1101
1217
|
|
|
1218
|
+
- id: check_static_parity
|
|
1219
|
+
argv: ["--quiet"]
|
|
1220
|
+
min_scanned: 20
|
|
1221
|
+
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."
|
|
1222
|
+
status: enforced
|
|
1223
|
+
no_canary_reason: >-
|
|
1224
|
+
No plantable violation: the gate's finding is a DIVERGENCE between two
|
|
1225
|
+
whole-suite runs, not a pattern in a file. Planting one would mean making
|
|
1226
|
+
the collector behave differently under the two runs, i.e. writing the bug
|
|
1227
|
+
it exists to detect.
|
|
1228
|
+
note: >
|
|
1229
|
+
road-to-supervised-telemetry-collector step 4.2 (AC-7). Runs the
|
|
1230
|
+
dispatcher-reaching suite twice — collector present-but-off, then aliased
|
|
1231
|
+
away entirely — and compares per-test verdicts rather than declaring each
|
|
1232
|
+
run green. Two green runs are not the assertion; a test that silently
|
|
1233
|
+
turns from `passed` to `skipped` keeps both suites green and only the
|
|
1234
|
+
per-test comparison sees it.
|
|
1235
|
+
|
|
1236
|
+
SELF-TEST EXEMPT, with the reason rather than the omission: a
|
|
1237
|
+
`--self-test` here would have to spawn two full vitest runs over a fixture
|
|
1238
|
+
repository, minutes per invocation, to prove a comparator that is already
|
|
1239
|
+
unit-tested with a REJECTING case —
|
|
1240
|
+
`tests/scripts/check_static_parity.test.ts` drives `compare()` through the
|
|
1241
|
+
`passed → skipped` divergence a length-only check would miss, plus both
|
|
1242
|
+
only-in-one-run directions. The discrimination is proven; what is skipped
|
|
1243
|
+
is proving it a second time through the slowest possible harness. The
|
|
1244
|
+
marker the self-test ratchet reads lives in the gate's own source, beside
|
|
1245
|
+
`main` — this note explains it; that line is what is counted.
|
|
1102
1246
|
- id: check_completion_review
|
|
1103
1247
|
argv: ["--advisory", "--base", "origin/main"]
|
|
1104
1248
|
min_scanned: 1
|
|
1105
|
-
corpus: "findings
|
|
1249
|
+
corpus: "findings artifacts under agents/evidence/reviews/ + the current-diff evaluation (1 at baseline — the evaluation itself; artifact count grows with gated PRs)"
|
|
1106
1250
|
status: enforced
|
|
1107
1251
|
no_canary_reason: >-
|
|
1108
1252
|
git-dependent: it evaluates the current diff against a base ref.
|
|
1109
1253
|
note: >
|
|
1110
1254
|
Gate R2 (docs/contracts/plan-review-gates.md § 2). HONEST LIMIT, stated
|
|
1111
1255
|
because a floor that cannot fail is exactly the false green this file
|
|
1112
|
-
exists to prevent: scanned =
|
|
1256
|
+
exists to prevent: scanned = artifacts inspected + 1 for the diff
|
|
1113
1257
|
evaluation, so on any run that REACHES the count `min_scanned: 1` cannot
|
|
1114
1258
|
trip. It is not unreachable in principle — a moved reviews root exits
|
|
1115
1259
|
before the inventory and reports `scanned: 0`, which the guard does read —
|
|
@@ -1141,7 +1285,7 @@ gates:
|
|
|
1141
1285
|
deleted, so a drop to 7 means the reviews root moved or the naming
|
|
1142
1286
|
convention drifted — not that the work went clean. That is precisely the
|
|
1143
1287
|
case rule 3 exists for. The gate reads the FROZEN records because R2
|
|
1144
|
-
selects only
|
|
1288
|
+
selects only artifacts in the CURRENT review scope, so a superseded round
|
|
1145
1289
|
renamed out of the `*.findings.md` glob is read by nothing at all — two
|
|
1146
1290
|
findings sat recorded as `open` in this repo's own corpus for a day
|
|
1147
1291
|
through exactly that gap.
|
|
@@ -1184,15 +1328,15 @@ gates:
|
|
|
1184
1328
|
collision gate across four roots at once; one planted name collides with nothing.
|
|
1185
1329
|
note: >
|
|
1186
1330
|
Counts NAMES, not files — the scan-scope census counts files under the same
|
|
1187
|
-
roots, so the two
|
|
1331
|
+
roots, so the two artifacts legitimately report different numbers here.
|
|
1188
1332
|
|
|
1189
1333
|
- id: lint_artefact_frontmatter
|
|
1190
1334
|
argv: ["--quiet"]
|
|
1191
1335
|
min_scanned: 540
|
|
1192
|
-
corpus: "
|
|
1336
|
+
corpus: "artifacts carrying frontmatter across the discovery roots (619 at baseline)"
|
|
1193
1337
|
status: enforced
|
|
1194
1338
|
no_canary_reason: >-
|
|
1195
|
-
a planted
|
|
1339
|
+
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
1340
|
|
|
1197
1341
|
- id: audit_skill_overlap
|
|
1198
1342
|
argv: ["--quiet", "--print-table", "--strict"]
|
|
@@ -1410,7 +1554,7 @@ gates:
|
|
|
1410
1554
|
note: >
|
|
1411
1555
|
The plant needs a slug that already carries a `prompt_hash` but no committed
|
|
1412
1556
|
package — a brand-new `zz-canary` slug is skipped, not caught, because an
|
|
1413
|
-
|
|
1557
|
+
artifact without a package is deliberately out of scope. `zcs-closure` is a
|
|
1414
1558
|
closed round, so it will not gain a real package and the plant cannot
|
|
1415
1559
|
collide with one. The two planted failures the roadmap asked for (a one-byte
|
|
1416
1560
|
prompt edit, a pre-loaded verdict) are pinned in
|
|
@@ -1469,7 +1613,7 @@ gates:
|
|
|
1469
1613
|
That case is the gate's own subject, so it is pinned by a test fixture
|
|
1470
1614
|
too (`a table that parses to zero rows reds rather than exiting green`).
|
|
1471
1615
|
No `canary:` recipe: this gate's only violation shape is a MODIFICATION of
|
|
1472
|
-
a tracked
|
|
1616
|
+
a tracked artifact (`docs/MIGRATION.md`), and the canary contract is
|
|
1473
1617
|
create-only, so it reports UNPROVEN rather than green. Discrimination is
|
|
1474
1618
|
proven instead by paired fixtures in
|
|
1475
1619
|
`tests/scripts/lint_scheduled_deprecations.test.ts`, verified by mutation:
|
|
@@ -1600,7 +1744,7 @@ gates:
|
|
|
1600
1744
|
# cmd_settings_check), forcing them into the ledger contract and reddening
|
|
1601
1745
|
# the completeness ratchet for work nobody asked for;
|
|
1602
1746
|
# - renaming the script to `check_adr_citations.ts` is the convention-conform
|
|
1603
|
-
# answer and touches 26 files, including archived review
|
|
1747
|
+
# answer and touches 26 files, including archived review artifacts and a
|
|
1604
1748
|
# committed diff.patch that must not be rewritten;
|
|
1605
1749
|
# - manifest-driven classification is explicitly rejected by
|
|
1606
1750
|
# gate_population.ts's own header (a new gate lands before anyone
|
|
@@ -1623,7 +1767,7 @@ gates:
|
|
|
1623
1767
|
the gate correctly stays green. Measured on a previous attempt, where the
|
|
1624
1768
|
gate was then mis-reported as dead. Same class as `check_condensation` and
|
|
1625
1769
|
`check_ci_local_parity` — the only possible violation is a modification of
|
|
1626
|
-
an existing tracked
|
|
1770
|
+
an existing tracked artifact. The red is proven instead by the committed
|
|
1627
1771
|
violating fixture `tests/fixtures/automerge-key/` plus two recorded
|
|
1628
1772
|
sabotage probes in `tests/scripts/check_no_automerge_key.test.ts`.
|
|
1629
1773
|
note: >
|
|
@@ -1632,7 +1776,7 @@ gates:
|
|
|
1632
1776
|
lands OUTSIDE the corpus and the gate correctly stays green — measured on a
|
|
1633
1777
|
previous attempt at this gate, where it was then mis-reported as dead. The
|
|
1634
1778
|
only violation this gate can have is a modification of an existing tracked
|
|
1635
|
-
|
|
1779
|
+
artifact, which is the same class as `check_condensation` and
|
|
1636
1780
|
`check_ci_local_parity`, and the CANARY section above already states that
|
|
1637
1781
|
such a gate carries no recipe and is reported UNPROVEN rather than green.
|
|
1638
1782
|
|
|
@@ -1750,42 +1894,54 @@ gates:
|
|
|
1750
1894
|
ADR whose dated record must not be rewritten, and a bare rule count with no
|
|
1751
1895
|
enforcement sense ("2 rules" in a concepts page) which must not be a finding.
|
|
1752
1896
|
|
|
1897
|
+
- id: check_supervision_claim_atomicity
|
|
1898
|
+
argv: []
|
|
1899
|
+
min_scanned: 6
|
|
1900
|
+
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"
|
|
1901
|
+
status: enforced
|
|
1902
|
+
no_canary_reason: >-
|
|
1903
|
+
A create-only canary cannot express this gate's violation. The corpus is a
|
|
1904
|
+
committed CONSTANT (`PUBLIC_SURFACES`), so a planted file lands in no row —
|
|
1905
|
+
the eight rows exist whatever the filesystem holds. The violation is a
|
|
1906
|
+
present-tense supervision claim appearing INSIDE one of those tracked
|
|
1907
|
+
pages, which is a modification. Same class as `check_score_contract`,
|
|
1908
|
+
`check_no_automerge_key` and `check_condensation`.
|
|
1909
|
+
Discrimination is proven instead by the gate's own `--self-test`, which is
|
|
1910
|
+
the step that created it: road-to-runtime-governance-flip 3.4 required
|
|
1911
|
+
seeded negatives to be OBSERVED red, not asserted. **7/7, 5 rejecting**,
|
|
1912
|
+
each building a throwaway git repo so the revision check is real and each
|
|
1913
|
+
driving the real CLI. The rejecting cases: no evidence at all; an emptied
|
|
1914
|
+
suite whose cases all skipped; a result recorded against a different
|
|
1915
|
+
revision; a suite that did not exercise real processes; and a non-integer
|
|
1916
|
+
case count. Two accepting controls: sufficient evidence lets the claim
|
|
1917
|
+
through, and a DENIAL of supervision needs no evidence at all.
|
|
1918
|
+
The refusals are separate because a suite that ran on a parent commit, one
|
|
1919
|
+
that skipped everything, and one that mocked the process layer are three
|
|
1920
|
+
different lies, and a file-presence check catches none of them.
|
|
1921
|
+
**Grown from 4/4 by a neutral council review of the code**, which found the
|
|
1922
|
+
docstring advertising a mocked-process negative the case list did not
|
|
1923
|
+
contain, and — worse — that the pattern matched `is NOT supervised`, so the
|
|
1924
|
+
gate would have refused a truthful denial. Both are closed with regression
|
|
1925
|
+
cases; the second is the `denial` accepting control above.
|
|
1753
1926
|
- id: check_score_contract
|
|
1754
1927
|
argv: ["--quiet"]
|
|
1755
1928
|
min_scanned: 20
|
|
1756
1929
|
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
1930
|
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
|
|
1931
|
+
no_canary_reason: >-
|
|
1932
|
+
Create-only canary cannot reach this corpus. Measured 2026-08-26: the row
|
|
1933
|
+
declared one, and `check_gate_coverage --canary` reported the gate DEAD —
|
|
1934
|
+
it stayed green over the plant. The gate is not dead; the recipe was
|
|
1935
|
+
unreachable. `check_score_contract` reads ONE file (`DEFAULT_REL`, or
|
|
1936
|
+
`--file`), so a newly created `ac-capability-scorecard-zz-canary.yaml`
|
|
1937
|
+
sits outside the corpus by construction and the gate correctly ignores it.
|
|
1938
|
+
Same class as `check_no_automerge_key` and `check_condensation`: the only
|
|
1939
|
+
violation this gate can have is a MODIFICATION of the one tracked
|
|
1940
|
+
scorecard, which a create-only canary cannot express. Discrimination is
|
|
1941
|
+
proven instead by the gate's own `--self-test` (8 cases, 6 of them
|
|
1942
|
+
pointing at the committed twins under `tests/fixtures/score-contract/twins/`)
|
|
1943
|
+
and by `tests/scripts/check_score_contract.test.ts`, which asserts each
|
|
1944
|
+
twin reds on exactly one finding CODE rather than merely on a non-zero exit.
|
|
1789
1945
|
note: >
|
|
1790
1946
|
The floor is 20 against a live corpus of 23, and the gap is deliberately
|
|
1791
1947
|
narrow because this corpus does not grow by ordinary work: a row is added
|
|
@@ -1805,3 +1961,363 @@ gates:
|
|
|
1805
1961
|
`tests/scripts/check_score_contract.test.ts` asserts each reds on exactly
|
|
1806
1962
|
one finding CODE — not merely on a non-zero exit, which would let a twin
|
|
1807
1963
|
keep passing while testing the wrong defect.
|
|
1964
|
+
- id: check_beta_review_markers
|
|
1965
|
+
argv: []
|
|
1966
|
+
min_scanned: 100
|
|
1967
|
+
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."
|
|
1968
|
+
status: enforced
|
|
1969
|
+
canary:
|
|
1970
|
+
class: contract-violation
|
|
1971
|
+
path: docs/contracts/zz-canary-beta-lapse.md
|
|
1972
|
+
content: |
|
|
1973
|
+
---
|
|
1974
|
+
stability: beta
|
|
1975
|
+
keep-beta-until: 2026-01-01
|
|
1976
|
+
---
|
|
1977
|
+
|
|
1978
|
+
# ZZ canary — a beta contract whose review deadline lapsed
|
|
1979
|
+
|
|
1980
|
+
Planted by `check_gate_coverage --canary`; never ships. The date is far
|
|
1981
|
+
in the past, so this is a FRESH lapse rather than one inside the frozen
|
|
1982
|
+
2026-08-25 baseline — the distinction is the whole point of the gate,
|
|
1983
|
+
because an inherited lapse warns and a new one must fail.
|
|
1984
|
+
- id: lint_canonical_terms
|
|
1985
|
+
argv: []
|
|
1986
|
+
min_scanned: 1200
|
|
1987
|
+
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."
|
|
1988
|
+
status: enforced
|
|
1989
|
+
canary:
|
|
1990
|
+
class: contract-violation
|
|
1991
|
+
path: src/skills/zz-canary-canonical-terms/SKILL.md
|
|
1992
|
+
content: |
|
|
1993
|
+
---
|
|
1994
|
+
name: zz-canary-canonical-terms
|
|
1995
|
+
description: Canary planted by check_gate_coverage --canary; never ships.
|
|
1996
|
+
---
|
|
1997
|
+
|
|
1998
|
+
# Canary
|
|
1999
|
+
|
|
2000
|
+
This sentence describes the observed behaviour of an artifact, in prose,
|
|
2001
|
+
outside any fence — two non-canonical spellings the house dialect
|
|
2002
|
+
recorded in `src/config/canonical-terms.yml` decided against. The gate
|
|
2003
|
+
must red on it, because a ratchet that cannot see a NEW occurrence is a
|
|
2004
|
+
ratchet that only records history.
|
|
2005
|
+
- id: lint_host_portability
|
|
2006
|
+
argv: []
|
|
2007
|
+
min_scanned: 600
|
|
2008
|
+
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."
|
|
2009
|
+
status: enforced
|
|
2010
|
+
canary:
|
|
2011
|
+
class: contract-violation
|
|
2012
|
+
path: src/skills/zz-canary-host-portability/SKILL.md
|
|
2013
|
+
content: |
|
|
2014
|
+
---
|
|
2015
|
+
name: zz-canary-host-portability
|
|
2016
|
+
description: Canary planted by check_gate_coverage --canary; never ships.
|
|
2017
|
+
execution:
|
|
2018
|
+
type: assisted
|
|
2019
|
+
handler: internal
|
|
2020
|
+
allowed_tools: ["FileWriterTool"]
|
|
2021
|
+
---
|
|
2022
|
+
|
|
2023
|
+
# Canary
|
|
2024
|
+
|
|
2025
|
+
The grant above names a tool no host in this tree is known to honour. A
|
|
2026
|
+
loader IGNORES an unrecognised key, so this artifact reads as restricted
|
|
2027
|
+
and is not — which is the whole defect class the gate exists to refuse.
|
|
2028
|
+
- id: check_host_loadability
|
|
2029
|
+
argv: ["--reach", "--root", "."]
|
|
2030
|
+
min_scanned: 6
|
|
2031
|
+
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."
|
|
2032
|
+
status: enforced
|
|
2033
|
+
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."
|
|
2034
|
+
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."
|
|
2035
|
+
- id: lint_eval_specs
|
|
2036
|
+
argv: []
|
|
2037
|
+
min_scanned: 120
|
|
2038
|
+
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."
|
|
2039
|
+
status: enforced
|
|
2040
|
+
canary:
|
|
2041
|
+
class: contract-violation
|
|
2042
|
+
path: src/skills/zz-canary-eval-specs/evals/evals.json
|
|
2043
|
+
content: |
|
|
2044
|
+
{
|
|
2045
|
+
"skill": "zz-canary-eval-specs",
|
|
2046
|
+
"scenarios": [
|
|
2047
|
+
{ "id": "x", "prompt": "planted by check_gate_coverage --canary; never ships", "assertions": [{ "kind": "tool-choice" }] }
|
|
2048
|
+
]
|
|
2049
|
+
}
|
|
2050
|
+
- id: lint_memory_twin_parity
|
|
2051
|
+
argv: []
|
|
2052
|
+
min_scanned: 7
|
|
2053
|
+
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."
|
|
2054
|
+
status: enforced
|
|
2055
|
+
no_canary_reason: >-
|
|
2056
|
+
Create-only canary cannot reach this corpus. The gate's population is the
|
|
2057
|
+
`twins:` list inside one tracked config file, and every violation it can
|
|
2058
|
+
have is a MODIFICATION — a twin drifting, a verdict deleted, a ceiling
|
|
2059
|
+
exceeded. A newly created file lands outside the list by construction and
|
|
2060
|
+
the gate correctly ignores it. Same class as `check_no_automerge_key`,
|
|
2061
|
+
`check_condensation` and `check_ci_local_parity`. Discrimination is proven
|
|
2062
|
+
instead by the gate's own `--self-test`: 5 cases, 3 rejecting, including
|
|
2063
|
+
the two states the roadmap's verify clause names by hand — a one-line
|
|
2064
|
+
behavioural divergence must RED, and a comment-only divergence must stay
|
|
2065
|
+
GREEN.
|
|
2066
|
+
- id: lint_skill_link_reach
|
|
2067
|
+
argv: []
|
|
2068
|
+
min_scanned: 200
|
|
2069
|
+
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."
|
|
2070
|
+
status: enforced
|
|
2071
|
+
canary:
|
|
2072
|
+
class: contract-violation
|
|
2073
|
+
path: dist/agent-src/skills/zz-canary-link-reach/SKILL.md
|
|
2074
|
+
content: |
|
|
2075
|
+
---
|
|
2076
|
+
name: zz-canary-link-reach
|
|
2077
|
+
description: Canary planted by check_gate_coverage --canary; never ships.
|
|
2078
|
+
---
|
|
2079
|
+
|
|
2080
|
+
# Canary
|
|
2081
|
+
|
|
2082
|
+
This body links to [a skill that is not delivered](../zz-canary-absent-target/SKILL.md).
|
|
2083
|
+
The gate must red on it: a consumer following that link gets a 404, and a
|
|
2084
|
+
link checker that reads only `src/` cannot see the difference between a
|
|
2085
|
+
missing file and a file that exists but did not ship.
|
|
2086
|
+
- id: lint_composition_review
|
|
2087
|
+
argv: []
|
|
2088
|
+
min_scanned: 380
|
|
2089
|
+
corpus: "the skill + rule corpus — every src/skills/*/SKILL.md and src/rules/*.md (419 at baseline: 299 skills + 120 rules)"
|
|
2090
|
+
status: enforced
|
|
2091
|
+
canary:
|
|
2092
|
+
class: contract-violation
|
|
2093
|
+
path: src/rules/__canary_composition_review__.md
|
|
2094
|
+
content: |
|
|
2095
|
+
---
|
|
2096
|
+
name: __canary_composition_review__
|
|
2097
|
+
composition_review:
|
|
2098
|
+
- candidate: rule:this-rule-does-not-exist
|
|
2099
|
+
disposition: create_separate
|
|
2100
|
+
rationale: a canary record naming an incumbent that is not in the tree
|
|
2101
|
+
---
|
|
2102
|
+
|
|
2103
|
+
# canary
|
|
2104
|
+
note: >
|
|
2105
|
+
road-to-composition-before-creation Phase 4.1. Two halves with different
|
|
2106
|
+
teeth, on purpose. The STRUCTURAL half is hard: a present record whose
|
|
2107
|
+
candidate resolves to nothing, whose `none`/`none_found` pair disagrees,
|
|
2108
|
+
whose disposition is off-enum, which repeats a candidate, which is empty,
|
|
2109
|
+
or which uses a YAML block scalar, exits 1. The PRESENCE half is advisory
|
|
2110
|
+
and exits 0: an artifact added without a record is reported by path and
|
|
2111
|
+
never blocks. Flipping that to a block needs a false-positive rate from at
|
|
2112
|
+
least one release of advisory operation, which the roadmap records as not
|
|
2113
|
+
yet measured and does not pre-authorise.
|
|
2114
|
+
|
|
2115
|
+
WHAT IT CERTIFIES, narrowed after an independent review (2 seats, both
|
|
2116
|
+
raising it): REFERENTIAL CONSISTENCY, never that a search happened. An
|
|
2117
|
+
author can name any existing artifact, write `create_separate` and a
|
|
2118
|
+
sixteen-character rationale, and pass. The earlier wording here said a
|
|
2119
|
+
record pointing at a non-existent incumbent "reads as evidence of a search
|
|
2120
|
+
that cannot have happened", which reads as a claim about the search — it is
|
|
2121
|
+
not one, and the module docstring makes the same narrowing. What the hard
|
|
2122
|
+
half buys is that a record cannot point at nothing; whether it points at
|
|
2123
|
+
the RIGHT thing is a reviewer's judgement, and the roadmap's own Risk 1 is
|
|
2124
|
+
that the field becomes a pro-forma line.
|
|
2125
|
+
|
|
2126
|
+
DISCRIMINATION is carried by `--self-test` (8 cases, 5 rejecting), not by
|
|
2127
|
+
the canary. The canary is one create-only recipe by design and exercises
|
|
2128
|
+
the unresolvable-candidate door only; the other five hard doors and the
|
|
2129
|
+
advisory path are covered by the self-test and by
|
|
2130
|
+
tests/scripts/lint_composition_review.test.ts, including a real-git
|
|
2131
|
+
fixture for the untracked-addition union.
|
|
2132
|
+
|
|
2133
|
+
COMPATIBILITY: this is a new HARD whole-corpus gate, so a pre-existing
|
|
2134
|
+
malformed record anywhere in the tree would fail every later PR. Measured
|
|
2135
|
+
at landing: 419 artifacts scanned, 0 records malformed, because zero
|
|
2136
|
+
artifacts carry the field at all — the hard half can only fire on a record
|
|
2137
|
+
that EXISTS, so a corpus with none cannot fail it. The first record written
|
|
2138
|
+
is the first thing that can.
|
|
2139
|
+
|
|
2140
|
+
`{{.QUIET_FLAG}}` in the taskfile against `argv: []` here: `--quiet`
|
|
2141
|
+
suppresses per-finding lines only. Verified — `scanned: 419` and the exit
|
|
2142
|
+
code are byte-identical with and without it, so the coverage measurement
|
|
2143
|
+
and the CI invocation cannot diverge.
|
|
2144
|
+
|
|
2145
|
+
The floor is 380 against a live 419 — room for real deletions, far above
|
|
2146
|
+
a collapse. The corpus is the whole estate rather than the diff precisely
|
|
2147
|
+
so the floor can be honest: `lint_evidence_artifacts` declines
|
|
2148
|
+
registration here because a diff-scoped gate legitimately scans 0, and
|
|
2149
|
+
this gate narrows to the diff only for the advisory half.
|
|
2150
|
+
|
|
2151
|
+
- id: check_prefix_stable_mutation
|
|
2152
|
+
argv: []
|
|
2153
|
+
min_scanned: 35
|
|
2154
|
+
corpus: "hook-manifest concerns bound on at least one mid-session slot, whose script exists (45 at baseline, across 45 mid-session concerns)"
|
|
2155
|
+
status: enforced
|
|
2156
|
+
canary:
|
|
2157
|
+
class: contract-violation
|
|
2158
|
+
path: src/scripts/__canary_prefix_stable__.ts
|
|
2159
|
+
content: |
|
|
2160
|
+
// A canary hook that writes a prefix-stable surface mid-session.
|
|
2161
|
+
// The gate reads the MANIFEST, so this file alone cannot trip it —
|
|
2162
|
+
// which is why DISCRIMINATION is carried by --self-test, not here.
|
|
2163
|
+
import * as fs from 'node:fs';
|
|
2164
|
+
fs.writeFileSync('dist/agent-src/rules/__canary__.md', 'x');
|
|
2165
|
+
note: >
|
|
2166
|
+
road-to-runtime-context-floors step 1.2 — the RUNTIME half of prefix
|
|
2167
|
+
stability. `check_kernel_prefix_stability` guards the kernel prefix at
|
|
2168
|
+
authoring time against a committed snapshot, and `_lib/payload_hash_drift`
|
|
2169
|
+
measures churn after the fact from an audit ledger; neither can see a hook
|
|
2170
|
+
rewriting a prefix-stable surface DURING a session, which invalidates the
|
|
2171
|
+
prompt cache for the rest of it.
|
|
2172
|
+
|
|
2173
|
+
THE SURFACE LIST IS LOADED, NOT RESTATED. Both this gate and
|
|
2174
|
+
`check_preamble_payload_budget` import `PREFIX_STABLE_SURFACES` from
|
|
2175
|
+
`_lib/prefix_stable_surfaces.ts`. That refactor is part of the same change:
|
|
2176
|
+
the budget gate previously stated its three roots twice inside its own
|
|
2177
|
+
file, and a third statement here would be the drift shape this repository
|
|
2178
|
+
already pays for elsewhere.
|
|
2179
|
+
|
|
2180
|
+
DISCRIMINATION is carried by `--self-test` (7 cases, 2 rejecting), NOT by
|
|
2181
|
+
the canary. The gate's corpus is the hook manifest, so a planted script
|
|
2182
|
+
that no manifest binds is invisible to it by construction — the canary
|
|
2183
|
+
above documents the violating SHAPE for a reader and is honestly not the
|
|
2184
|
+
discriminator. The self-test plants a manifest as well as a script, which
|
|
2185
|
+
is what actually proves the red path: a fixture concern on `post_tool_use`
|
|
2186
|
+
writing `dist/agent-src/rules/` fails, and the same concern with
|
|
2187
|
+
`re_arm: pre_compact` passes.
|
|
2188
|
+
|
|
2189
|
+
FAIL-CLOSED on an undecidable target, per the council that resolved
|
|
2190
|
+
`which-surfaces-are-prefix-stable` (2026-08-28, 2/2): a write whose target
|
|
2191
|
+
is computed at runtime, in a file that ALSO carries a literal resolving
|
|
2192
|
+
into a declared surface, fails. Narrow on purpose — a dynamic write in a
|
|
2193
|
+
file with no such literal is not reported, because a gate that flagged
|
|
2194
|
+
every dynamic write in every hook is one nobody can keep green.
|
|
2195
|
+
|
|
2196
|
+
The floor is 35 against a live 45: room for real concern deletions, far
|
|
2197
|
+
above a collapse. `{{.QUIET_FLAG}}` against `argv: []` is safe here —
|
|
2198
|
+
`--quiet` suppresses only the success line, and `scanned:` is emitted
|
|
2199
|
+
outside that guard.
|
|
2200
|
+
|
|
2201
|
+
- id: check_loss_class_declared
|
|
2202
|
+
argv: []
|
|
2203
|
+
min_scanned: 45
|
|
2204
|
+
corpus: "every hook-manifest concern whose script exists (53 at baseline); of those, the model-facing lossy subset is the gated population"
|
|
2205
|
+
status: enforced
|
|
2206
|
+
canary:
|
|
2207
|
+
class: contract-violation
|
|
2208
|
+
path: src/scripts/__canary_loss_class__.ts
|
|
2209
|
+
content: |
|
|
2210
|
+
// A model-facing lossy transform with no loss_class declaration.
|
|
2211
|
+
// As with the sibling gate, the manifest is the corpus, so the
|
|
2212
|
+
// discriminator is --self-test rather than this plant.
|
|
2213
|
+
const WORD_CAP = 400;
|
|
2214
|
+
export function run() {
|
|
2215
|
+
return { context: redactLines(body).slice(0, WORD_CAP).join('\n') };
|
|
2216
|
+
}
|
|
2217
|
+
note: >
|
|
2218
|
+
road-to-runtime-context-floors step 3.2. Strictness was decided, not
|
|
2219
|
+
assumed: council 2026-08-28 (2/2 convergent) resolved
|
|
2220
|
+
`how-strict-the-loss-class-lint-is` as option (b) — FAIL on transforms
|
|
2221
|
+
whose output reaches the model, WARN elsewhere. Option (a) (fail
|
|
2222
|
+
everywhere in `src/`) buys a first-run backlog whose usual answer is a
|
|
2223
|
+
broad allowlist, which this repository has measured emptying a gate;
|
|
2224
|
+
option (c) (warn everywhere, ratchet later) is the shape this repository
|
|
2225
|
+
has measurably never ratcheted. Both seats added the refinement adopted
|
|
2226
|
+
here: unknown reachability is classified as model-reaching.
|
|
2227
|
+
|
|
2228
|
+
MEASURED AT LANDING: **1** module qualifies — `hot_context_hook`, which is
|
|
2229
|
+
exactly the `ephemeral-lossy` exemplar `docs/contracts/loss-classes.md`
|
|
2230
|
+
classifies. A gated population of one is the honest state of this tree,
|
|
2231
|
+
not a broken detector, and it is why the floor below is set on the SCANNED
|
|
2232
|
+
corpus (53 hook scripts) rather than on the gated subset.
|
|
2233
|
+
|
|
2234
|
+
THE DETECTOR READS CODE, NOT PROSE. Its first cut matched `truncat` inside
|
|
2235
|
+
three docblocks that describe truncation without performing any and
|
|
2236
|
+
reported a corpus of four; three of those four were comments. Comments are
|
|
2237
|
+
stripped before matching, and one self-test case pins that direction
|
|
2238
|
+
("prose about truncation is not truncation"), because a gate that fires on
|
|
2239
|
+
writing about a defect is how a real corpus of one becomes a pro-forma
|
|
2240
|
+
corpus of four.
|
|
2241
|
+
|
|
2242
|
+
DISCRIMINATION: `--self-test`, 8 cases, 3 rejecting — including the two
|
|
2243
|
+
that matter beyond "missing declaration": a `recoverable-lossy` with no
|
|
2244
|
+
`loss_recovery` locator (without it the class is indistinguishable from
|
|
2245
|
+
`ephemeral-lossy`) and a misspelled class name.
|
|
2246
|
+
|
|
2247
|
+
- id: check_benchmark_report_fields
|
|
2248
|
+
argv: []
|
|
2249
|
+
min_scanned: 4
|
|
2250
|
+
corpus: "committed benchmark reports under internal/bench/reports/ that announce a schema_version and a corpus/selection block (6 at baseline)"
|
|
2251
|
+
status: enforced
|
|
2252
|
+
canary:
|
|
2253
|
+
class: contract-violation
|
|
2254
|
+
path: internal/bench/reports/__canary_missing_cache__.json
|
|
2255
|
+
content: |
|
|
2256
|
+
{
|
|
2257
|
+
"schema_version": 1,
|
|
2258
|
+
"corpus": { "id": "__canary__" },
|
|
2259
|
+
"selection": { "top_k": 3 }
|
|
2260
|
+
}
|
|
2261
|
+
note: >
|
|
2262
|
+
road-to-runtime-context-floors step 4.1. `cache.read_write_ratio` and
|
|
2263
|
+
`cache.stable_prefix_share` are REQUIRED fields; a report that cannot
|
|
2264
|
+
compute one emits `{ unavailable: "<reason>" }` rather than omitting the
|
|
2265
|
+
key or emitting a zero. A blank reads as "no cache activity" and a zero
|
|
2266
|
+
reads as "the worst possible ratio" — both are claims, and neither is the
|
|
2267
|
+
claim "this was not measured".
|
|
2268
|
+
|
|
2269
|
+
The canary IS the discriminator here, unlike its two siblings: this gate's
|
|
2270
|
+
corpus is a directory of files, so a planted report is genuinely in scope
|
|
2271
|
+
and a create-only plant exercises the real red path. `--self-test` adds 7
|
|
2272
|
+
cases (5 rejecting) covering the forms a plant cannot reach — a blank
|
|
2273
|
+
`unavailable` reason, and a share above 1.
|
|
2274
|
+
|
|
2275
|
+
COMPATIBILITY: six committed reports predate the requirement, and all six
|
|
2276
|
+
were backfilled in the landing change with a stated reason rather than a
|
|
2277
|
+
fabricated number — additively, 48 insertions and 0 deletions, so no
|
|
2278
|
+
historical measurement moved.
|
|
2279
|
+
|
|
2280
|
+
The floor is 4 against a live 6. `allowEmpty` is declared
|
|
2281
|
+
(`OPTIONAL_INPUT:`) because benchmark reports are run artefacts rather
|
|
2282
|
+
than source and a checkout may legitimately carry none; the floor applies
|
|
2283
|
+
whenever any are present.
|
|
2284
|
+
|
|
2285
|
+
- id: check_no_currency_in_cost_surfaces
|
|
2286
|
+
argv: []
|
|
2287
|
+
min_scanned: 4
|
|
2288
|
+
corpus: "the four cost surfaces road-to-delivered-cost-truth built (4 at baseline) — a named watchlist, not a tree walk"
|
|
2289
|
+
status: enforced
|
|
2290
|
+
canary:
|
|
2291
|
+
class: contract-violation
|
|
2292
|
+
path: src/scripts/__canary_currency__.ts
|
|
2293
|
+
content: |
|
|
2294
|
+
// A planted file is NOT in this gate's corpus by construction — the
|
|
2295
|
+
// watchlist is four named files. Discrimination is --self-test's job.
|
|
2296
|
+
out.push(`total: $42`);
|
|
2297
|
+
note: >
|
|
2298
|
+
road-to-delivered-cost-truth AC-7. The suite does not know a consumer's
|
|
2299
|
+
contract — subscription, per-token, committed spend, a reseller rate — so
|
|
2300
|
+
any monetary figure it printed would be extrapolated from a rate it
|
|
2301
|
+
invented. That is worse than no number, because it is actionable and wrong,
|
|
2302
|
+
and it is exactly the thing someone reasonably adds back later on the
|
|
2303
|
+
grounds that a cost report should show cost.
|
|
2304
|
+
|
|
2305
|
+
SCOPE IS A NAMED LIST, NOT A PATTERN, and that is the load-bearing choice.
|
|
2306
|
+
`cache_realization_report` legitimately carries a `cost_usd` block for
|
|
2307
|
+
back-compat with downstream consumers; a gate sweeping `src/scripts/*cost*`
|
|
2308
|
+
would fail on it and be neutered with an allowlist inside a release. The
|
|
2309
|
+
watchlist is asserted by `assertWatchlistResolves`, so a renamed surface is
|
|
2310
|
+
a dead scope (exit 2) rather than a silent pass.
|
|
2311
|
+
|
|
2312
|
+
THE DETECTOR TOOK TWO CORRECTIONS, BOTH FROM ITS OWN SELF-TEST, and both
|
|
2313
|
+
are pinned as accepting cases so a future widening cannot reintroduce them:
|
|
2314
|
+
a bare `$` substring matches TEMPLATE INTERPOLATION (`${value}`), and
|
|
2315
|
+
excluding `${` alone still matched a REGEX END ANCHOR (`/\.md$/`). The
|
|
2316
|
+
shipped pattern is positive rather than subtractive — a currency `$` is
|
|
2317
|
+
followed by a digit or by an interpolated amount — because a gate whose
|
|
2318
|
+
first real run produces dozens of false positives gets an allowlist within
|
|
2319
|
+
a release and then guards nothing.
|
|
2320
|
+
|
|
2321
|
+
DISCRIMINATION: `--self-test`, 9 cases, 4 rejecting. The canary above
|
|
2322
|
+
documents the violating shape for a reader and is honestly NOT the
|
|
2323
|
+
discriminator, because a created file lands outside a four-name watchlist.
|