@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
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
* CI=true ./scripts-run src/scripts/check_claims # re-runs exec: claims
|
|
37
37
|
*/
|
|
38
38
|
import * as fs from 'node:fs';
|
|
39
|
+
import * as os from 'node:os';
|
|
39
40
|
import * as path from 'node:path';
|
|
40
41
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
41
42
|
import {
|
|
@@ -44,7 +45,13 @@ import {
|
|
|
44
45
|
parse_exec_pointer,
|
|
45
46
|
run_exec_evidence,
|
|
46
47
|
} from './_lib/exec_evidence.js';
|
|
47
|
-
import {
|
|
48
|
+
import { checkRatchet } from './_lib/gate_baseline.js';
|
|
49
|
+
import { runGateCli, runSelfTest, type SelfTestCase } from './_lib/gate_self_test.js';
|
|
50
|
+
import {
|
|
51
|
+
assertWatchlistResolves,
|
|
52
|
+
DeadScopeError,
|
|
53
|
+
reportScanned,
|
|
54
|
+
} from './_lib/scan_scope.js';
|
|
48
55
|
|
|
49
56
|
const _FILE = fileURLToPath(import.meta.url);
|
|
50
57
|
const _HERE = path.dirname(_FILE);
|
|
@@ -69,6 +76,61 @@ const URL_DATED = /^https?:\/\/\S+\s*\(\d{4}-\d{2}-\d{2}\)\s*$/;
|
|
|
69
76
|
* are structurally witnessed (pointer columns + their own linters). */
|
|
70
77
|
const WITNESS_SURFACES = ['README.md', 'CAPABILITIES.yaml'];
|
|
71
78
|
|
|
79
|
+
/**
|
|
80
|
+
* The publish-surface set — and the RULE that decides membership.
|
|
81
|
+
*
|
|
82
|
+
* `SURFACE_ROOTS` above is where the package looks for claim MARKERS; this is
|
|
83
|
+
* where the package's own words are RENDERED BY SOMEBODY ELSE. The two are not
|
|
84
|
+
* the same set and conflating them is what let a retired claim keep shipping:
|
|
85
|
+
* `package.json.description` and `.github/about.yml` carried the withdrawn
|
|
86
|
+
* `no-runtime-daemon` wording for weeks while `check_claims` read neither.
|
|
87
|
+
*
|
|
88
|
+
* THE RULE, stated once so a channel that does not appear below is still
|
|
89
|
+
* answerable: a file belongs to this set when a distribution channel the
|
|
90
|
+
* package publishes to renders its content to a reader who never opens the
|
|
91
|
+
* repository. Three consequences, each of which decides a real case:
|
|
92
|
+
*
|
|
93
|
+
* 1. SOURCE, not derived artefact. `dist/mcp/server.json` and
|
|
94
|
+
* `dist/mcp/registry-manifest.json` are published, and they are BUILT from
|
|
95
|
+
* `package.json` + `README.md`. Scanning the source covers them and
|
|
96
|
+
* scanning the artefact would not — a fresh checkout has no `dist/`, so a
|
|
97
|
+
* gate reading it dies on a missing file rather than on the property.
|
|
98
|
+
* 2. RENDERED, not merely shipped. `docs/**` ships inside the npm tarball but
|
|
99
|
+
* no channel renders it as the package's pitch; it is documentation a
|
|
100
|
+
* reader reaches after choosing the package. `README.md` is rendered by
|
|
101
|
+
* both the npm page and the GitHub repo page, so it is in.
|
|
102
|
+
* 3. THE PITCH FIELD, not the whole file. A JSON/YAML publish surface is
|
|
103
|
+
* scanned whole rather than per-key on purpose: a retired phrasing is
|
|
104
|
+
* equally wrong in `keywords`, in a nested plugin `description`, or in a
|
|
105
|
+
* comment, and a per-key list is the snapshot-of-today this rule exists to
|
|
106
|
+
* replace.
|
|
107
|
+
*
|
|
108
|
+
* Applying the rule to a channel not listed: a registry page whose copy is
|
|
109
|
+
* pasted by hand is IN and needs a file here holding that copy; a generated
|
|
110
|
+
* badge is OUT because its text derives from a source already in the set.
|
|
111
|
+
*/
|
|
112
|
+
const PUBLISH_SURFACES = [
|
|
113
|
+
'README.md',
|
|
114
|
+
'package.json',
|
|
115
|
+
'.github/about.yml',
|
|
116
|
+
'.github/topics.yml',
|
|
117
|
+
'.claude-plugin/marketplace.json',
|
|
118
|
+
];
|
|
119
|
+
|
|
120
|
+
/** The sentinel `retires_phrasings` value for a claim that never left the ledger. */
|
|
121
|
+
const NEVER_PUBLISHED = 'never-published';
|
|
122
|
+
|
|
123
|
+
/** A phrasing shorter than this matches too much prose to be a safe needle. */
|
|
124
|
+
const MIN_PHRASING_CHARS = 12;
|
|
125
|
+
|
|
126
|
+
/** Split a `retires_phrasings` value into its literal phrasings. */
|
|
127
|
+
export function parse_retired_phrasings(raw: string): string[] {
|
|
128
|
+
return raw
|
|
129
|
+
.split('|')
|
|
130
|
+
.map((x) => x.trim())
|
|
131
|
+
.filter((x) => x !== '');
|
|
132
|
+
}
|
|
133
|
+
|
|
72
134
|
/**
|
|
73
135
|
* Shapes that read as a measured capability figure.
|
|
74
136
|
*
|
|
@@ -103,7 +165,48 @@ const RATIO = /\b\d+(?:\.\d+)?\s*(?:%|[x×](?![A-Za-z0-9]))/;
|
|
|
103
165
|
// The optional `<word>-` allows a qualified unit: `13,881 GPT-tokens` is the
|
|
104
166
|
// same claim shape as `13,881 tokens` and was missed without it.
|
|
105
167
|
const MAGNITUDE = /\b\d[\d,._]*\s*(?:[A-Za-z]+-)?(?:tokens?|ms|USD|KB|MB|GB|chars?)\b/i;
|
|
106
|
-
|
|
168
|
+
/**
|
|
169
|
+
* The nouns this package counts ITSELF in. Widened 2026-08-26
|
|
170
|
+
* (road-to-published-number-truth 2.1) from the three host-reach nouns to the
|
|
171
|
+
* package's own artifact vocabulary, because the host-reach miss was an
|
|
172
|
+
* instance and the artifact counts are the population: the badge block alone
|
|
173
|
+
* publishes six of them, and until this widening `is_quantified_claim` returned
|
|
174
|
+
* false for every one.
|
|
175
|
+
*
|
|
176
|
+
* Extended rather than given a sibling pattern on purpose — the sweep, the
|
|
177
|
+
* surfaces and the `unverified` allow path all already exist, and a second gate
|
|
178
|
+
* would trip three ratchets to reach the same lines.
|
|
179
|
+
*/
|
|
180
|
+
const SELF_COUNT_NOUNS =
|
|
181
|
+
'host agents?|hosts|supported (?:agents?|hosts)|' +
|
|
182
|
+
'skills?|commands?|rules?|guidelines?|personas?|advisors?|' +
|
|
183
|
+
'packs?|profiles?|ADRs?|contexts?|scripts?';
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Prose shape: `299 skills`, `7+ host agents`, `13,881 tokens`, and — the shape
|
|
187
|
+
* that shipped wrong twice — a QUALIFIED noun, `112 Python scripts`. The
|
|
188
|
+
* optional `<word> ` before the noun is what makes the qualified form match; a
|
|
189
|
+
* pattern anchored directly on the noun read straight past it.
|
|
190
|
+
*/
|
|
191
|
+
const SELF_COUNT_PROSE = new RegExp(
|
|
192
|
+
String.raw`\b\d[\d,]*\+?\s+(?:[A-Za-z][A-Za-z.+-]*\s+)?(?:` + SELF_COUNT_NOUNS + String.raw`)\b`,
|
|
193
|
+
'i',
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Badge-URL shape: `badge/Skills-299`. This is how six of this package's own
|
|
198
|
+
* counts are published, and it carries no whitespace at all, so no prose
|
|
199
|
+
* pattern can see it. `Personas-29` is the live instance that motivated it.
|
|
200
|
+
*/
|
|
201
|
+
const SELF_COUNT_BADGE = new RegExp(
|
|
202
|
+
String.raw`badge/(?:` + SELF_COUNT_NOUNS + String.raw`)-\d[\d,]*\b`,
|
|
203
|
+
'i',
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
const SELF_COUNT = new RegExp(
|
|
207
|
+
`(?:${SELF_COUNT_PROSE.source})|(?:${SELF_COUNT_BADGE.source})`,
|
|
208
|
+
'i',
|
|
209
|
+
);
|
|
107
210
|
|
|
108
211
|
/** True when a line carries any figure shape that must bind to a claim. */
|
|
109
212
|
export function is_quantified_claim(line: string): boolean {
|
|
@@ -136,6 +239,89 @@ export interface LedgerEntry {
|
|
|
136
239
|
* ledger exists to make impossible.
|
|
137
240
|
*/
|
|
138
241
|
superseded_by: string;
|
|
242
|
+
/**
|
|
243
|
+
* REQUIRED on a `withdrawn` entry: the decision record that retired the
|
|
244
|
+
* claim. Empty everywhere else.
|
|
245
|
+
*
|
|
246
|
+
* `road-to-runtime-governance-flip` Phase 2, on an AI council ruling
|
|
247
|
+
* (2026-08-27, 4/4 across two rounds). `withdrawn` is the ledger's third
|
|
248
|
+
* closure — a claim that was true and asserted, and that the package decided
|
|
249
|
+
* to stop having. The status alone does not say WHOSE decision, and a
|
|
250
|
+
* withdrawal nobody can trace to a record is an unexplained deletion wearing
|
|
251
|
+
* a status. Requiring the pointer is what keeps the fourth status from
|
|
252
|
+
* becoming the dumping ground both council rounds warned about.
|
|
253
|
+
*/
|
|
254
|
+
retired_by: string;
|
|
255
|
+
/**
|
|
256
|
+
* Optional: the build a quantitative measurement describes, when that is not
|
|
257
|
+
* the current one.
|
|
258
|
+
*
|
|
259
|
+
* `road-to-inbox-harvest-2026-08-f-code-graph-evidence-refresh` 3.2, on an
|
|
260
|
+
* AI council ruling (2026-08-26, 2/2). `claim:code-graph-retrieval-null` is
|
|
261
|
+
* a real measurement of a build that no longer exists: its figures date from
|
|
262
|
+
* 2026-07-28 and the extractor defect they blame was repaired on 2026-08-22.
|
|
263
|
+
*
|
|
264
|
+
* The council rejected both obvious statuses. `resolved-null` would say the
|
|
265
|
+
* retrieval question was ANSWERED null on the current build, which is
|
|
266
|
+
* exactly what nobody has measured; `superseded_by` expects replacement
|
|
267
|
+
* EVIDENCE, and a repair commit is the wrong semantic object for it. What
|
|
268
|
+
* was required instead was structured scoping — and that it reach every
|
|
269
|
+
* index and summary rather than only the detailed entry, because a prose-only
|
|
270
|
+
* qualification drifts from the structured record it qualifies.
|
|
271
|
+
*
|
|
272
|
+
* So this field is printed in `docs/proof.md`'s ledger table, not merely
|
|
273
|
+
* parsed.
|
|
274
|
+
*/
|
|
275
|
+
measured_on: string;
|
|
276
|
+
/**
|
|
277
|
+
* Optional: the inferences this claim's data does NOT license.
|
|
278
|
+
*
|
|
279
|
+
* `road-to-skill-ecosystem-eval-integrity` Phase 5 Step 5. A measured number
|
|
280
|
+
* travels further than its measurement, and the sentence that stops it is
|
|
281
|
+
* one nobody writes unless a field asks for it. A `quant` claim backed by a
|
|
282
|
+
* benchmark supports exactly what the benchmark measured, on the population
|
|
283
|
+
* it ran over — and a reader with only the headline has no way to know which
|
|
284
|
+
* neighbouring reading it does not support.
|
|
285
|
+
*
|
|
286
|
+
* Optional rather than required, with a shrink-only ratchet on `backed`
|
|
287
|
+
* quant entries that lack it. Making it required would fail the build on
|
|
288
|
+
* every existing entry at once, which is the shape this repository's own
|
|
289
|
+
* records call a gate that could only block.
|
|
290
|
+
*/
|
|
291
|
+
non_inference: string;
|
|
292
|
+
/**
|
|
293
|
+
* Optional, CLOSED entries only: the literal phrasings this claim was
|
|
294
|
+
* PUBLISHED under, `|`-separated — or the sentinel
|
|
295
|
+
* `never-published — <reason>` when it never appeared outside the ledger.
|
|
296
|
+
*
|
|
297
|
+
* `road-to-retired-claims-stay-retired` Phase 1. Retiring a claim was a
|
|
298
|
+
* bookkeeping act with no reach: `check_claims` validated a `withdrawn`
|
|
299
|
+
* row's own shape and `lint_positioning` validated three surfaces agreeing
|
|
300
|
+
* with each other, and neither read the other's input. A row could go
|
|
301
|
+
* `withdrawn` while its exact wording stayed on the npm page.
|
|
302
|
+
*
|
|
303
|
+
* The list lives ON THE ROW rather than in a sibling deny-list file, so
|
|
304
|
+
* retiring a claim and forbidding its wording are one edit. A second file
|
|
305
|
+
* is the one nobody updates.
|
|
306
|
+
*
|
|
307
|
+
* Populated from HISTORY, never from imagination — `MIN_PHRASING_CHARS` and
|
|
308
|
+
* the read-it-from-git discipline in docs/CLAIMS.md are both aimed at the
|
|
309
|
+
* same failure: a list of plausible paraphrases becomes a gate that fires
|
|
310
|
+
* on legitimate prose and is muted within a release.
|
|
311
|
+
*/
|
|
312
|
+
retires_phrasings: string;
|
|
313
|
+
/**
|
|
314
|
+
* Whether the `- retires_phrasings:` LINE exists at all, independent of
|
|
315
|
+
* whether it carries a value.
|
|
316
|
+
*
|
|
317
|
+
* The two states are different findings and the string alone cannot tell
|
|
318
|
+
* them apart: an ABSENT field is a row nobody has got to yet (the coverage
|
|
319
|
+
* ratchet's business), while a PRESENT-BUT-EMPTY one is an author who
|
|
320
|
+
* answered the question with silence — the same distinction `non_inference`
|
|
321
|
+
* draws with its 20-character floor, and the reason that field's check is
|
|
322
|
+
* separate from its ratchet.
|
|
323
|
+
*/
|
|
324
|
+
retires_phrasings_present: boolean;
|
|
139
325
|
}
|
|
140
326
|
|
|
141
327
|
interface Args {
|
|
@@ -147,6 +333,10 @@ function parse_args(argv: string[]): Args {
|
|
|
147
333
|
for (const a of argv) {
|
|
148
334
|
if (a === '--quiet') {
|
|
149
335
|
out.quiet = true;
|
|
336
|
+
} else if (a === '--self-test') {
|
|
337
|
+
// Handled in main() before parse_args is reached; accepted here so
|
|
338
|
+
// a stray ordering never turns the flag into a usage error.
|
|
339
|
+
continue;
|
|
150
340
|
} else if (a === '-h' || a === '--help') {
|
|
151
341
|
process.stdout.write('usage: check_claims [--quiet]\n');
|
|
152
342
|
throw new ExitCode(0);
|
|
@@ -177,6 +367,11 @@ function load_ledger(): Map<string, LedgerEntry> {
|
|
|
177
367
|
status: cur.status ?? '',
|
|
178
368
|
last_verified: cur.last_verified ?? '',
|
|
179
369
|
superseded_by: cur.superseded_by ?? '',
|
|
370
|
+
retired_by: cur.retired_by ?? '',
|
|
371
|
+
measured_on: cur.measured_on ?? '',
|
|
372
|
+
non_inference: cur.non_inference ?? '',
|
|
373
|
+
retires_phrasings: cur.retires_phrasings ?? '',
|
|
374
|
+
retires_phrasings_present: cur.retires_phrasings_present ?? false,
|
|
180
375
|
});
|
|
181
376
|
}
|
|
182
377
|
cur = {};
|
|
@@ -189,10 +384,19 @@ function load_ledger(): Map<string, LedgerEntry> {
|
|
|
189
384
|
continue;
|
|
190
385
|
}
|
|
191
386
|
if (!cur.id) continue;
|
|
192
|
-
|
|
387
|
+
// Keeping both sides of the merge is right for the FIELD LIST and wrong
|
|
388
|
+
// for the call: `String.match` takes one pattern, so two lines here
|
|
389
|
+
// would have silently ignored the second and dropped whichever field
|
|
390
|
+
// came from the other branch. One union, both fields.
|
|
391
|
+
const field = line.match(
|
|
392
|
+
/^-\s+(claim|kind|evidence|status|last_verified|superseded_by|retired_by|measured_on|non_inference|retires_phrasings):\s*(.*)$/,
|
|
393
|
+
);
|
|
193
394
|
if (field) {
|
|
194
395
|
const key = field[1] as keyof LedgerEntry;
|
|
195
396
|
(cur as Record<string, string>)[key] = (field[2] ?? '').trim();
|
|
397
|
+
if (key === 'retires_phrasings') {
|
|
398
|
+
(cur as Record<string, unknown>)['retires_phrasings_present'] = true;
|
|
399
|
+
}
|
|
196
400
|
}
|
|
197
401
|
}
|
|
198
402
|
flush();
|
|
@@ -289,6 +493,7 @@ interface Finding {
|
|
|
289
493
|
}
|
|
290
494
|
|
|
291
495
|
function main(argv: string[] = process.argv.slice(2)): number {
|
|
496
|
+
if (argv.includes('--self-test')) return selfTest();
|
|
292
497
|
const args = parse_args(argv);
|
|
293
498
|
const ledger = load_ledger();
|
|
294
499
|
// The ledger is the corpus both passes depend on: markers resolve against
|
|
@@ -299,7 +504,7 @@ function main(argv: string[] = process.argv.slice(2)): number {
|
|
|
299
504
|
// Marker count is deliberately not the unit: a surface tree with zero
|
|
300
505
|
// markers is a legitimate state, an absent ledger never is.
|
|
301
506
|
try {
|
|
302
|
-
|
|
507
|
+
reportScanned({
|
|
303
508
|
gate: 'check_claims',
|
|
304
509
|
scanned: ledger.size,
|
|
305
510
|
units: 'ledger entry(s)',
|
|
@@ -344,13 +549,19 @@ function main(argv: string[] = process.argv.slice(2)): number {
|
|
|
344
549
|
// reader arriving at a `resolved-null` learns the question was reopened
|
|
345
550
|
// by a different mechanism — a dangling id would send them nowhere, and
|
|
346
551
|
// the field on a live entry would claim a closure that never happened.
|
|
552
|
+
//
|
|
553
|
+
// `withdrawn` joins `resolved-null` as a closure that may carry a
|
|
554
|
+
// successor (road-to-runtime-governance-flip Phase 2). The two are
|
|
555
|
+
// different closures — one is "we measured and the threshold was missed",
|
|
556
|
+
// the other is "we decided to stop having the property" — but both are
|
|
557
|
+
// closed, and both leave a reader who needs the forward link.
|
|
347
558
|
for (const entry of ledger.values()) {
|
|
348
559
|
if (!entry.superseded_by) continue;
|
|
349
|
-
if (entry.status !== 'resolved-null') {
|
|
560
|
+
if (entry.status !== 'resolved-null' && entry.status !== 'withdrawn') {
|
|
350
561
|
findings.push({
|
|
351
562
|
id: entry.id,
|
|
352
563
|
file: LEDGER_REL,
|
|
353
|
-
reason: `superseded_by is only meaningful on a resolved-null
|
|
564
|
+
reason: `superseded_by is only meaningful on a closed entry — resolved-null or withdrawn (status: ${entry.status || 'missing'})`,
|
|
354
565
|
});
|
|
355
566
|
continue;
|
|
356
567
|
}
|
|
@@ -369,6 +580,154 @@ function main(argv: string[] = process.argv.slice(2)): number {
|
|
|
369
580
|
}
|
|
370
581
|
}
|
|
371
582
|
|
|
583
|
+
// 2c. A withdrawal names the decision that retired it. Without the pointer
|
|
584
|
+
// `withdrawn` says only "this closed for a reason that was not a
|
|
585
|
+
// measurement", which is the half of the statement a reader can already
|
|
586
|
+
// infer from the absence of `resolved-null`.
|
|
587
|
+
for (const entry of ledger.values()) {
|
|
588
|
+
if (entry.status !== 'withdrawn') continue;
|
|
589
|
+
if (!entry.retired_by) {
|
|
590
|
+
findings.push({
|
|
591
|
+
id: entry.id,
|
|
592
|
+
file: LEDGER_REL,
|
|
593
|
+
reason: 'status is withdrawn but no `retired_by` names the decision that retired it',
|
|
594
|
+
});
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
for (const entry of ledger.values()) {
|
|
598
|
+
if (entry.retired_by && entry.status !== 'withdrawn') {
|
|
599
|
+
findings.push({
|
|
600
|
+
id: entry.id,
|
|
601
|
+
file: LEDGER_REL,
|
|
602
|
+
reason: `retired_by is only meaningful on a withdrawn entry (status: ${entry.status || 'missing'})`,
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
// 2d. `retires_phrasings` — shape. A retirement that names no wording
|
|
608
|
+
// forbids no wording, and a wording too short to be specific forbids
|
|
609
|
+
// half the tree. Both are findings at any count; the COVERAGE question
|
|
610
|
+
// (is every closed row populated?) is a ratchet further down, because
|
|
611
|
+
// that is the number that can only shrink.
|
|
612
|
+
for (const entry of ledger.values()) {
|
|
613
|
+
const raw = entry.retires_phrasings;
|
|
614
|
+
if (!entry.retires_phrasings_present) continue;
|
|
615
|
+
if (entry.status !== 'resolved-null' && entry.status !== 'withdrawn') {
|
|
616
|
+
findings.push({
|
|
617
|
+
id: entry.id,
|
|
618
|
+
file: LEDGER_REL,
|
|
619
|
+
reason: `retires_phrasings is only meaningful on a closed entry — resolved-null or withdrawn (status: ${entry.status || 'missing'})`,
|
|
620
|
+
});
|
|
621
|
+
continue;
|
|
622
|
+
}
|
|
623
|
+
if (raw.startsWith(NEVER_PUBLISHED)) {
|
|
624
|
+
// The sentinel is a claim about history, so it carries its reason.
|
|
625
|
+
// `never-published` alone is indistinguishable from "nobody looked".
|
|
626
|
+
const reason = raw.slice(NEVER_PUBLISHED.length).replace(/^[\s\u2014-]+/, '').trim();
|
|
627
|
+
if (reason.length < 20) {
|
|
628
|
+
findings.push({
|
|
629
|
+
id: entry.id,
|
|
630
|
+
file: LEDGER_REL,
|
|
631
|
+
reason:
|
|
632
|
+
'retires_phrasings says never-published but states no reason — the sentinel ' +
|
|
633
|
+
'asserts that history was read and came back empty, and an unreasoned one is ' +
|
|
634
|
+
'indistinguishable from nobody having looked',
|
|
635
|
+
});
|
|
636
|
+
}
|
|
637
|
+
continue;
|
|
638
|
+
}
|
|
639
|
+
const phrasings = parse_retired_phrasings(raw);
|
|
640
|
+
if (phrasings.length === 0) {
|
|
641
|
+
findings.push({
|
|
642
|
+
id: entry.id,
|
|
643
|
+
file: LEDGER_REL,
|
|
644
|
+
reason: 'retires_phrasings is present but empty — a retirement that names no wording forbids none',
|
|
645
|
+
});
|
|
646
|
+
continue;
|
|
647
|
+
}
|
|
648
|
+
for (const ph of phrasings) {
|
|
649
|
+
if (ph.length < MIN_PHRASING_CHARS) {
|
|
650
|
+
findings.push({
|
|
651
|
+
id: entry.id,
|
|
652
|
+
file: LEDGER_REL,
|
|
653
|
+
reason: `retires_phrasings carries "${ph}" (${ph.length} chars) — under ${MIN_PHRASING_CHARS} it is a needle that matches ordinary prose, which is how this gate gets muted`,
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
// 2e. THE REACH. A retired phrasing may not appear on a publish surface.
|
|
660
|
+
// This is the half the ledger never had: `check_claims` read the row's
|
|
661
|
+
// own shape, `lint_positioning` read three surfaces against each other,
|
|
662
|
+
// and nothing read the row against the surfaces. The live instance was
|
|
663
|
+
// the withdrawn `no-runtime-daemon` wording still shipping in
|
|
664
|
+
// `package.json.description` and `.github/about.yml`.
|
|
665
|
+
//
|
|
666
|
+
// Match is case-insensitive substring over the raw file, per rule (3)
|
|
667
|
+
// at PUBLISH_SURFACES: a retired phrasing is equally wrong in a
|
|
668
|
+
// keyword, a nested description, or a comment.
|
|
669
|
+
//
|
|
670
|
+
// THE SCAN ROOT IS ASSERTED, and asserted CONDITIONALLY. A watch-list
|
|
671
|
+
// guard whose paths all vanish reports clean forever — the
|
|
672
|
+
// `check_safety_floor_untouched` shape, which announced "4 rules
|
|
673
|
+
// guarded" while guarding none. `assertWatchlistResolves` is that
|
|
674
|
+
// assertion. It runs only when there is at least one needle to look
|
|
675
|
+
// for, because a ledger carrying no retired phrasings has nothing to
|
|
676
|
+
// watch, and a phantom watchlist over an empty needle set is a false
|
|
677
|
+
// alarm rather than a caught defect (it is also every fixture tree).
|
|
678
|
+
//
|
|
679
|
+
// A needle under MIN_PHRASING_CHARS is already a finding above and is
|
|
680
|
+
// excluded here rather than searched: reporting it twice, once as a
|
|
681
|
+
// bad needle and once as a phantom watchlist, buries the actionable
|
|
682
|
+
// message under the derived one.
|
|
683
|
+
const usableNeedles = new Map<string, string[]>();
|
|
684
|
+
for (const e of ledger.values()) {
|
|
685
|
+
if (e.status !== 'resolved-null' && e.status !== 'withdrawn') continue;
|
|
686
|
+
if (e.retires_phrasings === '' || e.retires_phrasings.startsWith(NEVER_PUBLISHED)) continue;
|
|
687
|
+
const usable = parse_retired_phrasings(e.retires_phrasings).filter(
|
|
688
|
+
(ph) => ph.length >= MIN_PHRASING_CHARS,
|
|
689
|
+
);
|
|
690
|
+
if (usable.length > 0) usableNeedles.set(e.id, usable);
|
|
691
|
+
}
|
|
692
|
+
let liveSurfaces: string[] = [];
|
|
693
|
+
if (usableNeedles.size > 0) {
|
|
694
|
+
try {
|
|
695
|
+
liveSurfaces = assertWatchlistResolves({
|
|
696
|
+
gate: 'check_claims:publish-surfaces',
|
|
697
|
+
candidates: PUBLISH_SURFACES,
|
|
698
|
+
repoRoot: REPO,
|
|
699
|
+
});
|
|
700
|
+
} catch (exc) {
|
|
701
|
+
if (!(exc instanceof DeadScopeError)) throw exc;
|
|
702
|
+
// A FINDING, not an early return. Returning here would suppress
|
|
703
|
+
// every finding already collected, and the dead-root message would
|
|
704
|
+
// arrive alone — hiding the shape errors that are usually the
|
|
705
|
+
// reason somebody is reading this output.
|
|
706
|
+
findings.push({
|
|
707
|
+
id: 'publish-surfaces',
|
|
708
|
+
file: LEDGER_REL,
|
|
709
|
+
reason: exc.message,
|
|
710
|
+
});
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
for (const entry of ledger.values()) {
|
|
714
|
+
const phrasings = usableNeedles.get(entry.id);
|
|
715
|
+
if (phrasings === undefined) continue;
|
|
716
|
+
for (const rel of liveSurfaces) {
|
|
717
|
+
const abs = path.join(REPO, rel);
|
|
718
|
+
const body = fs.readFileSync(abs, 'utf8').toLowerCase();
|
|
719
|
+
for (const ph of phrasings) {
|
|
720
|
+
if (body.includes(ph.toLowerCase())) {
|
|
721
|
+
findings.push({
|
|
722
|
+
id: entry.id,
|
|
723
|
+
file: rel,
|
|
724
|
+
reason: `publishes the retired phrasing "${ph}" — claim:${entry.id} is ${entry.status}, so this wording may no longer ship`,
|
|
725
|
+
});
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
|
|
372
731
|
// 3. Witness sweep (road-to-opt-subagent-harvest P1.2): a QUANTIFIED
|
|
373
732
|
// capability claim on a marketing-class surface must be witnessed — a
|
|
374
733
|
// `<!-- claim:ID -->` marker on the same line, or an explicit
|
|
@@ -486,6 +845,98 @@ function main(argv: string[] = process.argv.slice(2)): number {
|
|
|
486
845
|
}
|
|
487
846
|
}
|
|
488
847
|
|
|
848
|
+
// 5. Non-inference ratchet (road-to-skill-ecosystem-eval-integrity 5.5).
|
|
849
|
+
//
|
|
850
|
+
// A measured number travels further than its measurement. `non_inference`
|
|
851
|
+
// is the sentence that stops it, and it is a sentence nobody writes unless
|
|
852
|
+
// something asks. Scoped to `backed` + `quant`, which is exactly the class
|
|
853
|
+
// that gets quoted out of context: a qualitative claim carries its own
|
|
854
|
+
// hedge in the prose, a quantitative one carries a figure.
|
|
855
|
+
//
|
|
856
|
+
// A RATCHET rather than a requirement, deliberately: 42 backed quant
|
|
857
|
+
// entries lack the field today, and failing the build on all of them at
|
|
858
|
+
// once produces a gate that can only block — the shape this repository's
|
|
859
|
+
// own records name as the reason a gate gets suppressed. Every NEW backed
|
|
860
|
+
// quant claim must carry it; the inherited 42 come along as they are
|
|
861
|
+
// touched. A present-but-empty field is a finding at any count, because
|
|
862
|
+
// that is an author answering the question with silence.
|
|
863
|
+
const missingNonInference = [...ledger.values()].filter(
|
|
864
|
+
(e) => e.status === 'backed' && e.kind === 'quant' && e.non_inference === '',
|
|
865
|
+
);
|
|
866
|
+
const emptyNonInference = [...ledger.values()].filter(
|
|
867
|
+
(e) => e.non_inference !== '' && e.non_inference.trim().length < 20,
|
|
868
|
+
);
|
|
869
|
+
for (const e of emptyNonInference) {
|
|
870
|
+
findings.push({
|
|
871
|
+
id: e.id,
|
|
872
|
+
file: LEDGER_REL,
|
|
873
|
+
reason:
|
|
874
|
+
'non_inference is present but says almost nothing — the field exists to enumerate ' +
|
|
875
|
+
'what the data does NOT license, and a placeholder is worse than an absent field ' +
|
|
876
|
+
'because it reads as answered',
|
|
877
|
+
});
|
|
878
|
+
}
|
|
879
|
+
// The ratchet is a property of a repository that RECORDS baselines. A tree
|
|
880
|
+
// with no baselines file at all is a fixture, not a repository silencing a
|
|
881
|
+
// gate, and the two are distinguishable: a MISSING FILE skips, while a
|
|
882
|
+
// present file with no entry still fails — which is the anti-silencing
|
|
883
|
+
// property, since deleting one entry from a tracked file is the cheap way
|
|
884
|
+
// to make this go away and it must not work.
|
|
885
|
+
const baselinesPath = path.join(REPO, 'src', 'config', 'gate-violation-baselines.json');
|
|
886
|
+
const nonInferenceVerdict = fs.existsSync(baselinesPath)
|
|
887
|
+
? checkRatchet({
|
|
888
|
+
gate: 'check_claims:non-inference',
|
|
889
|
+
actual: missingNonInference.length,
|
|
890
|
+
repoRoot: REPO,
|
|
891
|
+
})
|
|
892
|
+
: { ok: true, message: '' };
|
|
893
|
+
if (!nonInferenceVerdict.ok) {
|
|
894
|
+
findings.push({
|
|
895
|
+
id: 'non-inference',
|
|
896
|
+
file: LEDGER_REL,
|
|
897
|
+
reason: nonInferenceVerdict.message,
|
|
898
|
+
});
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
// 6. Retired-phrasings COVERAGE ratchet (road-to-retired-claims-stay-retired
|
|
902
|
+
// Phase 1.2). Every closed entry names what its retirement forbids; the
|
|
903
|
+
// field stays optional at the SCHEMA level so a fixture and a
|
|
904
|
+
// mid-authoring row still parse, and this is where absence becomes a
|
|
905
|
+
// finding.
|
|
906
|
+
//
|
|
907
|
+
// DELIBERATELY UNBASELINED, unlike the `non_inference` ratchet above.
|
|
908
|
+
// All eight closed rows were populated in the change that introduced the
|
|
909
|
+
// field, so there is no inherited debt to carry — and `checkRatchet`
|
|
910
|
+
// with no recorded entry returns `ok: actual === 0`
|
|
911
|
+
// (src/scripts/_lib/gate_baseline.ts:288-301), which is exactly the
|
|
912
|
+
// hard-zero this needs. Recording a baseline of 0 would be worse than
|
|
913
|
+
// recording none: a 0 can never DROP, so the 56-day anti-fossilization
|
|
914
|
+
// clause (STALE_AFTER_DAYS, :41) would fail the gate two months from now
|
|
915
|
+
// for a count that was correct the whole time.
|
|
916
|
+
const closedWithoutPhrasings = [...ledger.values()].filter(
|
|
917
|
+
(e) =>
|
|
918
|
+
(e.status === 'resolved-null' || e.status === 'withdrawn') &&
|
|
919
|
+
!e.retires_phrasings_present,
|
|
920
|
+
);
|
|
921
|
+
const phrasingsVerdict = fs.existsSync(baselinesPath)
|
|
922
|
+
? checkRatchet({
|
|
923
|
+
gate: 'check_claims:retired-phrasings',
|
|
924
|
+
actual: closedWithoutPhrasings.length,
|
|
925
|
+
repoRoot: REPO,
|
|
926
|
+
})
|
|
927
|
+
: { ok: true, message: '' };
|
|
928
|
+
if (!phrasingsVerdict.ok) {
|
|
929
|
+
findings.push({
|
|
930
|
+
id: 'retired-phrasings',
|
|
931
|
+
file: LEDGER_REL,
|
|
932
|
+
reason:
|
|
933
|
+
`${phrasingsVerdict.message}` +
|
|
934
|
+
(closedWithoutPhrasings.length > 0
|
|
935
|
+
? ` — closed without the field: ${closedWithoutPhrasings.map((e) => e.id).join(', ')}`
|
|
936
|
+
: ''),
|
|
937
|
+
});
|
|
938
|
+
}
|
|
939
|
+
|
|
489
940
|
if (findings.length > 0) {
|
|
490
941
|
process.stderr.write(`❌ check_claims: ${findings.length} unbacked/dangling claim(s):\n`);
|
|
491
942
|
for (const f of findings) {
|
|
@@ -526,6 +977,125 @@ function _isCliEntry(): boolean {
|
|
|
526
977
|
return false;
|
|
527
978
|
}
|
|
528
979
|
}
|
|
980
|
+
/**
|
|
981
|
+
* `--self-test` — the gate proving its own rejections still fire.
|
|
982
|
+
*
|
|
983
|
+
* Required by the `gate-self-test:registered-non-adopters` ratchet once this
|
|
984
|
+
* gate joined `src/config/gate-coverage.yml`, and worth having on its own
|
|
985
|
+
* terms: `check_claims` resolves `REPO` from its own file location rather than
|
|
986
|
+
* from `cwd`, so the only way to point it at a fixture is to COPY it into one.
|
|
987
|
+
* That is what the harness below does, and it is why `runGateCli` is handed a
|
|
988
|
+
* path that walks back out of the repository — `path.join(REPO, relative)`
|
|
989
|
+
* resolves into the temporary tree while `tsx` is still found under the real
|
|
990
|
+
* `node_modules`.
|
|
991
|
+
*
|
|
992
|
+
* Four of the five cases are the retired-phrasings reach added by
|
|
993
|
+
* road-to-retired-claims-stay-retired; the fixture in the rejecting one carries
|
|
994
|
+
* the LITERAL historical string that shipped on two publish surfaces while
|
|
995
|
+
* `claim:no-runtime-daemon` was already `withdrawn`.
|
|
996
|
+
*/
|
|
997
|
+
function selfTest(): number {
|
|
998
|
+
const roots: string[] = [];
|
|
999
|
+
// FOUR, not three: this gate imports `gate_self_test.ts` for the harness
|
|
1000
|
+
// it is running right now, and a missing fourth lib fails as a module
|
|
1001
|
+
// resolution error in EVERY case at once — which reads as the detection
|
|
1002
|
+
// having broken rather than the fixture being incomplete.
|
|
1003
|
+
const libs = ['exec_evidence.ts', 'scan_scope.ts', 'gate_baseline.ts', 'gate_self_test.ts'];
|
|
1004
|
+
|
|
1005
|
+
const fixture = (files: Record<string, string>): number => {
|
|
1006
|
+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'check-claims-selftest-'));
|
|
1007
|
+
roots.push(dir);
|
|
1008
|
+
fs.mkdirSync(path.join(dir, 'src', 'scripts', '_lib'), { recursive: true });
|
|
1009
|
+
fs.copyFileSync(_FILE, path.join(dir, 'src', 'scripts', 'check_claims.ts'));
|
|
1010
|
+
for (const lib of libs) {
|
|
1011
|
+
fs.copyFileSync(
|
|
1012
|
+
path.join(REPO, 'src', 'scripts', '_lib', lib),
|
|
1013
|
+
path.join(dir, 'src', 'scripts', '_lib', lib),
|
|
1014
|
+
);
|
|
1015
|
+
}
|
|
1016
|
+
fs.mkdirSync(path.join(dir, 'docs'), { recursive: true });
|
|
1017
|
+
fs.writeFileSync(path.join(dir, 'docs', 'evidence.md'), 'Contains the ANCHOR string.\n');
|
|
1018
|
+
for (const [rel, body] of Object.entries(files)) {
|
|
1019
|
+
const abs = path.join(dir, rel);
|
|
1020
|
+
fs.mkdirSync(path.dirname(abs), { recursive: true });
|
|
1021
|
+
fs.writeFileSync(abs, body);
|
|
1022
|
+
}
|
|
1023
|
+
const rel = path.relative(REPO, path.join(dir, 'src', 'scripts', 'check_claims.ts'));
|
|
1024
|
+
return runGateCli(REPO, rel, [], dir);
|
|
1025
|
+
};
|
|
1026
|
+
|
|
1027
|
+
const closed = (phrasings: string | null): string =>
|
|
1028
|
+
[
|
|
1029
|
+
'# Claims Ledger',
|
|
1030
|
+
'',
|
|
1031
|
+
'### claim: no-runtime-daemon',
|
|
1032
|
+
'- claim: Compiled into host agents with zero runtime daemon.',
|
|
1033
|
+
'- kind: qual',
|
|
1034
|
+
'- evidence: docs/evidence.md#ANCHOR',
|
|
1035
|
+
'- status: withdrawn',
|
|
1036
|
+
'- last_verified: 2026-07-04',
|
|
1037
|
+
'- retired_by: ADR-249',
|
|
1038
|
+
...(phrasings === null ? [] : [`- retires_phrasings: ${phrasings}`]),
|
|
1039
|
+
'',
|
|
1040
|
+
].join('\n');
|
|
1041
|
+
|
|
1042
|
+
const CLEAN_README = '# Agent Config\n\nGoverned skills, rules and commands.\n';
|
|
1043
|
+
|
|
1044
|
+
const cases: SelfTestCase[] = [
|
|
1045
|
+
{
|
|
1046
|
+
name: 'a retired phrasing absent from every publish surface → accept',
|
|
1047
|
+
expect: 'accept',
|
|
1048
|
+
run: () =>
|
|
1049
|
+
fixture({
|
|
1050
|
+
'docs/CLAIMS.md': closed('zero runtime daemon'),
|
|
1051
|
+
'README.md': CLEAN_README,
|
|
1052
|
+
}),
|
|
1053
|
+
},
|
|
1054
|
+
{
|
|
1055
|
+
name: 'the LITERAL historical string in package.json.description → reject',
|
|
1056
|
+
expect: 'reject',
|
|
1057
|
+
run: () =>
|
|
1058
|
+
fixture({
|
|
1059
|
+
'docs/CLAIMS.md': closed('zero runtime daemon'),
|
|
1060
|
+
'package.json':
|
|
1061
|
+
'{\n "description": "every claim machine-checked, including \\"zero runtime daemon\\"."\n}\n',
|
|
1062
|
+
}),
|
|
1063
|
+
},
|
|
1064
|
+
{
|
|
1065
|
+
name: 'a present-but-empty retires_phrasings → reject',
|
|
1066
|
+
expect: 'reject',
|
|
1067
|
+
run: () => fixture({ 'docs/CLAIMS.md': closed(''), 'README.md': CLEAN_README }),
|
|
1068
|
+
},
|
|
1069
|
+
{
|
|
1070
|
+
name: 'a needle too short to be specific → reject',
|
|
1071
|
+
expect: 'reject',
|
|
1072
|
+
run: () => fixture({ 'docs/CLAIMS.md': closed('daemon'), 'README.md': CLEAN_README }),
|
|
1073
|
+
},
|
|
1074
|
+
{
|
|
1075
|
+
name: 'the never-published sentinel with a stated reason → accept',
|
|
1076
|
+
expect: 'accept',
|
|
1077
|
+
run: () =>
|
|
1078
|
+
fixture({
|
|
1079
|
+
'docs/CLAIMS.md': closed(
|
|
1080
|
+
'never-published — verified by `git log -S` over every publish surface: zero commits.',
|
|
1081
|
+
),
|
|
1082
|
+
'README.md': `${CLEAN_README}\nIt mentions zero runtime daemon freely.\n`,
|
|
1083
|
+
}),
|
|
1084
|
+
},
|
|
1085
|
+
];
|
|
1086
|
+
|
|
1087
|
+
try {
|
|
1088
|
+
return runSelfTest({
|
|
1089
|
+
gate: 'check_claims',
|
|
1090
|
+
cases,
|
|
1091
|
+
minCases: 5,
|
|
1092
|
+
minRejectCases: 3,
|
|
1093
|
+
});
|
|
1094
|
+
} finally {
|
|
1095
|
+
for (const d of roots) fs.rmSync(d, { recursive: true, force: true });
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
|
|
529
1099
|
if (_isCliEntry()) {
|
|
530
1100
|
try {
|
|
531
1101
|
process.exit(main());
|