Skip to content

[bug] The $50 circuit breaker is denominated in dollars for work nobody is billed for — subscription engine usage blocks delegations #343

Description

@serge-ivo

What happened

2026-08-07, 00:35. A delegation to Heartfull was refused:

The run failed immediately — the $50.00 daily spend limit has been hit across all agents.

Today's ledger: $47.54, of which $48.76 (7-day) is a single engine row — 17 calls on
claude-opus-5[1m], 13.4M cache-read tokens, ~790K re-read per turn.

The spend was not real money

The session's own auth report says resolved: "machine-login", and the runner derives that by
inspecting the engine's merged spawn env (packages/browser-runner/src/coding/engine-auth.ts:63):

if (has(env, API_KEY_ENV[clientType])) return "api-key";
if (has(env, SUBSCRIPTION_ENV[clientType])) return "subscription";
return "machine-login";

ANTHROPIC_API_KEY was not in the environment — otherwise it would have reported api-key. So
the CLI used its stored login: the user's claude.ai subscription, not the API account at
platform.claude.com.

But Claude Code computes total_cost_usd from token counts regardless of how it authenticated,
and recordEngineUsage ledgers that verbatim as cost_source: 'reported' — correctly, since it is
the CLI's own measurement. What is missing is that a reported cost is not necessarily a charged
cost.

DAILY_CEILING_MICROS then counted it. From its own comment:

checked at admission so an exhausted account cannot open new work rather than being discovered
on a bill. Generous on purpose: it is a circuit breaker, not a quota.

There was no bill to be discovered. A circuit breaker for real spend fired on notional spend,
and blocked hours of queued work.

Why this will keep happening

Subscription-authenticated engine work is the expected configuration — it is what auto resolves
to when no key is set, and it is the cheaper choice the platform should encourage. At ~790K
cache-read tokens per turn, a subscription session accrues $2.87/call of notional cost, so the
$50 ceiling is reachable in under twenty engine turns of ordinary work that costs nothing.

The better the user's setup, the faster they hit a wall built for the worse one.

Fix

Do not count subscription-authenticated engine usage against a money ceiling. The runner
already knows the auth mode per session and already reports it; the ledger row can carry it
alongside cost_source.

Options, roughly in order:

  1. Record billed: false for machine-login/subscription engine rows and exclude them from
    DAILY_CEILING_MICROS. Keep them in Usage — the token cost is real even when the dollar cost is
    not, and it is exactly what a user wants to see about their subscription consumption.
  2. Show them distinctly in Usage: "subscription (no charge)" vs "billed to your API key". The page
    already distinguishes estimated from reported (Usage page doesn't disclose what the cost estimate excludes (Engine spend) or over-counts (cache) #270); this is the second axis, and the more
    consequential one.
  3. If a separate bound on subscription work is wanted, it should be a rate/quota, not dollars —
    different thing, different number, different message.

Also worth fixing while here

  • machine-login currently produces no warning at all (engineAuthWarning only fires on
    mismatches, and auto + machine-login is a match). It is the most common resolution and the
    one where the user cannot tell which account is paying. It should state the outcome positively:
    "using this machine's Claude login — not billed to your API key."
  • The refusal message should say what was counted. "The $50 daily limit has been hit" sent the
    user to check an API dashboard that shows nothing for today.

Verification

  • An engine session on a subscription login accrues Usage rows but does not advance the daily
    ceiling.
  • An engine session with ANTHROPIC_API_KEY present does advance it.
  • Usage labels the two differently, per session.
  • The refusal names which spend hit the ceiling and over what window.

Correction and refocus (after reading the vendor docs)

The analysis above conceded too much. It said recordEngineUsage ledgers total_cost_usd as
cost_source: 'reported' "correctly, since it is the CLI's own measurement." That is wrong,
and it is the same mistake the rest of the ticket is complaining about.

From Manage costs effectively (Anthropic):

Claude Code computes the dollar figure locally from token counts priced at standard list
rates
, so it doesn't reflect promotional pricing or contracted discounts and may differ from
your actual bill
.

Claude Max and Pro subscribers have usage included in their subscription, so the session cost
figure isn't relevant for billing purposes
.

total_cost_usd is not a measurement of money in any auth mode. It is tokens × list price —
structurally identical to our own estimate, just computed by a different process. So the
reported / estimated axis was never the billability axis, and this ticket should not be
scoped as "exclude subscription rows from a mostly-correct ledger".

The missing fact is who pays, which nothing in the schema records. That is now #346.
The parallel dishonesty in the UI and code comments is #347.

Two further corrections to the text above:

  • machine-login does not establish "the user's claude.ai subscription". It means neither
    credential was in the merged env and the CLI used its stored login — which could be either a
    subscription or a configured API key. The stated conclusion was more confident than the
    evidence. Correct value is unknown; see [design] The usage ledger records value, not charge — add payer attribution #346 for the proposed one-time per-machine
    declaration that makes it knowable instead of guessed.
  • Fix option 3 was right and should be promoted, not left as an afterthought. Subscription
    limits are not denominated in dollars at all — the docs describe a rolling 5-hour window and a
    weekly window, shared across Claude chat, Claude Code and Cowork. There is no subscription
    figure a $50 ceiling could be comparing against. A bound on subscription work has to be in
    tokens over a rolling window, with its own message.

Scope, restated

This ticket is now specifically the circuit breaker's unit, on top of #346:

  1. userSpendSinceMicros (workers/api/src/lib/usage.ts:528) sums cost_micros with no payer
    filter. The dollar ceiling must sum only payer = 'byok-api'.
  2. Add a token ceiling over the same rolling window covering all payers, so subscription and
    unknown work is still bounded — against burning the user's plan allowance, which is the real
    harm there, rather than against a bill that does not exist.
  3. Two different refusal messages, naming the resource, the window and the payer. The current one
    sent the user to an API dashboard that showed nothing for that day.
  4. spendPercentileMicros (:490) derives per-tree budgets from the same unfiltered sum, so
    notional subscription value is inflating derived ceilings too. Same filter.
  5. Keep the machine-login disclosure item from the original text — it is still right, and [design] The usage ledger records value, not charge — add payer attribution #346
    makes it answerable rather than inferred.

Verification (revised)

  • An engine session on a declared subscription accrues Usage rows and advances the token
    ceiling, never the dollar one.
  • An engine session with ANTHROPIC_API_KEY present advances the dollar ceiling.
  • An undeclared machine is never blocked by the dollar ceiling, and the refusal — if the token
    ceiling fires — says so in tokens.
  • The refusal names which resource hit which limit over which window.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions