The Anthropic billing console showed one of my API keys burning $5.75 a day. That’s a $175/month trajectory against a $50/month ceiling, and — this is the good part — it was a key I was pretty sure nothing was using. Bubbles, our family AI assistant, chats on a cheaper model. Every session log agreed. The gateway showed zero calls to Anthropic all month.

So something on that machine was spending money, around the clock, without appearing in any log I normally read.

The accidental dream loop

The trail led back to an upgrade session the day before. Along with the update, I’d run the tool’s autopilot --install — which sounded harmless and turned out to install a background job that runs the knowledge base’s “dream” cycle continuously. Dreaming, for this tool, means re-reading pages, proposing connections, grading its own takes, looking for drift. Neat idea. The catch: the dream phases were hardcoded to use the expensive “reasoning” model tier, and the background job happily picked up my API key from the shell environment like it owned the place.

Where the money went

The audit files showed about 1,100 calls a day. And the cost shape explained why it was so expensive: 96% of the spend was uncached input — the dream loop was stuffing full page context into every single call. $11.14 of the $11.53 total, just re-reading its own homework at retail prices.

The guard that never fired

Then the detail that rearranged how I run things. The tool has a budget guard — a $5 cap on dream spending, which should have shut this down on day one. It never fired. Its internal ledger estimated costs at a flat rate per call, and that estimate was wrong by a factor of seven: on the day I caught it, the ledger believed it had spent $0.86 while the actual bill was $5.84. The guard wasn’t broken. It was faithfully enforcing a limit against numbers it was making up.

I no longer treat an agent’s self-reported spend as enough. In this setup, the provider’s console is the meter I trust; everything else is the agent grading its own homework—see also: the dream loop, above, literally grading its own takes.

Two minutes to fix

The fix took two minutes: unload the background job, rename the plist so it can’t resurrect itself on reboot, and leave the cheap embedding sync (pennies) untouched so retrieval stays current. I also filed a task to check the console again in three days and confirm the line went flat. It did.

If I ever turn dreams back on, the first move is pointing them at the cheapest model that can do the job, and the second is watching the console — not the tool’s ledger — for the first week. The AI can dream. It can dream on a budget, on a meter I own.