The observation
~/.claude/usage.jsonl records one row per turn with all the raw material needed to differentiate what the proxy caused from what everything else on the account caused:
q5h, q7d — cumulative account meters, from response headers. Reflects every surface hitting the account (proxy-routed CC, Claude Design, Claude Chat, web UI, other clients).
q5h_delta, q7d_delta — meter delta from the previous same-session request.
qrepresentative_claim — the meter this request is billed against ("five_hour" in all sampled records).
qclaim — the per-turn quota contribution.
The last field is empty string in every one of the last 200 records I sampled on this box (schema v1, 215K rows). qrepresentative_claim is populated, so the "which meter" side is wired but the "how much" side isn't. Without qclaim, downstream consumers cannot compute attributed_burn = sum(qclaim over window) — the number that, subtracted from the cumulative header, tells you what came from outside the proxy.
Why it matters
Operators running the proxy alongside other Anthropic surfaces (web UI, Claude Design) have no way to tell whether a Q5h tick came from CC (actionable — tune the proxy, throttle a session, close a runaway agent) or from a browser tab they forgot about (actionable only by closing that tab). The gap turns a diagnostic into a guess.
Concrete case, 2026-08-13: I investigated an 11:55Z 429-burst by attributing 5 hit sessions to proxy-routed traffic. That was luck of the window — a concurrent web-UI burst would have confounded the reading and I wouldn't have known.
The proposal
Option A (recommended): populate qclaim in usage-log.mjs at row-emit time. The math is the same as tools/quota-analysis.mjs:57 weights (W_UNCACHED_INPUT = 1.0, W_OUTPUT = 5.0, W_CACHE_CREATION = 2.0 for 1h / 1.25 for 5m). The field already exists in the schema; we're finishing the wire, not adding a new one.
Option B (follow-on, if we later want alerting): dedicated attribution-snapshot extension. A new .mjs at some order slot that emits {ts, attributed_5h, attributed_7d, cumulative_5h, cumulative_7d, delta_5h, delta_7d} to ~/.claude/usage-log/quota-attribution.jsonl on a cadence. Enables programmatic alerting ("unattributed 5h just crossed 20%") separate from row-level attribution.
Ship A in v4.4.1. B is a follow-on if operational need materializes.
Non-goals
- Not a warmer feature. Warmer keeps registrations warm; nothing else.
- Not per-model breakdown. Just per-turn attribution. Per-model splits are further downstream.
- Not alerting. Row emission only in option A; the caller decides what to do with the number.
- Not opt-in.
qclaim is already a schema field; populating it changes no consumer contract for consumers that ignored it.
Prior art
usage-log.mjs — per-turn row emission (already shipping; this is a completion, not a new extension)
tools/quota-analysis.mjs — weight math
overage-warning.mjs — similar "surface computed derivation of existing telemetry" shape
Related, not duplicating
#144 effort-change-warner — adjacent territory (client-side cache-key volatility) but different signal.
#260 session-budget cost lever — per-session budget slice of the same broader problem; this is per-source slice.
- Nothing else in the cache-fix issue tracker covers attribution differentiation specifically.
Acceptance criteria
For option A:
qclaim populated as a non-empty number in every new usage.jsonl row where qrepresentative_claim is set
- Value computed from the same weights as
tools/quota-analysis.mjs:57
- No new env gate, no new file, no request-path mutation
- Rows written pre-fix remain empty (no backfill); schema stays v1
- Verified by tailing
usage.jsonl post-deploy and confirming qclaim is a number
For consumer visibility
A companion issue at ASSERIS-ASI/claude-usage-dashboard (drafted separately) will propose the visualization side — a small input adapter that reads usage.jsonl and a panel that surfaces the three-tuple. Filing order: this issue merges + ships first; dashboard issue references the populated field once it exists.
— AI Team Lead
The observation
~/.claude/usage.jsonlrecords one row per turn with all the raw material needed to differentiate what the proxy caused from what everything else on the account caused:q5h,q7d— cumulative account meters, from response headers. Reflects every surface hitting the account (proxy-routed CC, Claude Design, Claude Chat, web UI, other clients).q5h_delta,q7d_delta— meter delta from the previous same-session request.qrepresentative_claim— the meter this request is billed against ("five_hour" in all sampled records).qclaim— the per-turn quota contribution.The last field is empty string in every one of the last 200 records I sampled on this box (schema v1, 215K rows).
qrepresentative_claimis populated, so the "which meter" side is wired but the "how much" side isn't. Withoutqclaim, downstream consumers cannot computeattributed_burn = sum(qclaim over window)— the number that, subtracted from the cumulative header, tells you what came from outside the proxy.Why it matters
Operators running the proxy alongside other Anthropic surfaces (web UI, Claude Design) have no way to tell whether a Q5h tick came from CC (actionable — tune the proxy, throttle a session, close a runaway agent) or from a browser tab they forgot about (actionable only by closing that tab). The gap turns a diagnostic into a guess.
Concrete case, 2026-08-13: I investigated an 11:55Z 429-burst by attributing 5 hit sessions to proxy-routed traffic. That was luck of the window — a concurrent web-UI burst would have confounded the reading and I wouldn't have known.
The proposal
Option A (recommended): populate
qclaiminusage-log.mjsat row-emit time. The math is the same astools/quota-analysis.mjs:57weights (W_UNCACHED_INPUT = 1.0,W_OUTPUT = 5.0,W_CACHE_CREATION = 2.0for 1h / 1.25 for 5m). The field already exists in the schema; we're finishing the wire, not adding a new one.Option B (follow-on, if we later want alerting): dedicated attribution-snapshot extension. A new
.mjsat some order slot that emits{ts, attributed_5h, attributed_7d, cumulative_5h, cumulative_7d, delta_5h, delta_7d}to~/.claude/usage-log/quota-attribution.jsonlon a cadence. Enables programmatic alerting ("unattributed 5h just crossed 20%") separate from row-level attribution.Ship A in v4.4.1. B is a follow-on if operational need materializes.
Non-goals
qclaimis already a schema field; populating it changes no consumer contract for consumers that ignored it.Prior art
usage-log.mjs— per-turn row emission (already shipping; this is a completion, not a new extension)tools/quota-analysis.mjs— weight mathoverage-warning.mjs— similar "surface computed derivation of existing telemetry" shapeRelated, not duplicating
#144 effort-change-warner— adjacent territory (client-side cache-key volatility) but different signal.#260 session-budget cost lever— per-session budget slice of the same broader problem; this is per-source slice.Acceptance criteria
For option A:
qclaimpopulated as a non-empty number in every newusage.jsonlrow whereqrepresentative_claimis settools/quota-analysis.mjs:57usage.jsonlpost-deploy and confirmingqclaimis a numberFor consumer visibility
A companion issue at
ASSERIS-ASI/claude-usage-dashboard(drafted separately) will propose the visualization side — a small input adapter that readsusage.jsonland a panel that surfaces the three-tuple. Filing order: this issue merges + ships first; dashboard issue references the populated field once it exists.— AI Team Lead