fix(credits): derive agent/quota/cycle surfaces from the ledger (retire counter drift)#35
Merged
Merged
Conversation
…re drift) Whole denormalized-counter drift class in one pass (after invoice #32, pioneer #33). Each surface now reads the immutable credit_transactions ledger. 1. Agent CREDITS (30D). - get_agent (/cloud/agents/{id}, the DETAIL page) exposed NO 30-day credits field at all, so the dashboard had nothing to read and showed 0 even though runs billed correctly. Added a ledger-derived credits_30d (sum of the agent's run debits over 30d; cloud-run debits are tagged with the run id). - list_agents credits_30d previously summed agent_runs.credits_total (a denormalized per-run column that can lag/zero). Now ledger-derived too. 2. compute_calls_remaining() — the pre-money quota figure — read api_keys.monthly_calls_count, which drifts LOW (never counts NULL-key /search debits; LLM path under-increments), over-stating remaining (under-charge). Now = plan allotment − credits_used_this_cycle (ledger sum, per user). New shared helper credits_used_this_cycle() is the single source. 3. The "X this cycle" usage subtitle and the /billing/balance forecast also read monthly_calls_count. Both now use credits_used_this_cycle(). "Used this cycle" = settled spend (execution + cross_rail + cloud_compute); transient agent_reserve holds are excluded (they release on run completion and would otherwise double-count the run's execution debits). monthly_calls_count is now display-vestigial (still written by _increment_calls, read by nothing) — can be dropped in a later migration. Validated read-only against real prod data: get_agent credits_30d=6 (was 0); compute_calls_remaining 239,560→239,112 (counter under-counted by 448). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Whole denormalized-counter drift class in one pass (after invoice #32, pioneer #33).
1. Agent CREDITS (30D). The detail endpoint
get_agentexposed no 30-day credits field → dashboard showed 0. Added a ledger-derivedcredits_30dtoget_agent, and madelist_agents.credits_30dledger-derived (wasSUM(agent_runs.credits_total), a denormalized column that can lag).2. compute_calls_remaining (pre-money quota) read
monthly_calls_count(drifts low → over-states remaining → under-charge). Now = allotment −credits_used_this_cycle()(ledger, per user). New shared helper.3. The "X this cycle" subtitle +
/billing/balanceforecast also usedmonthly_calls_count→ now ledger-derived."Used this cycle" = settled spend (
execution+cross_rail+cloud_compute); transientagent_reserveholds excluded (release on completion; would double-count).Validation (read-only, real prod data — staging lacks this data, so the exact queries were checked against prod): get_agent credits_30d=6 (was 0); compute_calls_remaining 239,560→239,112 (counter under-counted by 448). Read-only display change: no writes, no schema, no enforcement-path change (
check_and_deduct_creditsoncredits_balanceis unchanged).🤖 Generated with Claude Code