@event4u/agent-config 9.9.0 → 9.10.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/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +153 -194
- package/README.md +1 -1
- package/dist/agent-src/commands/agent-status.md +12 -11
- package/dist/agent-src/commands/agents/user/accept.md +115 -30
- package/dist/agent-src/commands/agents/user/delete.md +147 -0
- package/dist/agent-src/commands/agents/user/review.md +65 -28
- package/dist/agent-src/commands/agents/user/show.md +82 -29
- package/dist/agent-src/commands/agents/user/update.md +2 -2
- package/dist/agent-src/commands/agents/user.md +16 -3
- package/dist/agent-src/commands/check-current-md.md +0 -10
- package/dist/agent-src/commands/condense.md +28 -97
- package/dist/agent-src/commands/cost/report.md +7 -0
- package/dist/agent-src/commands/fix/portability.md +0 -8
- package/dist/agent-src/commands/fix/refs.md +0 -8
- package/dist/agent-src/commands/humanize.md +2 -2
- package/dist/agent-src/commands/jira-ticket.md +1 -1
- package/dist/agent-src/commands/memory/load.md +11 -0
- package/dist/agent-src/commands/optimize/skills.md +1 -1
- package/dist/agent-src/commands/pr/create.md +4 -4
- package/dist/agent-src/commands/profile/show.md +3 -3
- package/dist/agent-src/commands/rule-compliance-audit.md +5 -4
- package/dist/agent-src/commands/security-audit-config.md +1 -1
- package/dist/agent-src/commands/sync/gitignore/fix.md +1 -1
- package/dist/agent-src/commands/tdd.md +21 -0
- package/dist/agent-src/commands/team/delegate.md +2 -2
- package/dist/agent-src/commands/team-knowledge/bootstrap.md +9 -8
- package/dist/agent-src/commands/team-knowledge/consolidate.md +8 -7
- package/dist/agent-src/commands/team.md +4 -1
- package/dist/agent-src/commands/upstream-contribute.md +0 -1
- package/dist/agent-src/contexts/authority/commit-mechanics.md +7 -0
- package/dist/agent-src/contexts/authority/destructive-mechanics.md +16 -0
- package/dist/agent-src/contexts/authority/scope-mechanics.md +61 -0
- package/dist/agent-src/contexts/communication/rules-auto/reply-close-mechanics.md +20 -18
- package/dist/agent-src/contexts/communication/rules-auto/skill-quality-mechanics.md +1 -1
- package/dist/agent-src/contexts/communication/rules-auto/slash-command-routing-policy-mechanics.md +1 -1
- package/dist/agent-src/contexts/communication/rules-auto/source-of-truth-mechanics.md +9 -10
- package/dist/agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +1 -1
- package/dist/agent-src/contexts/communication/rules-auto/user-interaction-mechanics.md +11 -0
- package/dist/agent-src/contexts/contracts/artifact-engagement-flow.md +26 -15
- package/dist/agent-src/contexts/contracts/command-suggestion-flow.md +3 -0
- package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +67 -37
- package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +1 -1
- package/dist/agent-src/contexts/execution/autonomy-examples.md +1 -1
- package/dist/agent-src/contexts/execution/autonomy-mechanics.md +7 -6
- package/dist/agent-src/contexts/execution/evidence-discipline.md +92 -77
- package/dist/agent-src/contexts/execution/orchestration-benchmark-gate.md +22 -21
- package/dist/agent-src/contexts/execution/orchestration-telemetry.md +24 -0
- package/dist/agent-src/contexts/execution/project-intelligence.md +122 -103
- package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +23 -21
- package/dist/agent-src/contexts/execution/subagent-response-contract.md +5 -5
- package/dist/agent-src/contexts/execution/subagent-routing.md +11 -0
- package/dist/agent-src/contexts/execution/subagent-spawn-contract.md +13 -13
- package/dist/agent-src/contexts/execution/subagent-steering.md +36 -34
- package/dist/agent-src/contexts/execution/toolchain-resolver.md +1 -1
- package/dist/agent-src/contexts/execution/user-memory-channels.md +189 -0
- package/dist/agent-src/contexts/execution/verification-mechanics.md +9 -0
- package/dist/agent-src/contexts/model-recommendations.md +3 -2
- package/dist/agent-src/contexts/subagent-configuration.md +3 -3
- package/dist/agent-src/ghostwriter/README.md +2 -2
- package/dist/agent-src/packs/README.md +1 -1
- package/dist/agent-src/personas/README.md +5 -5
- package/dist/agent-src/personas/_template-specialist/persona.md +3 -3
- package/dist/agent-src/personas/backend-architect.md +24 -23
- package/dist/agent-src/personas/eloquent-tamer.md +30 -30
- package/dist/agent-src/personas/frontend-engineer.md +30 -30
- package/dist/agent-src/personas/product-owner.md +41 -38
- package/dist/agent-src/personas/qa.md +13 -13
- package/dist/agent-src/personas/security-engineer.md +22 -22
- package/dist/agent-src/presets/README.md +3 -3
- package/dist/agent-src/profiles/README.md +3 -3
- package/dist/agent-src/rules/active-remediation.md +2 -2
- package/dist/agent-src/rules/artifact-engagement-recording.md +4 -4
- package/dist/agent-src/rules/ask-when-uncertain.md +0 -4
- package/dist/agent-src/rules/augment-edit-discipline.md +1 -1
- package/dist/agent-src/rules/broken-access-control.md +4 -4
- package/dist/agent-src/rules/code-comment-discipline.md +1 -1
- package/dist/agent-src/rules/code-provenance.md +2 -2
- package/dist/agent-src/rules/commit-policy.md +4 -9
- package/dist/agent-src/rules/communication-through-line.md +5 -5
- package/dist/agent-src/rules/decision-revisit-gate.md +1 -1
- package/dist/agent-src/rules/doc-screenshot-hygiene.md +1 -1
- package/dist/agent-src/rules/domain-adoption-policy.md +1 -1
- package/dist/agent-src/rules/domain-safety-pii.md +1 -1
- package/dist/agent-src/rules/external-code-graph-interop.md +1 -1
- package/dist/agent-src/rules/fast-path-marker-visibility.md +43 -7
- package/dist/agent-src/rules/finance-safety-floor.md +1 -1
- package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +3 -3
- package/dist/agent-src/rules/history-discipline.md +1 -1
- package/dist/agent-src/rules/legal-safety-floor.md +1 -1
- package/dist/agent-src/rules/lethal-trifecta-guard.md +5 -5
- package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +10 -8
- package/dist/agent-src/rules/media-governance-routing.md +13 -13
- package/dist/agent-src/rules/media-sync-ground-truth.md +29 -11
- package/dist/agent-src/rules/no-cheap-questions.md +7 -7
- package/dist/agent-src/rules/no-decorative-emojis-in-git-surfaces.md +29 -18
- package/dist/agent-src/rules/non-destructive-by-default.md +5 -23
- package/dist/agent-src/rules/onboarding-gate.md +14 -4
- package/dist/agent-src/rules/persona-governance.md +2 -2
- package/dist/agent-src/rules/prefer-enums-over-literals.md +9 -9
- package/dist/agent-src/rules/preservation-guard.md +10 -2
- package/dist/agent-src/rules/question-not-instruction.md +1 -1
- package/dist/agent-src/rules/roadmap-progress-sync.md +6 -6
- package/dist/agent-src/rules/rule-type-governance.md +1 -1
- package/dist/agent-src/rules/scale-discipline.md +1 -1
- package/dist/agent-src/rules/scope-control.md +1 -1
- package/dist/agent-src/rules/secret-vcs-guard.md +1 -1
- package/dist/agent-src/rules/security-sensitive-stop.md +17 -11
- package/dist/agent-src/rules/senior-engineering-discipline.md +17 -17
- package/dist/agent-src/rules/session-canary.md +1 -1
- package/dist/agent-src/rules/skill-quality.md +1 -1
- package/dist/agent-src/rules/source-confidentiality.md +21 -19
- package/dist/agent-src/rules/source-of-truth.md +6 -5
- package/dist/agent-src/rules/spreadsheet-source-quality.md +2 -2
- package/dist/agent-src/rules/strategy-safety-floor.md +1 -1
- package/dist/agent-src/rules/think-before-action.md +5 -5
- package/dist/agent-src/rules/token-budget-discipline.md +5 -3
- package/dist/agent-src/rules/token-efficiency.md +2 -2
- package/dist/agent-src/rules/untrusted-input-defense.md +4 -4
- package/dist/agent-src/rules/user-interaction.md +12 -0
- package/dist/agent-src/rules/verify-before-complete.md +4 -24
- package/dist/agent-src/skills/adversarial-review/SKILL.md +2 -2
- package/dist/agent-src/skills/agent-security-review/SKILL.md +52 -45
- package/dist/agent-src/skills/agents-md-thin-root/SKILL.md +2 -2
- package/dist/agent-src/skills/ai-code-blindspots/SKILL.md +20 -20
- package/dist/agent-src/skills/ai-council/SKILL.md +185 -128
- package/dist/agent-src/skills/analysis-skill-router/SKILL.md +3 -3
- package/dist/agent-src/skills/api-endpoint/SKILL.md +2 -2
- package/dist/agent-src/skills/artisan-commands/SKILL.md +2 -2
- package/dist/agent-src/skills/async-python-patterns/SKILL.md +8 -7
- package/dist/agent-src/skills/authz-review/SKILL.md +16 -15
- package/dist/agent-src/skills/aws-infrastructure/SKILL.md +5 -5
- package/dist/agent-src/skills/blade-ui/SKILL.md +1 -1
- package/dist/agent-src/skills/bug-analyzer/SKILL.md +30 -12
- package/dist/agent-src/skills/code-intelligence/SKILL.md +0 -1
- package/dist/agent-src/skills/code-intelligence/evals/triggers.json +52 -0
- package/dist/agent-src/skills/code-review/SKILL.md +6 -6
- package/dist/agent-src/skills/command-routing/SKILL.md +5 -4
- package/dist/agent-src/skills/composer-packages/SKILL.md +2 -2
- package/dist/agent-src/skills/condense-memory/SKILL.md +43 -41
- package/dist/agent-src/skills/context-document/SKILL.md +23 -21
- package/dist/agent-src/skills/copilot-config/SKILL.md +6 -1
- package/dist/agent-src/skills/decision-record/SKILL.md +20 -18
- package/dist/agent-src/skills/design-intelligence/SKILL.md +4 -4
- package/dist/agent-src/skills/design-review/SKILL.md +15 -14
- package/dist/agent-src/skills/design-system-capture/reference/design-system-json.md +28 -25
- package/dist/agent-src/skills/devcontainer/SKILL.md +2 -2
- package/dist/agent-src/skills/docker/SKILL.md +1 -1
- package/dist/agent-src/skills/docx-authoring/evals/triggers.json +52 -0
- package/dist/agent-src/skills/emit-tickets/SKILL.md +2 -2
- package/dist/agent-src/skills/error-handling-patterns/SKILL.md +1 -1
- package/dist/agent-src/skills/estimate-ticket/SKILL.md +2 -2
- package/dist/agent-src/skills/evaluate-llm-feature/SKILL.md +0 -1
- package/dist/agent-src/skills/evaluate-llm-feature/evals/triggers.json +52 -0
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +6 -5
- package/dist/agent-src/skills/feature-planning/SKILL.md +2 -2
- package/dist/agent-src/skills/finishing-a-development-branch/SKILL.md +3 -3
- package/dist/agent-src/skills/flux/SKILL.md +1 -1
- package/dist/agent-src/skills/frontend-render-security/SKILL.md +13 -13
- package/dist/agent-src/skills/git-workflow/SKILL.md +33 -33
- package/dist/agent-src/skills/grafana/SKILL.md +5 -0
- package/dist/agent-src/skills/humanizer/SKILL.md +83 -66
- package/dist/agent-src/skills/humanizer/data/patterns.md +14 -14
- package/dist/agent-src/skills/humanizer/references/anti-aiisms.md +4 -4
- package/dist/agent-src/skills/judge-artifact-completeness/SKILL.md +82 -37
- package/dist/agent-src/skills/judge-bug-hunter/SKILL.md +17 -5
- package/dist/agent-src/skills/judge-injection-defense/SKILL.md +63 -25
- package/dist/agent-src/skills/judge-security-auditor/SKILL.md +2 -0
- package/dist/agent-src/skills/judge-synthesis/SKILL.md +72 -28
- package/dist/agent-src/skills/laravel-horizon/SKILL.md +5 -0
- package/dist/agent-src/skills/laravel-mail/SKILL.md +5 -4
- package/dist/agent-src/skills/laravel-middleware/SKILL.md +5 -4
- package/dist/agent-src/skills/laravel-notifications/SKILL.md +10 -9
- package/dist/agent-src/skills/laravel-pennant/SKILL.md +1 -1
- package/dist/agent-src/skills/laravel-pulse/SKILL.md +9 -8
- package/dist/agent-src/skills/laravel-reverb/SKILL.md +6 -5
- package/dist/agent-src/skills/laravel-scheduling/SKILL.md +6 -1
- package/dist/agent-src/skills/laravel-validation/SKILL.md +12 -0
- package/dist/agent-src/skills/launch-readiness/SKILL.md +1 -1
- package/dist/agent-src/skills/learning-to-rule-or-skill/SKILL.md +7 -7
- package/dist/agent-src/skills/learning-tutor/SKILL.md +44 -43
- package/dist/agent-src/skills/learning-tutor/evals/triggers.json +52 -0
- package/dist/agent-src/skills/license-compliance-audit/SKILL.md +7 -7
- package/dist/agent-src/skills/license-compliance-borrow-check/SKILL.md +3 -3
- package/dist/agent-src/skills/license-compliance-credits/SKILL.md +4 -4
- package/dist/agent-src/skills/llm-provider-knowledge/SKILL.md +0 -1
- package/dist/agent-src/skills/memory-consolidation/SKILL.md +69 -64
- package/dist/agent-src/skills/motion-choreographer/SKILL.md +6 -6
- package/dist/agent-src/skills/pdf-tools/evals/triggers.json +52 -0
- package/dist/agent-src/skills/performance-analysis/SKILL.md +7 -3
- package/dist/agent-src/skills/persona-improvement/SKILL.md +0 -2
- package/dist/agent-src/skills/persona-improvement/evals/triggers.json +52 -0
- package/dist/agent-src/skills/php-coder/SKILL.md +10 -0
- package/dist/agent-src/skills/prediction-pool-optimizer/SKILL.md +129 -120
- package/dist/agent-src/skills/prediction-pool-optimizer/reference/ev-fixtures.md +36 -35
- package/dist/agent-src/skills/prediction-pool-optimizer/reference/odds-and-bonus.md +45 -41
- package/dist/agent-src/skills/project-analysis-core/SKILL.md +4 -4
- package/dist/agent-src/skills/project-analysis-hypothesis-driven/SKILL.md +3 -3
- package/dist/agent-src/skills/project-analysis-react/SKILL.md +1 -1
- package/dist/agent-src/skills/project-analysis-symfony/SKILL.md +1 -1
- package/dist/agent-src/skills/project-analysis-zend-laminas/SKILL.md +2 -2
- package/dist/agent-src/skills/prompt-engineering-patterns/SKILL.md +1 -1
- package/dist/agent-src/skills/prompt-validator/SKILL.md +39 -39
- package/dist/agent-src/skills/quality-tools/SKILL.md +15 -15
- package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +55 -19
- package/dist/agent-src/skills/react-shadcn-ui/reference/registry.md +29 -27
- package/dist/agent-src/skills/readme-writing-package/SKILL.md +2 -2
- package/dist/agent-src/skills/reasoning-orchestrator/SKILL.md +25 -25
- package/dist/agent-src/skills/recursive-verification/SKILL.md +6 -5
- package/dist/agent-src/skills/refine-prompt/SKILL.md +1 -1
- package/dist/agent-src/skills/refine-ticket/SKILL.md +20 -2
- package/dist/agent-src/skills/repomix-packer/SKILL.md +1 -1
- package/dist/agent-src/skills/requesting-code-review/SKILL.md +2 -2
- package/dist/agent-src/skills/roadmap-management/SKILL.md +80 -66
- package/dist/agent-src/skills/roadmap-writing/SKILL.md +84 -77
- package/dist/agent-src/skills/rule-refactor/SKILL.md +1 -1
- package/dist/agent-src/skills/screenshot-hygiene/evals/triggers.json +52 -0
- package/dist/agent-src/skills/security-audit/SKILL.md +26 -9
- package/dist/agent-src/skills/security-maturity-assessment/SKILL.md +38 -16
- package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +14 -11
- package/dist/agent-src/skills/skill-writing/SKILL.md +9 -8
- package/dist/agent-src/skills/song-to-script/SKILL.md +93 -85
- package/dist/agent-src/skills/sql-writing/SKILL.md +2 -2
- package/dist/agent-src/skills/stakeholder-tradeoff/SKILL.md +4 -3
- package/dist/agent-src/skills/standards-from-config/SKILL.md +61 -43
- package/dist/agent-src/skills/subagent-orchestration/SKILL.md +22 -8
- package/dist/agent-src/skills/subagent-orchestration/prompts/README.md +28 -2
- package/dist/agent-src/skills/supply-chain-intake/SKILL.md +13 -13
- package/dist/agent-src/skills/systematic-debugging/SKILL.md +22 -21
- package/dist/agent-src/skills/tailwind-engineer/SKILL.md +1 -1
- package/dist/agent-src/skills/technical-specification/SKILL.md +5 -0
- package/dist/agent-src/skills/terraform/SKILL.md +2 -2
- package/dist/agent-src/skills/terragrunt/SKILL.md +8 -8
- package/dist/agent-src/skills/testing-anti-patterns/process-anti-patterns.md +1 -1
- package/dist/agent-src/skills/threat-modeling/SKILL.md +19 -13
- package/dist/agent-src/skills/universal-project-analysis/SKILL.md +1 -1
- package/dist/agent-src/skills/upstream-contribute/SKILL.md +0 -1
- package/dist/agent-src/skills/using-git-worktrees/SKILL.md +9 -9
- package/dist/agent-src/skills/validate-feature-fit/SKILL.md +3 -1
- package/dist/agent-src/skills/verify-completion-evidence/SKILL.md +4 -6
- package/dist/agent-src/skills/verify-repair-loop/SKILL.md +67 -61
- package/dist/agent-src/skills/video-director/SKILL.md +7 -7
- package/dist/agent-src/skills/worktree-lifecycle/SKILL.md +3 -3
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/contexts/knowledge-pages.md +47 -45
- package/dist/agent-src/templates/contexts/lesson-card.md +2 -2
- package/dist/agent-src/templates/contexts/tenant-boundaries.md +2 -2
- package/dist/agent-src/templates/contexts.md +1 -1
- package/dist/agent-src/templates/features.md +1 -1
- package/dist/agent-src/templates/roadmaps.md +125 -116
- package/dist/agent-src/templates/rule.md +2 -1
- package/dist/agent-src/templates/scripts/pr_risk_review.ts +0 -0
- package/dist/agent-src/templates/scripts/telemetry/aggregator.ts +0 -0
- package/dist/agent-src/templates/scripts/tier_usage_report.ts +2 -2
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +2 -2
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/review.ts +1 -1
- package/dist/agent-src/user-types/README.md +8 -8
- package/dist/agent-src/user-types/galabau-field-crew.md +34 -33
- package/dist/agent-src/user-types/metalworking-shop.md +35 -34
- package/dist/agent-src/user-types/truck-driver.md +22 -20
- package/dist/cli/python/workspace_roles.js +2 -2
- package/dist/cli/python/workspace_roles.js.map +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +88 -62
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +3 -3
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +6 -5
- package/dist/discovery/trust-report.md +2 -2
- package/dist/discovery/workspaces.json +5 -4
- package/dist/hooks/dispatch.js +186 -12
- package/dist/install/install.mjs +8 -0
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +1199 -857
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/compile_time_toggles.js +48 -0
- package/dist/scripts/_lib/compile_time_toggles.js.map +1 -0
- package/dist/scripts/condense.js +234 -217
- package/dist/scripts/condense.js.map +1 -1
- package/dist/server/schemas/settings.js +4 -0
- package/dist/server/schemas/settings.js.map +1 -1
- package/dist/shared/userMd/utils.js +30 -0
- package/dist/shared/userMd/utils.js.map +1 -1
- package/dist/ui/assets/index-BpSQt5vm.js.map +1 -1
- package/docs/guidelines/agent-infra/api-cost-levers.md +56 -5
- package/docs/guidelines/agent-infra/simplicity-and-goal-demos.md +93 -33
- package/package.json +1 -1
- package/src/agent-src/templates/scripts/pr_risk_review.ts +0 -0
- package/src/agent-src/templates/scripts/telemetry/aggregator.ts +0 -0
- package/src/agent-src/templates/scripts/tier_usage_report.ts +2 -2
- package/src/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +2 -2
- package/src/agent-src/templates/scripts/work_engine/directives/ui/review.ts +1 -1
- package/src/config/agent-settings.template.yml +32 -2
- package/src/config/ci-local-parity.yml +142 -0
- package/src/config/gate-coverage.yml +127 -0
- package/src/config/preamble-payload-budget.json +44 -0
- package/src/scripts/_cli/cmd_doctor.ts +78 -2
- package/src/scripts/_lib/agent_user_profile.ts +381 -0
- package/src/scripts/_lib/agents_overlay.ts +9 -0
- package/src/scripts/_lib/anchor_eval.ts +311 -0
- package/src/scripts/_lib/cc_transcript.ts +316 -0
- package/src/scripts/_lib/compile_time_toggles.ts +79 -0
- package/src/scripts/_lib/confusables.ts +101 -0
- package/src/scripts/_lib/duplicate_scope_census.ts +77 -0
- package/src/scripts/_lib/managed_agents_folder.ts +181 -0
- package/src/scripts/_lib/payload_hash_drift.ts +126 -0
- package/src/scripts/_lib/preservation_migration.ts +291 -0
- package/src/scripts/_lib/retrieval_sanitize.ts +166 -2
- package/src/scripts/_lib/scan_scope.ts +115 -0
- package/src/scripts/_lib/user_global_memory_audit.ts +187 -0
- package/src/scripts/_lib/user_global_observations.ts +830 -0
- package/src/scripts/_lib/user_global_revocations.ts +110 -0
- package/src/scripts/_lib/user_memory_gate_counters.ts +291 -0
- package/src/scripts/ai_council/blind_review.ts +0 -0
- package/src/scripts/ai_council/budget_guard.ts +90 -11
- package/src/scripts/ai_council/bundler.ts +2 -2
- package/src/scripts/ai_council/clients.ts +59 -3
- package/src/scripts/ai_council/config.ts +38 -0
- package/src/scripts/ai_council/orchestrator.ts +54 -9
- package/src/scripts/ai_team/team_dispatch.ts +17 -6
- package/src/scripts/anchor_eval_falsify.ts +198 -0
- package/src/scripts/anchor_scoring_run.ts +239 -0
- package/src/scripts/annotate_discovery.ts +1 -65
- package/src/scripts/bench_quality_run.ts +168 -4
- package/src/scripts/cache_realization_report.ts +782 -0
- package/src/scripts/check_artefact_count_messaging.ts +5 -1
- package/src/scripts/check_augment_description_cap.ts +15 -4
- package/src/scripts/check_ci_local_parity.ts +317 -0
- package/src/scripts/check_condensation.ts +96 -191
- package/src/scripts/check_context_paths.ts +38 -9
- package/src/scripts/check_gate_coverage.ts +299 -0
- package/src/scripts/check_iron_law_prominence.ts +22 -1
- package/src/scripts/check_kernel_prefix_stability.ts +0 -0
- package/src/scripts/check_no_new_legacy_path.ts +16 -6
- package/src/scripts/check_no_roadmap_refs.ts +22 -9
- package/src/scripts/check_originality_freshness.ts +167 -0
- package/src/scripts/check_preamble_payload_budget.ts +130 -0
- package/src/scripts/check_proposal.ts +0 -0
- package/src/scripts/check_references.ts +0 -1
- package/src/scripts/check_safety_floor_untouched.ts +171 -24
- package/src/scripts/check_site_links.ts +62 -3
- package/src/scripts/ci_status.ts +0 -0
- package/src/scripts/cluster_near_miss_patterns.ts +0 -0
- package/src/scripts/code_graph/build.ts +0 -0
- package/src/scripts/command_suggester/types.ts +0 -0
- package/src/scripts/compile_router.ts +10 -14
- package/src/scripts/condense.sh +3 -4
- package/src/scripts/condense.ts +247 -228
- package/src/scripts/cost/track.mjs +168 -33
- package/src/scripts/cost_summary.ts +33 -1
- package/src/scripts/council_cli.ts +45 -3
- package/src/scripts/discovery_graph.ts +0 -0
- package/src/scripts/encoding_corpus.ts +500 -0
- package/src/scripts/encoding_corpus_report.ts +216 -0
- package/src/scripts/generate_index.ts +19 -2
- package/src/scripts/install-hooks.sh +2 -2
- package/src/scripts/learning_sidecar.ts +0 -0
- package/src/scripts/lint_confusables.ts +10 -72
- package/src/scripts/lint_featured_skills.ts +0 -0
- package/src/scripts/lint_hidden_unicode.ts +208 -0
- package/src/scripts/lint_load_context.ts +17 -5
- package/src/scripts/lint_new_skill_gate.ts +9 -3
- package/src/scripts/lint_no_python_twin_rationale.ts +17 -2
- package/src/scripts/lint_originality.ts +1 -1
- package/src/scripts/lint_skill_originality.ts +1 -1
- package/src/scripts/lint_ticket_buildable.ts +1 -1
- package/src/scripts/mcp_server/tools.ts +4 -4
- package/src/scripts/measure_scope_dedup.ts +224 -0
- package/src/scripts/memory_lookup.ts +0 -0
- package/src/scripts/mine_session.ts +98 -0
- package/src/scripts/orchestration_payload_hash_drift.ts +145 -0
- package/src/scripts/preamble_byte_census.ts +574 -0
- package/src/scripts/probe_skill_registration.ts +2 -2
- package/src/scripts/redact_hook_capture.ts +13 -0
- package/src/scripts/release.ts +65 -10
- package/src/scripts/router_telemetry.ts +1 -1
- package/src/scripts/second_brain_retrieval.ts +14 -4
- package/src/scripts/skill_linter.ts +5 -0
- package/src/scripts/surface-tiers.yml +2 -0
- package/src/scripts/validate_pack_yaml.ts +0 -0
- package/src/server/schemas/settings.ts +8 -0
- package/src/shared/userMd/utils.ts +31 -0
- package/dist/agent-src/rules/telegraph-speak.md +0 -87
|
@@ -6,6 +6,20 @@
|
|
|
6
6
|
// Local-JSONL swap replaces the upstream `mcp__claude-flow__memory_store`
|
|
7
7
|
// dependency. Pricing constants are kept in sync with REFERENCE.md.
|
|
8
8
|
//
|
|
9
|
+
// Dedup + main/subagent split, and the logic driving them, are mirrored
|
|
10
|
+
// (not imported) from `src/scripts/_lib/cc_transcript.ts`: this file ships
|
|
11
|
+
// to consumers as a plain `.mjs` run via bare `node` (see the `/cost:report`
|
|
12
|
+
// command doc), and `tsx` — the only thing in this repo that can execute a
|
|
13
|
+
// `.ts` module at runtime — is a devDependency, never shipped. A shared
|
|
14
|
+
// `.ts` import here would work in this repo's own dev shell and break for
|
|
15
|
+
// every consumer. On this repo's own transcripts, 50.3% of assistant/usage
|
|
16
|
+
// records in a single active session file are replays (message.id +
|
|
17
|
+
// requestId collide) — the resumed/compacted-session mechanic rewrites
|
|
18
|
+
// prior turns back into the transcript — so an un-deduped sum overstates
|
|
19
|
+
// real spend by roughly 2x, on top of never having counted subagent legs
|
|
20
|
+
// (they live in a sibling `<sessionId>/subagents/agent-*.jsonl` tree the
|
|
21
|
+
// old single-file read never visited).
|
|
22
|
+
//
|
|
9
23
|
// Env:
|
|
10
24
|
// TRACK_CWD=<path> override which project's sessions to scan
|
|
11
25
|
// TRACK_SESSION=<file> pin to a specific session jsonl
|
|
@@ -15,17 +29,20 @@
|
|
|
15
29
|
// TRACK_STORE=<path> override (default: agents/cost-tracking/sessions.jsonl)
|
|
16
30
|
|
|
17
31
|
import { readFileSync, writeFileSync, readdirSync, statSync, existsSync, mkdirSync, appendFileSync } from 'node:fs';
|
|
18
|
-
import { join, dirname } from 'node:path';
|
|
32
|
+
import { join, dirname, basename } from 'node:path';
|
|
19
33
|
import { homedir } from 'node:os';
|
|
20
34
|
|
|
21
35
|
const PROJECTS_DIR = join(homedir(), '.claude', 'projects');
|
|
22
36
|
const DEFAULT_STORE = 'agents/cost-tracking/sessions.jsonl';
|
|
23
37
|
|
|
24
|
-
// USD per 1M tokens.
|
|
38
|
+
// USD per 1M tokens. cache_write_5m / cache_write_1h are Anthropic's two
|
|
39
|
+
// cache-write TTL rates (1.25x / 2x of `input`) — a single flat rate here
|
|
40
|
+
// previously priced every write at the 5m rate regardless of the TTL the
|
|
41
|
+
// call actually used.
|
|
25
42
|
const PRICING = {
|
|
26
|
-
haiku: { input: 0.25, output: 1.25,
|
|
27
|
-
sonnet: { input: 3.00, output: 15.00,
|
|
28
|
-
opus: { input: 15.00, output: 75.00,
|
|
43
|
+
haiku: { input: 0.25, output: 1.25, cache_write_5m: 0.30, cache_write_1h: 0.50, cache_read: 0.03 },
|
|
44
|
+
sonnet: { input: 3.00, output: 15.00, cache_write_5m: 3.75, cache_write_1h: 6.00, cache_read: 0.30 },
|
|
45
|
+
opus: { input: 15.00, output: 75.00, cache_write_5m: 18.75, cache_write_1h: 30.00, cache_read: 1.50 },
|
|
29
46
|
};
|
|
30
47
|
|
|
31
48
|
function modelTier(model) {
|
|
@@ -37,16 +54,59 @@ function modelTier(model) {
|
|
|
37
54
|
return 'unknown';
|
|
38
55
|
}
|
|
39
56
|
|
|
57
|
+
// A record's cache_creation_input_tokens is split into ephemeral_5m /
|
|
58
|
+
// ephemeral_1h by `usage.cache_creation` (see usageTokens()). Any part of
|
|
59
|
+
// cache_creation_input_tokens NOT covered by that split (older records that
|
|
60
|
+
// predate the TTL breakdown) is priced at the 5m rate — Anthropic's default
|
|
61
|
+
// TTL — rather than silently dropped.
|
|
40
62
|
function costForUsage(tier, u) {
|
|
41
63
|
const p = PRICING[tier];
|
|
42
64
|
if (!p || !u) return 0;
|
|
65
|
+
const knownSplit = (u.ephemeral_5m_input_tokens || 0) + (u.ephemeral_1h_input_tokens || 0);
|
|
66
|
+
const unaccounted = Math.max(0, (u.cache_creation_input_tokens || 0) - knownSplit);
|
|
43
67
|
return (u.input_tokens || 0) / 1e6 * p.input
|
|
44
68
|
+ (u.output_tokens || 0) / 1e6 * p.output
|
|
45
|
-
+ (u.
|
|
69
|
+
+ ((u.ephemeral_5m_input_tokens || 0) + unaccounted) / 1e6 * p.cache_write_5m
|
|
70
|
+
+ (u.ephemeral_1h_input_tokens || 0) / 1e6 * p.cache_write_1h
|
|
46
71
|
+ (u.cache_read_input_tokens || 0) / 1e6 * p.cache_read;
|
|
47
72
|
}
|
|
48
73
|
|
|
49
|
-
|
|
74
|
+
// Normalize a raw `message.usage` block into the flat shape costForUsage()
|
|
75
|
+
// and the model-tally accumulator both consume, pulling the TTL split out
|
|
76
|
+
// of the nested `cache_creation` object Anthropic ships it under.
|
|
77
|
+
function usageTokens(raw) {
|
|
78
|
+
const cc = (raw && raw.cache_creation) || {};
|
|
79
|
+
return {
|
|
80
|
+
input_tokens: Number(raw?.input_tokens) || 0,
|
|
81
|
+
output_tokens: Number(raw?.output_tokens) || 0,
|
|
82
|
+
cache_creation_input_tokens: Number(raw?.cache_creation_input_tokens) || 0,
|
|
83
|
+
cache_read_input_tokens: Number(raw?.cache_read_input_tokens) || 0,
|
|
84
|
+
ephemeral_5m_input_tokens: Number(cc.ephemeral_5m_input_tokens) || 0,
|
|
85
|
+
ephemeral_1h_input_tokens: Number(cc.ephemeral_1h_input_tokens) || 0,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Subagent iff a non-empty top-level agentId OR isSidechain === true —
|
|
90
|
+
// both signals are checked because observed subagent transcripts carry
|
|
91
|
+
// both, but a differently-shaped one could carry only one.
|
|
92
|
+
function classifyBucket(rec) {
|
|
93
|
+
const hasAgentId = typeof rec.agentId === 'string' && rec.agentId.length > 0;
|
|
94
|
+
return (hasAgentId || rec.isSidechain === true) ? 'subagent' : 'main';
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// message.id + requestId together identify one real API call; Claude Code
|
|
98
|
+
// can replay the same turn into more than one transcript file (see the
|
|
99
|
+
// header comment) and this is what collapses those replays back to one.
|
|
100
|
+
function dedupKey(rec) {
|
|
101
|
+
const id = typeof rec.message?.id === 'string' ? rec.message.id : '';
|
|
102
|
+
const reqId = typeof rec.requestId === 'string' ? rec.requestId : '';
|
|
103
|
+
return `${id} ${reqId}`;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Claude Code encodes BOTH separators and dots: `/x/.claude/y` → `-x--claude-y`.
|
|
107
|
+
// Replacing only `/` never resolves a dotted path segment, so any cwd under
|
|
108
|
+
// `.claude/worktrees/` silently missed its project dir and exited 2.
|
|
109
|
+
function encodeProjectPath(cwd) { return cwd.replace(/[/.]/g, '-'); }
|
|
50
110
|
|
|
51
111
|
function findProjectDir(cwd) {
|
|
52
112
|
const c = join(PROJECTS_DIR, encodeProjectPath(cwd));
|
|
@@ -60,37 +120,101 @@ function findActiveSession(dir) {
|
|
|
60
120
|
return e[0] ? join(dir, e[0].f) : null;
|
|
61
121
|
}
|
|
62
122
|
|
|
63
|
-
|
|
64
|
-
|
|
123
|
+
// Recursively list every *.jsonl under dir — how the sibling
|
|
124
|
+
// <sessionId>/subagents/agent-*.jsonl tree gets visited without a second
|
|
125
|
+
// code path.
|
|
126
|
+
function walkJsonl(dir) {
|
|
127
|
+
const out = [];
|
|
128
|
+
const stack = [dir];
|
|
129
|
+
while (stack.length > 0) {
|
|
130
|
+
const cur = stack.pop();
|
|
131
|
+
let entries;
|
|
132
|
+
try { entries = readdirSync(cur, { withFileTypes: true }); } catch { continue; }
|
|
133
|
+
for (const entry of entries) {
|
|
134
|
+
const full = join(cur, entry.name);
|
|
135
|
+
if (entry.isDirectory()) stack.push(full);
|
|
136
|
+
else if (entry.isFile() && entry.name.endsWith('.jsonl')) out.push(full);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return out;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// The active session's own file plus every transcript under its sibling
|
|
143
|
+
// <sessionId>/ directory (subagent legs, and any nested sub-subagent legs).
|
|
144
|
+
function collectSessionFiles(projectDir, sessionPath) {
|
|
145
|
+
const files = [sessionPath];
|
|
146
|
+
const sideDir = join(projectDir, basename(sessionPath, '.jsonl'));
|
|
147
|
+
if (existsSync(sideDir) && statSync(sideDir).isDirectory()) {
|
|
148
|
+
files.push(...walkJsonl(sideDir));
|
|
149
|
+
}
|
|
150
|
+
return files;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function emptyBucketSlot() {
|
|
154
|
+
return { messages: 0, input_tokens: 0, output_tokens: 0,
|
|
155
|
+
cache_creation_input_tokens: 0, cache_read_input_tokens: 0, cost_usd: 0 };
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function summarizeSession(files) {
|
|
65
159
|
const byModel = {};
|
|
66
160
|
const byTier = { haiku: 0, sonnet: 0, opus: 0, unknown: 0 };
|
|
161
|
+
const byBucket = { main: emptyBucketSlot(), subagent: emptyBucketSlot() };
|
|
67
162
|
let messageCount = 0, totalCost = 0, firstTs = null, lastTs = null;
|
|
68
163
|
let sessionId = null, cwd = null;
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
164
|
+
let totalSeen = 0;
|
|
165
|
+
const seen = new Set();
|
|
166
|
+
|
|
167
|
+
for (const file of files) {
|
|
168
|
+
let text;
|
|
169
|
+
try { text = readFileSync(file, 'utf-8'); } catch { continue; }
|
|
170
|
+
for (const line of text.split('\n')) {
|
|
171
|
+
if (!line.trim()) continue;
|
|
172
|
+
let m; try { m = JSON.parse(line); } catch { continue; }
|
|
173
|
+
if (!sessionId && m.sessionId) sessionId = m.sessionId;
|
|
174
|
+
if (!cwd && m.cwd) cwd = m.cwd;
|
|
175
|
+
if (m.timestamp) {
|
|
176
|
+
if (!firstTs || m.timestamp < firstTs) firstTs = m.timestamp;
|
|
177
|
+
if (!lastTs || m.timestamp > lastTs) lastTs = m.timestamp;
|
|
178
|
+
}
|
|
179
|
+
if (m.type !== 'assistant' || !m.message?.usage) continue;
|
|
180
|
+
|
|
181
|
+
totalSeen++;
|
|
182
|
+
const key = dedupKey(m);
|
|
183
|
+
if (seen.has(key)) continue; // replay — see the header comment
|
|
184
|
+
seen.add(key);
|
|
185
|
+
|
|
186
|
+
const bucket = classifyBucket(m);
|
|
187
|
+
const model = m.message.model || 'unknown';
|
|
188
|
+
const tier = modelTier(model);
|
|
189
|
+
const u = usageTokens(m.message.usage);
|
|
190
|
+
const cost = costForUsage(tier, u);
|
|
191
|
+
|
|
192
|
+
const slot = byModel[model] || { tier, input_tokens: 0, output_tokens: 0,
|
|
193
|
+
cache_creation_input_tokens: 0, cache_read_input_tokens: 0, messages: 0, cost_usd: 0 };
|
|
194
|
+
slot.input_tokens += u.input_tokens;
|
|
195
|
+
slot.output_tokens += u.output_tokens;
|
|
196
|
+
slot.cache_creation_input_tokens += u.cache_creation_input_tokens;
|
|
197
|
+
slot.cache_read_input_tokens += u.cache_read_input_tokens;
|
|
198
|
+
slot.messages++; slot.cost_usd += cost;
|
|
199
|
+
byModel[model] = slot;
|
|
200
|
+
|
|
201
|
+
const bs = byBucket[bucket];
|
|
202
|
+
bs.input_tokens += u.input_tokens;
|
|
203
|
+
bs.output_tokens += u.output_tokens;
|
|
204
|
+
bs.cache_creation_input_tokens += u.cache_creation_input_tokens;
|
|
205
|
+
bs.cache_read_input_tokens += u.cache_read_input_tokens;
|
|
206
|
+
bs.messages++; bs.cost_usd += cost;
|
|
207
|
+
|
|
208
|
+
messageCount++; byTier[tier] += cost; totalCost += cost;
|
|
76
209
|
}
|
|
77
|
-
if (m.type !== 'assistant' || !m.message?.usage) continue;
|
|
78
|
-
messageCount++;
|
|
79
|
-
const model = m.message.model || 'unknown';
|
|
80
|
-
const tier = modelTier(model);
|
|
81
|
-
const u = m.message.usage;
|
|
82
|
-
const cost = costForUsage(tier, u);
|
|
83
|
-
const slot = byModel[model] || { tier, input_tokens: 0, output_tokens: 0,
|
|
84
|
-
cache_creation_input_tokens: 0, cache_read_input_tokens: 0, messages: 0, cost_usd: 0 };
|
|
85
|
-
slot.input_tokens += u.input_tokens || 0;
|
|
86
|
-
slot.output_tokens += u.output_tokens || 0;
|
|
87
|
-
slot.cache_creation_input_tokens += u.cache_creation_input_tokens || 0;
|
|
88
|
-
slot.cache_read_input_tokens += u.cache_read_input_tokens || 0;
|
|
89
|
-
slot.messages++; slot.cost_usd += cost;
|
|
90
|
-
byModel[model] = slot; byTier[tier] += cost; totalCost += cost;
|
|
91
210
|
}
|
|
211
|
+
|
|
212
|
+
const dedupedCount = messageCount;
|
|
213
|
+
const dedup_ratio = totalSeen > 0 ? (totalSeen - dedupedCount) / totalSeen : 0;
|
|
92
214
|
return { sessionId, cwd, startedAt: firstTs, endedAt: lastTs, messageCount,
|
|
93
|
-
byModel, byTier, total_cost_usd: totalCost,
|
|
215
|
+
byModel, byTier, byBucket, total_cost_usd: totalCost,
|
|
216
|
+
totalRecordsSeen: totalSeen, dedupedRecordsCount: dedupedCount, dedup_ratio,
|
|
217
|
+
capturedAt: new Date().toISOString() };
|
|
94
218
|
}
|
|
95
219
|
|
|
96
220
|
function persistJsonl(summary, store) {
|
|
@@ -111,7 +235,8 @@ function main() {
|
|
|
111
235
|
if (!sessionPath || !existsSync(sessionPath)) {
|
|
112
236
|
console.error(`cost-track: no session jsonl in ${projectDir}`); process.exit(2);
|
|
113
237
|
}
|
|
114
|
-
const
|
|
238
|
+
const files = collectSessionFiles(projectDir, sessionPath);
|
|
239
|
+
const summary = summarizeSession(files);
|
|
115
240
|
if (process.env.TRACK_OUT) writeFileSync(process.env.TRACK_OUT, JSON.stringify(summary, null, 2));
|
|
116
241
|
const store = process.env.TRACK_STORE || DEFAULT_STORE;
|
|
117
242
|
let res = { ok: false, reason: 'dry-run' };
|
|
@@ -125,7 +250,9 @@ function main() {
|
|
|
125
250
|
console.log(`| Project | \`${summary.cwd}\` |`);
|
|
126
251
|
console.log(`| First message | ${summary.startedAt} |`);
|
|
127
252
|
console.log(`| Last message | ${summary.endedAt} |`);
|
|
128
|
-
console.log(`| Assistant messages | ${summary.messageCount} |`);
|
|
253
|
+
console.log(`| Assistant messages (deduped) | ${summary.messageCount} |`);
|
|
254
|
+
console.log(`| Replay dedup ratio | ${(summary.dedup_ratio * 100).toFixed(1)}% (${summary.dedupedRecordsCount}/${summary.totalRecordsSeen} records kept) |`);
|
|
255
|
+
console.log(`| Transcript files scanned | ${files.length} |`);
|
|
129
256
|
console.log(`| **Total cost** | **$${summary.total_cost_usd.toFixed(6)}** |`);
|
|
130
257
|
console.log(`| Persisted | ${res.ok ? `\`${res.path}\`` : `**FAILED** (${res.reason})`} |`);
|
|
131
258
|
console.log('\n## Per-model breakdown\n');
|
|
@@ -139,6 +266,14 @@ function main() {
|
|
|
139
266
|
for (const [t, c] of Object.entries(summary.byTier).sort((a, b) => b[1] - a[1])) {
|
|
140
267
|
if (c > 0) console.log(`| ${t} | $${c.toFixed(6)} |`);
|
|
141
268
|
}
|
|
269
|
+
console.log('\n## Agent-bucket breakdown\n');
|
|
270
|
+
console.log('_main = the orchestrator session; subagent = Task-tool legs, previously uncounted or merged in._\n');
|
|
271
|
+
console.log('| Bucket | Messages | Input | Output | Cache write | Cache read | Cost |');
|
|
272
|
+
console.log('|---|---:|---:|---:|---:|---:|---:|');
|
|
273
|
+
for (const bucket of ['main', 'subagent']) {
|
|
274
|
+
const b = summary.byBucket[bucket];
|
|
275
|
+
console.log(`| ${bucket} | ${b.messages} | ${b.input_tokens} | ${b.output_tokens} | ${b.cache_creation_input_tokens} | ${b.cache_read_input_tokens} | $${b.cost_usd.toFixed(6)} |`);
|
|
276
|
+
}
|
|
142
277
|
}
|
|
143
278
|
|
|
144
279
|
main();
|
|
@@ -64,6 +64,11 @@ interface KvBucket {
|
|
|
64
64
|
total_cost_usd: number;
|
|
65
65
|
input_tokens: number;
|
|
66
66
|
output_tokens: number;
|
|
67
|
+
// Additive (cost-summary/v1 stays additive-only per the schema doc):
|
|
68
|
+
// absent-on-row reads as 0 via `_int`, so rows written before this
|
|
69
|
+
// extension aggregate identically to explicit zeros.
|
|
70
|
+
cache_read_input_tokens: number;
|
|
71
|
+
cache_creation_input_tokens: number;
|
|
67
72
|
telegraph_delta_tokens: number;
|
|
68
73
|
}
|
|
69
74
|
|
|
@@ -73,6 +78,8 @@ function _zero_kv(): KvBucket {
|
|
|
73
78
|
total_cost_usd: 0.0,
|
|
74
79
|
input_tokens: 0,
|
|
75
80
|
output_tokens: 0,
|
|
81
|
+
cache_read_input_tokens: 0,
|
|
82
|
+
cache_creation_input_tokens: 0,
|
|
76
83
|
telegraph_delta_tokens: 0,
|
|
77
84
|
};
|
|
78
85
|
}
|
|
@@ -83,10 +90,21 @@ interface ModelBucket {
|
|
|
83
90
|
total_cost_usd: number;
|
|
84
91
|
input_tokens: number;
|
|
85
92
|
output_tokens: number;
|
|
93
|
+
// Unlike telegraph fields, cache accounting IS model-scoped (the prompt
|
|
94
|
+
// cache itself is model-scoped — see pricing.ts), so by_model carries it.
|
|
95
|
+
cache_read_input_tokens: number;
|
|
96
|
+
cache_creation_input_tokens: number;
|
|
86
97
|
}
|
|
87
98
|
|
|
88
99
|
function _zero_model(): ModelBucket {
|
|
89
|
-
return {
|
|
100
|
+
return {
|
|
101
|
+
sessions: 0,
|
|
102
|
+
total_cost_usd: 0.0,
|
|
103
|
+
input_tokens: 0,
|
|
104
|
+
output_tokens: 0,
|
|
105
|
+
cache_read_input_tokens: 0,
|
|
106
|
+
cache_creation_input_tokens: 0,
|
|
107
|
+
};
|
|
90
108
|
}
|
|
91
109
|
|
|
92
110
|
/** Aggregate rows into the cost-summary structure (PyFloat-aware output). */
|
|
@@ -104,6 +122,8 @@ export function aggregate(rows: Row[]): Json {
|
|
|
104
122
|
const cost = _float(row['total_cost_usd']);
|
|
105
123
|
const itok = _int(row['input_tokens']);
|
|
106
124
|
const otok = _int(row['output_tokens']);
|
|
125
|
+
const cread = _int(row['cache_read_input_tokens']);
|
|
126
|
+
const cwrite = _int(row['cache_creation_input_tokens']);
|
|
107
127
|
const delta = _delta(row);
|
|
108
128
|
|
|
109
129
|
const sessBucket = _getOr(by_sess, sid, _zero_kv);
|
|
@@ -113,6 +133,8 @@ export function aggregate(rows: Row[]): Json {
|
|
|
113
133
|
bucket.total_cost_usd += cost;
|
|
114
134
|
bucket.input_tokens += itok;
|
|
115
135
|
bucket.output_tokens += otok;
|
|
136
|
+
bucket.cache_read_input_tokens += cread;
|
|
137
|
+
bucket.cache_creation_input_tokens += cwrite;
|
|
116
138
|
bucket.telegraph_delta_tokens += delta;
|
|
117
139
|
}
|
|
118
140
|
const m = _getOr(by_model, model, _zero_model);
|
|
@@ -120,6 +142,8 @@ export function aggregate(rows: Row[]): Json {
|
|
|
120
142
|
m.total_cost_usd += cost;
|
|
121
143
|
m.input_tokens += itok;
|
|
122
144
|
m.output_tokens += otok;
|
|
145
|
+
m.cache_read_input_tokens += cread;
|
|
146
|
+
m.cache_creation_input_tokens += cwrite;
|
|
123
147
|
}
|
|
124
148
|
|
|
125
149
|
return {
|
|
@@ -130,6 +154,8 @@ export function aggregate(rows: Row[]): Json {
|
|
|
130
154
|
total_cost_usd: new PyFloat(totals.total_cost_usd),
|
|
131
155
|
input_tokens: totals.input_tokens,
|
|
132
156
|
output_tokens: totals.output_tokens,
|
|
157
|
+
cache_read_input_tokens: totals.cache_read_input_tokens,
|
|
158
|
+
cache_creation_input_tokens: totals.cache_creation_input_tokens,
|
|
133
159
|
telegraph_delta_tokens: totals.telegraph_delta_tokens,
|
|
134
160
|
telegraph_multiplier_version: MULTIPLIER_VERSION,
|
|
135
161
|
telegraph_multiplier_active: MULTIPLIER_ACTIVE,
|
|
@@ -140,6 +166,8 @@ export function aggregate(rows: Row[]): Json {
|
|
|
140
166
|
total_cost_usd: new PyFloat(v.total_cost_usd),
|
|
141
167
|
input_tokens: v.input_tokens,
|
|
142
168
|
output_tokens: v.output_tokens,
|
|
169
|
+
cache_read_input_tokens: v.cache_read_input_tokens,
|
|
170
|
+
cache_creation_input_tokens: v.cache_creation_input_tokens,
|
|
143
171
|
telegraph_delta_tokens: v.telegraph_delta_tokens,
|
|
144
172
|
})),
|
|
145
173
|
by_conversation: _sortedEntries(by_conv).map(([k, v]) => ({
|
|
@@ -148,6 +176,8 @@ export function aggregate(rows: Row[]): Json {
|
|
|
148
176
|
total_cost_usd: new PyFloat(v.total_cost_usd),
|
|
149
177
|
input_tokens: v.input_tokens,
|
|
150
178
|
output_tokens: v.output_tokens,
|
|
179
|
+
cache_read_input_tokens: v.cache_read_input_tokens,
|
|
180
|
+
cache_creation_input_tokens: v.cache_creation_input_tokens,
|
|
151
181
|
telegraph_delta_tokens: v.telegraph_delta_tokens,
|
|
152
182
|
})),
|
|
153
183
|
by_model: _sortedEntries(by_model).map(([k, v]) => ({
|
|
@@ -156,6 +186,8 @@ export function aggregate(rows: Row[]): Json {
|
|
|
156
186
|
total_cost_usd: new PyFloat(v.total_cost_usd),
|
|
157
187
|
input_tokens: v.input_tokens,
|
|
158
188
|
output_tokens: v.output_tokens,
|
|
189
|
+
cache_read_input_tokens: v.cache_read_input_tokens,
|
|
190
|
+
cache_creation_input_tokens: v.cache_creation_input_tokens,
|
|
159
191
|
})),
|
|
160
192
|
};
|
|
161
193
|
}
|
|
@@ -444,6 +444,12 @@ function _synthesize_ai_council_block(cfg: CouncilConfig): Dict {
|
|
|
444
444
|
if (m.model_ladder && m.model_ladder.length > 0) {
|
|
445
445
|
entry['model_ladder'] = [...m.model_ladder];
|
|
446
446
|
}
|
|
447
|
+
// road-to-cache-economy Phase 4: forward only an explicit override —
|
|
448
|
+
// the '5m' default needs no key, keeping the synthesized block
|
|
449
|
+
// byte-identical to pre-Phase-4 output when nobody opted in.
|
|
450
|
+
if (m.prompt_cache_ttl !== '5m') {
|
|
451
|
+
entry['prompt_cache_ttl'] = m.prompt_cache_ttl;
|
|
452
|
+
}
|
|
447
453
|
members[name] = entry;
|
|
448
454
|
}
|
|
449
455
|
const advisors: Dict = {};
|
|
@@ -483,6 +489,7 @@ function _synthesize_ai_council_block(cfg: CouncilConfig): Dict {
|
|
|
483
489
|
max_output_tokens: cfg.cost_budget.max_output_tokens,
|
|
484
490
|
max_calls: cfg.cost_budget.max_calls,
|
|
485
491
|
max_total_usd: cfg.cost_budget.max_total_usd,
|
|
492
|
+
daily_limit_usd: cfg.cost_budget.daily_limit_usd,
|
|
486
493
|
},
|
|
487
494
|
consensus_scoring: {
|
|
488
495
|
enabled: cfg.consensus_scoring.enabled,
|
|
@@ -617,9 +624,16 @@ function build_members(settings: Dict, opts: BuildMembersOptions = {}): External
|
|
|
617
624
|
// Council opts in explicitly (caching is client-default OFF): on
|
|
618
625
|
// unless the operator sets `prompt_cache: false` on the member.
|
|
619
626
|
const enable_prompt_cache = cfg['prompt_cache'] !== false;
|
|
627
|
+
// road-to-cache-economy Phase 4: absent → AnthropicClient's own
|
|
628
|
+
// '5m' default; only an explicit '1h' override reaches here.
|
|
629
|
+
const prompt_cache_ttl = (cfg['prompt_cache_ttl'] as '5m' | '1h' | undefined) ?? undefined;
|
|
620
630
|
for (const sib_model of siblings[name] as string[]) {
|
|
621
631
|
members.push(
|
|
622
|
-
_construct_api_member(name, sib_model, {
|
|
632
|
+
_construct_api_member(name, sib_model, {
|
|
633
|
+
api_key_ref,
|
|
634
|
+
enable_prompt_cache,
|
|
635
|
+
prompt_cache_ttl,
|
|
636
|
+
}),
|
|
623
637
|
);
|
|
624
638
|
}
|
|
625
639
|
continue;
|
|
@@ -632,6 +646,8 @@ function build_members(settings: Dict, opts: BuildMembersOptions = {}): External
|
|
|
632
646
|
// Council opts in explicitly (client-default OFF); on unless
|
|
633
647
|
// the operator sets `prompt_cache: false`.
|
|
634
648
|
enable_prompt_cache: cfg['prompt_cache'] !== false,
|
|
649
|
+
// road-to-cache-economy Phase 4 — see the siblings branch above.
|
|
650
|
+
prompt_cache_ttl: (cfg['prompt_cache_ttl'] as '5m' | '1h' | undefined) ?? undefined,
|
|
635
651
|
}),
|
|
636
652
|
);
|
|
637
653
|
} else if (mode === 'cli' && _CLI_PROVIDERS.has(name)) {
|
|
@@ -766,7 +782,11 @@ function _format_advisor_summary(
|
|
|
766
782
|
function _construct_api_member(
|
|
767
783
|
name: string,
|
|
768
784
|
model: string | null,
|
|
769
|
-
opts: {
|
|
785
|
+
opts: {
|
|
786
|
+
api_key_ref?: string | null;
|
|
787
|
+
enable_prompt_cache?: boolean | undefined;
|
|
788
|
+
prompt_cache_ttl?: '5m' | '1h' | undefined;
|
|
789
|
+
} = {},
|
|
770
790
|
): ExternalAIClient {
|
|
771
791
|
const api_key_ref = opts.api_key_ref ?? null;
|
|
772
792
|
if (name === 'anthropic') {
|
|
@@ -777,6 +797,7 @@ function _construct_api_member(
|
|
|
777
797
|
model: model || 'claude-sonnet-4-5',
|
|
778
798
|
api_key,
|
|
779
799
|
enable_prompt_cache: opts.enable_prompt_cache,
|
|
800
|
+
prompt_cache_ttl: opts.prompt_cache_ttl,
|
|
780
801
|
});
|
|
781
802
|
}
|
|
782
803
|
if (name === 'openai') {
|
|
@@ -2020,6 +2041,11 @@ function cmd_run(
|
|
|
2020
2041
|
max_output_tokens: _pyInt(cost_cfg['max_output_tokens'] ?? 20_000, 20_000),
|
|
2021
2042
|
max_calls: _pyInt(cost_cfg['max_calls'] ?? 10, 10),
|
|
2022
2043
|
max_total_usd: _pyFloat(cost_cfg['max_total_usd'] ?? 0.0, 0.0) || 0.0,
|
|
2044
|
+
// Rolling 24h cap. Unwired until now: the field existed on CostBudget and
|
|
2045
|
+
// gated the spend-ledger append, but no caller ever passed it, so the
|
|
2046
|
+
// ledger could not be written at all — an archived acceptance criterion
|
|
2047
|
+
// claimed otherwise. 0 keeps the cap disabled, which stays the default.
|
|
2048
|
+
daily_limit_usd: _pyFloat(cost_cfg['daily_limit_usd'] ?? 0.0, 0.0) || 0.0,
|
|
2023
2049
|
});
|
|
2024
2050
|
const rounds = _resolve_rounds(args, ai_cfg);
|
|
2025
2051
|
// Phase 1: stance tally — defensive read; malformed/absent block reads as off.
|
|
@@ -2184,6 +2210,11 @@ function _write_debate_round(
|
|
|
2184
2210
|
table: PriceTable;
|
|
2185
2211
|
prompt_mode: string | null;
|
|
2186
2212
|
prose_synthesis: boolean | null;
|
|
2213
|
+
// road-to-cache-economy Phase 4: the observed wall-clock gap (ms)
|
|
2214
|
+
// between the previous round finishing and this round starting —
|
|
2215
|
+
// `null`/absent on round 1, since nothing was written to the
|
|
2216
|
+
// prompt cache yet. See `run_debate`'s `on_round_complete`.
|
|
2217
|
+
cache_gap_ms_since_previous_round?: number | null | undefined;
|
|
2187
2218
|
},
|
|
2188
2219
|
): string {
|
|
2189
2220
|
fs.mkdirSync(_resolveTarget(out_dir), { recursive: true });
|
|
@@ -2207,6 +2238,7 @@ function _write_debate_round(
|
|
|
2207
2238
|
debate_total_rounds: opts.total_planned_rounds,
|
|
2208
2239
|
rounds: 1,
|
|
2209
2240
|
cost_usd_actual: _pyRound(actual_total, 6),
|
|
2241
|
+
prompt_cache_round_gap_ms: opts.cache_gap_ms_since_previous_round ?? null,
|
|
2210
2242
|
responses: _serialise_responses(responses),
|
|
2211
2243
|
};
|
|
2212
2244
|
const out_path = path.join(_resolveTarget(out_dir), _debate_round_filename(round_number));
|
|
@@ -2410,6 +2442,11 @@ function cmd_debate(
|
|
|
2410
2442
|
max_output_tokens: _pyInt(cost_cfg['max_output_tokens'] ?? 20_000, 20_000),
|
|
2411
2443
|
max_calls: _pyInt(cost_cfg['max_calls'] ?? 10, 10),
|
|
2412
2444
|
max_total_usd: _pyFloat(cost_cfg['max_total_usd'] ?? 0.0, 0.0) || 0.0,
|
|
2445
|
+
// Rolling 24h cap. Unwired until now: the field existed on CostBudget and
|
|
2446
|
+
// gated the spend-ledger append, but no caller ever passed it, so the
|
|
2447
|
+
// ledger could not be written at all — an archived acceptance criterion
|
|
2448
|
+
// claimed otherwise. 0 keeps the cap disabled, which stays the default.
|
|
2449
|
+
daily_limit_usd: _pyFloat(cost_cfg['daily_limit_usd'] ?? 0.0, 0.0) || 0.0,
|
|
2413
2450
|
});
|
|
2414
2451
|
|
|
2415
2452
|
const out_dir = _validate_council_output_path(args.output as string, {
|
|
@@ -2427,7 +2464,11 @@ function cmd_debate(
|
|
|
2427
2464
|
|
|
2428
2465
|
const written: string[] = [];
|
|
2429
2466
|
|
|
2430
|
-
const _on_round_complete = (
|
|
2467
|
+
const _on_round_complete = (
|
|
2468
|
+
round_number: number,
|
|
2469
|
+
results: CouncilResponse[],
|
|
2470
|
+
cache_gap_ms_since_previous_round?: number | null,
|
|
2471
|
+
): void => {
|
|
2431
2472
|
const p = _write_debate_round(out_dir, round_number, results, {
|
|
2432
2473
|
question,
|
|
2433
2474
|
members: members as ExternalAIClient[],
|
|
@@ -2437,6 +2478,7 @@ function cmd_debate(
|
|
|
2437
2478
|
table: table as PriceTable,
|
|
2438
2479
|
prompt_mode: 'debate',
|
|
2439
2480
|
prose_synthesis: _getattr<boolean | null>(args, 'prose_synthesis', null),
|
|
2481
|
+
cache_gap_ms_since_previous_round,
|
|
2440
2482
|
});
|
|
2441
2483
|
written.push(p);
|
|
2442
2484
|
const errors = results.filter((r) => r.error);
|
|
Binary file
|