The gap
ai_usage is written at exactly one choke point — runUserWorkersAi in lib/user-ai.ts (plus recordVoiceUsage for the key-proxy and recordPlatformUsage for Workers-AI). The coding Engine never passes through any of them. Claude Code / Codex / Grok run on the user's own machine, spending on their own subscription or key, and the platform records nothing.
Measured on the live ledger (30d, operator account):
| kind | cost | calls |
|---|
| chat | $18.95 | 814 |
| voice | $8.51 | 840 |
| overseer | $7.45 | 326 |
| copilot | $4.85 | 244 |
| coding | $0.70 | 67 |
That coding row is only the cloud-side Pilot deciding what to do next. The Engine's own consumption — almost certainly the single largest item for anyone using Coder in earnest — is absent. So the Usage page reads $40.92 when real spend is materially higher, and there is no signal that anything is missing.
Why this matters beyond curiosity
The implementation path is already open
packages/browser-runner/src/coding/headless.ts parses Claude Code's stream-json and already handles the result event (line ~497) — it reads is_error/result/subtype and discards the usage and total_cost_usd fields on the same object. The data is flowing through today and being thrown away.
- In the
result case, capture usage (input/output/cache tokens) + total_cost_usd when present. - Report it with the existing session event channel (
/coding/event) — no new transport, no relay change. - Cloud side: ledger it as
kind:"engine", provider:"anthropic", with the CLI-reported cost — this is the one number that is not an estimate, since Claude Code computes it itself. - Raw (non-Claude) engines emit no such event → record nothing rather than guess. Codex/Grok stay invisible until each exposes an equivalent; say so in the UI rather than implying zero.
Acceptance
Found while answering "what is $40.92 and is it real". Related: #45 (platform actuals), #56, #57, #68.
The gap
ai_usageis written at exactly one choke point —runUserWorkersAiinlib/user-ai.ts(plusrecordVoiceUsagefor the key-proxy andrecordPlatformUsagefor Workers-AI). The coding Engine never passes through any of them. Claude Code / Codex / Grok run on the user's own machine, spending on their own subscription or key, and the platform records nothing.Measured on the live ledger (30d, operator account):
That
codingrow is only the cloud-side Pilot deciding what to do next. The Engine's own consumption — almost certainly the single largest item for anyone using Coder in earnest — is absent. So the Usage page reads $40.92 when real spend is materially higher, and there is no signal that anything is missing.Why this matters beyond curiosity
The implementation path is already open
packages/browser-runner/src/coding/headless.tsparses Claude Code's stream-json and already handles theresultevent (line ~497) — it readsis_error/result/subtypeand discards theusageandtotal_cost_usdfields on the same object. The data is flowing through today and being thrown away.resultcase, captureusage(input/output/cache tokens) +total_cost_usdwhen present./coding/event) — no new transport, no relay change.kind:"engine",provider:"anthropic", with the CLI-reported cost — this is the one number that is not an estimate, since Claude Code computes it itself.Acceptance
claudeengine producesai_usagerows withkind:"engine".ai-pricing.ts.Found while answering "what is $40.92 and is it real". Related: #45 (platform actuals), #56, #57, #68.