@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,299 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Re-council savings — the reconciliation half of Phase 10.5.
|
|
3
|
+
*
|
|
4
|
+
* `road-to-inbox-harvest-2026-08-e-council-topology-evidence` step 10.5 asks
|
|
5
|
+
* for four figures — *duplicates prevented, near-duplicate warnings, reruns
|
|
6
|
+
* intentionally confirmed, spend saved* — and its `verify:` is
|
|
7
|
+
* *"the figures reconcile against the retained artifacts"*.
|
|
8
|
+
*
|
|
9
|
+
* WHAT THIS IS, AND WHAT IT IS NOT — read this before quoting a number.
|
|
10
|
+
*
|
|
11
|
+
* 1. **It is a reconstruction, not instrumentation.** The guard it measures,
|
|
12
|
+
* `recouncil_guard.ts`, PERSISTS NOTHING: `warnIfRecounciled` returns
|
|
13
|
+
* `void` and writes only to an injected sink (`recouncil_guard.ts:273`,
|
|
14
|
+
* `:289`). Nothing in the tree records that a warning fired, that a user
|
|
15
|
+
* saw it, or that a run was abandoned because of it. So `duplicates
|
|
16
|
+
* prevented` and `reruns intentionally confirmed` are NOT observable, and
|
|
17
|
+
* this module refuses to emit a number for them — see
|
|
18
|
+
* {@link RecouncilSavings.duplicates_prevented}. What IS computable is the
|
|
19
|
+
* guard's own detector replayed over the retained corpus: how many
|
|
20
|
+
* questions the guard WOULD have flagged.
|
|
21
|
+
* 2. **The denominator is accidental, not designed.** The retained corpus is
|
|
22
|
+
* whatever the (unrun) reaper left behind — `prune_all_council_artifacts`
|
|
23
|
+
* (`session.ts:468`) has exactly one caller, the manual CLI
|
|
24
|
+
* `council_prune.ts`, bound to no hook, Taskfile target or workflow. So
|
|
25
|
+
* the corpus is not "the last N days of council traffic"; it is "every
|
|
26
|
+
* artefact ever written that nobody deleted by hand". A rate computed
|
|
27
|
+
* over it is a rate over an unknown sampling frame.
|
|
28
|
+
*
|
|
29
|
+
* Both limits are structural, and the report prints them next to every figure
|
|
30
|
+
* rather than in a footnote, because a savings number quoted without them is
|
|
31
|
+
* the exact overstatement this roadmap's § Prevented items exists to catch.
|
|
32
|
+
*
|
|
33
|
+
* Deterministic and offline: no provider call, no network, no writes.
|
|
34
|
+
*/
|
|
35
|
+
import * as fs from 'node:fs';
|
|
36
|
+
import * as path from 'node:path';
|
|
37
|
+
|
|
38
|
+
import { jaccardSimilarity } from '../_lib/text_similarity.js';
|
|
39
|
+
import { _sha256_hex } from './blind_review.js';
|
|
40
|
+
import { NEAR_DUPLICATE_THRESHOLD, checkRecouncil, readPriorRuns } from './recouncil_guard.js';
|
|
41
|
+
import type { PriorRun } from './recouncil_guard.js';
|
|
42
|
+
|
|
43
|
+
/** One retained question file, hashed and read. */
|
|
44
|
+
export interface QuestionRecord {
|
|
45
|
+
/** Path relative to the corpus root — stable across machines. */
|
|
46
|
+
readonly rel: string;
|
|
47
|
+
readonly text: string;
|
|
48
|
+
readonly sha256: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** A pair of distinct questions at or above the threshold. */
|
|
52
|
+
export interface NearDuplicatePair {
|
|
53
|
+
readonly a: string;
|
|
54
|
+
readonly b: string;
|
|
55
|
+
readonly score: number;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* The four figures 10.5 names, with the two that are NOT observable typed as
|
|
60
|
+
* `null` rather than zero.
|
|
61
|
+
*
|
|
62
|
+
* `null` and `0` are different claims and the difference is the whole point:
|
|
63
|
+
* zero would assert *"the guard prevented no duplicate"*, which nothing in the
|
|
64
|
+
* tree can support; `null` asserts *"no mechanism records this"*, which is a
|
|
65
|
+
* fact about `recouncil_guard.ts` and is citable.
|
|
66
|
+
*/
|
|
67
|
+
export interface RecouncilSavings {
|
|
68
|
+
/** Retained question files read. */
|
|
69
|
+
readonly questions: number;
|
|
70
|
+
/** Distinct sha256 over those files. */
|
|
71
|
+
readonly distinct_hashes: number;
|
|
72
|
+
/** Question files whose hash is shared with an earlier file — exact repeats. */
|
|
73
|
+
readonly exact_repeat_files: number;
|
|
74
|
+
/** Distinct unordered pairs at or above the threshold, excluding exact repeats. */
|
|
75
|
+
readonly near_duplicate_pairs: number;
|
|
76
|
+
/** Questions that participate in at least one such pair. */
|
|
77
|
+
readonly near_duplicate_questions: number;
|
|
78
|
+
/** Response artefacts the guard's own reader admits as prior runs. */
|
|
79
|
+
readonly prior_runs_readable: number;
|
|
80
|
+
/**
|
|
81
|
+
* Prior runs whose question file still resolves, i.e. the ones the guard can
|
|
82
|
+
* actually COMPARE against. The gap between this and `prior_runs_readable`
|
|
83
|
+
* is the guard's real reach over the retained corpus.
|
|
84
|
+
*/
|
|
85
|
+
readonly prior_runs_with_question_text: number;
|
|
86
|
+
/** Retained artefacts the reader rejects (no leading JSON, unreadable, a directory). */
|
|
87
|
+
readonly prior_runs_rejected: number;
|
|
88
|
+
/** Questions the guard's own `checkRecouncil` flags against the prior runs. */
|
|
89
|
+
readonly guard_would_flag: number;
|
|
90
|
+
/** NOT OBSERVABLE — the guard persists no outcome. Always `null`; see the module header. */
|
|
91
|
+
readonly duplicates_prevented: null;
|
|
92
|
+
/** NOT OBSERVABLE — same reason. Always `null`. */
|
|
93
|
+
readonly reruns_confirmed: null;
|
|
94
|
+
/** NOT OBSERVABLE — a spend figure needs a prevented run, which is not recorded. Always `null`. */
|
|
95
|
+
readonly spend_saved_usd: null;
|
|
96
|
+
readonly threshold: number;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** Read every `*.md` question under `root`, recursively, sorted for determinism. */
|
|
100
|
+
export function readQuestions(root: string): QuestionRecord[] {
|
|
101
|
+
const out: QuestionRecord[] = [];
|
|
102
|
+
const walk = (dir: string): void => {
|
|
103
|
+
let entries: fs.Dirent[];
|
|
104
|
+
try {
|
|
105
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
106
|
+
} catch {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
for (const e of [...entries].sort((x, y) => (x.name < y.name ? -1 : x.name > y.name ? 1 : 0))) {
|
|
110
|
+
const abs = path.join(dir, e.name);
|
|
111
|
+
if (e.isDirectory()) {
|
|
112
|
+
walk(abs);
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (!e.name.endsWith('.md')) continue;
|
|
116
|
+
let text: string;
|
|
117
|
+
try {
|
|
118
|
+
text = fs.readFileSync(abs, 'utf8');
|
|
119
|
+
} catch {
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
out.push({ rel: path.relative(root, abs), text, sha256: _sha256_hex(text) });
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
walk(root);
|
|
126
|
+
return out;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** Files whose hash was already seen — the exact-repeat count, first occurrence excluded. */
|
|
130
|
+
export function exactRepeats(questions: readonly QuestionRecord[]): QuestionRecord[] {
|
|
131
|
+
const seen = new Set<string>();
|
|
132
|
+
const repeats: QuestionRecord[] = [];
|
|
133
|
+
for (const q of questions) {
|
|
134
|
+
if (seen.has(q.sha256)) repeats.push(q);
|
|
135
|
+
else seen.add(q.sha256);
|
|
136
|
+
}
|
|
137
|
+
return repeats;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Every distinct unordered pair at or above `threshold`, EXCLUDING identical
|
|
142
|
+
* texts — an exact repeat is already counted by {@link exactRepeats} and
|
|
143
|
+
* counting it twice would inflate the near-duplicate figure with the same
|
|
144
|
+
* event.
|
|
145
|
+
*
|
|
146
|
+
* O(n²) on purpose: n is the retained corpus (hundreds), the comparison is the
|
|
147
|
+
* guard's own `jaccardSimilarity`, and an index would be a second similarity
|
|
148
|
+
* mechanism beside the one `recouncil_guard.ts:1A.3` pins.
|
|
149
|
+
*/
|
|
150
|
+
export function nearDuplicatePairs(
|
|
151
|
+
questions: readonly QuestionRecord[],
|
|
152
|
+
threshold: number = NEAR_DUPLICATE_THRESHOLD,
|
|
153
|
+
): NearDuplicatePair[] {
|
|
154
|
+
const pairs: NearDuplicatePair[] = [];
|
|
155
|
+
for (let i = 0; i < questions.length; i++) {
|
|
156
|
+
const a = questions[i] as QuestionRecord;
|
|
157
|
+
for (let j = i + 1; j < questions.length; j++) {
|
|
158
|
+
const b = questions[j] as QuestionRecord;
|
|
159
|
+
if (a.sha256 === b.sha256) continue;
|
|
160
|
+
const score = jaccardSimilarity(a.text, b.text);
|
|
161
|
+
if (score >= threshold) pairs.push({ a: a.rel, b: b.rel, score });
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return pairs;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/** How many distinct questions appear in at least one pair. */
|
|
168
|
+
export function questionsInPairs(pairs: readonly NearDuplicatePair[]): number {
|
|
169
|
+
const ids = new Set<string>();
|
|
170
|
+
for (const p of pairs) {
|
|
171
|
+
ids.add(p.a);
|
|
172
|
+
ids.add(p.b);
|
|
173
|
+
}
|
|
174
|
+
return ids.size;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Replay the guard's own detector: for each question, would `checkRecouncil`
|
|
179
|
+
* have returned a verdict against the retained prior runs?
|
|
180
|
+
*
|
|
181
|
+
* The question's own prior run is excluded by artefact path where it is
|
|
182
|
+
* identifiable, so a question is not reported as a repeat of itself.
|
|
183
|
+
*/
|
|
184
|
+
export function guardWouldFlag(
|
|
185
|
+
questions: readonly QuestionRecord[],
|
|
186
|
+
priors: readonly PriorRun[],
|
|
187
|
+
corpusRelPrefix: string,
|
|
188
|
+
): number {
|
|
189
|
+
let flagged = 0;
|
|
190
|
+
for (const q of questions) {
|
|
191
|
+
const own = path.posix.join(corpusRelPrefix, q.rel.split(path.sep).join('/'));
|
|
192
|
+
const others = priors.filter((p) => p.questionPath !== own);
|
|
193
|
+
if (checkRecouncil(q.text, '(config not reconstructible)', others) !== null) flagged++;
|
|
194
|
+
}
|
|
195
|
+
return flagged;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/** Everything, over one corpus root. `repoRoot` is where `questionPath` values resolve. */
|
|
199
|
+
export function computeSavings(
|
|
200
|
+
repoRoot: string,
|
|
201
|
+
threshold: number = NEAR_DUPLICATE_THRESHOLD,
|
|
202
|
+
): RecouncilSavings {
|
|
203
|
+
const questionsDir = path.join(repoRoot, 'agents/runtime/council/questions');
|
|
204
|
+
const responsesDir = path.join(repoRoot, 'agents/runtime/council/responses');
|
|
205
|
+
const questions = readQuestions(questionsDir);
|
|
206
|
+
const priors = readPriorRuns(responsesDir, repoRoot);
|
|
207
|
+
let candidates = 0;
|
|
208
|
+
try {
|
|
209
|
+
candidates = fs.readdirSync(responsesDir).filter((f) => f.endsWith('.md')).length;
|
|
210
|
+
} catch {
|
|
211
|
+
candidates = 0;
|
|
212
|
+
}
|
|
213
|
+
const pairs = nearDuplicatePairs(questions, threshold);
|
|
214
|
+
return {
|
|
215
|
+
questions: questions.length,
|
|
216
|
+
distinct_hashes: new Set(questions.map((q) => q.sha256)).size,
|
|
217
|
+
exact_repeat_files: exactRepeats(questions).length,
|
|
218
|
+
near_duplicate_pairs: pairs.length,
|
|
219
|
+
near_duplicate_questions: questionsInPairs(pairs),
|
|
220
|
+
prior_runs_readable: priors.length,
|
|
221
|
+
prior_runs_with_question_text: priors.filter((p) => p.questionText !== null).length,
|
|
222
|
+
prior_runs_rejected: candidates - priors.length,
|
|
223
|
+
guard_would_flag: guardWouldFlag(questions, priors, 'agents/runtime/council/questions'),
|
|
224
|
+
duplicates_prevented: null,
|
|
225
|
+
reruns_confirmed: null,
|
|
226
|
+
spend_saved_usd: null,
|
|
227
|
+
threshold,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/** The two limits, printed with every figure rather than footnoted. */
|
|
232
|
+
export const SAVINGS_LIMITS: readonly string[] = [
|
|
233
|
+
'RECONSTRUCTION, NOT INSTRUMENTATION — recouncil_guard.warnIfRecounciled returns void ' +
|
|
234
|
+
'and writes only to an injected sink (recouncil_guard.ts:273,:289). No warning, ' +
|
|
235
|
+
'no abandonment and no confirmation is persisted anywhere, so duplicates_prevented, ' +
|
|
236
|
+
'reruns_confirmed and spend_saved_usd are null, never zero.',
|
|
237
|
+
'ACCIDENTAL DENOMINATOR — the retained corpus is what an unrun reaper left behind. ' +
|
|
238
|
+
'prune_all_council_artifacts (session.ts:468) has one caller, the manual CLI ' +
|
|
239
|
+
'council_prune.ts, bound to no hook, Taskfile target or workflow. Any rate over ' +
|
|
240
|
+
'this corpus is a rate over an unknown sampling frame.',
|
|
241
|
+
];
|
|
242
|
+
|
|
243
|
+
export function renderSavings(s: RecouncilSavings): string {
|
|
244
|
+
const n = (v: number | null): string => (v === null ? 'null (not observable)' : String(v));
|
|
245
|
+
return (
|
|
246
|
+
[
|
|
247
|
+
`retained questions ${String(s.questions)}`,
|
|
248
|
+
`distinct question hashes ${String(s.distinct_hashes)}`,
|
|
249
|
+
`exact repeat files ${String(s.exact_repeat_files)}`,
|
|
250
|
+
`near-duplicate pairs ${String(s.near_duplicate_pairs)} (threshold ${s.threshold.toFixed(2)})`,
|
|
251
|
+
`questions in >=1 pair ${String(s.near_duplicate_questions)}`,
|
|
252
|
+
`prior runs readable ${String(s.prior_runs_readable)}`,
|
|
253
|
+
` …with a resolvable question ${String(s.prior_runs_with_question_text)}`,
|
|
254
|
+
`prior runs rejected ${String(s.prior_runs_rejected)}`,
|
|
255
|
+
`guard would flag ${String(s.guard_would_flag)}`,
|
|
256
|
+
`duplicates prevented ${n(s.duplicates_prevented)}`,
|
|
257
|
+
`reruns confirmed ${n(s.reruns_confirmed)}`,
|
|
258
|
+
`spend saved (USD) ${n(s.spend_saved_usd)}`,
|
|
259
|
+
'',
|
|
260
|
+
'LIMITS:',
|
|
261
|
+
]
|
|
262
|
+
.concat(SAVINGS_LIMITS.map((l) => ` - ${l}`))
|
|
263
|
+
.join('\n') + '\n'
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/** `./scripts-run src/scripts/ai_council/recouncil_savings [--root <path>]` */
|
|
268
|
+
export async function main(argv: readonly string[] = process.argv.slice(2)): Promise<number> {
|
|
269
|
+
const i = argv.indexOf('--root');
|
|
270
|
+
const root = i !== -1 && argv[i + 1] !== undefined ? (argv[i + 1] as string) : process.cwd();
|
|
271
|
+
process.stdout.write(`corpus root ${root}\n`);
|
|
272
|
+
process.stdout.write(renderSavings(computeSavings(root)));
|
|
273
|
+
if (argv.includes('--pairs')) {
|
|
274
|
+
const qs = readQuestions(path.join(root, 'agents/runtime/council/questions'));
|
|
275
|
+
for (const p of nearDuplicatePairs(qs)) {
|
|
276
|
+
process.stdout.write(` pair ${p.score.toFixed(3)} ${p.a} <-> ${p.b}\n`);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return 0;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Self-execution guard — see topology_bench_manifest.ts for why realpath on both sides.
|
|
283
|
+
{
|
|
284
|
+
const nodeFs = await import('node:fs');
|
|
285
|
+
const nodeUrl = await import('node:url');
|
|
286
|
+
const invoked = process.argv[1];
|
|
287
|
+
if (invoked !== undefined && invoked !== '') {
|
|
288
|
+
let here = '';
|
|
289
|
+
let there = ' ';
|
|
290
|
+
try {
|
|
291
|
+
here = nodeFs.realpathSync(nodeUrl.fileURLToPath(import.meta.url));
|
|
292
|
+
there = nodeFs.realpathSync(invoked);
|
|
293
|
+
} catch {
|
|
294
|
+
here = '';
|
|
295
|
+
there = ' ';
|
|
296
|
+
}
|
|
297
|
+
if (here === there) process.exit(await main());
|
|
298
|
+
}
|
|
299
|
+
}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The route half of decision replay — step 10.1.
|
|
3
|
+
*
|
|
4
|
+
* `road-to-inbox-harvest-2026-08-e-council-topology-evidence` step 10.1:
|
|
5
|
+
* *"Extend decision replay (`ai_council/replay.ts`) with: ladder council
|
|
6
|
+
* resolution, council-internal topology, initial route, escalation, stage
|
|
7
|
+
* outputs, stop reason, synthesis policy, cost, latency, final verdict"*,
|
|
8
|
+
* verified by *"a replayed run reproduces the recorded route"*.
|
|
9
|
+
*
|
|
10
|
+
* ## Why a separate module, and why the existing renderer is untouched
|
|
11
|
+
*
|
|
12
|
+
* `replay.ts` is a py2ts parity port whose header pins Python-mirroring
|
|
13
|
+
* behaviour down to `round-half-to-even` float formatting and a trailing
|
|
14
|
+
* `rstrip()`. Editing its renderer to interleave new sections would put every
|
|
15
|
+
* one of those parity notes at risk for a purely additive feature. So the route
|
|
16
|
+
* record lives here, renders as its own appendable section, and the existing
|
|
17
|
+
* output is byte-identical for every caller that does not pass one — which the
|
|
18
|
+
* test asserts rather than assumes.
|
|
19
|
+
*
|
|
20
|
+
* ## Nine of the ten fields are populated; one is structurally unavailable
|
|
21
|
+
*
|
|
22
|
+
* `councilInternalTopology` is typed `null` and only `null`. No topology
|
|
23
|
+
* selector exists — 7.2 is open and nothing in `src/` is named
|
|
24
|
+
* `topology_selector` or exports `selectTopology` — so a populated value would
|
|
25
|
+
* be invented. {@link auditRouteRecord} reports it as
|
|
26
|
+
* `structurally-unavailable`, which is a different report from "missing" and is
|
|
27
|
+
* the distinction the whole record exists to preserve.
|
|
28
|
+
*
|
|
29
|
+
* ## Round-trip is the verify clause
|
|
30
|
+
*
|
|
31
|
+
* {@link renderRouteSection} and {@link parseRouteSection} are inverses over
|
|
32
|
+
* the record's own fields, so "a replayed run reproduces the recorded route" is
|
|
33
|
+
* decidable: render, parse, compare. Numbers are rendered at fixed precision so
|
|
34
|
+
* the comparison is exact rather than approximate.
|
|
35
|
+
*
|
|
36
|
+
* Pure and offline.
|
|
37
|
+
*/
|
|
38
|
+
import type { LadderRung, LadderVerdict } from '../_lib/judgment_ladder.js';
|
|
39
|
+
import type { SynthesisStrategyId } from './synthesis_strategy.js';
|
|
40
|
+
|
|
41
|
+
/** How the ONE task-side resolver landed on council. */
|
|
42
|
+
export interface LadderResolution {
|
|
43
|
+
readonly rung: LadderRung;
|
|
44
|
+
readonly verdict: LadderVerdict;
|
|
45
|
+
readonly reason: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** One deliberation stage and what it produced. */
|
|
49
|
+
export interface StageOutput {
|
|
50
|
+
readonly stage: string;
|
|
51
|
+
/** Findings, critiques or verdict lines the stage emitted. */
|
|
52
|
+
readonly produced: number;
|
|
53
|
+
readonly calls: number;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface RouteEscalation {
|
|
57
|
+
readonly escalated: boolean;
|
|
58
|
+
readonly from: string | null;
|
|
59
|
+
readonly to: string | null;
|
|
60
|
+
readonly reason: string;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Every field 10.1 names, with the unavailable one typed as unavailable. */
|
|
64
|
+
export interface CouncilRouteRecord {
|
|
65
|
+
readonly ladderResolution: LadderResolution;
|
|
66
|
+
/**
|
|
67
|
+
* FUTURE MECHANISM. Typed `null` and only `null`: no selector exists, so a
|
|
68
|
+
* value here would be invented. Widening this type is the change that makes
|
|
69
|
+
* 10.1 closable.
|
|
70
|
+
*/
|
|
71
|
+
readonly councilInternalTopology: null;
|
|
72
|
+
readonly initialRoute: string;
|
|
73
|
+
readonly escalation: RouteEscalation;
|
|
74
|
+
readonly stageOutputs: readonly StageOutput[];
|
|
75
|
+
/** `null` means the run completed all configured rounds — not "unknown". */
|
|
76
|
+
readonly stopReason: string | null;
|
|
77
|
+
readonly synthesisPolicy: SynthesisStrategyId | null;
|
|
78
|
+
readonly costCalls: number;
|
|
79
|
+
readonly costUsd: number;
|
|
80
|
+
readonly latencyMs: number;
|
|
81
|
+
readonly finalVerdict: string;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** The ten field names 10.1 enumerates, in its own order. */
|
|
85
|
+
export const ROUTE_FIELDS: readonly string[] = Object.freeze([
|
|
86
|
+
'ladderResolution',
|
|
87
|
+
'councilInternalTopology',
|
|
88
|
+
'initialRoute',
|
|
89
|
+
'escalation',
|
|
90
|
+
'stageOutputs',
|
|
91
|
+
'stopReason',
|
|
92
|
+
'synthesisPolicy',
|
|
93
|
+
'costCalls',
|
|
94
|
+
'costUsd',
|
|
95
|
+
'latencyMs',
|
|
96
|
+
'finalVerdict',
|
|
97
|
+
]);
|
|
98
|
+
|
|
99
|
+
export type FieldState = 'populated' | 'structurally-unavailable' | 'missing';
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Per-field state. `structurally-unavailable` and `missing` are different
|
|
103
|
+
* claims: the first says the tree cannot produce a value, the second says the
|
|
104
|
+
* caller did not supply one.
|
|
105
|
+
*/
|
|
106
|
+
export function auditRouteRecord(record: CouncilRouteRecord): Record<string, FieldState> {
|
|
107
|
+
const out: Record<string, FieldState> = {};
|
|
108
|
+
for (const f of ROUTE_FIELDS) {
|
|
109
|
+
if (f === 'councilInternalTopology') {
|
|
110
|
+
out[f] = 'structurally-unavailable';
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
const v = (record as unknown as Record<string, unknown>)[f];
|
|
114
|
+
// `stopReason: null` is a real value ("ran to completion"), and so is
|
|
115
|
+
// `synthesisPolicy: null` ("host synthesis, no strategy recorded"); an
|
|
116
|
+
// ABSENT key is what counts as missing.
|
|
117
|
+
out[f] = Object.prototype.hasOwnProperty.call(record, f) && v !== undefined ? 'populated' : 'missing';
|
|
118
|
+
}
|
|
119
|
+
return out;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** USD is rendered at 4 decimals so render→parse→compare is exact. */
|
|
123
|
+
const USD_PRECISION = 4;
|
|
124
|
+
|
|
125
|
+
/** The appendable section. Deterministic — no clock, no randomness. */
|
|
126
|
+
export function renderRouteSection(record: CouncilRouteRecord): string {
|
|
127
|
+
const stages = record.stageOutputs
|
|
128
|
+
.map((s) => ` - ${s.stage}: produced ${String(s.produced)}, ${String(s.calls)} call(s)`)
|
|
129
|
+
.join('\n');
|
|
130
|
+
return [
|
|
131
|
+
'',
|
|
132
|
+
'## Route',
|
|
133
|
+
'',
|
|
134
|
+
`- ladder: rung ${String(record.ladderResolution.rung)} / ${record.ladderResolution.verdict} — ${record.ladderResolution.reason}`,
|
|
135
|
+
'- council-internal topology: (not applicable — no topology selector exists)',
|
|
136
|
+
`- initial route: ${record.initialRoute}`,
|
|
137
|
+
`- escalation: ${
|
|
138
|
+
record.escalation.escalated
|
|
139
|
+
? `${String(record.escalation.from)} → ${String(record.escalation.to)} — ${record.escalation.reason}`
|
|
140
|
+
: `none — ${record.escalation.reason}`
|
|
141
|
+
}`,
|
|
142
|
+
'- stage outputs:',
|
|
143
|
+
stages === '' ? ' - (none recorded)' : stages,
|
|
144
|
+
`- stop reason: ${record.stopReason ?? '(ran to completion)'}`,
|
|
145
|
+
`- synthesis policy: ${record.synthesisPolicy ?? '(host synthesis)'}`,
|
|
146
|
+
`- cost: ${String(record.costCalls)} call(s), $${record.costUsd.toFixed(USD_PRECISION)}`,
|
|
147
|
+
`- latency: ${String(record.latencyMs)} ms`,
|
|
148
|
+
`- final verdict: ${record.finalVerdict}`,
|
|
149
|
+
'',
|
|
150
|
+
].join('\n');
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const _LADDER_RE = /^- ladder: rung (\S+) \/ (\S+) — ([\s\S]*)$/;
|
|
154
|
+
const _COST_RE = /^- cost: (\d+) call\(s\), \$([0-9.]+)$/;
|
|
155
|
+
|
|
156
|
+
/** Parse a rendered section back into the record. Inverse of {@link renderRouteSection}. */
|
|
157
|
+
export function parseRouteSection(section: string): CouncilRouteRecord | null {
|
|
158
|
+
const lines = section.split('\n');
|
|
159
|
+
const get = (prefix: string): string | null => {
|
|
160
|
+
const l = lines.find((x) => x.startsWith(prefix));
|
|
161
|
+
return l === undefined ? null : l.slice(prefix.length);
|
|
162
|
+
};
|
|
163
|
+
const ladderLine = lines.find((l) => l.startsWith('- ladder: '));
|
|
164
|
+
const ladder = ladderLine === undefined ? null : _LADDER_RE.exec(ladderLine);
|
|
165
|
+
const costLine = lines.find((l) => l.startsWith('- cost: '));
|
|
166
|
+
const cost = costLine === undefined ? null : _COST_RE.exec(costLine);
|
|
167
|
+
if (ladder === null || cost === null) return null;
|
|
168
|
+
|
|
169
|
+
const rungRaw = ladder[1] as string;
|
|
170
|
+
const escRaw = get('- escalation: ') ?? '';
|
|
171
|
+
const escalated = !escRaw.startsWith('none — ');
|
|
172
|
+
const arrow = escRaw.split(' — ')[0] ?? '';
|
|
173
|
+
const [from, to] = escalated ? arrow.split(' → ') : [null, null];
|
|
174
|
+
|
|
175
|
+
const stageOutputs: StageOutput[] = [];
|
|
176
|
+
const start = lines.indexOf('- stage outputs:');
|
|
177
|
+
for (let i = start + 1; i < lines.length && (lines[i] as string).startsWith(' - '); i++) {
|
|
178
|
+
const m = /^ {2}- (.+): produced (\d+), (\d+) call\(s\)$/.exec(lines[i] as string);
|
|
179
|
+
if (m) stageOutputs.push({ stage: m[1] as string, produced: Number(m[2]), calls: Number(m[3]) });
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const stop = get('- stop reason: ') ?? '';
|
|
183
|
+
const policy = get('- synthesis policy: ') ?? '';
|
|
184
|
+
return {
|
|
185
|
+
ladderResolution: {
|
|
186
|
+
rung: (rungRaw === 'null' ? null : Number(rungRaw)) as LadderRung,
|
|
187
|
+
verdict: ladder[2] as LadderVerdict,
|
|
188
|
+
reason: ladder[3] as string,
|
|
189
|
+
},
|
|
190
|
+
councilInternalTopology: null,
|
|
191
|
+
initialRoute: get('- initial route: ') ?? '',
|
|
192
|
+
escalation: {
|
|
193
|
+
escalated,
|
|
194
|
+
from: from ?? null,
|
|
195
|
+
to: to ?? null,
|
|
196
|
+
reason: escRaw.split(' — ').slice(1).join(' — '),
|
|
197
|
+
},
|
|
198
|
+
stageOutputs,
|
|
199
|
+
stopReason: stop === '(ran to completion)' ? null : stop,
|
|
200
|
+
synthesisPolicy: policy === '(host synthesis)' ? null : (policy as SynthesisStrategyId),
|
|
201
|
+
costCalls: Number(cost[1]),
|
|
202
|
+
costUsd: Number(cost[2]),
|
|
203
|
+
latencyMs: Number(get('- latency: ')?.replace(/ ms$/, '') ?? '0'),
|
|
204
|
+
finalVerdict: get('- final verdict: ') ?? '',
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/** The verify clause, executable: does a replay reproduce the recorded route? */
|
|
209
|
+
export function replayReproducesRoute(record: CouncilRouteRecord): boolean {
|
|
210
|
+
const parsed = parseRouteSection(renderRouteSection(record));
|
|
211
|
+
return parsed !== null && JSON.stringify(parsed) === JSON.stringify(record);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Append the route section to an existing replay body.
|
|
216
|
+
*
|
|
217
|
+
* `null` returns the body UNCHANGED — byte for byte — which is what keeps
|
|
218
|
+
* `replay.ts`'s parity contract intact for every caller that does not record a
|
|
219
|
+
* route.
|
|
220
|
+
*/
|
|
221
|
+
export function withRouteSection(replayBody: string, record: CouncilRouteRecord | null): string {
|
|
222
|
+
return record === null ? replayBody : `${replayBody}${renderRouteSection(record)}`;
|
|
223
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How a `CouncilResponse` is shaped for the persisted session record.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from `council_cli.ts` on 2026-08-30. It belongs here on its own
|
|
5
|
+
* merits — it is a pure data-shaping function over a type this directory owns,
|
|
6
|
+
* with no CLI concern in it — and it pays for the lines the same change spent
|
|
7
|
+
* in files that are thousands past `check_source_size_budget`'s ceiling. That
|
|
8
|
+
* gate's own convention is that the total falls through extraction and never
|
|
9
|
+
* rises through a baseline edit.
|
|
10
|
+
*
|
|
11
|
+
* `metadata` values are stringified deliberately, and two consumers depend on
|
|
12
|
+
* it: `ai_council/pricing.ts` coerces them back, and `billable_cost.test.ts`
|
|
13
|
+
* pins the behavior.
|
|
14
|
+
*
|
|
15
|
+
* Side-effect-free, no CLI entry, no `process.exit`.
|
|
16
|
+
*/
|
|
17
|
+
import type { CouncilResponse } from './clients.js';
|
|
18
|
+
|
|
19
|
+
type Dict = Record<string, unknown>;
|
|
20
|
+
|
|
21
|
+
export function serializeResponses(responses: CouncilResponse[]): Dict[] {
|
|
22
|
+
const out: Dict[] = [];
|
|
23
|
+
for (const r of responses) {
|
|
24
|
+
const metadata: Dict = {};
|
|
25
|
+
for (const [k, v] of Object.entries(r.metadata || {})) {
|
|
26
|
+
metadata[k] = String(v);
|
|
27
|
+
}
|
|
28
|
+
out.push({
|
|
29
|
+
provider: r.provider,
|
|
30
|
+
model: r.model,
|
|
31
|
+
text: r.text,
|
|
32
|
+
// Present ONLY when something rewrote `text` in place — today that
|
|
33
|
+
// is the inline-findings harvest, whose emitted marker promises
|
|
34
|
+
// exactly this retention. Omitted otherwise rather than written as
|
|
35
|
+
// a copy of `text`, so an unmodified reply does not carry a
|
|
36
|
+
// duplicate of itself into every session record. The full account
|
|
37
|
+
// of why the field exists is at its single write site in
|
|
38
|
+
// `inline_findings.ts`.
|
|
39
|
+
...(r.raw_text === null ? {} : { raw_text: r.raw_text }),
|
|
40
|
+
input_tokens: r.input_tokens,
|
|
41
|
+
output_tokens: r.output_tokens,
|
|
42
|
+
cache_creation_input_tokens: r.cache_creation_input_tokens,
|
|
43
|
+
cache_read_input_tokens: r.cache_read_input_tokens,
|
|
44
|
+
latency_ms: r.latency_ms,
|
|
45
|
+
error: r.error,
|
|
46
|
+
metadata,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
return out;
|
|
50
|
+
}
|