2026-08-17 · 3 min · agents
My agent uploaded a family recording to a cloud API. I had three local ways to do it.
I asked my agent to do something small: transcribe a family recording sitting in my Drive and text me the result.
It extracted the audio and sent it to OpenAI's transcription API. Eight times. The first key was over quota, and the API rejected the request - after the audio had already been transmitted. So the agent reached for a second key and carried on.
Here is what was sitting unused on hardware I own while that happened: whisper on my laptop, with the model already downloaded. A whisper server on my own GPU box. And the transcription pipeline inside condensr - I build a video transcription product. Three local options, zero of them checked.
The total damage on the bill was about seven cents. A private family recording went to a third party by reflex, while the machine it sat on could have done the job locally.
It happened because the agent asked the easy question: is there an API key in the environment? There was. The right question was: what does this person already run? Its one attempt to actually look was a search across my entire home directory, which timed out and returned its answer after everything had already been sent. A search whose answer arrives after the decision it was meant to inform is decoration.
The part that stung: three of my standing rules already covered this, in writing. Search existing tooling first. Never assume, check. Query the knowledge base before non-trivial work. Zero of them fired. One query would have surfaced the local option in ten seconds. Nobody ran it.
So the fix was not a fourth rule. Sentences do not fire. The fix went one layer down: a hook that inspects outbound commands and blocks audio uploads to third-party transcription APIs before they leave the machine.
Then I put the guard itself through adversarial review, and this is the half of the story I would want to read from anyone else. Four cycles, and every cycle found a real hole. The first: the guard did not resolve relative paths, so it waved through the exact script from the original incident - and my test corpus was green because I had written every fixture with absolute paths. The second: you could delete an entire carve-out from the guard and the tests stayed green. Twice more after that, same shape in new costumes. A check that has quietly stopped checking looks identical to one that is working.
Four minutes after it went live, it produced a real false positive on a command shape nothing in my test corpus had imagined. Later, a nightly job committed the hook mid-edit and shipped it broken for about 35 hours.
One number puts the whole thing in perspective. A sibling hook, before it was wired in, was swept against my real command history: of 14,415 real commands, 1,166 would have been blocked. Eight percent. That is how often a documented rule was being broken while it was merely documented.
"We wrote it down" is not a control.
This is how I work in client repos too.
I install the harness that makes rules like this one enforceable instead of aspirational. See what that involves.