@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
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider-recognition leakage bench — does anonymisation actually anonymise?
|
|
3
|
+
*
|
|
4
|
+
* `road-to-inbox-harvest-2026-08-e-council-topology-evidence` Phase 3, step 3.3:
|
|
5
|
+
* "ask reviewers and judges to guess the provider family from anonymized
|
|
6
|
+
* answers; measure recognition against chance. **Measurement first** — not a
|
|
7
|
+
* justification for rewriting anything." Verified by "recognition rate and
|
|
8
|
+
* chance baseline are both published".
|
|
9
|
+
*
|
|
10
|
+
* The council already strips provider identity from a peer-review or chairman
|
|
11
|
+
* transcript (`consensus.anonymize_responses`, `blind_review.build_blind_labels`).
|
|
12
|
+
* Stripping the LABEL is not the same as removing the SIGNAL: models have house
|
|
13
|
+
* styles, and a reviewer that can name the author of `Response-B` is not blind,
|
|
14
|
+
* whatever the header says. Nothing in this tree had ever measured that, so
|
|
15
|
+
* "the council is blind" was an assumption with a mechanism behind it rather
|
|
16
|
+
* than a result.
|
|
17
|
+
*
|
|
18
|
+
* ── This module measures; it does not decide ────────────────────────────────
|
|
19
|
+
* Step 3.4 (style normalization) is gated on this bench's result, and the gate
|
|
20
|
+
* lives here as `normalizationGateVerdict` so the gate cannot be satisfied by
|
|
21
|
+
* prose. Its default with no data is `unrun`, which is NOT `below-bar`: the
|
|
22
|
+
* difference is the whole point of the step. A null is what a measurement
|
|
23
|
+
* returns; `unrun` is what you have before one.
|
|
24
|
+
*
|
|
25
|
+
* ── Why the transport is injected ───────────────────────────────────────────
|
|
26
|
+
* Everything here is a pure function over data plus one `RaterFn` seam, the
|
|
27
|
+
* same LIBRARY/RUNNER split `check_quality_regression.ts:19-24` uses: the
|
|
28
|
+
* library is unit-tested against a scripted rater at zero cost, and the live
|
|
29
|
+
* pass — which is a paid council call per item per rater — is the operator
|
|
30
|
+
* step. A bench that could only be exercised by spending is a bench nobody
|
|
31
|
+
* regression-tests.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
/** Provider families a rater may name. Closed set: an open guess is ungradeable. */
|
|
35
|
+
export interface LeakageOptions {
|
|
36
|
+
/** The closed option list shown to every rater, in a fixed order. */
|
|
37
|
+
readonly families: readonly string[];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** One anonymised answer whose true author is known to the scorer, never to the rater. */
|
|
41
|
+
export interface LeakageItem {
|
|
42
|
+
readonly id: string;
|
|
43
|
+
/** The anonymised body exactly as a reviewer or judge would receive it. */
|
|
44
|
+
readonly text: string;
|
|
45
|
+
/** Ground truth. MUST be a member of `LeakageOptions.families`. */
|
|
46
|
+
readonly true_family: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** What a rater answered for one item. `null` = declined or unparseable. */
|
|
50
|
+
export interface LeakageGuess {
|
|
51
|
+
readonly rater: string;
|
|
52
|
+
readonly item_id: string;
|
|
53
|
+
readonly guess: string | null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The paid seam. Given the closed option list and one anonymised body, return
|
|
58
|
+
* the rater's guess, or `null` when it declined or its answer did not parse.
|
|
59
|
+
*/
|
|
60
|
+
export type RaterFn = (rater: string, item: LeakageItem, options: LeakageOptions) => string | null;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* The prompt a rater sees. Deliberately narrow: it asks ONLY for a family name
|
|
64
|
+
* from the closed list, so a rater cannot pass by hedging and the answer is
|
|
65
|
+
* gradeable without an LLM in the scoring loop.
|
|
66
|
+
*
|
|
67
|
+
* The body is NOT fenced here even though it is untrusted, and that is a
|
|
68
|
+
* deliberate difference from `build_peer_review_user_prompt`. Fencing a body
|
|
69
|
+
* inserts a nonce and a security preamble around it; this bench measures how
|
|
70
|
+
* recognisable a body is, so anything the bench adds to the body is a confound
|
|
71
|
+
* the live path does not have. The rater is asked for one word from a closed
|
|
72
|
+
* list and its answer is matched against that list, so an injected instruction
|
|
73
|
+
* has no schema to alter — the risk fencing buys back is absent by construction.
|
|
74
|
+
*/
|
|
75
|
+
export function buildRecognitionPrompt(item: LeakageItem, options: LeakageOptions): string {
|
|
76
|
+
return [
|
|
77
|
+
'Below is one anonymised answer produced by an AI model. Its provider',
|
|
78
|
+
'identity has been stripped. Guess which provider family wrote it.',
|
|
79
|
+
'',
|
|
80
|
+
`Answer with EXACTLY one of: ${options.families.join(', ')}`,
|
|
81
|
+
'Answer `unknown` if you genuinely cannot tell. Do not explain.',
|
|
82
|
+
'',
|
|
83
|
+
'---',
|
|
84
|
+
'',
|
|
85
|
+
item.text,
|
|
86
|
+
].join('\n');
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** Run the bench over `items` for each rater, via the injected paid seam. */
|
|
90
|
+
export function collectGuesses(
|
|
91
|
+
raters: readonly string[],
|
|
92
|
+
items: readonly LeakageItem[],
|
|
93
|
+
options: LeakageOptions,
|
|
94
|
+
ask: RaterFn,
|
|
95
|
+
): LeakageGuess[] {
|
|
96
|
+
const out: LeakageGuess[] = [];
|
|
97
|
+
for (const rater of raters) {
|
|
98
|
+
for (const item of items) {
|
|
99
|
+
const raw = ask(rater, item, options);
|
|
100
|
+
const guess = raw !== null && options.families.includes(raw) ? raw : null;
|
|
101
|
+
out.push({ rater, item_id: item.id, guess });
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return out;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface RecognitionResult {
|
|
108
|
+
readonly rater: string;
|
|
109
|
+
/** Guesses attempted, gradeable or not. */
|
|
110
|
+
readonly attempted: number;
|
|
111
|
+
/** Guesses that named a family in the closed list. */
|
|
112
|
+
readonly gradeable: number;
|
|
113
|
+
readonly correct: number;
|
|
114
|
+
/** `correct / gradeable`, or `null` when nothing was gradeable. */
|
|
115
|
+
readonly recognition_rate: number | null;
|
|
116
|
+
/**
|
|
117
|
+
* Chance under uniform guessing over the closed list — `1 / families`.
|
|
118
|
+
*/
|
|
119
|
+
readonly chance_uniform: number;
|
|
120
|
+
/**
|
|
121
|
+
* Chance for the best CONSTANT guesser: the largest share any single family
|
|
122
|
+
* holds in the graded items. Published beside the uniform baseline because
|
|
123
|
+
* a skewed corpus makes uniform chance the wrong bar — a rater that always
|
|
124
|
+
* says the majority family beats `1/k` while recognising nothing.
|
|
125
|
+
*/
|
|
126
|
+
readonly chance_majority: number;
|
|
127
|
+
/**
|
|
128
|
+
* One-sided exact binomial tail: P(at least `correct` successes in
|
|
129
|
+
* `gradeable` trials at the STRICTER of the two baselines). `null` when
|
|
130
|
+
* nothing was gradeable.
|
|
131
|
+
*/
|
|
132
|
+
readonly p_value: number | null;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/** Score one rater's guesses against ground truth. */
|
|
136
|
+
export function scoreRecognition(
|
|
137
|
+
rater: string,
|
|
138
|
+
guesses: readonly LeakageGuess[],
|
|
139
|
+
items: readonly LeakageItem[],
|
|
140
|
+
options: LeakageOptions,
|
|
141
|
+
): RecognitionResult {
|
|
142
|
+
const truth = new Map(items.map((i) => [i.id, i.true_family]));
|
|
143
|
+
const mine = guesses.filter((g) => g.rater === rater);
|
|
144
|
+
let gradeable = 0;
|
|
145
|
+
let correct = 0;
|
|
146
|
+
const gradedFamilies: string[] = [];
|
|
147
|
+
for (const g of mine) {
|
|
148
|
+
if (g.guess === null) {
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
const t = truth.get(g.item_id);
|
|
152
|
+
if (t === undefined) {
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
gradeable += 1;
|
|
156
|
+
gradedFamilies.push(t);
|
|
157
|
+
if (g.guess === t) {
|
|
158
|
+
correct += 1;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
const k = options.families.length;
|
|
162
|
+
const chance_uniform = k > 0 ? 1 / k : 0;
|
|
163
|
+
const counts = new Map<string, number>();
|
|
164
|
+
for (const f of gradedFamilies) {
|
|
165
|
+
counts.set(f, (counts.get(f) ?? 0) + 1);
|
|
166
|
+
}
|
|
167
|
+
const chance_majority = gradeable > 0 ? Math.max(...counts.values()) / gradeable : 0;
|
|
168
|
+
const bar = Math.max(chance_uniform, chance_majority);
|
|
169
|
+
return {
|
|
170
|
+
rater,
|
|
171
|
+
attempted: mine.length,
|
|
172
|
+
gradeable,
|
|
173
|
+
correct,
|
|
174
|
+
recognition_rate: gradeable > 0 ? correct / gradeable : null,
|
|
175
|
+
chance_uniform,
|
|
176
|
+
chance_majority,
|
|
177
|
+
p_value: gradeable > 0 ? binomialUpperTail(correct, gradeable, bar) : null,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* P(X >= k) for X ~ Binomial(n, p), computed exactly.
|
|
183
|
+
*
|
|
184
|
+
* Exact rather than normal-approximated because this bench's honest sample size
|
|
185
|
+
* is small — a few dozen graded items — and a normal approximation at n=20 is
|
|
186
|
+
* the kind of shortcut that turns a null into a finding.
|
|
187
|
+
*/
|
|
188
|
+
export function binomialUpperTail(k: number, n: number, p: number): number {
|
|
189
|
+
if (n <= 0) {
|
|
190
|
+
return 1;
|
|
191
|
+
}
|
|
192
|
+
if (k <= 0) {
|
|
193
|
+
return 1;
|
|
194
|
+
}
|
|
195
|
+
if (p <= 0) {
|
|
196
|
+
return k > 0 ? 0 : 1;
|
|
197
|
+
}
|
|
198
|
+
if (p >= 1) {
|
|
199
|
+
return k <= n ? 1 : 0;
|
|
200
|
+
}
|
|
201
|
+
let total = 0;
|
|
202
|
+
for (let i = k; i <= n; i += 1) {
|
|
203
|
+
total += Math.exp(_logChoose(n, i) + i * Math.log(p) + (n - i) * Math.log1p(-p));
|
|
204
|
+
}
|
|
205
|
+
return Math.min(1, Math.max(0, total));
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function _logChoose(n: number, k: number): number {
|
|
209
|
+
return _logGamma(n + 1) - _logGamma(k + 1) - _logGamma(n - k + 1);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/** Lanczos log-gamma — enough precision for the small n this bench grades. */
|
|
213
|
+
function _logGamma(x: number): number {
|
|
214
|
+
const g = [
|
|
215
|
+
76.18009172947146, -86.5053203294167, 24.01409824083091, -1.231739572450155, 0.1208650973866179e-2,
|
|
216
|
+
-0.5395239384953e-5,
|
|
217
|
+
];
|
|
218
|
+
let y = x;
|
|
219
|
+
let tmp = x + 5.5;
|
|
220
|
+
tmp -= (x + 0.5) * Math.log(tmp);
|
|
221
|
+
let ser = 1.000000000190015;
|
|
222
|
+
for (let j = 0; j < 6; j += 1) {
|
|
223
|
+
y += 1;
|
|
224
|
+
ser += (g[j] as number) / y;
|
|
225
|
+
}
|
|
226
|
+
return -tmp + Math.log((2.5066282746310005 * ser) / x);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// ── Step 3.4 — the gate style normalization has to clear ────────────────────
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* The step's two conditions, verbatim: normalization lands only if this tree's
|
|
233
|
+
* own leakage bench shows "materially above-chance recognition **and** that
|
|
234
|
+
* recognition correlates with judgment distortion".
|
|
235
|
+
*/
|
|
236
|
+
export interface NormalizationGateInput {
|
|
237
|
+
/** Per-rater recognition results. Empty = the bench has not been run. */
|
|
238
|
+
readonly recognition: readonly RecognitionResult[];
|
|
239
|
+
/**
|
|
240
|
+
* Whether a SEPARATE measurement established that recognition correlates
|
|
241
|
+
* with judgment distortion. `null` when that arm has not been run — which is
|
|
242
|
+
* not the same as "measured and found absent", and is why this is
|
|
243
|
+
* three-valued rather than a boolean.
|
|
244
|
+
*/
|
|
245
|
+
readonly distortion_correlated: boolean | null;
|
|
246
|
+
/** Significance bar for "materially above chance". */
|
|
247
|
+
readonly alpha?: number;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export type NormalizationVerdict =
|
|
251
|
+
/** The bench has not produced data. Not a null — nothing was measured. */
|
|
252
|
+
| 'unrun'
|
|
253
|
+
/** Measured, and at least one condition failed. Normalization must NOT land. */
|
|
254
|
+
| 'below-bar'
|
|
255
|
+
/** Both conditions recorded met. Normalization is permitted, still not required. */
|
|
256
|
+
| 'bar-cleared';
|
|
257
|
+
|
|
258
|
+
export interface NormalizationGateResult {
|
|
259
|
+
readonly verdict: NormalizationVerdict;
|
|
260
|
+
/** Why, in one clause, printable beside the verdict. */
|
|
261
|
+
readonly reason: string;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Decide whether step 3.4 may proceed.
|
|
266
|
+
*
|
|
267
|
+
* Fails CLOSED in every ambiguous direction: no gradeable data, or a distortion
|
|
268
|
+
* arm that was never run, returns `unrun` and not `below-bar` — because
|
|
269
|
+
* "measured and found harmless" is a claim, and this function must never make
|
|
270
|
+
* one on behalf of a measurement nobody took.
|
|
271
|
+
*/
|
|
272
|
+
export function normalizationGateVerdict(input: NormalizationGateInput): NormalizationGateResult {
|
|
273
|
+
const alpha = input.alpha ?? 0.05;
|
|
274
|
+
const graded = input.recognition.filter((r) => r.gradeable > 0);
|
|
275
|
+
if (graded.length === 0) {
|
|
276
|
+
return {
|
|
277
|
+
verdict: 'unrun',
|
|
278
|
+
reason: 'no gradeable recognition data — the leakage bench has not been run',
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
const significant = graded.filter((r) => r.p_value !== null && r.p_value < alpha);
|
|
282
|
+
if (significant.length === 0) {
|
|
283
|
+
return {
|
|
284
|
+
verdict: 'below-bar',
|
|
285
|
+
reason:
|
|
286
|
+
`no rater recognised the provider above chance at alpha=${String(alpha)} ` +
|
|
287
|
+
`(${String(graded.length)} rater(s) graded) — condition 1 not met`,
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
if (input.distortion_correlated === null) {
|
|
291
|
+
return {
|
|
292
|
+
verdict: 'unrun',
|
|
293
|
+
reason:
|
|
294
|
+
`${String(significant.length)} rater(s) recognise above chance, but the ` +
|
|
295
|
+
'recognition-to-distortion correlation arm has not been run — condition 2 unmeasured',
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
if (!input.distortion_correlated) {
|
|
299
|
+
return {
|
|
300
|
+
verdict: 'below-bar',
|
|
301
|
+
reason: 'recognition is above chance but does not correlate with judgment distortion — condition 2 not met',
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
return {
|
|
305
|
+
verdict: 'bar-cleared',
|
|
306
|
+
reason:
|
|
307
|
+
`${String(significant.length)} rater(s) recognise above chance AND recognition correlates ` +
|
|
308
|
+
'with judgment distortion — both conditions recorded met',
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/** The publishable block: recognition rate AND chance baseline, per the step's verify. */
|
|
313
|
+
export function renderRecognitionReport(rows: readonly RecognitionResult[]): string {
|
|
314
|
+
if (rows.length === 0) {
|
|
315
|
+
return 'provider-recognition leakage: NOT RUN — no rater produced a guess.';
|
|
316
|
+
}
|
|
317
|
+
const pct = (v: number | null): string => (v === null ? 'n/a' : `${(v * 100).toFixed(1)}%`);
|
|
318
|
+
return rows
|
|
319
|
+
.map(
|
|
320
|
+
(r) =>
|
|
321
|
+
`recognition · ${r.rater}: ${pct(r.recognition_rate)} ` +
|
|
322
|
+
`(${String(r.correct)}/${String(r.gradeable)} gradeable of ${String(r.attempted)} attempted) · ` +
|
|
323
|
+
`chance uniform ${pct(r.chance_uniform)} · chance majority-class ${pct(r.chance_majority)} · ` +
|
|
324
|
+
`p=${r.p_value === null ? 'n/a' : r.p_value.toFixed(4)}`,
|
|
325
|
+
)
|
|
326
|
+
.join('\n');
|
|
327
|
+
}
|
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Python-format helpers, extracted from `config.ts`.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* THE LIVE CONTRACT, stated instead of a fidelity claim: `config.ts` and
|
|
5
|
+
* `clients.ts` raise `ValueError` / `TypeError` whose messages are built from
|
|
6
|
+
* these helpers — `invalid literal for int() with base 10: <repr>`, `could not
|
|
7
|
+
* convert string to float: <repr>`, `'<typeName>'`. That exact wording is what
|
|
8
|
+
* makes a malformed `.ai-council.yml` diagnosable, so the helpers reimplement
|
|
9
|
+
* `repr()`, `type().__name__` and `oct()` rather than approximating them with
|
|
10
|
+
* template literals.
|
|
11
|
+
*
|
|
12
|
+
* WHAT PINS IT TODAY: nothing. Searched 2026-08-26 — no test in `tests/` asserts
|
|
13
|
+
* any of those three strings, and the only other occurrences in the tree are
|
|
14
|
+
* independent copies in the work-engine templates. So this docstring records an
|
|
15
|
+
* INTENDED contract with no gate behind it; a refactor that changed the wording
|
|
16
|
+
* would pass every check in this repository. Naming the gap is the honest form,
|
|
17
|
+
* and it is cheaper than a fidelity claim to a deleted file nobody can consult.
|
|
7
18
|
*
|
|
8
19
|
* Pure and self-contained: these functions call only each other, which is what
|
|
9
20
|
* made the section safe to move out whole. Extracted because config.ts is
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The re-council guard — warn before paying twice for one deliberation.
|
|
3
|
+
*
|
|
4
|
+
* `road-to-inbox-harvest-2026-08-e-council-topology-evidence` Phase 1A. The
|
|
5
|
+
* phase's own framing is the design constraint: *"the cheapest quality
|
|
6
|
+
* improvement is not paying twice for the same deliberation"*, and it sits
|
|
7
|
+
* before any sophisticated routing on purpose.
|
|
8
|
+
*
|
|
9
|
+
* FOUR CONSTRAINTS FROM THE STEPS, EACH LOAD-BEARING:
|
|
10
|
+
*
|
|
11
|
+
* 1A.1 Reuse the EXISTING question hash. `_sha256_hex` is imported from
|
|
12
|
+
* `blind_review.ts`, not reimplemented — two hashes of one question are
|
|
13
|
+
* two answers to "is this the same question", and the second is the one
|
|
14
|
+
* nobody updates.
|
|
15
|
+
* 1A.2 WARN, NEVER PROHIBIT. {@link RecouncilVerdict} carries no field a
|
|
16
|
+
* caller could read as a block, which is stronger than a documented
|
|
17
|
+
* promise not to block: there is nothing to misread.
|
|
18
|
+
* 1A.3 Near-duplicate detection on the ALREADY-IMPORTED similarity
|
|
19
|
+
* mechanism — `trigrams` from `_lib/lexical_index.ts`, the BM25 core
|
|
20
|
+
* ADR-061 already sanctions. No embeddings, no new infrastructure. The
|
|
21
|
+
* threshold is PRE-REGISTERED below, before any tuning on the retained
|
|
22
|
+
* corpus.
|
|
23
|
+
* 1A.4 Three states, distinguishable: exact + same config, exact + stale
|
|
24
|
+
* config, near-duplicate.
|
|
25
|
+
*/
|
|
26
|
+
import * as fs from 'node:fs';
|
|
27
|
+
import * as path from 'node:path';
|
|
28
|
+
|
|
29
|
+
import { jaccardSimilarity, MERGE_THRESHOLD } from '../_lib/text_similarity.js';
|
|
30
|
+
import { _sha256_hex } from './blind_review.js';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The near-duplicate threshold — and it is REUSED, not chosen.
|
|
34
|
+
*
|
|
35
|
+
* Step 1A.3 asks for the threshold to be pre-registered before any tuning on
|
|
36
|
+
* the retained local corpus. `MERGE_THRESHOLD` in `_lib/text_similarity.ts` is
|
|
37
|
+
* already that: fixed by an AI-council verdict of 2026-07-05 as the point at
|
|
38
|
+
* which two texts are treated as duplicates, long before this guard existed and
|
|
39
|
+
* with no knowledge of the council-question corpus it is now applied to. A
|
|
40
|
+
* number nobody could have tuned against this corpus is the strongest form of
|
|
41
|
+
* pre-registration available, and re-declaring `0.8` here would fork it — the
|
|
42
|
+
* same defect 1A.1 forbids for the hash.
|
|
43
|
+
*
|
|
44
|
+
* `revisit-if`: the retained corpus produces a false positive at this value
|
|
45
|
+
* (two questions a human calls different, scored at or above it), or a
|
|
46
|
+
* one-sentence rewrite of a real question scores below it. Either falsifies the
|
|
47
|
+
* number, and the fix then belongs in `text_similarity.ts` where its other
|
|
48
|
+
* consumers can see it move.
|
|
49
|
+
*/
|
|
50
|
+
export const NEAR_DUPLICATE_THRESHOLD = MERGE_THRESHOLD;
|
|
51
|
+
|
|
52
|
+
/** The three states step 1A.4 requires the warning to distinguish. */
|
|
53
|
+
export type RepeatState =
|
|
54
|
+
/** Same question text, and the configuration that would run it is unchanged. */
|
|
55
|
+
| 'exact-same-config'
|
|
56
|
+
/** Same question text, but the members or round count have moved since. */
|
|
57
|
+
| 'exact-stale-config'
|
|
58
|
+
/** Not the same text, but above the pre-registered similarity threshold. */
|
|
59
|
+
| 'near-duplicate';
|
|
60
|
+
|
|
61
|
+
/** One prior run, as read from a retained response artefact. */
|
|
62
|
+
export interface PriorRun {
|
|
63
|
+
/** Path of the retained artefact. */
|
|
64
|
+
readonly artifactPath: string;
|
|
65
|
+
/** The question file it ran over, as the artefact recorded it. */
|
|
66
|
+
readonly questionPath: string;
|
|
67
|
+
/** ISO date of the artefact, for the warning's "prior run date". */
|
|
68
|
+
readonly ranAt: string;
|
|
69
|
+
/** Sorted member ids + round count — the "relevant configuration". */
|
|
70
|
+
readonly configFingerprint: string;
|
|
71
|
+
/** `_sha256_hex` of the question text, when the question file still exists. */
|
|
72
|
+
readonly questionHash: string | null;
|
|
73
|
+
/** The question text, for the near-duplicate pass. `null` when the file is gone. */
|
|
74
|
+
readonly questionText: string | null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* A finding. There is DELIBERATELY no `block`, `refuse` or `severity` field:
|
|
79
|
+
* step 1A.2 requires that no code path can turn this into an unconditional
|
|
80
|
+
* block, and a type that cannot express one is the strongest available form of
|
|
81
|
+
* that guarantee.
|
|
82
|
+
*/
|
|
83
|
+
export interface RecouncilVerdict {
|
|
84
|
+
readonly state: RepeatState;
|
|
85
|
+
readonly prior: PriorRun;
|
|
86
|
+
/** Token Jaccard against the prior question, 0..1. Exactly 1 on an exact repeat. */
|
|
87
|
+
readonly similarity: number;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Sorted members plus rounds — what 1A.4 calls the relevant configuration. */
|
|
91
|
+
export function configFingerprint(members: readonly string[], rounds: number): string {
|
|
92
|
+
return `${[...members].sort().join(',')}|rounds=${String(rounds)}`;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Read the retained response artefacts into prior runs.
|
|
97
|
+
*
|
|
98
|
+
* Tolerant of every read failure by design: a malformed or half-written
|
|
99
|
+
* artefact must not break a council run. The guard is an advisory, and an
|
|
100
|
+
* advisory that can throw is worse than one that stays quiet.
|
|
101
|
+
*/
|
|
102
|
+
export function readPriorRuns(responsesDir: string, repoRoot: string): PriorRun[] {
|
|
103
|
+
let names: string[];
|
|
104
|
+
try {
|
|
105
|
+
names = fs.readdirSync(responsesDir).filter((f) => f.endsWith('.md'));
|
|
106
|
+
} catch {
|
|
107
|
+
return [];
|
|
108
|
+
}
|
|
109
|
+
const out: PriorRun[] = [];
|
|
110
|
+
for (const name of names) {
|
|
111
|
+
const abs = path.join(responsesDir, name);
|
|
112
|
+
let head: Record<string, unknown>;
|
|
113
|
+
let stat: fs.Stats;
|
|
114
|
+
try {
|
|
115
|
+
stat = fs.statSync(abs);
|
|
116
|
+
const text = fs.readFileSync(abs, 'utf8');
|
|
117
|
+
const json = _leadingJson(text);
|
|
118
|
+
// A file with no leading object is not a council artefact at all —
|
|
119
|
+
// skipped rather than admitted as a prior run with empty fields,
|
|
120
|
+
// which would put noise in a warning whose whole value is that it
|
|
121
|
+
// is rare enough to read.
|
|
122
|
+
if (json === null) continue;
|
|
123
|
+
head = JSON.parse(json) as Record<string, unknown>;
|
|
124
|
+
} catch {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
const questionPath = typeof head['artefact'] === 'string' ? head['artefact'] : '';
|
|
128
|
+
const members = Array.isArray(head['members']) ? (head['members'] as string[]) : [];
|
|
129
|
+
const rounds = typeof head['rounds'] === 'number' ? head['rounds'] : 0;
|
|
130
|
+
let questionHash: string | null = null;
|
|
131
|
+
let questionText: string | null = null;
|
|
132
|
+
if (questionPath !== '') {
|
|
133
|
+
try {
|
|
134
|
+
const q = fs.readFileSync(path.join(repoRoot, questionPath), 'utf8');
|
|
135
|
+
questionHash = _sha256_hex(q);
|
|
136
|
+
questionText = q;
|
|
137
|
+
} catch {
|
|
138
|
+
// The question file was moved or pruned. The run is still a
|
|
139
|
+
// prior run; it simply cannot be compared by text, and saying
|
|
140
|
+
// that is better than dropping the record.
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
out.push({
|
|
144
|
+
artifactPath: abs,
|
|
145
|
+
questionPath,
|
|
146
|
+
ranAt: stat.mtime.toISOString().slice(0, 10),
|
|
147
|
+
configFingerprint: configFingerprint(members, rounds),
|
|
148
|
+
questionHash,
|
|
149
|
+
questionText,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
return out;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** The leading `{...}` object of an artefact, brace-balanced, or `null`. */
|
|
156
|
+
function _leadingJson(text: string): string | null {
|
|
157
|
+
const start = text.indexOf('{');
|
|
158
|
+
if (start === -1) return null;
|
|
159
|
+
let depth = 0;
|
|
160
|
+
let inStr = false;
|
|
161
|
+
let esc = false;
|
|
162
|
+
for (let i = start; i < text.length; i++) {
|
|
163
|
+
const c = text[i] as string;
|
|
164
|
+
if (inStr) {
|
|
165
|
+
if (esc) esc = false;
|
|
166
|
+
else if (c === '\\') esc = true;
|
|
167
|
+
else if (c === '"') inStr = false;
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
if (c === '"') inStr = true;
|
|
171
|
+
else if (c === '{') depth += 1;
|
|
172
|
+
else if (c === '}') {
|
|
173
|
+
depth -= 1;
|
|
174
|
+
if (depth === 0) return text.slice(start, i + 1);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Is this question already deliberated?
|
|
182
|
+
*
|
|
183
|
+
* Returns the STRONGEST finding, or `null`. Exact beats near-duplicate, and a
|
|
184
|
+
* stale-config exact beats a near-duplicate: a caller shown two findings reads
|
|
185
|
+
* neither, and the exact one carries more information.
|
|
186
|
+
*/
|
|
187
|
+
export function checkRecouncil(
|
|
188
|
+
questionText: string,
|
|
189
|
+
currentConfig: string,
|
|
190
|
+
priors: readonly PriorRun[],
|
|
191
|
+
threshold: number = NEAR_DUPLICATE_THRESHOLD,
|
|
192
|
+
): RecouncilVerdict | null {
|
|
193
|
+
const hash = _sha256_hex(questionText);
|
|
194
|
+
|
|
195
|
+
for (const p of priors) {
|
|
196
|
+
if (p.questionHash === hash) {
|
|
197
|
+
return {
|
|
198
|
+
state: p.configFingerprint === currentConfig ? 'exact-same-config' : 'exact-stale-config',
|
|
199
|
+
prior: p,
|
|
200
|
+
similarity: 1,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
let best: RecouncilVerdict | null = null;
|
|
205
|
+
for (const p of priors) {
|
|
206
|
+
if (p.questionText === null) continue;
|
|
207
|
+
const s = jaccardSimilarity(questionText, p.questionText);
|
|
208
|
+
if (s >= threshold && (best === null || s > best.similarity)) {
|
|
209
|
+
best = { state: 'near-duplicate', prior: p, similarity: s };
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return best;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* The warning text.
|
|
217
|
+
*
|
|
218
|
+
* Every line step 1A.2 names is present — prior run date, prior artifact path,
|
|
219
|
+
* the fact that the question appears already deliberated, and the path to
|
|
220
|
+
* re-run — and 1A.3 requires the SCORE to be printed, so it is, on every state
|
|
221
|
+
* rather than only the near-duplicate one. A score of 1.00 on an exact repeat
|
|
222
|
+
* tells the reader which comparison fired.
|
|
223
|
+
*/
|
|
224
|
+
export function renderRecouncilWarning(v: RecouncilVerdict): string {
|
|
225
|
+
const what: Record<RepeatState, string> = {
|
|
226
|
+
'exact-same-config':
|
|
227
|
+
'this exact question has already been deliberated, and the configuration that would run it is unchanged',
|
|
228
|
+
'exact-stale-config':
|
|
229
|
+
'this exact question has already been deliberated, but the members or round count have moved since — the prior verdict may rest on evidence this configuration would not produce',
|
|
230
|
+
'near-duplicate':
|
|
231
|
+
'a question above the pre-registered similarity threshold has already been deliberated',
|
|
232
|
+
};
|
|
233
|
+
return [
|
|
234
|
+
`⚠️ council:re-council — ${what[v.state]}.`,
|
|
235
|
+
` prior run ${v.prior.ranAt}`,
|
|
236
|
+
` prior answer ${v.prior.artifactPath}`,
|
|
237
|
+
` question ${v.prior.questionPath || '(not recorded)'}`,
|
|
238
|
+
` similarity ${v.similarity.toFixed(2)} (threshold ${String(NEAR_DUPLICATE_THRESHOLD)}, pre-registered)`,
|
|
239
|
+
' This is a WARNING, never a refusal. Re-run with --confirm to deliberate again.',
|
|
240
|
+
'',
|
|
241
|
+
].join('\n');
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* The whole call site, in one function.
|
|
246
|
+
*
|
|
247
|
+
* Lives here rather than in `council_cli.ts` for a reason the source-size
|
|
248
|
+
* ratchet made concrete: that file is already 2,525 lines over the 1,500-line
|
|
249
|
+
* ceiling, so every line added to it is a line the ratchet counts, and a
|
|
250
|
+
* twenty-line comment explaining a guard belongs beside the guard anyway.
|
|
251
|
+
*
|
|
252
|
+
* IT CANNOT REFUSE, and the signature is where that is guaranteed: it returns
|
|
253
|
+
* `void`. Step 1A.2 requires that no code path turn the warning into an
|
|
254
|
+
* unconditional block, and a function with nothing to return gives a caller
|
|
255
|
+
* nothing to branch on.
|
|
256
|
+
*
|
|
257
|
+
* Every read is wrapped: an advisory that throws is worse than one that stays
|
|
258
|
+
* quiet, because the guard exists to save a duplicate run and never to prevent
|
|
259
|
+
* a legitimate one.
|
|
260
|
+
*
|
|
261
|
+
* `questionFile` is the RAW question file, not the built prompt. Measured on
|
|
262
|
+
* the first live run: the built prompt hashes differently from the file the
|
|
263
|
+
* prior artefact recorded, so the exact-repeat states were unreachable in
|
|
264
|
+
* production and every true repeat reported as a near-duplicate at similarity
|
|
265
|
+
* 1.00. `fallbackText` covers a question that arrived on stdin and has no file.
|
|
266
|
+
*/
|
|
267
|
+
export function warnIfRecounciled(
|
|
268
|
+
repoRoot: string,
|
|
269
|
+
questionFile: string,
|
|
270
|
+
fallbackText: string,
|
|
271
|
+
members: readonly { name: string; model: string }[],
|
|
272
|
+
rounds: number,
|
|
273
|
+
write: (s: string) => void,
|
|
274
|
+
): void {
|
|
275
|
+
try {
|
|
276
|
+
let text = fallbackText;
|
|
277
|
+
try {
|
|
278
|
+
text = fs.readFileSync(path.resolve(repoRoot, questionFile), 'utf8');
|
|
279
|
+
} catch {
|
|
280
|
+
// No file behind this question; the built prompt is the best text
|
|
281
|
+
// available, and a near-duplicate finding is still useful.
|
|
282
|
+
}
|
|
283
|
+
const v = checkRecouncil(
|
|
284
|
+
text,
|
|
285
|
+
// `name/model` — the SAME shape the artefact writer records.
|
|
286
|
+
configFingerprint(members.map((m) => `${m.name}/${m.model}`), rounds),
|
|
287
|
+
readPriorRuns(path.join(repoRoot, 'agents/runtime/council/responses'), repoRoot),
|
|
288
|
+
);
|
|
289
|
+
if (v !== null) write(renderRecouncilWarning(v));
|
|
290
|
+
} catch {
|
|
291
|
+
// See the docstring: quiet beats loud-and-broken for an advisory.
|
|
292
|
+
}
|
|
293
|
+
}
|