At 7:48 on a Thursday morning, my phone started buzzing. Multiple iMessages, in a row, from Bubbles, our family AI. I hadn’t asked it anything. Nobody had. It was just… texting me. My first message to my other computer that morning was, verbatim: “why did Bubbles just send me a bunch of texts.”

There’s a special flavor of dread when a machine you built starts doing things unprompted. It’s your own house haunting you, and you’re also the ghost.

The texts were legitimate

The investigation was less spooky than the symptom. The texts were legitimate — that was the uncomfortable part. A scheduled morning-brief job and a memory-maintenance job had both fired at 7:48, done their work correctly, and then delivered their output the way the system was configured to deliver everything: straight to my phone. Nothing was broken. I had simply built a system where “the cron job finished” and “your family is texting you” arrived through the same door, wearing the same clothes.

Pulling the thread

That morning turned into a six-and-a-half-hour cleanup, because pulling one thread exposed the sweater. At the time, Bubbles was running two agent frameworks side by side — an older one and the newer gateway I’d been migrating to — and the old one still had five launch agents alive on the machine. (They were named Julian, Ricky, and Lahey, among others, because if you’re going to have background processes you can’t fully account for, they should at least be named after people you can’t fully account for.) The crash-looping model backend got downgraded a version to stop a cascade of errors while I was in there.

iMessage is for humans

By the end of the day: all five of the old framework’s launch agents unloaded, one runtime instead of two, and — the actual keeper — a delivery rule written down where the system can’t forget it. Automated output goes to a Discord channel. iMessage is for humans. If Bubbles texts my phone, it’s because a person asked it to relay something, not because a scheduler felt chatty at dawn.

Loud by default

That rule sounds obvious in hindsight, and it is. But nobody designs the notification architecture of a home AI on day one — you bolt on channels as you build, and every channel defaults to the loudest one, because when you’re testing, loud is convenient. Then one morning all your conveniences fire at once, at 7:48, and you find out what you actually built.

The texts stopped. The jobs still run. And now when my phone buzzes, it’s a person — which, it turns out, is a feature you have to engineer on purpose.