Problem
SPEND (#44/#45) prices seats. When a seat's included usage runs out, both vendors keep working and start billing overflow — Claude "extra usage" (per-seat opt-in flag hasExtraUsageEnabled), ChatGPT/Codex "credits" — and none of that money appears anywhere in surface. The SPEND card silently under-reports exactly when spend accelerates, which is the moment the reader most needs it not to.
What the local data can and cannot say (verified on a real machine, 2026-08-01)
Can say — the trigger:
- Codex: every
token_count record surface already parses carries rate_limits: primary.used_percent / secondary.used_percent (rolling windows, window_minutes, resets_at) and a credits field — null on every record on this machine (weekly window peaked at 39%). Credits going non-null in a transcript is consumption, on lines we already read.
- Claude Desktop:
%APPDATA%\Claude\plan-usage-history.json (version: 2) logs {t, org, u:{fh, sd}} every ~5 minutes per org — the 5-hour (fh) and 7-day (sd) windows as percentages. 3,218 samples on this machine; fh peaked at 75, sd at 22, never 100. A sample at 100 followed by continued usage (ledger has tokens after that timestamp) is the extra-usage trigger.
- Claude Code:
system/api_error transcript records carry a rateLimits field. Observed exactly once here, null, on a connection error — it should populate with the unified rate-limit/overage status on a real 429. Shape-when-populated unverified.
Cannot say — the amount: neither vendor writes overflow dollars to disk. Claude extra-usage charges live in the Team admin console; Codex's credits object shape when active is unknown until someone consumes one.
Design sketch (the house pattern)
Blocked on ground truth, by design
The populated shapes (credits non-null; Claude Code rateLimits on a real 429; whether fh/sd exceed 100 or peg) are unverified, and building parsers against imagined payloads is how silent misattribution happens. Before any PR, capture a real overflow. Probe script (PowerShell, run any time; capture the output the day a cap is hit):
# Codex: last rate_limits per recent session
Get-ChildItem -Recurse "$env:USERPROFILE\.codex\sessions" -Filter *.jsonl | Sort-Object LastWriteTime -Descending | Select-Object -First 3 | ForEach-Object {
$last = $null; foreach ($l in [System.IO.File]::ReadLines($_.FullName)) { if ($l -match '"token_count"') { $last = $l } }
if ($last) { ($last | ConvertFrom-Json).payload.rate_limits | ConvertTo-Json -Depth 5 }
}
# Claude: utilization now, and any sample >= 100
$s = (Get-Content "$env:APPDATA\Claude\plan-usage-history.json" -Raw | ConvertFrom-Json).samples
"now: fh=$($s[-1].u.fh) sd=$($s[-1].u.sd)"; $s | Where-Object { $_.u.fh -ge 100 -or $_.u.sd -ge 100 } | Select-Object -Last 3 | ConvertTo-Json -Depth 4
# Claude Code: populated rateLimits on api_error records, if any ever occur
Select-String -Path (Get-ChildItem -Recurse "$env:USERPROFILE\.claude\projects" -Filter *.jsonl).FullName -Pattern '"rateLimits"\s*:\s*\{' -List | Select-Object -First 3 Path
What to do
Related: #25 (budget pacing), #13 (notifications). Verified-quiet case: an account that has never hit a cap shows nothing new — today's dashboards stay exactly as they are.
Problem
SPEND (#44/#45) prices seats. When a seat's included usage runs out, both vendors keep working and start billing overflow — Claude "extra usage" (per-seat opt-in flag
hasExtraUsageEnabled), ChatGPT/Codex "credits" — and none of that money appears anywhere in surface. The SPEND card silently under-reports exactly when spend accelerates, which is the moment the reader most needs it not to.What the local data can and cannot say (verified on a real machine, 2026-08-01)
Can say — the trigger:
token_countrecord surface already parses carriesrate_limits:primary.used_percent/secondary.used_percent(rolling windows,window_minutes,resets_at) and acreditsfield —nullon every record on this machine (weekly window peaked at 39%). Credits going non-null in a transcript is consumption, on lines we already read.%APPDATA%\Claude\plan-usage-history.json(version: 2) logs{t, org, u:{fh, sd}}every ~5 minutes per org — the 5-hour (fh) and 7-day (sd) windows as percentages. 3,218 samples on this machine;fhpeaked at 75,sdat 22, never 100. A sample at 100 followed by continued usage (ledger has tokens after that timestamp) is the extra-usage trigger.system/api_errortranscript records carry arateLimitsfield. Observed exactly once here,null, on a connection error — it should populate with the unified rate-limit/overage status on a real 429. Shape-when-populated unverified.Cannot say — the amount: neither vendor writes overflow dollars to disk. Claude extra-usage charges live in the Team admin console; Codex's
creditsobject shape when active is unknown until someone consumes one.Design sketch (the house pattern)
≥$125/mo · ▲ extra usage active. Never a guessed amount.[cost.budget]row (fh/sd/used_percentare ready-made pace inputs), and the alert version is feat: add a lightweight notification system #13.[cost.extra_usage]config entry could carry actual overflow dollars for those who read them off the admin console, plain like every configured figure.Blocked on ground truth, by design
The populated shapes (
creditsnon-null; Claude CoderateLimitson a real 429; whetherfh/sdexceed 100 or peg) are unverified, and building parsers against imagined payloads is how silent misattribution happens. Before any PR, capture a real overflow. Probe script (PowerShell, run any time; capture the output the day a cap is hit):What to do
rate_limitsis on linesusage.rsalready reads; the Claude history file is a new, cheap source beside an existing config dir).▲ extra usage activewhen triggered;--jsoncarries the state.[cost.extra_usage]/ feat: [cost.budget] and a pace-vs-budget row in the Cost view #25[cost.budget]interaction so pace and overflow are one story, not two rows.Related: #25 (budget pacing), #13 (notifications). Verified-quiet case: an account that has never hit a cap shows nothing new — today's dashboards stay exactly as they are.