Files
gbrain/docs
MasaandClaude Opus 5 a13ecb1f0a fix(cycle): BudgetMeter prices from the derived Anthropic view, so the cap is off for canonically-priced models (#3951)
* fix(cycle): price BudgetMeter through the canonical table, not the derived Anthropic view

BudgetMeter estimated submit cost with `estimateMaxCostUsd`, which reads
ANTHROPIC_PRICING. CLAUDE.md defines that table as a DERIVED view of the one
canonical chat-pricing table, so any non-Anthropic model was unpriceable here
even when CANONICAL_PRICING carries its rates — and an unpriceable model does
not merely lose accuracy, it takes the `cost === null` branch and returns
`allowed: true` with cost 0. The cap is off for that model.

Measured on 130d321d: openai:gpt-5.2 and deepseek:deepseek-chat are both in
CANONICAL_PRICING and both absent from the derived view, so the gate was
disabled for them. claude-opus-4-7 resolves through either.

The estimate now goes through canonicalLookup, falling back to the existing
call for anything canonical does not carry. Anthropic numbers are unchanged
by construction — the derived view is generated from canonical — and a test
pins that parity.

Deliberately NOT changed: a model absent from canonical too keeps the
documented warn-and-allow bypass, with the same BUDGET_METER_NO_PRICING
warning, the same submit_unpriced ledger event, and the same
`unpricedSubmits` counter. Whether those should be priced at a conservative
fallback rate instead — as synthesize-concepts (#3915) and skillopt/preflight
already do — is a policy call, not this fix. The ledger schema is untouched;
`test/fixtures/dream-budget-schema-v1.jsonl` still describes it.

Related to #2149 (self-closed by its reporter without a fix; the pricing half
of what it described is still live). Distinct from #2504, which is the
opposite failure mode in BudgetTracker: hard-throw on a missing entry rather
than silent bypass.

Verification on 130d321d (v0.42.76.0):
- bun test budget-meter + auto-think-phase + propose-takes + model-pricing -> 93 pass / 0 fail
- red check: with upstream/master's budget-meter.ts -> 10 pass / 1 fail on the new gating test
- bun run typecheck -> clean
- bun run verify -> 34/34 green

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(cycle): guard the non-finite estimate, and correct the docs the change makes stale

Codex review, both verified before applying:

- Both pricing tables are object literals, so a model id colliding with an
  inherited key ('constructor', 'toString', '__proto__') resolves to a truthy
  Object.prototype value whose .input/.output are undefined and the rate
  arithmetic yields NaN. Measured: canonicalLookup('constructor') returns a
  function, and estimateMaxCostUsd('constructor', …) already returns NaN on
  master, so the shape predates this change — but it sits on the path this
  patch touches. `cumulative + NaN` is NaN and `NaN > budget` is false, so one
  such submit would disable the gate for the rest of the cycle. The estimate
  helper now treats a non-finite result as unpriceable, which routes that one
  submit into the documented warn-and-allow branch and leaves the running
  total finite. Regression test submits the poison id, then a submit that must
  be denied. The same shape on the estimateMaxCostUsd path is left alone.

- Two docs asserted the old behaviour and are now current-state: the
  anthropic-pricing.ts header ("non-Anthropic models … bypass … runs
  unbounded") and the KEY_FILES.md entry for the same file. Both now say the
  bypass applies only when canonical has no rates either. `bun run
  build:llms` regenerated; the bundles are unchanged because KEY_FILES.md is
  linked rather than inlined, and test/build-llms.test.ts passes.

Verification on 130d321d (v0.42.76.0):
- bun test budget-meter + auto-think-phase + propose-takes + model-pricing + build-llms -> 106 pass / 0 fail
- bun run typecheck -> clean
- bun run verify -> 34/34 green

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 21:32:46 +07:00
..