The footer showed invented percentages. It now shows what two harnesses actually report, or says it does not know. lumbridge-core gains an append-only per-profile UsageLedger and a projection that labels every derived value estimated, withholds a burn rate from a single sample, withholds a window fraction with no reported ceiling, withholds an exhaustion estimate that lands after the reset, and reports an expired window as rolled over rather than freezing its last percentage. A missing fact renders as missing, never as zero. (0012) lumbridge-harness is the impure side: processes, clocks, and untrusted wire text in, observations out. Three adapters: - Codex's account/rateLimits/read over the app-server's JSON-RPC stdio. The client cannot express a request outside a two-variant enum and answers every server-to-client request with -32601, so a harness asking Lumbridge for a credential is refused by construction. (0013) - Claude Code's session transcripts, as a byte-offset tail follower that reports nothing until the backlog is read to EOF — a partially-read backlog is indistinguishable from a burst of spend, and the first run against 20 MB reported forty-six billion tokens an hour. The parser models four counters, so the conversations in those files are not representable. (0014) - Claude Code's five-hour and seven-day subscription windows, via a bridge installed as its statusLine command. 0014 had claimed no such surface existed; it does, and the record is corrected in place rather than quietly edited. Lumbridge does not read the OAuth credential to call the account usage endpoint, which is what comparable tools do — AGENTS.md forbids it, and 0015 says so rather than leaving the gap unexplained. Also in here: a capability-check ordering fix in the workspace reducer, where the applied-request replay table was consulted before the capability check and so answered questions the caller had no right to ask; the GPUI spike wired to the live probes with per-harness gauges and provenance chips; and a launcher that matches its own window by PID, because GPUI sets WM_NAME but not _NET_WM_NAME and a title match never succeeded. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
68 lines
3.4 KiB
Markdown
68 lines
3.4 KiB
Markdown
# 0012: The footer renders a derived projection, never a stored percentage
|
|
|
|
Status: accepted. Supplemented by decisions 0013 and 0014, which supply the
|
|
first two real adapters. Every rule below still holds.
|
|
|
|
Decision 0002 established that usage observations carry provenance. This
|
|
decision fixes how those observations become the five answers the footer owes
|
|
the user, and what the footer must do when it cannot answer.
|
|
|
|
## The contract
|
|
|
|
`lumbridge-core` owns an append-only `UsageLedger` of `UsageObservation`s per
|
|
`AccountProfile`. An observation is a fact: consumed units, an optional ceiling,
|
|
an optional provider window, a provenance, and the time it was observed. The
|
|
ledger never edits an observation and refuses one that predates the newest entry
|
|
for that profile, because an append-only stream cannot move backwards.
|
|
|
|
`UsageLedger::project` derives the footer view. Reported facts keep their own
|
|
provenance. Anything the projection computes is labelled `Estimated` even when
|
|
every input was provider-reported, because a derived rate is not a reported
|
|
fact.
|
|
|
|
## Rules the projection enforces
|
|
|
|
- A burn rate needs at least two observations inside the same window, the same
|
|
unit, and a minimum elapsed sample. One reading yields no rate at all rather
|
|
than a rate of zero.
|
|
- A window fraction requires a reported ceiling. A self-hosted endpoint has no
|
|
quota, so it reports consumption and explicitly says no ceiling exists.
|
|
- An exhaustion estimate is withheld when the window resets first. Telling a
|
|
user they will run out after the quota has already refilled is worse than
|
|
telling them nothing.
|
|
- An `Unavailable` observation invalidates older facts for that profile instead
|
|
of letting a stale reading keep rendering as current.
|
|
- An expired window is reported as rolled over, not as a frozen percentage from
|
|
a window that ended.
|
|
- Staleness is surfaced, not hidden: past the staleness budget the value still
|
|
renders but its confidence drops to unknown and the footer says so.
|
|
|
|
## What the UI may do
|
|
|
|
A compact surface may substitute the short provenance label. It may not drop the
|
|
label, round an estimate into a reported fact, or substitute a placeholder
|
|
number for a missing one. `FooterUsage` therefore returns explicit phrases —
|
|
`usage unavailable`, `reset time unavailable`, `burn rate unavailable`,
|
|
`no usage source` — and the GPUI shell renders unavailable values in the quiet
|
|
tone with the provenance chip coloured by source rather than by value.
|
|
|
|
A pane with no harness attached shows the detached roll-up. It never inherits
|
|
another pane's account, because attributing one agent's spend to another is the
|
|
same class of untruth as inventing the number.
|
|
|
|
## Status of the numbers
|
|
|
|
The GPUI shell's observations are still a declared spike fixture. The path is
|
|
real: the fixture records through the same ledger and reads back through the
|
|
same projection, so the honest-gap behaviour above is exercised on every frame
|
|
rather than asserted only in tests.
|
|
|
|
The first real adapter now exists in `lumbridge-harness` (decision 0013) and its
|
|
integration tests drive a synthetic Codex transcript through this ledger and
|
|
this footer, proving every rule above survives the adapter path. Pointing the
|
|
running shell at a live account spawns a process against the user's own
|
|
subscription, so it stays a separate, user-consented step.
|
|
|
|
All arithmetic is integer arithmetic and fractions are carried as permille, so a
|
|
rendered percentage cannot drift from the stored fact.
|