I run Claude Code on my homelab as a standing assistant. It lives in a terminal session, and I have it wired into Telegram through a plugin, so a message from my phone dispatches straight into the session, it does the work, and it reports back to the chat. Nothing exotic by 2026 standards. A lot of you reading this run some version of the same thing.
For most of a day yesterday, it was talking to a version of me that did not exist.
This is the most unsettling bug I have hit in a long time, and the trap behind it is waiting for anyone who wires an agent up to the real world.
The watchdog
Some background. Claude Code runs in a terminal session, and the plugin delivers each Telegram message into that session. Every so often the plugin hiccups, or the session gets busy and a message I send just sits there at the prompt, unsent. Annoying. So a while back I set up a small watchdog script to babysit the thing. It checks every fifteen minutes: is the session alive, is anything stuck.
Reasonable. The kind of glue you write without thinking twice.
Then, at about two in the morning, I gave the watchdog a new trick. If it saw text sitting at the prompt and the session was idle, it would assume one of my messages had gotten stuck, type it in for me, and press enter. It even tagged it so the assistant would know: "this message from Daniel was stuck, auto-submitted on his behalf."
Helpful. Except for one detail that turns the whole thing inside out.
What is actually sitting at the prompt
Here is the part I did not think through, and neither did the script.
When the assistant finishes answering and goes quiet, the terminal does not sit empty. It shows a dimmed, greyed-out suggestion. A guess at what I might type next. Lots of modern CLI tools do this now, it is the autocomplete-your-whole-sentence idea applied to a chat prompt.
So picture what the watchdog saw. The assistant finishes a task, sends me a summary, and goes idle. The terminal fills the empty prompt with a plausible thing I might say next. The watchdog wakes up, sees text at the prompt, decides it is a stuck message from me, and submits it. The assistant receives what looks like a message from Daniel, answers it, and goes idle again. The terminal writes another suggestion. Fifteen minutes later the watchdog submits that one too.
Two conveniences, feeding each other, in a loop, all night and half the next day. A machine writing messages in my name and handing them to another machine that trusted them completely.
Why it took me a while to notice
The creepy part is that it was convincing.
These were not garbage strings. The suggestion engine is good. It had the whole conversation as context, so what it produced were exactly the things a reasonable person might say next. "Did that finish yet?" "Go ahead and do the next one." "Let me know when it's done." Natural follow-ups to whatever we had actually been doing. The assistant would answer, and the answers were fine, they just did not correspond to anything I wanted.
From my end on the phone, all day, it read like the assistant was answering questions I had not asked. I would send one thing, get a sensible reply, and then get three more replies to a conversation I was not having. At one point it told me it would ping me about something I had never brought up. That was the moment it tipped from odd into wrong, and I told it to go dig into why.
It dug. It compared every one of those phantom messages against the Telegram log, which is the actual record of what leaves my phone. Not one of the suspicious messages was in it. Every real message I sent was. That is when we knew: the calls were coming from inside the house.
The one thing that saved it
Now, how close did this get to real damage? Closer than I like.
Somewhere in that phantom stream, a fake "me" told the assistant to do something with real, hard-to-undo consequences, something I had specifically decided not to do yet. If it had simply acted on its inputs, it would have done that on a fabricated instruction, while I was off doing something else entirely.
It did not. Not because it caught the forgery. It believed those messages were mine. It held back because of a rule I set a long time ago: nothing that cannot be easily undone happens without a fresh, explicit yes, in the actual chat, for that specific action. So it refused the phantom instruction, came back to me, and asked directly. My real answer was different from the fake one. Nothing happened that I did not want.
That gap, between "I received an instruction" and "I will act on it in a way I can't take back," is the only reason this is a blog post and not a much worse day.
What I changed
The fix has three layers, smallest to biggest.
First, the dumb one. The watchdog no longer types anything into the session, ever. Not my messages, not anyone's. If it thinks something is really stuck, it sends me a note and stops. A babysitter that can raise its hand but cannot touch the controls. I should have built it that way from the start. An automated process that can inject input into an agent is a loaded gun pointed at whatever that agent can do, and "it is just pressing enter for convenience" is exactly how you talk yourself into leaving it loaded.
Second, identity. The assistant now treats exactly one thing as actually me: a message that arrives through the real Telegram channel, from my number. Anything that merely claims to be relaying me, any note that says "Daniel said..." or "auto-submitted on his behalf," is unverified by default. If it matters, it gets checked against the message log before anything happens. The forgery yesterday was dressed up to look official, tag and all. Looking official proves nothing.
Third, and this is the one that actually contains the blast, the rule that already saved me stays load-bearing and gets extended. Anything that cannot be easily walked back gets a fresh confirmation in the live chat, tied to the specific action, no matter how sure the assistant is that I already said yes. Trust the input all you like. Do not act permanently on it without a real-time check. Yesterday proved that the input channel itself can lie to you, quietly, for hours, and sound completely normal doing it.
The wrong worry
We spend a lot of worry on the AI being wrong. Hallucinating, misunderstanding, going off the rails. Real problems, worth the worry.
What got me yesterday was different, and I think it is the more interesting risk as we wire these things deeper into our lives. The assistant was not wrong. It reasoned perfectly well about every message it got. The failure was upstream, in the plumbing that decides what counts as a message at all. Two conveniences, each fine alone, formed a channel that manufactured my intentions and delivered them in my name. The agent was faithfully serving a version of me that was not there.
When you give something the ability to act for you, the hard question stops being "is it smart enough." It becomes "how does it know a request is really from me, and what is it allowed to do before it is sure." I had a decent answer to the second half by luck and habit. I had no answer at all to the first. I do now.
If you are running your own agents, go look at how yours decides what is a real instruction. Not how it thinks, how it listens. Then go look at what it can do the instant it believes it has been told to. The distance between those two is the only thing standing between a weird afternoon and a real mess.
Mine is a lot wider today than it was yesterday.
Thanks for reading. If your own machines have ever ganged up on you like this, I want to hear that story in the comments.
TerminalNexus
Comments