@event4u/agent-config 14.12.0 → 14.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.augment-plugin/marketplace.json +3 -3
- package/.augment-plugin/plugin.json +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +234 -0
- package/CONTRIBUTING.md +38 -0
- package/CREDITS.md +135 -0
- package/NOTICE +13 -0
- package/README.md +8 -6
- package/dist/agent-src/commands/analyze/inbox.md +109 -2
- package/dist/agent-src/commands/feature/dev.md +7 -2
- package/dist/agent-src/commands/ghostwriter/write.md +5 -1
- package/dist/agent-src/commands/implement-ticket.md +1 -1
- package/dist/agent-src/commands/mission/upgrade.md +1 -1
- package/dist/agent-src/commands/orchestrate.md +2 -2
- package/dist/agent-src/commands/post-as/me.md +5 -1
- package/dist/agent-src/commands/pr/merge.md +19 -6
- package/dist/agent-src/commands/roadmap/process-full.md +19 -5
- package/dist/agent-src/commands/tdd/red.md +12 -2
- package/dist/agent-src/commands/work.md +1 -1
- package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +40 -0
- package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +5 -2
- package/dist/agent-src/contexts/execution/autonomy-mechanics.md +21 -0
- package/dist/agent-src/contexts/execution/orchestration-telemetry.md +1 -0
- package/dist/agent-src/contexts/execution/subagent-response-contract.md +40 -0
- package/dist/agent-src/contexts/execution/subagent-steering.md +13 -1
- package/dist/agent-src/contexts/execution/terminal-states.md +96 -0
- package/dist/agent-src/rules/artifact-drafting-protocol.md +1 -1
- package/dist/agent-src/rules/broken-access-control.md +4 -0
- package/dist/agent-src/rules/code-provenance.md +4 -0
- package/dist/agent-src/rules/design-fidelity.md +1 -1
- package/dist/agent-src/rules/domain-safety-pii.md +4 -0
- package/dist/agent-src/rules/domain-safety-retention.md +4 -0
- package/dist/agent-src/rules/engineering-safety-floor.md +2 -0
- package/dist/agent-src/rules/external-code-graph-interop.md +14 -12
- package/dist/agent-src/rules/improve-before-implement.md +6 -8
- package/dist/agent-src/rules/laravel-routing.md +1 -1
- package/dist/agent-src/rules/lethal-trifecta-guard.md +4 -0
- package/dist/agent-src/rules/secret-vcs-guard.md +2 -0
- package/dist/agent-src/rules/security-sensitive-stop.md +2 -0
- package/dist/agent-src/rules/source-confidentiality.md +12 -34
- package/dist/agent-src/rules/symfony-routing.md +1 -1
- package/dist/agent-src/rules/token-efficiency.md +14 -0
- package/dist/agent-src/rules/tool-safety.md +4 -0
- package/dist/agent-src/rules/untrusted-input-defense.md +4 -0
- package/dist/agent-src/scripts/archive_completed_roadmaps.ts +247 -3
- package/dist/agent-src/scripts/guarded_baseline.ts +328 -0
- package/dist/agent-src/scripts/roadmap_set_step.ts +253 -0
- package/dist/agent-src/scripts/stub_queue.ts +82 -0
- package/dist/agent-src/scripts/stubs_due.ts +400 -0
- package/dist/agent-src/scripts/ticket_bundles.ts +84 -0
- package/dist/agent-src/scripts/update_roadmap_progress.ts +8 -4
- package/dist/agent-src/skills/brand-asset-generation/SKILL.md +17 -4
- package/dist/agent-src/skills/brand-audit/SKILL.md +33 -0
- package/dist/agent-src/skills/code-intelligence/SKILL.md +57 -0
- package/dist/agent-src/skills/database/SKILL.md +8 -0
- package/dist/agent-src/skills/dependency-upgrade/SKILL.md +27 -0
- package/dist/agent-src/skills/design-review/SKILL.md +1 -1
- package/dist/agent-src/skills/doc-coauthoring/SKILL.md +1 -1
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +17 -1
- package/dist/agent-src/skills/feature-planning/SKILL.md +9 -2
- package/dist/agent-src/skills/frontend-render-security/SKILL.md +44 -0
- package/dist/agent-src/skills/git-workflow/SKILL.md +1 -1
- package/dist/agent-src/skills/js-library-packaging/scripts/check_package_surface.ts +38 -4
- package/dist/agent-src/skills/judge-artifact-completeness/rubrics/ticket-quality-score.json +2 -2
- package/dist/agent-src/skills/laravel/SKILL.md +35 -0
- package/dist/agent-src/skills/laravel-migration/SKILL.md +57 -3
- package/dist/agent-src/skills/monorepo-workspace/SKILL.md +26 -0
- package/dist/agent-src/skills/playbook-authoring/SKILL.md +28 -1
- package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +1 -1
- package/dist/agent-src/skills/skill-writing/references/procedure.md +5 -5
- package/dist/agent-src/skills/sql-writing/SKILL.md +7 -1
- package/dist/agent-src/skills/standards-from-config/SKILL.md +27 -4
- package/dist/agent-src/skills/supply-chain-intake/SKILL.md +11 -4
- package/dist/agent-src/skills/symfony-workflow/SKILL.md +35 -0
- package/dist/agent-src/skills/test-case-discovery/SKILL.md +85 -0
- package/dist/agent-src/skills/test-driven-development/SKILL.md +33 -9
- package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
- package/dist/agent-src/skills/testing-anti-patterns/process-anti-patterns.md +37 -0
- package/dist/agent-src/skills/ui-component-architect/SKILL.md +45 -2
- package/dist/agent-src/skills/upstream-contribute/SKILL.md +38 -1
- package/dist/agent-src/skills/verify-repair-loop/SKILL.md +9 -4
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/roadmaps.md +97 -3
- package/dist/agent-src/templates/scripts/check_memory.ts +258 -17
- package/dist/agent-src/templates/scripts/check_memory_proposal.ts +9 -3
- package/dist/agent-src/templates/scripts/memory_lookup.ts +86 -0
- package/dist/agent-src/templates/scripts/memory_signal.ts +44 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/implement.ts +90 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/index.ts +11 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/test.ts +23 -1
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +10 -1
- package/dist/agent-src/templates/scripts/work_engine/directives/mixed/stitch.ts +5 -1
- package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +102 -14
- package/dist/cli/commands/uiAudit.js +124 -5
- package/dist/cli/registry.js +2 -0
- package/dist/cli-delegate/{chunk-HYWSRNUX.js → chunk-2DK2VJWG.js} +3 -3
- package/dist/cli-delegate/{chunk-JCW7ZLHK.js → chunk-4FS4WRXP.js} +5 -0
- package/dist/cli-delegate/{chunk-OMIVVCG2.js → chunk-A4QJ6ENT.js} +24 -0
- package/dist/cli-delegate/{chunk-JJA2QEWA.js → chunk-AKJGUQNO.js} +466 -285
- package/dist/cli-delegate/{chunk-E46KPN6K.js → chunk-BTWUYDGN.js} +424 -363
- package/dist/cli-delegate/{chunk-K4FFODTS.js → chunk-ILMUPLGW.js} +1227 -316
- package/dist/cli-delegate/{chunk-FF7WAFMR.js → chunk-KPBWFOPZ.js} +5 -1
- package/dist/cli-delegate/cmd_adr_effective.js +102 -0
- package/dist/cli-delegate/cmd_conformance.js +42 -10
- package/dist/cli-delegate/cmd_doctor.js +3 -3
- package/dist/cli-delegate/cmd_export.js +3 -2
- package/dist/cli-delegate/cmd_fleet.js +2 -2
- package/dist/cli-delegate/cmd_handoff.js +1 -1
- package/dist/cli-delegate/cmd_preflight.js +2 -2
- package/dist/cli-delegate/cmd_prune.js +3 -2
- package/dist/cli-delegate/cmd_settings_get.js +1 -1
- package/dist/cli-delegate/cmd_settings_migrate.js +3 -2
- package/dist/cli-delegate/cmd_settings_set.js +2 -2
- package/dist/cli-delegate/cmd_sync.js +3 -2
- package/dist/cli-delegate/cmd_uninstall.js +3 -2
- package/dist/cli-delegate/cmd_validate.js +3 -2
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +57 -57
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +1 -1
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +2 -2
- package/dist/discovery/trust-report.md +1 -1
- package/dist/discovery/workspaces.json +2 -2
- package/dist/hooks/dispatch.js +1836 -712
- package/dist/install/claudeRuleRewrite.js +254 -0
- package/dist/install/detect.js +29 -16
- package/dist/install/detect_php_shape.js +159 -0
- package/dist/install/install.mjs +634 -428
- package/dist/mcp/awesome-mcp-servers.row.md +1 -1
- package/dist/mcp/mcp-cloudflare-catalogue.json +1 -1
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +3 -3
- package/dist/mcp/server.mjs +4818 -2645
- package/dist/server/schemas/settings.js +3 -0
- package/dist/ui/assets/index-D0jaCRPM.js +29 -0
- package/dist/ui/index.html +1 -1
- package/docs/MIGRATION.md +1 -1
- package/docs/THIRD-PARTY-NOTICES.md +25 -0
- package/docs/contracts/provider-lifecycle.md +1 -1
- package/docs/contracts/settings-classes.md +10 -4
- package/docs/guidelines/agent-infra/5w2h-analysis.md +3 -3
- package/docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md +1 -0
- package/docs/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md +58 -3
- package/docs/guidelines/agent-infra/ask-when-uncertain-demos.md +2 -2
- package/docs/guidelines/agent-infra/asking-and-brevity-examples.md +3 -3
- package/docs/guidelines/agent-infra/break-glass-usage.md +7 -7
- package/docs/guidelines/agent-infra/carve-out-predicates.md +3 -3
- package/docs/guidelines/agent-infra/comparison-matrix.md +1 -1
- package/docs/guidelines/agent-infra/critical-thinking.md +4 -4
- package/docs/guidelines/agent-infra/direct-answers-demos.md +2 -2
- package/docs/guidelines/agent-infra/domain-eval-anti-pattern.md +1 -1
- package/docs/guidelines/agent-infra/engineering-memory-data-format.md +3 -3
- package/docs/guidelines/agent-infra/existence-question-verdicts.md +80 -0
- package/docs/guidelines/agent-infra/first-principles.md +2 -2
- package/docs/guidelines/agent-infra/framework-neutrality-patterns.md +2 -2
- package/docs/guidelines/agent-infra/guarded-baseline.md +39 -0
- package/docs/guidelines/agent-infra/inversion-thinking.md +5 -5
- package/docs/guidelines/agent-infra/language-and-tone-examples.md +1 -1
- package/docs/guidelines/agent-infra/layered-settings.md +10 -10
- package/docs/guidelines/agent-infra/memory-access.md +1 -1
- package/docs/guidelines/agent-infra/mental-models.md +3 -3
- package/docs/guidelines/agent-infra/reuse-verdict-mechanics.md +71 -0
- package/docs/guidelines/agent-infra/review-routing-data-format.md +7 -7
- package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +13 -7
- package/docs/guidelines/agent-infra/role-contracts.md +2 -2
- package/docs/guidelines/agent-infra/role-mode-router.md +3 -3
- package/docs/guidelines/agent-infra/rule-type-governance.md +2 -2
- package/docs/guidelines/agent-infra/scqa-framework.md +5 -5
- package/docs/guidelines/agent-infra/self-improvement-pipeline.md +6 -6
- package/docs/guidelines/agent-infra/simplicity-and-goal-demos.md +2 -2
- package/docs/guidelines/agent-infra/six-hats.md +3 -3
- package/docs/guidelines/agent-infra/skill-quality-checklist.md +6 -6
- package/docs/guidelines/agent-infra/source-confidentiality-mechanics.md +109 -0
- package/docs/guidelines/agent-infra/systems-thinking.md +1 -1
- package/docs/guidelines/agent-infra/verify-before-complete-demos.md +2 -2
- package/docs/guidelines/augment-portability-patterns.md +6 -4
- package/docs/guidelines/component-oriented-and-oop-development.md +3 -2
- package/docs/guidelines/cross-role-handoff.md +2 -2
- package/docs/guidelines/design-fidelity-mechanics.md +1 -1
- package/docs/guidelines/docs/readme-size-and-splitting.md +3 -3
- package/docs/guidelines/php/database.md +90 -7
- package/docs/guidelines/prompt-templates.md +7 -7
- package/llms.txt +2 -2
- package/package.json +5 -2
- package/src/agent-src/scripts/archive_completed_roadmaps.ts +247 -3
- package/src/agent-src/scripts/guarded_baseline.ts +328 -0
- package/src/agent-src/scripts/roadmap_set_step.ts +253 -0
- package/src/agent-src/scripts/stub_queue.ts +82 -0
- package/src/agent-src/scripts/stubs_due.ts +400 -0
- package/src/agent-src/scripts/ticket_bundles.ts +84 -0
- package/src/agent-src/scripts/update_roadmap_progress.ts +8 -4
- package/src/agent-src/templates/scripts/check_memory.ts +258 -17
- package/src/agent-src/templates/scripts/check_memory_proposal.ts +9 -3
- package/src/agent-src/templates/scripts/memory_lookup.ts +86 -0
- package/src/agent-src/templates/scripts/memory_signal.ts +44 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/implement.ts +90 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/index.ts +11 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/test.ts +23 -1
- package/src/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +10 -1
- package/src/agent-src/templates/scripts/work_engine/directives/mixed/stitch.ts +5 -1
- package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +102 -14
- package/src/config/agent-settings.template.yml +32 -3
- package/src/config/assurance-capability-registry.json +21 -9
- package/src/config/canonical-terms.yml +119 -0
- package/src/config/capability-native-outcome-bars.json +81 -0
- package/src/config/ci-local-parity.yml +80 -0
- package/src/config/drafting-channels.yml +43 -0
- package/src/config/estate-count-budget.json +38 -36
- package/src/config/evaluator-budgets.json +14 -14
- package/src/config/gate-coverage.yml +579 -63
- package/src/config/gate-reachability-exemptions.json +21 -0
- package/src/config/gate-violation-baselines.json +37 -19
- package/src/config/harness-evolution-budget.json +25 -0
- package/src/config/lapsed-beta-baseline.json +96 -0
- package/src/config/memory-twin-verdicts.yml +129 -0
- package/src/config/metric-registry.yml +124 -0
- package/src/config/pack-size-budget.json +16 -15
- package/src/config/preamble-payload-budget.json +8 -8
- package/src/config/profiles/balanced.ini +27 -0
- package/src/config/profiles/full.ini +27 -0
- package/src/config/profiles/minimal.ini +27 -0
- package/src/config/publish-surface.json +9 -2
- package/src/config/routing-coverage-seed.json +16 -2
- package/src/config/rule-stub-ceilings.json +126 -112
- package/src/config/turnaround-budget.json +66 -0
- package/src/install/claudeRuleRewrite.ts +288 -0
- package/src/install/detect.ts +60 -17
- package/src/install/detect_php_shape.ts +191 -0
- package/src/scripts/_cli/cmd_doctor.ts +27 -112
- package/src/scripts/_dispatch.bash +27 -0
- package/src/scripts/_lib/activation_ladder.ts +211 -0
- package/src/scripts/_lib/activation_states.ts +88 -0
- package/src/scripts/_lib/adherence_detectors.ts +143 -0
- package/src/scripts/_lib/arith_claims.ts +181 -0
- package/src/scripts/_lib/arm_ranking.ts +62 -0
- package/src/scripts/_lib/asset_delivery_ledger.ts +303 -0
- package/src/scripts/_lib/audit_field_provenance.ts +54 -0
- package/src/scripts/_lib/auto_dispatch.ts +32 -3
- package/src/scripts/_lib/bench_ab_size_claim.ts +98 -4
- package/src/scripts/_lib/benchmark_cache_fields.ts +158 -0
- package/src/scripts/_lib/candidate_proposer.ts +402 -0
- package/src/scripts/_lib/candidate_record.ts +601 -0
- package/src/scripts/_lib/capture_rate.ts +319 -0
- package/src/scripts/_lib/collector_denominator.ts +771 -0
- package/src/scripts/_lib/collector_record.ts +340 -0
- package/src/scripts/_lib/collector_store.ts +664 -0
- package/src/scripts/_lib/collector_supervision.ts +827 -0
- package/src/scripts/_lib/concern_estate.ts +77 -0
- package/src/scripts/_lib/config_chain.ts +477 -0
- package/src/scripts/_lib/config_cost.ts +209 -0
- package/src/scripts/_lib/council_settings_block.ts +6 -0
- package/src/scripts/_lib/curator_ops.ts +172 -0
- package/src/scripts/_lib/delivery_arm_experiment.ts +266 -0
- package/src/scripts/_lib/delivery_criticality.ts +126 -0
- package/src/scripts/_lib/doctor_runtime_checks.ts +70 -0
- package/src/scripts/_lib/empty_cycles.ts +88 -0
- package/src/scripts/_lib/eval_publication.ts +354 -0
- package/src/scripts/_lib/evaluation_vector.ts +283 -0
- package/src/scripts/_lib/evaluator_promotion.ts +225 -0
- package/src/scripts/_lib/evidence_basis.ts +118 -0
- package/src/scripts/_lib/exec_evidence.ts +8 -0
- package/src/scripts/_lib/experience_card.ts +272 -0
- package/src/scripts/_lib/experience_report.ts +151 -0
- package/src/scripts/_lib/experiment_freeze.ts +112 -0
- package/src/scripts/_lib/generated_by.ts +66 -0
- package/src/scripts/_lib/harness_evolution_guards.ts +229 -0
- package/src/scripts/_lib/hook_effect_probe.ts +141 -0
- package/src/scripts/_lib/host_denominator.ts +687 -0
- package/src/scripts/_lib/host_projection_reach.ts +157 -0
- package/src/scripts/_lib/ignored_blocker.ts +148 -0
- package/src/scripts/_lib/install_reach_checks.ts +495 -0
- package/src/scripts/_lib/json_duplicate_keys.ts +150 -0
- package/src/scripts/_lib/judge_hygiene.ts +228 -0
- package/src/scripts/_lib/legacy_boundary_map.ts +228 -0
- package/src/scripts/_lib/loop_guards.ts +299 -0
- package/src/scripts/_lib/loss_class.ts +129 -0
- package/src/scripts/_lib/machine_wake.ts +51 -0
- package/src/scripts/_lib/md_prose_lines.ts +177 -0
- package/src/scripts/_lib/minimality_tiebreak.ts +168 -0
- package/src/scripts/_lib/one_resolver_invariant.ts +449 -0
- package/src/scripts/_lib/orchestration_record.ts +253 -5
- package/src/scripts/_lib/outcome_envelope.ts +227 -0
- package/src/scripts/_lib/outcome_vocabularies.ts +125 -0
- package/src/scripts/_lib/paired_stats.ts +245 -0
- package/src/scripts/_lib/paired_verdict.ts +226 -0
- package/src/scripts/_lib/prefix_stable_surfaces.ts +123 -0
- package/src/scripts/_lib/privacy_class.ts +47 -0
- package/src/scripts/_lib/regression_neighbourhood.ts +259 -0
- package/src/scripts/_lib/repeated_failure.ts +105 -0
- package/src/scripts/_lib/repo_root.ts +111 -0
- package/src/scripts/_lib/review_skipped_record.ts +37 -0
- package/src/scripts/_lib/role_split.ts +338 -0
- package/src/scripts/_lib/runtime_journal.ts +1499 -0
- package/src/scripts/_lib/runtime_wiring_checks.ts +430 -0
- package/src/scripts/_lib/skill_catalogue.ts +11 -1
- package/src/scripts/_lib/source_digest.ts +200 -0
- package/src/scripts/_lib/source_redact.ts +260 -0
- package/src/scripts/_lib/source_shape.ts +502 -0
- package/src/scripts/_lib/source_snapshot_dedup.ts +199 -0
- package/src/scripts/_lib/strip_comments.d.mts +8 -0
- package/src/scripts/_lib/strip_comments.mjs +65 -0
- package/src/scripts/_lib/test_red_state.ts +154 -0
- package/src/scripts/_lib/trigger_shift.ts +144 -0
- package/src/scripts/_lib/untrusted_content.ts +82 -7
- package/src/scripts/adoption_report.ts +1 -1
- package/src/scripts/adr/evidence_census.ts +1 -1
- package/src/scripts/adr/regenerate_index.ts +26 -2
- package/src/scripts/adr_cite_check.ts +164 -1
- package/src/scripts/ai_council/blind_review.ts +11 -1
- package/src/scripts/ai_council/clients.ts +4 -0
- package/src/scripts/ai_council/config.ts +3 -0
- package/src/scripts/ai_council/consensus.ts +28 -8
- package/src/scripts/ai_council/consensus_round.ts +226 -0
- package/src/scripts/ai_council/disagreement_signal.ts +338 -0
- package/src/scripts/ai_council/inline_findings.ts +340 -0
- package/src/scripts/ai_council/judge_position_bias.ts +197 -0
- package/src/scripts/ai_council/orchestrator.ts +16 -203
- package/src/scripts/ai_council/orchestrator_results.ts +23 -3
- package/src/scripts/ai_council/pricing.ts +106 -0
- package/src/scripts/ai_council/prompts.ts +74 -7
- package/src/scripts/ai_council/provider_leakage_bench.ts +327 -0
- package/src/scripts/ai_council/py_format.ts +14 -3
- package/src/scripts/ai_council/recouncil_guard.ts +293 -0
- package/src/scripts/ai_council/response_record.ts +50 -0
- package/src/scripts/ai_council/topology_bench_manifest.ts +860 -0
- package/src/scripts/ai_council/topology_vocabulary.ts +175 -0
- package/src/scripts/asset_delivery_ledger.ts +157 -0
- package/src/scripts/attest_artifact.ts +193 -0
- package/src/scripts/audit_auto_rules.ts +2 -1
- package/src/scripts/audit_command_surface.ts +1 -1
- package/src/scripts/audit_mcp_tools.ts +2 -2
- package/src/scripts/audit_skill_overlap_allowlist.json +6 -1
- package/src/scripts/audit_user_type_axis.ts +2 -1
- package/src/scripts/bench_ab_clone.ts +215 -10
- package/src/scripts/bench_ab_integrity.ts +119 -5
- package/src/scripts/bench_ab_v2_stats.ts +40 -213
- package/src/scripts/build_archive_index.ts +1 -1
- package/src/scripts/build_linear_digest.ts +1 -1
- package/src/scripts/build_proof.ts +11 -4
- package/src/scripts/build_rule_trigger_matrix.ts +1 -1
- package/src/scripts/build_source_digests.ts +157 -0
- package/src/scripts/cache_realization_report.ts +103 -0
- package/src/scripts/check_adr_frontmatter.ts +126 -0
- package/src/scripts/check_benchmark_report_fields.ts +207 -0
- package/src/scripts/check_beta_review_markers.ts +235 -6
- package/src/scripts/check_bundle_path_leakage.ts +34 -1
- package/src/scripts/check_claims.ts +576 -6
- package/src/scripts/check_composite_arming.ts +35 -0
- package/src/scripts/check_concern_admissions.ts +365 -0
- package/src/scripts/check_enforcement_coverage.ts +28 -0
- package/src/scripts/check_estate_count.ts +142 -1
- package/src/scripts/check_gate_reachability.ts +383 -0
- package/src/scripts/check_host_loadability.ts +104 -0
- package/src/scripts/check_loss_class_declared.ts +308 -0
- package/src/scripts/check_md_language.ts +15 -98
- package/src/scripts/check_memory_proposal.ts +18 -11
- package/src/scripts/check_no_currency_in_cost_surfaces.ts +225 -0
- package/src/scripts/check_no_external_sources.ts +281 -6
- package/src/scripts/check_pack_conformance_fixture.ts +11 -1
- package/src/scripts/check_pack_size.ts +59 -2
- package/src/scripts/check_preamble_payload_budget.ts +114 -3
- package/src/scripts/check_prefix_stable_mutation.ts +372 -0
- package/src/scripts/check_publish_surface.ts +10 -1
- package/src/scripts/check_references.ts +24 -1
- package/src/scripts/check_rule_evidence_declaration.ts +316 -0
- package/src/scripts/check_rule_projection_integrity.ts +14 -4
- package/src/scripts/check_score_contract.ts +26 -3
- package/src/scripts/check_static_parity.ts +285 -0
- package/src/scripts/check_supervision_claim_atomicity.ts +498 -0
- package/src/scripts/check_suppression_hygiene.ts +15 -0
- package/src/scripts/ci_settle.ts +39 -2
- package/src/scripts/code_graph/build.ts +60 -3
- package/src/scripts/code_graph/extract.ts +44 -0
- package/src/scripts/code_graph/types.ts +24 -0
- package/src/scripts/collector_daemon.ts +714 -0
- package/src/scripts/config_cost_report.ts +302 -0
- package/src/scripts/consumer_matrix.ts +74 -1
- package/src/scripts/cost/budget.mjs +10 -3
- package/src/scripts/cost/track.mjs +10 -3
- package/src/scripts/council_cli.ts +37 -54
- package/src/scripts/dispatch_r2_reviewer.ts +46 -5
- package/src/scripts/evolution_lab.ts +980 -0
- package/src/scripts/external_sources_denylist.json +5 -18
- package/src/scripts/extract_audit_patterns.ts +21 -0
- package/src/scripts/fold_intake.ts +12 -1
- package/src/scripts/gen_discovery_baseline.ts +1 -1
- package/src/scripts/generate_capabilities_index.ts +12 -5
- package/src/scripts/generate_capability_matrix.ts +3 -3
- package/src/scripts/generate_command_flows.ts +2 -2
- package/src/scripts/generate_cookbook.ts +2 -2
- package/src/scripts/generate_index.ts +8 -1
- package/src/scripts/generate_knowledge_index.ts +2 -1
- package/src/scripts/generate_ownership_matrix.ts +2 -1
- package/src/scripts/generate_pack_manifests.ts +10 -2
- package/src/scripts/generate_role_experiences_catalog.ts +2 -2
- package/src/scripts/generate_settings_reference.ts +1 -1
- package/src/scripts/git_authorization_hook.ts +22 -1
- package/src/scripts/grade_target_readiness.ts +48 -5
- package/src/scripts/hook_effect_doctor.ts +261 -0
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +98 -11
- package/src/scripts/hooks/block_speaking_inbox_dir.ts +271 -0
- package/src/scripts/hooks/block_unauthorized_git.ts +18 -0
- package/src/scripts/hooks/concern_registry.ts +4 -0
- package/src/scripts/hooks/dispatch_hook.ts +32 -0
- package/src/scripts/hooks/journal_record_hook.ts +345 -0
- package/src/scripts/hooks/prepush_metadata_sources.sh +110 -0
- package/src/scripts/hooks/run_continuation_hook.ts +44 -9
- package/src/scripts/hooks/shims/install.sh +61 -0
- package/src/scripts/hooks/shims/php +101 -0
- package/src/scripts/hooks/suggestion_capture_hook.ts +10 -0
- package/src/scripts/hot_context_hook.ts +16 -0
- package/src/scripts/install-hooks.sh +20 -5
- package/src/scripts/install.ts +17 -35
- package/src/scripts/inventory_frontmatter.ts +2 -1
- package/src/scripts/lint_adr_sweep_routing.ts +12 -0
- package/src/scripts/lint_canonical_terms.ts +604 -0
- package/src/scripts/lint_composition_review.ts +619 -0
- package/src/scripts/lint_consolidation_lineage.ts +666 -0
- package/src/scripts/lint_eval_specs.ts +593 -0
- package/src/scripts/lint_hook_manifest.ts +19 -0
- package/src/scripts/lint_host_portability.ts +373 -0
- package/src/scripts/lint_judge_prompt_expectation.ts +27 -1
- package/src/scripts/lint_memory_twin_parity.ts +335 -0
- package/src/scripts/lint_metric_consumers.ts +355 -0
- package/src/scripts/lint_skill_descriptions.ts +18 -1
- package/src/scripts/lint_skill_frontmatter_safety.ts +58 -0
- package/src/scripts/lint_skill_link_reach.ts +252 -0
- package/src/scripts/lint_skill_trigger_corpus.ts +426 -23
- package/src/scripts/lint_ticket_buildable.ts +17 -1
- package/src/scripts/mcp_server/consumer_tool_catalog.json +1 -1
- package/src/scripts/mcp_server/tool_catalog_source.ts +1 -1
- package/src/scripts/measure_docs_dead_links.ts +348 -0
- package/src/scripts/measure_host_capture.ts +461 -0
- package/src/scripts/migration_status.ts +3 -3
- package/src/scripts/model_rule_injection.ts +60 -0
- package/src/scripts/orchestration_record.ts +14 -0
- package/src/scripts/preamble_byte_census.ts +139 -10
- package/src/scripts/prepack-check.mjs +4 -1
- package/src/scripts/probe_turnaround.ts +384 -0
- package/src/scripts/probe_unblocked_ask.ts +279 -0
- package/src/scripts/render_benchmark_md.ts +1 -1
- package/src/scripts/rule_activation_census.ts +70 -9
- package/src/scripts/rule_backlinks.ts +1 -1
- package/src/scripts/run_lifecycle_suite.ts +208 -0
- package/src/scripts/run_skill_evals.ts +40 -0
- package/src/scripts/schemas/delivery-manifest.schema.json +43 -0
- package/src/scripts/schemas/drafting-channels.schema.json +43 -0
- package/src/scripts/schemas/evals.schema.json +24 -1
- package/src/scripts/schemas/rule.schema.json +52 -1
- package/src/scripts/schemas/skill.schema.json +17 -2
- package/src/scripts/skill_overlap.ts +7 -1
- package/src/scripts/skill_tools/run_block_d_eval.ts +8 -1
- package/src/scripts/skill_tools/score_skill_relevance.ts +84 -3
- package/src/scripts/skill_tools/suggest_skill_for_task.ts +8 -1
- package/src/scripts/skill_usage_report.ts +2 -1
- package/src/scripts/stubs_due.ts +211 -0
- package/src/scripts/sweep_source_surfaces.ts +678 -0
- package/src/scripts/sync_pr_branch.ts +3 -3
- package/src/scripts/trigger_eval_grandfather.json +202 -222
- package/src/scripts/utilization_report.ts +22 -2
- package/src/server/schemas/settings.ts +5 -0
- package/src/templates/marketing-copy.yml +1 -1
- package/dist/ui/assets/index-Cxgy63kz.js +0 -26
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* `config-cost report` — what does this configuration cost per session
|
|
4
|
+
* (`road-to-delivered-cost-truth` Phase 1).
|
|
5
|
+
*
|
|
6
|
+
* Class A per ADR-124: in-process, per-invocation, no socket, no daemon, no
|
|
7
|
+
* network, no writes outside a stdout/JSON report. The same class
|
|
8
|
+
* `cache_realization_report` already occupies, and for the same reason.
|
|
9
|
+
*
|
|
10
|
+
* Four figures, and the discipline is the point of each:
|
|
11
|
+
*
|
|
12
|
+
* delivered payload from the per-asset ledger, exact BPE where it resolves
|
|
13
|
+
* billable_input split fresh input · cache read · cache creation
|
|
14
|
+
* cache-read share `null` when nothing was billed, never 0 %
|
|
15
|
+
* payload_amplification delivered / profile-declared, or `unknown_profile`
|
|
16
|
+
*
|
|
17
|
+
* NO CURRENCY, ANYWHERE. The suite does not know the consumer's contract, so a
|
|
18
|
+
* monetary figure would be extrapolated from a rate it invented — actionable and
|
|
19
|
+
* wrong, which is worse than absent. `check_no_currency_in_cost_surfaces` gates
|
|
20
|
+
* it rather than leaving it to intent.
|
|
21
|
+
*
|
|
22
|
+
* Usage:
|
|
23
|
+
* ./scripts-run src/scripts/config_cost_report [--format text|json]
|
|
24
|
+
* [--root <path>] [--profile <name>] [--transcript-root <path>]
|
|
25
|
+
* [--max-age-days <n>] [--summary-line]
|
|
26
|
+
*/
|
|
27
|
+
import * as fs from 'node:fs';
|
|
28
|
+
import * as path from 'node:path';
|
|
29
|
+
|
|
30
|
+
import { buildLedger } from './_lib/asset_delivery_ledger.js';
|
|
31
|
+
import {
|
|
32
|
+
amplification,
|
|
33
|
+
billableSplit,
|
|
34
|
+
rereadCost,
|
|
35
|
+
summaryLine,
|
|
36
|
+
type AmplificationResult,
|
|
37
|
+
type BillableSplit,
|
|
38
|
+
type ProfileDeclaration,
|
|
39
|
+
type RereadCost,
|
|
40
|
+
type RereadLeg,
|
|
41
|
+
} from './_lib/config_cost.js';
|
|
42
|
+
import { prefixStableDirRoots } from './_lib/prefix_stable_surfaces.js';
|
|
43
|
+
import { DEFAULT_PROJECTS_ROOT, aggregateByBucket, scanTranscripts } from './_lib/cc_transcript.js';
|
|
44
|
+
import { computeRereads } from './_lib/transcript_reads.js';
|
|
45
|
+
import { gpt_tokens } from './_lib/token_count.js';
|
|
46
|
+
|
|
47
|
+
const HERE = path.dirname(new URL(import.meta.url).pathname);
|
|
48
|
+
const REPO_ROOT = path.resolve(HERE, '..', '..');
|
|
49
|
+
|
|
50
|
+
export interface Options {
|
|
51
|
+
format: 'text' | 'json';
|
|
52
|
+
transcript: string | null;
|
|
53
|
+
root: string;
|
|
54
|
+
profile: string | null;
|
|
55
|
+
transcriptRoot: string;
|
|
56
|
+
maxAgeDays: number;
|
|
57
|
+
summaryOnly: boolean;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function parseArgs(argv: string[]): Options {
|
|
61
|
+
const o: Options = {
|
|
62
|
+
format: 'text',
|
|
63
|
+
transcript: null,
|
|
64
|
+
root: REPO_ROOT,
|
|
65
|
+
profile: null,
|
|
66
|
+
transcriptRoot: DEFAULT_PROJECTS_ROOT,
|
|
67
|
+
maxAgeDays: 14,
|
|
68
|
+
summaryOnly: false,
|
|
69
|
+
};
|
|
70
|
+
for (let i = 0; i < argv.length; i++) {
|
|
71
|
+
const a = argv[i];
|
|
72
|
+
if (a === undefined) continue;
|
|
73
|
+
if (a === '--format') o.format = (argv[++i] as Options['format']) ?? o.format;
|
|
74
|
+
else if (a.startsWith('--format=')) o.format = a.slice('--format='.length) as Options['format'];
|
|
75
|
+
else if (a === '--root') o.root = path.resolve(argv[++i] ?? o.root);
|
|
76
|
+
else if (a.startsWith('--root=')) o.root = path.resolve(a.slice('--root='.length));
|
|
77
|
+
else if (a === '--profile') o.profile = argv[++i] ?? null;
|
|
78
|
+
else if (a.startsWith('--profile=')) o.profile = a.slice('--profile='.length);
|
|
79
|
+
else if (a === '--transcript-root') o.transcriptRoot = argv[++i] ?? o.transcriptRoot;
|
|
80
|
+
else if (a.startsWith('--transcript-root=')) o.transcriptRoot = a.slice('--transcript-root='.length);
|
|
81
|
+
else if (a === '--max-age-days') o.maxAgeDays = Number(argv[++i]) || o.maxAgeDays;
|
|
82
|
+
else if (a.startsWith('--max-age-days=')) o.maxAgeDays = Number(a.slice('--max-age-days='.length)) || o.maxAgeDays;
|
|
83
|
+
else if (a === '--transcript') o.transcript = argv[++i] ?? null;
|
|
84
|
+
else if (a.startsWith('--transcript=')) o.transcript = a.slice('--transcript='.length);
|
|
85
|
+
else if (a === '--summary-line') o.summaryOnly = true;
|
|
86
|
+
}
|
|
87
|
+
if (o.format !== 'text' && o.format !== 'json') o.format = 'text';
|
|
88
|
+
return o;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** Read a profile's declared standing payload. Absent file or key → `null`, never a default. */
|
|
92
|
+
export function readProfileDeclaration(root: string, profile: string): ProfileDeclaration | null {
|
|
93
|
+
const file = path.join(root, 'src', 'config', 'profiles', `${profile}.ini`);
|
|
94
|
+
let text: string;
|
|
95
|
+
try {
|
|
96
|
+
text = fs.readFileSync(file, 'utf-8');
|
|
97
|
+
} catch {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
const num = (key: string): number | null => {
|
|
101
|
+
const m = new RegExp(`^${key}\\s*=\\s*([0-9.]+)\\s*$`, 'm').exec(text);
|
|
102
|
+
if (m === null) return null;
|
|
103
|
+
const v = Number(m[1]);
|
|
104
|
+
return Number.isFinite(v) ? v : null;
|
|
105
|
+
};
|
|
106
|
+
const rules = num('declared_rules_tokens');
|
|
107
|
+
const skills = num('declared_skill_catalogue_tokens');
|
|
108
|
+
const headroom = num('declared_payload_sanity_headroom');
|
|
109
|
+
if (rules === null || skills === null || headroom === null) return null;
|
|
110
|
+
return { profile, declared: { rules_tokens: rules, skill_catalogue_tokens: skills }, sanity_headroom: headroom };
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** The active profile, read from the settings cascade. `full` is the shipped default. */
|
|
114
|
+
export function activeProfile(root: string, override: string | null): string {
|
|
115
|
+
if (override !== null) return override;
|
|
116
|
+
for (const rel of ['.agent-settings.yml', path.join('agents', 'settings', '.agent-settings.yml')]) {
|
|
117
|
+
try {
|
|
118
|
+
const m = /^\s*profile:\s*['"]?([A-Za-z0-9_-]+)/m.exec(fs.readFileSync(path.join(root, rel), 'utf-8'));
|
|
119
|
+
if (m !== null) return m[1] as string;
|
|
120
|
+
} catch {
|
|
121
|
+
/* absent layer — try the next */
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return 'full';
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Turn the re-reads `hot_context_hook` already counts into a token figure
|
|
129
|
+
* (step 1.3).
|
|
130
|
+
*
|
|
131
|
+
* The hook notices a repeated read and renders it as an advisory line; nothing
|
|
132
|
+
* ever priced it, so a re-read was visible and free-looking. The cost is
|
|
133
|
+
* `duplicate_reads x the file's MEASURED size` — derived, never a constant,
|
|
134
|
+
* because a constant would rank a re-read of a one-line config beside a re-read
|
|
135
|
+
* of a 3,000-token rule.
|
|
136
|
+
*
|
|
137
|
+
* A file that no longer exists is skipped rather than priced at zero: it was
|
|
138
|
+
* genuinely read, and a zero would understate the cost while looking measured.
|
|
139
|
+
*/
|
|
140
|
+
export function collectRereadLegs(transcriptPath: string | null, root: string): RereadLeg[] {
|
|
141
|
+
if (transcriptPath === null) return [];
|
|
142
|
+
let result;
|
|
143
|
+
try {
|
|
144
|
+
result = computeRereads([transcriptPath]);
|
|
145
|
+
} catch {
|
|
146
|
+
return [];
|
|
147
|
+
}
|
|
148
|
+
const legs: RereadLeg[] = [];
|
|
149
|
+
for (const f of result.files) {
|
|
150
|
+
if (f.duplicate_reads <= 0) continue;
|
|
151
|
+
const rel = path.relative(root, f.file_path);
|
|
152
|
+
if (rel === '' || rel.startsWith('..') || path.isAbsolute(rel)) continue;
|
|
153
|
+
let text: string;
|
|
154
|
+
try {
|
|
155
|
+
text = fs.readFileSync(f.file_path, 'utf-8');
|
|
156
|
+
} catch {
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
legs.push({
|
|
160
|
+
file: rel,
|
|
161
|
+
total_reads: f.total_reads,
|
|
162
|
+
duplicate_reads: f.duplicate_reads,
|
|
163
|
+
file_tokens: gpt_tokens(text).tokens,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
legs.sort((a, b) => b.duplicate_reads * b.file_tokens - a.duplicate_reads * a.file_tokens);
|
|
167
|
+
return legs;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export interface CostReport {
|
|
171
|
+
schema: 'config-cost-report/v1';
|
|
172
|
+
profile: string;
|
|
173
|
+
delivered: { total_tokens: number; rules_tokens: number; skill_catalogue_tokens: number; exact_throughout: boolean };
|
|
174
|
+
/** `null` with a stated reason when the transcript ledger carries nothing. */
|
|
175
|
+
billable: BillableSplit | null;
|
|
176
|
+
billable_reason: string | null;
|
|
177
|
+
amplification: AmplificationResult;
|
|
178
|
+
reread: RereadCost;
|
|
179
|
+
summary_line: string;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export function buildReport(o: Options, legsOverride?: readonly RereadLeg[]): CostReport {
|
|
183
|
+
const legs = legsOverride ?? collectRereadLegs(o.transcript, o.root);
|
|
184
|
+
const [rulesRel, skillsRel] = prefixStableDirRoots();
|
|
185
|
+
const ledger = buildLedger(
|
|
186
|
+
path.join(o.root, rulesRel ?? 'dist/agent-src/rules'),
|
|
187
|
+
path.join(o.root, skillsRel ?? 'dist/agent-src/skills'),
|
|
188
|
+
o.root,
|
|
189
|
+
);
|
|
190
|
+
const measured = {
|
|
191
|
+
rules_tokens: ledger.by_kind.rule.tokens,
|
|
192
|
+
skill_catalogue_tokens: ledger.by_kind['skill-catalogue-line'].tokens,
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
let billable: BillableSplit | null = null;
|
|
196
|
+
let billableReason: string | null = null;
|
|
197
|
+
try {
|
|
198
|
+
const scan = scanTranscripts({ root: o.transcriptRoot, maxAgeDays: o.maxAgeDays });
|
|
199
|
+
const buckets = aggregateByBucket(scan.records);
|
|
200
|
+
const fresh = buckets.main.input_tokens + buckets.subagent.input_tokens;
|
|
201
|
+
const read = buckets.main.cache_read_input_tokens + buckets.subagent.cache_read_input_tokens;
|
|
202
|
+
const creation = buckets.main.cache_creation_input_tokens + buckets.subagent.cache_creation_input_tokens;
|
|
203
|
+
if (fresh + read + creation === 0) {
|
|
204
|
+
billableReason = `no billable input recorded under ${o.transcriptRoot} in the last ${String(o.maxAgeDays)} day(s)`;
|
|
205
|
+
} else {
|
|
206
|
+
billable = billableSplit(fresh, read, creation);
|
|
207
|
+
}
|
|
208
|
+
} catch (err) {
|
|
209
|
+
billableReason = `the transcript ledger at ${o.transcriptRoot} could not be read: ${(err as Error).message}`;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const profile = activeProfile(o.root, o.profile);
|
|
213
|
+
return {
|
|
214
|
+
schema: 'config-cost-report/v1',
|
|
215
|
+
profile,
|
|
216
|
+
delivered: {
|
|
217
|
+
total_tokens: ledger.total_tokens,
|
|
218
|
+
rules_tokens: measured.rules_tokens,
|
|
219
|
+
skill_catalogue_tokens: measured.skill_catalogue_tokens,
|
|
220
|
+
exact_throughout: ledger.exact_throughout,
|
|
221
|
+
},
|
|
222
|
+
billable,
|
|
223
|
+
billable_reason: billableReason,
|
|
224
|
+
amplification: amplification(ledger.total_tokens, measured, readProfileDeclaration(o.root, profile)),
|
|
225
|
+
reread: rereadCost(legs),
|
|
226
|
+
summary_line: summaryLine(ledger.total_tokens, billable),
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export function renderText(r: CostReport): string {
|
|
231
|
+
const out: string[] = [];
|
|
232
|
+
const n = (v: number): string => String(v);
|
|
233
|
+
out.push('Config-cost report — what this configuration costs per session');
|
|
234
|
+
out.push(` profile: ${r.profile}`);
|
|
235
|
+
out.push(
|
|
236
|
+
` delivered standing payload: ${n(r.delivered.total_tokens)} tok ` +
|
|
237
|
+
`(rules ${n(r.delivered.rules_tokens)} · skill catalogue ${n(r.delivered.skill_catalogue_tokens)})` +
|
|
238
|
+
`${r.delivered.exact_throughout ? '' : ' — MIXED measurement, some rows fell back to the chars/4 proxy'}`,
|
|
239
|
+
);
|
|
240
|
+
out.push('');
|
|
241
|
+
out.push('billable_input = fresh input + cache read + cache creation');
|
|
242
|
+
if (r.billable === null) {
|
|
243
|
+
out.push(` unavailable — ${r.billable_reason ?? 'no reason recorded'}`);
|
|
244
|
+
out.push(' (a stated reason, never zeros standing in for absence)');
|
|
245
|
+
} else {
|
|
246
|
+
const b = r.billable;
|
|
247
|
+
out.push(` fresh input: ${n(b.fresh_input_tokens)} tok`);
|
|
248
|
+
out.push(` cache read: ${n(b.cache_read_tokens)} tok`);
|
|
249
|
+
out.push(` cache creation: ${n(b.cache_creation_tokens)} tok`);
|
|
250
|
+
out.push(` billable total: ${n(b.billable_input_tokens)} tok`);
|
|
251
|
+
out.push(
|
|
252
|
+
` cache-read share: ${b.cache_read_share === null ? 'unavailable (nothing was billed)' : `${(b.cache_read_share * 100).toFixed(1)}%`}`,
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
out.push('');
|
|
256
|
+
out.push('payload amplification (delivered ÷ profile-declared)');
|
|
257
|
+
out.push(` verdict: ${r.amplification.verdict}`);
|
|
258
|
+
out.push(` ratio: ${r.amplification.ratio === null ? 'not computed' : r.amplification.ratio.toFixed(2)}`);
|
|
259
|
+
out.push(` ${r.amplification.reason}`);
|
|
260
|
+
out.push('');
|
|
261
|
+
out.push(' This measures AMPLIFICATION, not net value. It never observes what the payload');
|
|
262
|
+
out.push(' returned, so it informs the question of whether the configuration earns its cost');
|
|
263
|
+
out.push(' and is not allowed to answer it.');
|
|
264
|
+
if (r.reread.legs.length > 0) {
|
|
265
|
+
out.push('');
|
|
266
|
+
out.push('re-read cost (content paid for twice)');
|
|
267
|
+
out.push(` wasted: ${n(r.reread.wasted_tokens)} tok across ${n(r.reread.legs.length)} file(s)`);
|
|
268
|
+
if (r.reread.worst_file !== null) out.push(` worst: ${r.reread.worst_file}`);
|
|
269
|
+
}
|
|
270
|
+
out.push('');
|
|
271
|
+
out.push(r.summary_line);
|
|
272
|
+
return out.join('\n') + '\n';
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
export function main(argv: string[] = process.argv.slice(2)): number {
|
|
276
|
+
const o = parseArgs(argv);
|
|
277
|
+
let report: CostReport;
|
|
278
|
+
try {
|
|
279
|
+
report = buildReport(o);
|
|
280
|
+
} catch (err) {
|
|
281
|
+
process.stderr.write(`❌ config_cost_report: ${(err as Error).message}\n`);
|
|
282
|
+
return 2;
|
|
283
|
+
}
|
|
284
|
+
if (report.delivered.total_tokens === 0) {
|
|
285
|
+
process.stderr.write(
|
|
286
|
+
'❌ config_cost_report: no standing asset measured. The rule and skill trees are\n' +
|
|
287
|
+
' generated (`task sync && task generate-tools`); a checkout that has not run them\n' +
|
|
288
|
+
' has no payload to price. Stated, not reported as a cost of zero.\n',
|
|
289
|
+
);
|
|
290
|
+
return 2;
|
|
291
|
+
}
|
|
292
|
+
if (o.summaryOnly) {
|
|
293
|
+
process.stdout.write(report.summary_line + '\n');
|
|
294
|
+
return 0;
|
|
295
|
+
}
|
|
296
|
+
process.stdout.write(o.format === 'json' ? JSON.stringify(report, null, 2) + '\n' : renderText(report));
|
|
297
|
+
return 0;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (process.argv[1] !== undefined && import.meta.url === `file://${process.argv[1]}`) {
|
|
301
|
+
process.exit(main());
|
|
302
|
+
}
|
|
@@ -344,7 +344,80 @@ interface MissingModule {
|
|
|
344
344
|
* deliberately ignores bare package specifiers (`from 'commander'`) so the
|
|
345
345
|
* walk never leaves the package's own `dist/` tree.
|
|
346
346
|
*/
|
|
347
|
-
|
|
347
|
+
/**
|
|
348
|
+
* Strip comments before scanning for import specifiers.
|
|
349
|
+
*
|
|
350
|
+
* A doc comment can contain a perfectly well-formed `export { X } from './X'`
|
|
351
|
+
* as an EXAMPLE, and the scanner had no way to tell one from a real import —
|
|
352
|
+
* `src/cli/commands/uiAudit.ts` carries exactly that line, and the built output
|
|
353
|
+
* keeps it, so the gate reported `commands/uiAudit.js → missing ./X` for a
|
|
354
|
+
* module nobody imports. That is a false red on a completeness gate, which is
|
|
355
|
+
* the worst kind: it says the shipped tarball is broken when it is not.
|
|
356
|
+
*
|
|
357
|
+
* ## Why the string state resets at every newline
|
|
358
|
+
*
|
|
359
|
+
* The first version carried quote state across the whole file, and it did not
|
|
360
|
+
* survive contact with that very comment: prose says `module's body`, and an
|
|
361
|
+
* apostrophe inside a comment is only inert while the lexer KNOWS it is inside
|
|
362
|
+
* one. One desync — a regex literal, an unpaired apostrophe reached in the
|
|
363
|
+
* wrong mode — and every subsequent `/*` reads as string content, so the doc
|
|
364
|
+
* comment is scanned as code and the false red survives the fix. Measured: the
|
|
365
|
+
* fix shipped, CI stayed red on the identical message.
|
|
366
|
+
*
|
|
367
|
+
* So block-comment state is tracked ACROSS lines (a block comment is the thing
|
|
368
|
+
* being removed) while quote state is tracked WITHIN one line and discarded at
|
|
369
|
+
* the newline. A desync then costs the remainder of one line instead of the
|
|
370
|
+
* remainder of the file. A multi-line template literal containing a relative
|
|
371
|
+
* specifier would be read as code — a false red, the same direction the gate
|
|
372
|
+
* already errs, and no such literal exists in the compiled output this walks.
|
|
373
|
+
*/
|
|
374
|
+
export function stripComments(source: string): string {
|
|
375
|
+
const out: string[] = [];
|
|
376
|
+
let inBlock = false;
|
|
377
|
+
for (const rawLine of source.split('\n')) {
|
|
378
|
+
let line = '';
|
|
379
|
+
let i = 0;
|
|
380
|
+
let quote: string | null = null;
|
|
381
|
+
while (i < rawLine.length) {
|
|
382
|
+
const c = rawLine[i] as string;
|
|
383
|
+
const next = rawLine[i + 1];
|
|
384
|
+
if (inBlock) {
|
|
385
|
+
if (c === '*' && next === '/') {
|
|
386
|
+
inBlock = false;
|
|
387
|
+
i += 2;
|
|
388
|
+
continue;
|
|
389
|
+
}
|
|
390
|
+
i += 1;
|
|
391
|
+
continue;
|
|
392
|
+
}
|
|
393
|
+
if (quote !== null) {
|
|
394
|
+
line += c;
|
|
395
|
+
if (c === '\\' && next !== undefined) {
|
|
396
|
+
line += next;
|
|
397
|
+
i += 2;
|
|
398
|
+
continue;
|
|
399
|
+
}
|
|
400
|
+
if (c === quote) quote = null;
|
|
401
|
+
i += 1;
|
|
402
|
+
continue;
|
|
403
|
+
}
|
|
404
|
+
if (c === '/' && next === '/') break;
|
|
405
|
+
if (c === '/' && next === '*') {
|
|
406
|
+
inBlock = true;
|
|
407
|
+
i += 2;
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
if (c === "'" || c === '"' || c === '`') quote = c;
|
|
411
|
+
line += c;
|
|
412
|
+
i += 1;
|
|
413
|
+
}
|
|
414
|
+
out.push(line);
|
|
415
|
+
}
|
|
416
|
+
return out.join('\n');
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
export function parseRelativeSpecifiers(rawSource: string): string[] {
|
|
420
|
+
const source = stripComments(rawSource);
|
|
348
421
|
const out = new Set<string>();
|
|
349
422
|
const patterns = [
|
|
350
423
|
/\bfrom\s*["']([^"']+)["']/g,
|
|
@@ -2,9 +2,16 @@
|
|
|
2
2
|
// cost-budget — set / get / check the project's cost budget against
|
|
3
3
|
// accumulated session spend in agents/cost-tracking/sessions.jsonl.
|
|
4
4
|
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
5
|
+
// Derived work. The upstream, its MIT terms and the reproduced copyright and
|
|
6
|
+
// permission notice are in CREDITS.md; the transformation record is in
|
|
7
|
+
// docs/THIRD-PARTY-NOTICES.md, generated from provenance/borrows.jsonl. The
|
|
8
|
+
// first two ship with the package, which is what discharges the obligation for
|
|
9
|
+
// a consumer who receives this file from npm. The source is not named here
|
|
10
|
+
// because a source name in a tracked source file is what
|
|
11
|
+
// `source-confidentiality` forbids, and MIT discharges through a distributed
|
|
12
|
+
// notice rather than an in-file one.
|
|
13
|
+
// Local-JSONL swap replaces the upstream MCP memory-store dependency. Budget
|
|
14
|
+
// config lives next to the sessions store as budget.json.
|
|
8
15
|
//
|
|
9
16
|
// Usage: node scripts/cost/budget.mjs {set <usd>|get|check}
|
|
10
17
|
// Env: BUDGET_STORE, BUDGET_CONFIG, BUDGET_PERIOD={today|week|month|all}, BUDGET_QUIET=1
|
|
@@ -2,9 +2,16 @@
|
|
|
2
2
|
// cost-track — auto-capture token usage from a Claude Code session jsonl
|
|
3
3
|
// and append a structured record to agents/cost-tracking/sessions.jsonl.
|
|
4
4
|
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
5
|
+
// Derived work. The upstream, its MIT terms and the reproduced copyright and
|
|
6
|
+
// permission notice are in CREDITS.md; the transformation record is in
|
|
7
|
+
// docs/THIRD-PARTY-NOTICES.md, generated from provenance/borrows.jsonl. The
|
|
8
|
+
// first two ship with the package, which is what discharges the obligation for
|
|
9
|
+
// a consumer who receives this file from npm. The source is not named here
|
|
10
|
+
// because a source name in a tracked source file is what
|
|
11
|
+
// `source-confidentiality` forbids, and MIT discharges through a distributed
|
|
12
|
+
// notice rather than an in-file one.
|
|
13
|
+
// Local-JSONL swap replaces the upstream MCP memory-store dependency. Pricing
|
|
14
|
+
// constants are kept in sync with REFERENCE.md.
|
|
8
15
|
//
|
|
9
16
|
// Dedup + main/subagent split, and the logic driving them, are mirrored
|
|
10
17
|
// (not imported) from `src/scripts/_lib/cc_transcript.ts`: this file ships
|
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
bundle_roadmap,
|
|
27
27
|
} from './ai_council/bundler.js';
|
|
28
28
|
import { select_chairman } from './ai_council/chairman.js';
|
|
29
|
+
import { warnIfRecounciled } from './ai_council/recouncil_guard.js';
|
|
29
30
|
import { jaccardSimilarity } from './_lib/text_similarity.js';
|
|
30
31
|
import type { ChairmanCandidate } from './ai_council/chairman.js';
|
|
31
32
|
import { synthesis_template } from './ai_council/prompts.js';
|
|
@@ -137,19 +138,23 @@ import {
|
|
|
137
138
|
run_debate,
|
|
138
139
|
run_peer_review,
|
|
139
140
|
} from './ai_council/orchestrator.js';
|
|
141
|
+
import { serializeResponses } from './ai_council/response_record.js';
|
|
140
142
|
import {
|
|
141
143
|
type PriceTable,
|
|
142
144
|
downgrade_coupling,
|
|
143
|
-
|
|
145
|
+
allSeatsNonBillable,
|
|
144
146
|
estimate_input_tokens,
|
|
145
147
|
load_prices,
|
|
146
148
|
prices_file_for,
|
|
149
|
+
sumBillableCost,
|
|
147
150
|
} from './ai_council/pricing.js';
|
|
148
151
|
import { detect_project_context } from './ai_council/project_context.js';
|
|
149
152
|
import {
|
|
150
153
|
DecisionReplayInputs,
|
|
151
154
|
render_decision_replay,
|
|
152
155
|
} from './ai_council/replay.js';
|
|
156
|
+
import type { FindingsExtraction } from './ai_council/consensus.js';
|
|
157
|
+
import { harvest_inline_findings, inlineFindingsActive } from './ai_council/inline_findings.js';
|
|
153
158
|
import {
|
|
154
159
|
Finding as ConsensusFinding,
|
|
155
160
|
FindingScore as ConsensusFindingScore,
|
|
@@ -471,8 +476,6 @@ function load_settings(
|
|
|
471
476
|
return settings;
|
|
472
477
|
}
|
|
473
478
|
|
|
474
|
-
|
|
475
|
-
|
|
476
479
|
// ── member construction ─────────────────────────────────────────────
|
|
477
480
|
|
|
478
481
|
interface BuildMembersOptions {
|
|
@@ -1186,6 +1189,7 @@ function _maybe_run_consensus(
|
|
|
1186
1189
|
table: PriceTable,
|
|
1187
1190
|
project: unknown,
|
|
1188
1191
|
args: Args,
|
|
1192
|
+
inline_extractions: ReadonlyMap<string, FindingsExtraction> | null = null,
|
|
1189
1193
|
): ConsensusResult | null {
|
|
1190
1194
|
const cs = (ai_cfg['consensus_scoring'] as Dict) || {};
|
|
1191
1195
|
if (!_pyBool(cs['enabled'])) {
|
|
@@ -1196,6 +1200,7 @@ function _maybe_run_consensus(
|
|
|
1196
1200
|
return null;
|
|
1197
1201
|
}
|
|
1198
1202
|
return run_consensus_scoring(members, responses, {
|
|
1203
|
+
inline_extractions,
|
|
1199
1204
|
budget,
|
|
1200
1205
|
table,
|
|
1201
1206
|
project: project as never,
|
|
@@ -1230,8 +1235,8 @@ function _serialise_consensus(consensus: ConsensusResult): Dict {
|
|
|
1230
1235
|
reason: s.reason,
|
|
1231
1236
|
})),
|
|
1232
1237
|
metadata,
|
|
1233
|
-
extraction_responses:
|
|
1234
|
-
scoring_responses:
|
|
1238
|
+
extraction_responses: serializeResponses(consensus.extraction_responses),
|
|
1239
|
+
scoring_responses: serializeResponses(consensus.scoring_responses),
|
|
1235
1240
|
};
|
|
1236
1241
|
}
|
|
1237
1242
|
|
|
@@ -1478,7 +1483,7 @@ function _maybe_run_peer_review(
|
|
|
1478
1483
|
|
|
1479
1484
|
function _serialise_peer_review(peer_review: PeerReviewResult): Dict {
|
|
1480
1485
|
return {
|
|
1481
|
-
responses:
|
|
1486
|
+
responses: serializeResponses(peer_review.responses),
|
|
1482
1487
|
label_to_source: _mapToObject(peer_review.label_to_source),
|
|
1483
1488
|
persona_labels: _mapToObject(peer_review.persona_labels),
|
|
1484
1489
|
};
|
|
@@ -1773,28 +1778,6 @@ function _emit_debate_estimate(
|
|
|
1773
1778
|
return 0;
|
|
1774
1779
|
}
|
|
1775
1780
|
|
|
1776
|
-
function _serialise_responses(responses: CouncilResponse[]): Dict[] {
|
|
1777
|
-
const out: Dict[] = [];
|
|
1778
|
-
for (const r of responses) {
|
|
1779
|
-
const metadata: Dict = {};
|
|
1780
|
-
for (const [k, v] of Object.entries(r.metadata || {})) {
|
|
1781
|
-
metadata[k] = String(v);
|
|
1782
|
-
}
|
|
1783
|
-
out.push({
|
|
1784
|
-
provider: r.provider,
|
|
1785
|
-
model: r.model,
|
|
1786
|
-
text: r.text,
|
|
1787
|
-
input_tokens: r.input_tokens,
|
|
1788
|
-
output_tokens: r.output_tokens,
|
|
1789
|
-
cache_creation_input_tokens: r.cache_creation_input_tokens,
|
|
1790
|
-
cache_read_input_tokens: r.cache_read_input_tokens,
|
|
1791
|
-
latency_ms: r.latency_ms,
|
|
1792
|
-
error: r.error,
|
|
1793
|
-
metadata,
|
|
1794
|
-
});
|
|
1795
|
-
}
|
|
1796
|
-
return out;
|
|
1797
|
-
}
|
|
1798
1781
|
|
|
1799
1782
|
function _deserialise_responses(items: Dict[]): CouncilResponse[] {
|
|
1800
1783
|
const out: CouncilResponse[] = [];
|
|
@@ -2503,6 +2486,7 @@ function cmd_run(
|
|
|
2503
2486
|
const [extra_calls, extra_usd] = _consensus_cost_delta(ai_cfg, question.mode, estimates, billable.length);
|
|
2504
2487
|
const [ch_calls, ch_usd] = _chairman_cost_delta(ai_cfg, estimates);
|
|
2505
2488
|
const [pr_extra_calls, pr_extra_usd] = _peer_review_cost_delta(ai_cfg, args, estimates, billable.length);
|
|
2489
|
+
warnIfRecounciled(REPO_ROOT, artefact, question.user_prompt, members, _resolve_rounds(args, ai_cfg), _stdout);
|
|
2506
2490
|
if (!args.confirm) _stdout('council:run · DRY PASS — estimate only, no seat is contacted. Add --confirm to run.\n');
|
|
2507
2491
|
_stdout(
|
|
2508
2492
|
`council:run · mode=${question.mode} · members=${members.length} ` +
|
|
@@ -2623,6 +2607,9 @@ function cmd_run(
|
|
|
2623
2607
|
rounds,
|
|
2624
2608
|
advisor_plans,
|
|
2625
2609
|
stance_tally: stance_tally_on,
|
|
2610
|
+
// Phase 1B — the same predicate the harvest below reads, so a member is asked
|
|
2611
|
+
// for the block exactly when the consensus round intends to read one.
|
|
2612
|
+
inline_findings: inlineFindingsActive(ai_cfg, question.mode),
|
|
2626
2613
|
member_prompt_suffix,
|
|
2627
2614
|
no_project_context_members,
|
|
2628
2615
|
// Mid-flight cli→api fallback (ai-council-config.md § failure-class-
|
|
@@ -2706,6 +2693,9 @@ function cmd_run(
|
|
|
2706
2693
|
// this is always additive, never a fabricated decision.
|
|
2707
2694
|
const handoff: HandoffEnvelope = buildHandoffFromStanceTally(stance_tally_result);
|
|
2708
2695
|
const persona_labels = build_persona_labels(advisor_plans, billable);
|
|
2696
|
+
// Phase 1B — BEFORE peer review, chairman synthesis and rendering read
|
|
2697
|
+
// `responses`; the block is scaffolding, not argument. Off → null, nothing touched.
|
|
2698
|
+
const inline_extractions = inlineFindingsActive(ai_cfg, question.mode) ? harvest_inline_findings(members, responses) : null;
|
|
2709
2699
|
const peer_review = _maybe_run_peer_review(
|
|
2710
2700
|
ai_cfg,
|
|
2711
2701
|
args,
|
|
@@ -2717,7 +2707,7 @@ function cmd_run(
|
|
|
2717
2707
|
project,
|
|
2718
2708
|
{ persona_labels },
|
|
2719
2709
|
);
|
|
2720
|
-
const consensus = _maybe_run_consensus(ai_cfg, question, members, responses, budget, table, project, args);
|
|
2710
|
+
const consensus = _maybe_run_consensus(ai_cfg, question, members, responses, budget, table, project, args, inline_extractions);
|
|
2721
2711
|
// Rendered attendance, re-derived after the parser. The event does not move.
|
|
2722
2712
|
quorum_out.result = annotateRenderedQuorum(quorum_out.result, consensus?.parse_outcomes);
|
|
2723
2713
|
const chairman = _maybe_run_chairman(
|
|
@@ -2761,13 +2751,10 @@ function cmd_run(
|
|
|
2761
2751
|
all_responses.push(chairman.response);
|
|
2762
2752
|
}
|
|
2763
2753
|
all_responses.push(...stance_repairs);
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
const ce = estimate_cost(r.provider, r.model, r.input_tokens, r.output_tokens, table);
|
|
2769
|
-
actual_total += ce.input_usd + ce.output_usd;
|
|
2770
|
-
}
|
|
2754
|
+
// Billable-aware: a subscription-CLI seat spent nothing, so pricing it at
|
|
2755
|
+
// API rates and calling the figure "actual" is a false statement about
|
|
2756
|
+
// money. See pricing.ts § billable-aware aggregation.
|
|
2757
|
+
actual_total += sumBillableCost(all_responses, table);
|
|
2771
2758
|
const payload: Dict = {
|
|
2772
2759
|
schema_version: SCHEMA_VERSION,
|
|
2773
2760
|
mode: question.mode,
|
|
@@ -2784,7 +2771,7 @@ function cmd_run(
|
|
|
2784
2771
|
stances: stances_on,
|
|
2785
2772
|
blind_chairman: blind_chairman_on,
|
|
2786
2773
|
chairman_fields: chairman_fields_on,
|
|
2787
|
-
responses:
|
|
2774
|
+
responses: serializeResponses(responses),
|
|
2788
2775
|
};
|
|
2789
2776
|
if (peer_review !== null) {
|
|
2790
2777
|
payload['peer_review'] = _serialise_peer_review(peer_review);
|
|
@@ -2819,9 +2806,16 @@ function cmd_run(
|
|
|
2819
2806
|
});
|
|
2820
2807
|
fs.mkdirSync(path.dirname(_resolveTarget(out_path)), { recursive: true });
|
|
2821
2808
|
fs.writeFileSync(_resolveTarget(out_path), _jsonDumpsIndent2(payload) + '\n', { encoding: 'utf-8' });
|
|
2809
|
+
// The trailing note is not decoration. Before 2026-08-27 this line read
|
|
2810
|
+
// `actual $0.1055` on a run whose every seat was subscription-authed, two
|
|
2811
|
+
// lines below a `TOTAL: $0.0000` from the pre-run path — and an operator
|
|
2812
|
+
// reading the tail of the output saw only the wrong one. When every seat is
|
|
2813
|
+
// non-billable the figure is now 0 and says why, so the two lines agree.
|
|
2814
|
+
const _all_subscription = allSeatsNonBillable(all_responses);
|
|
2822
2815
|
_stdout(
|
|
2823
2816
|
`\ncouncil:run · wrote ${out_path} ` +
|
|
2824
|
-
`(estimated $${_pyFixed(estimated_total, 4)} /
|
|
2817
|
+
`(estimated $${_pyFixed(estimated_total, 4)} / spent $${_pyFixed(actual_total, 4)}` +
|
|
2818
|
+
`${_all_subscription ? ' — all seats subscription-authed, nothing billed' : ''})\n`,
|
|
2825
2819
|
);
|
|
2826
2820
|
const replay_path = _maybe_write_decision_replay({
|
|
2827
2821
|
ai_cfg,
|
|
@@ -2863,14 +2857,9 @@ function _write_debate_round(
|
|
|
2863
2857
|
},
|
|
2864
2858
|
): string {
|
|
2865
2859
|
fs.mkdirSync(_resolveTarget(out_dir), { recursive: true });
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
continue;
|
|
2870
|
-
}
|
|
2871
|
-
const ce = estimate_cost(r.provider, r.model, r.input_tokens, r.output_tokens, opts.table);
|
|
2872
|
-
actual_total += ce.input_usd + ce.output_usd;
|
|
2873
|
-
}
|
|
2860
|
+
// Billable-aware, same reason as the sibling site above: a subscription
|
|
2861
|
+
// seat contributes nothing to `cost_usd_actual`.
|
|
2862
|
+
const actual_total = sumBillableCost(responses, opts.table);
|
|
2874
2863
|
const payload: Dict = {
|
|
2875
2864
|
schema_version: SCHEMA_VERSION,
|
|
2876
2865
|
mode: opts.question.mode,
|
|
@@ -2884,7 +2873,7 @@ function _write_debate_round(
|
|
|
2884
2873
|
rounds: 1,
|
|
2885
2874
|
cost_usd_actual: _pyRound(actual_total, 6),
|
|
2886
2875
|
prompt_cache_round_gap_ms: opts.cache_gap_ms_since_previous_round ?? null,
|
|
2887
|
-
responses:
|
|
2876
|
+
responses: serializeResponses(responses),
|
|
2888
2877
|
};
|
|
2889
2878
|
const out_path = path.join(_resolveTarget(out_dir), _debate_round_filename(round_number));
|
|
2890
2879
|
fs.writeFileSync(out_path, _jsonDumpsIndent2(payload) + '\n', { encoding: 'utf-8' });
|
|
@@ -3220,13 +3209,7 @@ function cmd_debate(
|
|
|
3220
3209
|
|
|
3221
3210
|
let actual_total = 0.0;
|
|
3222
3211
|
for (const rnd of [...all_rounds, restate_responses]) {
|
|
3223
|
-
|
|
3224
|
-
if (r.error) {
|
|
3225
|
-
continue;
|
|
3226
|
-
}
|
|
3227
|
-
const ce = estimate_cost(r.provider, r.model, r.input_tokens, r.output_tokens, table);
|
|
3228
|
-
actual_total += ce.input_usd + ce.output_usd;
|
|
3229
|
-
}
|
|
3212
|
+
actual_total += sumBillableCost(rnd, table);
|
|
3230
3213
|
}
|
|
3231
3214
|
_stdout(
|
|
3232
3215
|
`\ncouncil:debate · ${all_rounds.length} round(s) complete · ` +
|