Reliability & Ops
Spend Caps
A hard daily ceiling per edge provider, with a softer threshold that degrades before the hard one refuses.
Situation
The estate has no spend ceiling. The edge Worker makes the two billable third-party calls it controls — Anthropic (all chat/reasoning) and ElevenLabs (all TTS) — and nothing meters or caps them. Hermes's spend is Tower-side via an OpenRouter aggregator and is explicitly out of scope here.
The goal is a hard daily ceiling per provider with a softer degrade-first threshold, consistent with the estate's existing nudge soft-cap/hard-cap philosophy: stay responsive under the soft cap, true runaway guard at the hard cap, entirely edge-local with no hot-path call home.
Key decisions
Two-tier per provider: soft → degrade, hard → refuse
Mirrors the estate's existing D9 nudge soft/hard-cap philosophy rather than introducing a new pattern.
Meter estimated USD, not exact usage
A best-effort KV ledger (spend:<provider>:<London-day>) built from a chars→tokens→price table, since capturing exact token usage would mean threading counts through streaming.
Edge-only scope: Anthropic + ElevenLabs
These are the only providers the Worker itself controls; Hermes is separately managed in OpenRouter.
Caps live in wrangler.toml [vars], off by default
Tunable without a code change; nothing degrades until the operator opts in, but shipped defaults give runaway protection out of the box.
Ops alerts via notify() (FCM), deduped per provider/tier/day
A "your bill is running" push reaches the phone directly; a KV alert-flag prevents repeat buzzes.
Visibility via EOD addendum + a live Updates-tab chip
Both read the same ledger with no new spend — the addendum is the daily record, the chip is the always-current view.
Architecture
Metering happens at the provider call site (where token/char counts are in hand); enforcement happens at tier-selection time (where a cheaper path can still be chosen) — deliberately separate concerns.
londonDay, classifySpend (ok/soft/hard), KV ledger read-add-write with a ~35-day expirationTtl, buildSpendReport/buildSpendAddendum.checkSpend gates tier selection: soft forces the cheapest (fast) model for the turn; hard short-circuits to a canned persona-voiced line with no provider call at all.buildSpendReport.src/cron/eod.ts appends a per-provider spent/hard line (with a crossed-cap flag) to the daily summary; a ledger-read error drops the addendum without breaking EOD.Risks & guardrails
Estimation, not billing accuracy
Cost is approximated via a ~4-chars/token heuristic and a price table, explicitly a guardrail estimate rather than exact billing — acceptable for a runaway guard, not for invoicing.
KV has no atomic increment
Concurrent calls to recordSpend can race, so at worst the cap trips slightly late; judged acceptable for a single-operator guardrail.
Wiring depends on runTurn/handleSpeak shape at plan time
The exact seam for forcing the fast tier and for the hard-cap short-circuit is confirmed at build time, not locked in the spec.
Delivery
Edge core
src/lib/spend.ts + spend.test.ts — estimators, londonDay, classifySpend boundaries, ledger helpers.
Enforce/record wiring
providers/anthropic.ts record hook; src/routes/chat.ts/src/orchestrator.ts enforcement; src/routes/speech.ts/handleSpeak enforcement + record.
Reporting
GET /spend (src/routes/spend.ts + index registration) and the EOD addendum in src/cron/eod.ts.
Web
SpendChip + detail panel on the Updates view, following the existing chip/sheet pattern (e.g. StatusSheet).
Config
wrangler.toml [vars] caps (Anthropic 8/15 USD, ElevenLabs 5/10 USD suggested defaults) + rate + history-window vars.
Held for Alex
Confirm/tune cap values and the ElevenLabs per-char rate for the actual plan, then deploy the Worker.
Out of scope
docs/superpowers/specs/2026-06-21-spend-caps-design.mdplan ·
docs/superpowers/plans/2026-06-21-spend-caps.md