@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
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The evaluation gate's record type: a metric VECTOR, never a weighted total.
|
|
3
|
+
*
|
|
4
|
+
* `road-to-governed-harness-evolution` Phase 4, steps 4.2 and 4.3.
|
|
5
|
+
*
|
|
6
|
+
* > *4.2 Report a metric vector, never a weighted total. Include an
|
|
7
|
+
* > `artifact-count delta` row — that is where the sprawl concern belongs,
|
|
8
|
+
* > inside the gate where it can prevent something.*
|
|
9
|
+
* > verify: **no code path computes a single scalar score.**
|
|
10
|
+
*
|
|
11
|
+
* > *4.3 Make the verdict hierarchy explicit. `paired_verdict` per metric
|
|
12
|
+
* > decides; `underpowered` is not a pass; a Pareto frontier may only order
|
|
13
|
+
* > candidates that are already non-dominated and never promotes.*
|
|
14
|
+
* > verify: **a fixture where the frontier prefers a candidate whose
|
|
15
|
+
* > `paired_verdict` is `underpowered` produces no promotion.**
|
|
16
|
+
*
|
|
17
|
+
* ## Why a scalar is the defect and not merely a simplification
|
|
18
|
+
*
|
|
19
|
+
* A weighted total is a claim that the metrics are commensurable and that the
|
|
20
|
+
* author knew the exchange rate. Neither is established here. Worse, the
|
|
21
|
+
* collapse is lossy in exactly the direction that matters: a candidate that
|
|
22
|
+
* regresses one metric and wins three can outscore one that wins all four, and
|
|
23
|
+
* the report shows one number where the disagreement was. The vector keeps the
|
|
24
|
+
* disagreement visible and forces {@link promotionVerdict} to state which row
|
|
25
|
+
* refused.
|
|
26
|
+
*
|
|
27
|
+
* So the shape carries the guarantee rather than a comment asking for it:
|
|
28
|
+
* {@link MetricVector} has no total field, no weight field, and nothing in this
|
|
29
|
+
* module takes a vector and returns a number.
|
|
30
|
+
* `tests/scripts/evaluation_vector.test.ts` scans every file in `src/scripts`
|
|
31
|
+
* that mentions `MetricVector` for that construct set, in both polarities.
|
|
32
|
+
*
|
|
33
|
+
* ## The artifact-count row is inside the gate, not beside it
|
|
34
|
+
*
|
|
35
|
+
* Sprawl reported next to a gate is a note; sprawl reported inside it can
|
|
36
|
+
* refuse. {@link buildVector} REFUSES a vector that omits the
|
|
37
|
+
* {@link ARTIFACT_COUNT_METRIC} row, so a candidate cannot reach
|
|
38
|
+
* {@link promotionVerdict} without its artifact delta having been measured, and
|
|
39
|
+
* {@link promotionVerdict} blocks on a delta above its ceiling.
|
|
40
|
+
*
|
|
41
|
+
* The default ceiling is **0** — a candidate may not grow the artifact count
|
|
42
|
+
* unless the caller says so. That is a conservative default rather than a
|
|
43
|
+
* measured one, and it is stated as such: a curator `ADD` is a legitimate
|
|
44
|
+
* positive delta, and the caller that knows it is an `ADD` passes the ceiling
|
|
45
|
+
* it means.
|
|
46
|
+
*
|
|
47
|
+
* ## Two row kinds, because two things are being measured
|
|
48
|
+
*
|
|
49
|
+
* A paired row carries a {@link PairedVerdict} — direction decided by the exact
|
|
50
|
+
* sign test, with `underpowered` deliberately not a kind of pass. A counted row
|
|
51
|
+
* carries an integer delta read off the candidate, with no trials behind it.
|
|
52
|
+
* Forcing the artifact delta through a paired verdict would invent trials that
|
|
53
|
+
* do not exist; giving a metric row a bare number would let a caller put an
|
|
54
|
+
* outcome there without evidence. Both shapes exist so neither lie is available.
|
|
55
|
+
*/
|
|
56
|
+
import type { PairedVerdict, PairedVerdictKind } from './paired_verdict.js';
|
|
57
|
+
|
|
58
|
+
/** Which direction is better for a row. Read by {@link dominates}. */
|
|
59
|
+
export type MetricDirection = 'higher-better' | 'lower-better';
|
|
60
|
+
|
|
61
|
+
/** The counted row every vector must carry. Step 4.2 names it. */
|
|
62
|
+
export const ARTIFACT_COUNT_METRIC = 'artifact-count-delta';
|
|
63
|
+
|
|
64
|
+
export interface PairedRow {
|
|
65
|
+
kind: 'paired';
|
|
66
|
+
metric: string;
|
|
67
|
+
direction: MetricDirection;
|
|
68
|
+
verdict: PairedVerdict;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface CountedRow {
|
|
72
|
+
kind: 'counted';
|
|
73
|
+
metric: string;
|
|
74
|
+
direction: MetricDirection;
|
|
75
|
+
/** Signed delta against the baseline. No trials, no verdict, no inference. */
|
|
76
|
+
delta: number;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export type MetricRow = PairedRow | CountedRow;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* The evaluation record for one candidate.
|
|
83
|
+
*
|
|
84
|
+
* Deliberately absent: any field that would hold a summary number. Adding one
|
|
85
|
+
* is the failure this type exists to prevent, and the scanner test names it.
|
|
86
|
+
*/
|
|
87
|
+
export interface MetricVector {
|
|
88
|
+
candidate_id: string;
|
|
89
|
+
rows: readonly MetricRow[];
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export class VectorShapeError extends Error {
|
|
93
|
+
constructor(message: string) {
|
|
94
|
+
super(message);
|
|
95
|
+
this.name = 'VectorShapeError';
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Build a vector, refusing the three shapes that would make the gate lie:
|
|
101
|
+
* no rows at all, a duplicate metric name, or a missing artifact-count row.
|
|
102
|
+
*/
|
|
103
|
+
export function buildVector(candidate_id: string, rows: readonly MetricRow[]): MetricVector {
|
|
104
|
+
if (rows.length === 0) {
|
|
105
|
+
throw new VectorShapeError(`${candidate_id}: a vector with no rows measures nothing`);
|
|
106
|
+
}
|
|
107
|
+
const seen = new Set<string>();
|
|
108
|
+
for (const r of rows) {
|
|
109
|
+
if (seen.has(r.metric)) {
|
|
110
|
+
throw new VectorShapeError(`${candidate_id}: duplicate metric row '${r.metric}'`);
|
|
111
|
+
}
|
|
112
|
+
seen.add(r.metric);
|
|
113
|
+
}
|
|
114
|
+
if (!seen.has(ARTIFACT_COUNT_METRIC)) {
|
|
115
|
+
throw new VectorShapeError(
|
|
116
|
+
`${candidate_id}: missing the '${ARTIFACT_COUNT_METRIC}' row — the sprawl ` +
|
|
117
|
+
'measurement belongs inside the gate, so a vector without it cannot be evaluated',
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
return { candidate_id, rows: [...rows] };
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** The artifact-count row, or `null` on a vector that never went through {@link buildVector}. */
|
|
124
|
+
export function artifactCountRow(v: MetricVector): CountedRow | null {
|
|
125
|
+
for (const r of v.rows) {
|
|
126
|
+
if (r.metric === ARTIFACT_COUNT_METRIC && r.kind === 'counted') {
|
|
127
|
+
return r;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Row-level ordering: `-1` when `a` is worse, `1` when better, `0` when the two
|
|
135
|
+
* carry no ordering against each other.
|
|
136
|
+
*
|
|
137
|
+
* A paired row orders by VERDICT KIND, never by magnitude — `magnitude_mean`
|
|
138
|
+
* exists for triage and decides nothing (`paired_verdict.ts` header). An
|
|
139
|
+
* `underpowered` row is incomparable with everything including itself: it is
|
|
140
|
+
* not a worse pass, it is an absence of evidence, so it can neither win a row
|
|
141
|
+
* nor lose one.
|
|
142
|
+
*/
|
|
143
|
+
/**
|
|
144
|
+
* Paired-verdict ordering. `underpowered` is `null` — incomparable in both
|
|
145
|
+
* directions, because an absent measurement is not a worse pass.
|
|
146
|
+
*/
|
|
147
|
+
const VERDICT_RANK: Record<PairedVerdictKind, number | null> = {
|
|
148
|
+
pass: 2,
|
|
149
|
+
'no-change': 1,
|
|
150
|
+
regression: 0,
|
|
151
|
+
underpowered: null,
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
export function compareRow(a: MetricRow, b: MetricRow): -1 | 0 | 1 {
|
|
155
|
+
if (a.metric !== b.metric) {
|
|
156
|
+
throw new VectorShapeError(`cannot compare '${a.metric}' against '${b.metric}'`);
|
|
157
|
+
}
|
|
158
|
+
if (a.kind === 'counted' && b.kind === 'counted') {
|
|
159
|
+
if (a.delta === b.delta) return 0;
|
|
160
|
+
const aBetter = a.direction === 'higher-better' ? a.delta > b.delta : a.delta < b.delta;
|
|
161
|
+
return aBetter ? 1 : -1;
|
|
162
|
+
}
|
|
163
|
+
if (a.kind === 'paired' && b.kind === 'paired') {
|
|
164
|
+
const ra = VERDICT_RANK[a.verdict.kind];
|
|
165
|
+
const rb = VERDICT_RANK[b.verdict.kind];
|
|
166
|
+
if (ra === null || rb === null) return 0;
|
|
167
|
+
if (ra === rb) return 0;
|
|
168
|
+
return ra > rb ? 1 : -1;
|
|
169
|
+
}
|
|
170
|
+
return 0;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Pareto domination: `a` dominates `b` when no row is worse and at least one is
|
|
175
|
+
* better. Vectors must carry the same metric names — comparing different metric
|
|
176
|
+
* sets is a shape error, not a tie.
|
|
177
|
+
*/
|
|
178
|
+
export function dominates(a: MetricVector, b: MetricVector): boolean {
|
|
179
|
+
const bRows = new Map(b.rows.map((r) => [r.metric, r]));
|
|
180
|
+
if (a.rows.length !== b.rows.length) {
|
|
181
|
+
throw new VectorShapeError(
|
|
182
|
+
`${a.candidate_id} and ${b.candidate_id} carry different metric sets`,
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
let strictlyBetter = false;
|
|
186
|
+
for (const ar of a.rows) {
|
|
187
|
+
const br = bRows.get(ar.metric);
|
|
188
|
+
if (br === undefined) {
|
|
189
|
+
throw new VectorShapeError(
|
|
190
|
+
`${a.candidate_id} and ${b.candidate_id} carry different metric sets`,
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
const c = compareRow(ar, br);
|
|
194
|
+
if (c < 0) return false;
|
|
195
|
+
if (c > 0) strictlyBetter = true;
|
|
196
|
+
}
|
|
197
|
+
return strictlyBetter;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* The non-dominated set, in input order.
|
|
202
|
+
*
|
|
203
|
+
* ORDERING ONLY. This function promotes nothing and is not consulted by
|
|
204
|
+
* {@link promotionVerdict}; step 4.3's verify clause is precisely that a
|
|
205
|
+
* frontier preference cannot become a promotion. Membership here means "no
|
|
206
|
+
* other candidate beat this one on every row", which is a statement about the
|
|
207
|
+
* comparison set and not about whether the evidence concluded.
|
|
208
|
+
*/
|
|
209
|
+
export function paretoFrontier(vectors: readonly MetricVector[]): MetricVector[] {
|
|
210
|
+
return vectors.filter((v) => !vectors.some((o) => o !== v && dominates(o, v)));
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export interface PromotionOptions {
|
|
214
|
+
/** Largest artifact-count delta this candidate class may carry. Default 0. */
|
|
215
|
+
artifactDeltaCeiling?: number;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export interface PromotionVerdict {
|
|
219
|
+
promote: boolean;
|
|
220
|
+
/** Every row that refused, by metric name. Empty iff `promote` is true. */
|
|
221
|
+
blocking: readonly string[];
|
|
222
|
+
/** One sentence a report can print verbatim. */
|
|
223
|
+
reason: string;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* The ONLY promoter in this module, and the whole hierarchy in one place.
|
|
228
|
+
*
|
|
229
|
+
* Refuses on, in this order: a regression on any paired row; an `underpowered`
|
|
230
|
+
* paired row (not a pass — the remedy is more trials, not a promotion); an
|
|
231
|
+
* artifact-count delta above the ceiling; a vector with no paired row at all;
|
|
232
|
+
* and a vector where every paired row concluded `no-change`. The last is the
|
|
233
|
+
* one worth stating: `no-change` is a real verdict and it says the candidate
|
|
234
|
+
* did not help, so a vector of them is a decided absence of improvement rather
|
|
235
|
+
* than a clean sheet.
|
|
236
|
+
*/
|
|
237
|
+
export function promotionVerdict(v: MetricVector, opts: PromotionOptions = {}): PromotionVerdict {
|
|
238
|
+
const ceiling = opts.artifactDeltaCeiling ?? 0;
|
|
239
|
+
const blocking: string[] = [];
|
|
240
|
+
const notes: string[] = [];
|
|
241
|
+
let pairedRows = 0;
|
|
242
|
+
let passRows = 0;
|
|
243
|
+
|
|
244
|
+
for (const r of v.rows) {
|
|
245
|
+
if (r.kind === 'paired') {
|
|
246
|
+
pairedRows += 1;
|
|
247
|
+
if (r.verdict.kind === 'pass') passRows += 1;
|
|
248
|
+
if (r.verdict.kind === 'regression') {
|
|
249
|
+
blocking.push(r.metric);
|
|
250
|
+
notes.push(`${r.metric} regressed`);
|
|
251
|
+
} else if (r.verdict.kind === 'underpowered') {
|
|
252
|
+
blocking.push(r.metric);
|
|
253
|
+
notes.push(`${r.metric} is underpowered, which is not a pass`);
|
|
254
|
+
}
|
|
255
|
+
} else if (r.metric === ARTIFACT_COUNT_METRIC && r.delta > ceiling) {
|
|
256
|
+
blocking.push(r.metric);
|
|
257
|
+
notes.push(`artifact-count delta ${String(r.delta)} exceeds ceiling ${String(ceiling)}`);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if (pairedRows === 0) {
|
|
262
|
+
blocking.push('<no-paired-row>');
|
|
263
|
+
notes.push('no paired verdict in the vector, so no metric concluded');
|
|
264
|
+
} else if (passRows === 0 && blocking.length === 0) {
|
|
265
|
+
blocking.push('<no-pass-row>');
|
|
266
|
+
notes.push('every paired row concluded no-change, so nothing improved');
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if (blocking.length > 0) {
|
|
270
|
+
return {
|
|
271
|
+
promote: false,
|
|
272
|
+
blocking,
|
|
273
|
+
reason: `${v.candidate_id} is not promotable: ${notes.join('; ')}`,
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
return {
|
|
277
|
+
promote: true,
|
|
278
|
+
blocking: [],
|
|
279
|
+
reason:
|
|
280
|
+
`${v.candidate_id} carries ${String(pairedRows)} paired row(s), ${String(passRows)} of them a pass, ` +
|
|
281
|
+
`none regressed or underpowered, artifact delta within ceiling ${String(ceiling)}`,
|
|
282
|
+
};
|
|
283
|
+
}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evaluator promotion — a new evaluator earns its seat by cross-grading, or it
|
|
3
|
+
* does not get one.
|
|
4
|
+
*
|
|
5
|
+
* `road-to-governed-harness-evolution` Phase 4, step 4.7.
|
|
6
|
+
*
|
|
7
|
+
* > *Reuse the discrimination and hygiene machinery. `eval_publication`'s
|
|
8
|
+
* > `PlantedItem` for plants, `judge_hygiene` for order-swap. Add the
|
|
9
|
+
* > evaluator-promotion procedure the master omitted: an old and a new
|
|
10
|
+
* > evaluator must cross-grade frozen candidate sets, and evaluator promotion
|
|
11
|
+
* > itself requires discrimination plants.*
|
|
12
|
+
* > verify: **a planted candidate the control arm also satisfies is reported as
|
|
13
|
+
* > a discrimination deficit, not as a win; an evaluator change with no
|
|
14
|
+
* > cross-grade is refused.**
|
|
15
|
+
*
|
|
16
|
+
* ## Reuse, not reimplementation
|
|
17
|
+
*
|
|
18
|
+
* Risk 1 on this roadmap is a parallel rebuild of machinery that already
|
|
19
|
+
* exists, committed four times by the source proposals. So nothing here scores
|
|
20
|
+
* a plant, classifies an assertion, or decides a paired verdict:
|
|
21
|
+
* {@link reportPlants} delegates to `eval_publication.discriminationDeficit`
|
|
22
|
+
* and {@link assertEvaluatorPromotable} delegates to
|
|
23
|
+
* `judge_hygiene.auditAssertions`. What this module adds is the one thing
|
|
24
|
+
* neither has: the REFUSAL that turns an evaluator swap into a gated event.
|
|
25
|
+
*
|
|
26
|
+
* ## Why a satisfied plant can be a deficit rather than a win
|
|
27
|
+
*
|
|
28
|
+
* A plant exists to be recoverable only via the behaviour under test. If the
|
|
29
|
+
* control arm also satisfies it, then the item measured general competence and
|
|
30
|
+
* the treatment's success over it is not evidence about the treatment — the two
|
|
31
|
+
* arms scored the same for different-looking reasons. Counting it as a win is
|
|
32
|
+
* the exact inflation `eval_publication`'s header describes, so
|
|
33
|
+
* {@link reportPlants} moves it into `discrimination_deficits` and, critically,
|
|
34
|
+
* strips its `requires_artifact_behaviour` flag before handing the set to
|
|
35
|
+
* `discriminationDeficit` — otherwise a fixture set whose every discriminating
|
|
36
|
+
* plant turned out to be non-discriminating in practice would still pass the
|
|
37
|
+
* pre-run check on its declared intent.
|
|
38
|
+
*
|
|
39
|
+
* ## Order-swap is carried as a declared property, and refused when absent
|
|
40
|
+
*
|
|
41
|
+
* `judge_hygiene`'s header records that blinding and the order-swap are already
|
|
42
|
+
* met upstream by `check_quality_regression.evaluatePair`, which judges every
|
|
43
|
+
* pair in both orders and resolves a flip to `inconsistent`. This module does
|
|
44
|
+
* not re-implement that; it requires the cross-grade to DECLARE that it ran
|
|
45
|
+
* that way ({@link CrossGrade.order_swapped}) and refuses the promotion when it
|
|
46
|
+
* did not. That is an honest boundary: the property is asserted by the caller
|
|
47
|
+
* and checked here, not observed here.
|
|
48
|
+
*/
|
|
49
|
+
import { discriminationDeficit, type PlantedItem } from './eval_publication.js';
|
|
50
|
+
import { auditAssertions, type AssertionObservation } from './judge_hygiene.js';
|
|
51
|
+
|
|
52
|
+
/** One plant, and what each arm actually did with it. */
|
|
53
|
+
export interface PlantOutcome {
|
|
54
|
+
item: PlantedItem;
|
|
55
|
+
treatment_satisfied: boolean;
|
|
56
|
+
control_satisfied: boolean;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface DiscriminationDeficitFinding {
|
|
60
|
+
id: string;
|
|
61
|
+
reason: string;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface PlantReport {
|
|
65
|
+
/** Plants the treatment satisfied and the control did not. The measurement. */
|
|
66
|
+
wins: readonly string[];
|
|
67
|
+
/** Plants the control also satisfied. Never wins, whatever the treatment did. */
|
|
68
|
+
discrimination_deficits: readonly DiscriminationDeficitFinding[];
|
|
69
|
+
/**
|
|
70
|
+
* The set-level verdict from `eval_publication.discriminationDeficit`, run
|
|
71
|
+
* over the EFFECTIVE set (observed, not declared). Non-null means the set
|
|
72
|
+
* cannot adjudicate at all.
|
|
73
|
+
*/
|
|
74
|
+
set_deficit: string | null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Classify every plant outcome. See the header for why a shared satisfaction is a deficit. */
|
|
78
|
+
export function reportPlants(outcomes: readonly PlantOutcome[]): PlantReport {
|
|
79
|
+
const wins: string[] = [];
|
|
80
|
+
const deficits: DiscriminationDeficitFinding[] = [];
|
|
81
|
+
const effective: PlantedItem[] = [];
|
|
82
|
+
|
|
83
|
+
for (const o of outcomes) {
|
|
84
|
+
if (o.control_satisfied) {
|
|
85
|
+
deficits.push({
|
|
86
|
+
id: o.item.id,
|
|
87
|
+
reason:
|
|
88
|
+
`the control arm also satisfied '${o.item.id}', so it measures general ` +
|
|
89
|
+
'competence rather than the behaviour under test — a discrimination deficit, not a win',
|
|
90
|
+
});
|
|
91
|
+
effective.push({ id: o.item.id, requires_artifact_behaviour: false });
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
effective.push({ id: o.item.id, requires_artifact_behaviour: o.item.requires_artifact_behaviour });
|
|
95
|
+
if (o.treatment_satisfied && o.item.requires_artifact_behaviour) {
|
|
96
|
+
wins.push(o.item.id);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
wins,
|
|
102
|
+
discrimination_deficits: deficits,
|
|
103
|
+
set_deficit: discriminationDeficit(effective),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** The frozen candidate set both evaluators must grade. Frozen means: named and enumerated. */
|
|
108
|
+
export interface FrozenCandidateSet {
|
|
109
|
+
id: string;
|
|
110
|
+
candidate_ids: readonly string[];
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export interface CrossGrade {
|
|
114
|
+
from_evaluator: string;
|
|
115
|
+
to_evaluator: string;
|
|
116
|
+
/** Must equal the change's frozen set id — a cross-grade of some other set proves nothing. */
|
|
117
|
+
frozen_set_id: string;
|
|
118
|
+
/** Candidate ids the OLD evaluator graded. */
|
|
119
|
+
graded_by_from: readonly string[];
|
|
120
|
+
/** Candidate ids the NEW evaluator graded. */
|
|
121
|
+
graded_by_to: readonly string[];
|
|
122
|
+
/**
|
|
123
|
+
* Declared by the caller: every pair was judged in both orders upstream
|
|
124
|
+
* (`check_quality_regression.evaluatePair`). See the header — asserted, not
|
|
125
|
+
* observed here.
|
|
126
|
+
*/
|
|
127
|
+
order_swapped: boolean;
|
|
128
|
+
/** Rubric assertions used by the grading, audited via `judge_hygiene`. */
|
|
129
|
+
assertions: readonly AssertionObservation[];
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export interface EvaluatorChange {
|
|
133
|
+
from: string;
|
|
134
|
+
to: string;
|
|
135
|
+
frozen_set: FrozenCandidateSet;
|
|
136
|
+
/** `null` is the case step 4.7 names: an evaluator change with no cross-grade. */
|
|
137
|
+
cross_grade: CrossGrade | null;
|
|
138
|
+
/** Discrimination plants. Evaluator promotion requires them, per step 4.7. */
|
|
139
|
+
plants: readonly PlantOutcome[];
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export class EvaluatorPromotionRefused extends Error {
|
|
143
|
+
readonly reasons: readonly string[];
|
|
144
|
+
constructor(reasons: readonly string[]) {
|
|
145
|
+
super(`evaluator promotion refused: ${reasons.join('; ')}`);
|
|
146
|
+
this.name = 'EvaluatorPromotionRefused';
|
|
147
|
+
this.reasons = reasons;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function missing(required: readonly string[], graded: readonly string[]): string[] {
|
|
152
|
+
const seen = new Set(graded);
|
|
153
|
+
return required.filter((id) => !seen.has(id));
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Throw {@link EvaluatorPromotionRefused} unless every condition holds.
|
|
158
|
+
*
|
|
159
|
+
* Fail-closed by construction: the function has no permissive path and no
|
|
160
|
+
* option object that could relax one. A caller who wants to promote an
|
|
161
|
+
* evaluator without a cross-grade has to delete this call, which is visible in
|
|
162
|
+
* a diff, rather than pass a flag, which is not.
|
|
163
|
+
*/
|
|
164
|
+
export function assertEvaluatorPromotable(change: EvaluatorChange): void {
|
|
165
|
+
const reasons: string[] = [];
|
|
166
|
+
const cg = change.cross_grade;
|
|
167
|
+
|
|
168
|
+
if (cg === null) {
|
|
169
|
+
reasons.push(
|
|
170
|
+
`no cross-grade between '${change.from}' and '${change.to}' — an evaluator change ` +
|
|
171
|
+
'without one has no evidence that the two agree on anything',
|
|
172
|
+
);
|
|
173
|
+
} else {
|
|
174
|
+
if (cg.frozen_set_id !== change.frozen_set.id) {
|
|
175
|
+
reasons.push(
|
|
176
|
+
`the cross-grade names frozen set '${cg.frozen_set_id}' but the change is over ` +
|
|
177
|
+
`'${change.frozen_set.id}'`,
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
if (cg.from_evaluator !== change.from || cg.to_evaluator !== change.to) {
|
|
181
|
+
reasons.push(
|
|
182
|
+
`the cross-grade is between '${cg.from_evaluator}' and '${cg.to_evaluator}', ` +
|
|
183
|
+
`not between '${change.from}' and '${change.to}'`,
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
const missFrom = missing(change.frozen_set.candidate_ids, cg.graded_by_from);
|
|
187
|
+
const missTo = missing(change.frozen_set.candidate_ids, cg.graded_by_to);
|
|
188
|
+
if (missFrom.length > 0) {
|
|
189
|
+
reasons.push(`'${change.from}' did not grade: ${missFrom.join(', ')}`);
|
|
190
|
+
}
|
|
191
|
+
if (missTo.length > 0) {
|
|
192
|
+
reasons.push(`'${change.to}' did not grade: ${missTo.join(', ')}`);
|
|
193
|
+
}
|
|
194
|
+
if (!cg.order_swapped) {
|
|
195
|
+
reasons.push('the cross-grade did not declare the order-swap, so a position bias is unexcluded');
|
|
196
|
+
}
|
|
197
|
+
const audit = auditAssertions(cg.assertions);
|
|
198
|
+
const alwaysPass = audit.findings.filter((f) => f.verdict === 'non-discriminating-always-pass');
|
|
199
|
+
if (alwaysPass.length > 0) {
|
|
200
|
+
reasons.push(
|
|
201
|
+
`${String(alwaysPass.length)} assertion(s) pass in both arms and narrow nothing: ` +
|
|
202
|
+
alwaysPass.map((f) => f.id).join(', '),
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (change.plants.length === 0) {
|
|
208
|
+
reasons.push('evaluator promotion requires discrimination plants and this change carries none');
|
|
209
|
+
} else {
|
|
210
|
+
const report = reportPlants(change.plants);
|
|
211
|
+
if (report.set_deficit !== null) {
|
|
212
|
+
reasons.push(`plants cannot discriminate: ${report.set_deficit}`);
|
|
213
|
+
}
|
|
214
|
+
if (report.discrimination_deficits.length > 0) {
|
|
215
|
+
reasons.push(
|
|
216
|
+
`${String(report.discrimination_deficits.length)} plant(s) were also satisfied by the control arm: ` +
|
|
217
|
+
report.discrimination_deficits.map((d) => d.id).join(', '),
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (reasons.length > 0) {
|
|
223
|
+
throw new EvaluatorPromotionRefused(reasons);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One evidence-basis vocabulary (`road-to-delivered-cost-truth` step 4.1).
|
|
3
|
+
*
|
|
4
|
+
* Every number this suite reports rests on something, and until now the tree
|
|
5
|
+
* said what on at least three incompatible partial scales:
|
|
6
|
+
*
|
|
7
|
+
* `_lib/orchestration_record.ts` `'measured' | 'estimated'`
|
|
8
|
+
* `preamble_byte_census.ts` `'measured_local_file' | 'residual'`
|
|
9
|
+
* `_lib/value_ladder.ts` `'measured' | 'estimated' | 'vendor-claim' | 'pending' | 'available'`
|
|
10
|
+
*
|
|
11
|
+
* They overlap, disagree on naming for the same idea, and none of them can
|
|
12
|
+
* express "a model judged this" — which several surfaces in this tree do report.
|
|
13
|
+
* This module is the reconciliation, and it is deliberately NOT a fourth
|
|
14
|
+
* vocabulary sitting beside the three: the migration of the first two ships in
|
|
15
|
+
* the same change, and the third is documented as an unmigrated variant with the
|
|
16
|
+
* reason, rather than left looking like an oversight.
|
|
17
|
+
*
|
|
18
|
+
* WHAT EACH VALUE RESTS ON — one sentence, which is the whole contract:
|
|
19
|
+
*
|
|
20
|
+
* measured an instrument in this repository produced it from real input
|
|
21
|
+
* estimated derived by arithmetic from measured values, not itself observed
|
|
22
|
+
* inferred concluded from structure or convention, with no measurement behind it
|
|
23
|
+
* provider-reported a third party stated it and we recorded it unverified
|
|
24
|
+
* model-judged a language model's assessment, reproducible only in distribution
|
|
25
|
+
* unknown nothing establishes it, and that is the honest answer
|
|
26
|
+
*
|
|
27
|
+
* `unknown` is a first-class value, not a failure code. A surface that cannot
|
|
28
|
+
* establish a basis says `unknown`; it does not pick the nearest optimistic one.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
export const EVIDENCE_BASES = [
|
|
32
|
+
'measured',
|
|
33
|
+
'estimated',
|
|
34
|
+
'inferred',
|
|
35
|
+
'provider-reported',
|
|
36
|
+
'model-judged',
|
|
37
|
+
'unknown',
|
|
38
|
+
] as const;
|
|
39
|
+
export type EvidenceBasis = (typeof EVIDENCE_BASES)[number];
|
|
40
|
+
|
|
41
|
+
/** What each value rests on. Printed verbatim by surfaces that explain themselves. */
|
|
42
|
+
export const EVIDENCE_BASIS_MEANING: Record<EvidenceBasis, string> = {
|
|
43
|
+
measured: 'an instrument in this repository produced it from real input',
|
|
44
|
+
estimated: 'derived by arithmetic from measured values, not itself observed',
|
|
45
|
+
inferred: 'concluded from structure or convention, with no measurement behind it',
|
|
46
|
+
'provider-reported': 'a third party stated it and we recorded it unverified',
|
|
47
|
+
'model-judged': "a language model's assessment, reproducible only in distribution",
|
|
48
|
+
unknown: 'nothing establishes it, and that is the honest answer',
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export function isEvidenceBasis(v: unknown): v is EvidenceBasis {
|
|
52
|
+
return typeof v === 'string' && (EVIDENCE_BASES as readonly string[]).includes(v);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Ordering by how much a reader may lean on the value.
|
|
57
|
+
*
|
|
58
|
+
* Used for reporting, never for arithmetic: two figures on different bases do
|
|
59
|
+
* not become comparable by being ranked, and nothing here should be read as
|
|
60
|
+
* licence to average them.
|
|
61
|
+
*/
|
|
62
|
+
export const EVIDENCE_BASIS_STRENGTH: Record<EvidenceBasis, number> = {
|
|
63
|
+
measured: 5,
|
|
64
|
+
estimated: 4,
|
|
65
|
+
'provider-reported': 3,
|
|
66
|
+
inferred: 2,
|
|
67
|
+
'model-judged': 1,
|
|
68
|
+
unknown: 0,
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/** The weakest basis in a set — what a derived figure may honestly claim. */
|
|
72
|
+
export function weakestBasis(bases: readonly EvidenceBasis[]): EvidenceBasis {
|
|
73
|
+
if (bases.length === 0) return 'unknown';
|
|
74
|
+
return bases.reduce((a, b) => (EVIDENCE_BASIS_STRENGTH[b] < EVIDENCE_BASIS_STRENGTH[a] ? b : a));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
// Basis TAGS — a basis plus, where the basis is `estimated`, its method
|
|
79
|
+
// ---------------------------------------------------------------------------
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* `estimated` on its own is not a basis, it is a category.
|
|
83
|
+
*
|
|
84
|
+
* Two figures both marked `estimated` can differ by an order of magnitude in
|
|
85
|
+
* how much they should be trusted — one derived by arithmetic from measured
|
|
86
|
+
* inputs, one from a response-length heuristic — and a report that renders them
|
|
87
|
+
* identically has told the reader nothing they can act on. So wherever a figure
|
|
88
|
+
* is estimated, the METHOD travels with it.
|
|
89
|
+
*
|
|
90
|
+
* Every other basis is self-describing and takes no suffix: `measured` names
|
|
91
|
+
* the instrument by existing, `unknown` has no method by definition, and
|
|
92
|
+
* `model-judged` and `provider-reported` name their source in the value itself.
|
|
93
|
+
*
|
|
94
|
+
* road-to-experience-loop-broadening step 6.2.
|
|
95
|
+
*/
|
|
96
|
+
export type BasisTag = Exclude<EvidenceBasis, 'estimated'> | `estimated:${string}`;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* A bare `estimated` is REJECTED, and that is the whole point of the type.
|
|
100
|
+
* `estimated:` with nothing after it is rejected too — an empty method is the
|
|
101
|
+
* same omission wearing a colon.
|
|
102
|
+
*/
|
|
103
|
+
export function isBasisTag(v: unknown): v is BasisTag {
|
|
104
|
+
if (typeof v !== 'string') return false;
|
|
105
|
+
if (v === 'estimated') return false;
|
|
106
|
+
if (v.startsWith('estimated:')) return v.slice('estimated:'.length).trim().length > 0;
|
|
107
|
+
return isEvidenceBasis(v);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** The basis half of a tag, for grouping and for rendering the meaning table. */
|
|
111
|
+
export function basisOf(tag: BasisTag): EvidenceBasis {
|
|
112
|
+
return tag.startsWith('estimated:') ? 'estimated' : (tag as EvidenceBasis);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** The method half, or `null` for every non-estimated basis. */
|
|
116
|
+
export function methodOf(tag: BasisTag): string | null {
|
|
117
|
+
return tag.startsWith('estimated:') ? tag.slice('estimated:'.length) : null;
|
|
118
|
+
}
|
|
@@ -60,6 +60,14 @@ export const ALLOWLIST_PREFIXES: readonly (readonly string[])[] = [
|
|
|
60
60
|
// report exists. Read-only, deterministic, model-free, and already run in
|
|
61
61
|
// CI (`rule-backstops.yml`) for its own reasons.
|
|
62
62
|
['check_enforcement_denominator'],
|
|
63
|
+
// road-to-source-silence Phase 5.3. The source-confidentiality gate's exit
|
|
64
|
+
// code IS the verdict for `claim:plaintext-source-attribution`: 0 means zero
|
|
65
|
+
// deny-pattern matches in tracked content AND in every tracked path, plus the
|
|
66
|
+
// attribution-shape block count at or below its ratchet baseline. An
|
|
67
|
+
// existence-check pointer would have gone stale the first time somebody added
|
|
68
|
+
// a name. Read-only, deterministic, model-free, and already run in CI for its
|
|
69
|
+
// own reasons — the same class as its neighbours here.
|
|
70
|
+
['check_no_external_sources'],
|
|
63
71
|
['check_token_regression'],
|
|
64
72
|
['lint_agent_security'],
|
|
65
73
|
['measure_lexical_ranking'],
|