Skip to content

fix(wallet): report the unified spendable balance managed mode debits#204

Closed
Aayam Bansal (aayambansal) wants to merge 1 commit into
mainfrom
fix/cli-wallet-shows-unified-spendable
Closed

fix(wallet): report the unified spendable balance managed mode debits#204
Aayam Bansal (aayambansal) wants to merge 1 commit into
mainfrom
fix/cli-wallet-shows-unified-spendable

Conversation

@aayambansal

Copy link
Copy Markdown
Member

Symptom

Managed mode "isn't deducting my credits." The wallet balance in openscience billing and the Settings → Wallet panel sat frozen at $54.55 across a whole session of managed openrouter/claude-opus-4.8 calls.

Root cause

The gateway and billing are actually working — the freeze is a display bug. The CLI reported the CLI-only ledger (cli_balance_cents), but managed mode debits the unified wallet:

  • llm_proxy_service charges every managed call with category="unified".
  • usage_service.charge (unified) drains subscription pool → Atlas-web ledger → CLI ledger, in that order.

So a user who holds any Atlas-ledger balance has every managed call absorbed by the Atlas ledger first — the CLI ledger (the number we displayed) never moves, even though the spendable balance is dropping normally.

Confirmed against the live wallet for the affected account:

field value
atlas_balance_cents $101.79
cli_balance_cents $54.55 ← what the CLI showed (frozen)
unified_balance_cents $156.34 ← what managed mode actually spends
lifetime_spent_cents $3.99 (all managed_llm:openrouter holds, settled)

The recent session's 6 managed calls settled cleanly (pending_managed_debitssettled) and posted -$3.28 to credit_transactions, every cent drawn from atlas_topup_share — i.e. the money left the unified balance exactly as designed; only the displayed pool was wrong.

This supersedes the premise of #157 ("managed debits only the CLI wallet, category=cli"). That was true when written, but the backend has since moved managed spend onto the unified wallet, which is why the CLI-only display went stale.

Fix

Report the unified spendable balance everywhere the CLI answers "what can this call spend":

  • cliSpendableCents() prefers unified_balance_cents (then the aggregate, then the CLI ledger as a last-resort fallback).
  • getBalance() reads /api/credits/api/cli/balance only exposes the CLI ledger, so it can never reflect Atlas-ledger spend. Preserves the null-vs-zero distinction.
  • openscience billing shows that figure, labelled Atlas wallet.

Verification

  • bun test test/openscience — 35 pass (wallet-balance test updated to assert the unified preference + fallbacks).
  • bun run typecheck — clean.
  • Ran the built subcommand against the live backend: openscience billing now prints Atlas wallet : $156.34 (was $54.55) and tracks real spend.

Follow-ups (backend, not in this PR)

Client-side display is fixed; for full consistency the Atlas side still wants:

  1. /api/cli/balance and /api/cli/billing-mode should return the unified spendable balance (today they return CLI-only), so any client reading them agrees without special-casing.
  2. require_managed_unlocked / require_cli_access gate on balances["cli"] > 0; that gate should move to the unified balance, or a user with Atlas-ledger-only credit gets blocked from managed mode despite having spendable funds.
  3. The managed OpenRouter hold/settle path doesn't write an llm_usage audit row, so the web dashboard's usage history shows nothing for these calls (only credit_transactions records them). record_managed_usage already writes one on the non-hold path — the hold path should too.

The CLI wallet read the CLI-only ledger (cli_balance_cents), but managed
mode debits the UNIFIED wallet: Atlas charges every managed LLM call with
category="unified", draining the subscription pool, then the Atlas-web
ledger, then the CLI ledger. A user with any Atlas-ledger balance saw
managed calls drain that pool first while the displayed CLI wallet never
moved — reading as "credits aren't being deducted" even though the unified
balance was decreasing normally (observed: unified $156.34, already down
$3.99 over a session, while the CLI wallet sat frozen at $54.55).

Report the unified spendable balance everywhere the CLI surfaces what a
call can actually spend:
- cliSpendableCents prefers unified_balance_cents (then the aggregate,
  then the CLI ledger as a last-resort fallback)
- getBalance reads /api/credits; /api/cli/balance only exposes the CLI
  ledger, so it can never reflect Atlas-ledger spend
- `openscience billing` shows that figure and labels it "Atlas wallet"

Supersedes #157, whose "managed debits only the CLI wallet (category=cli)"
premise no longer holds now that the backend routes managed spend through
the unified wallet.
@vercel

vercel Bot commented Jul 24, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
openscience Ready Ready Preview, Comment Jul 24, 2026 7:43am

Request Review

@aayambansal

Copy link
Copy Markdown
Member Author

Superseded by the approved single-wallet, exact-value billing redesign. Closing this display-only approach so the replacement can coordinate Atlas and OpenScience end to end.

@aayambansal
Aayam Bansal (aayambansal) deleted the fix/cli-wallet-shows-unified-spendable branch July 25, 2026 15:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant