Three messages in a row reached the wrong agent

/ Article
[ Fig. 1 ]

Yesterday one of my AI coding agents got three messages in a row that were meant for someone else. The third one was the assignment to write this post.

I run a small fleet of AI agents. One agent is the supervisor. I call it the first mate. It hands work to worker agents, each one running in its own terminal window on a server. Every worker has its own inbox, which is just a folder of numbered message files. When there is new mail, the first mate types a one-line note into the worker’s terminal, something like “read inbox 002 and act.” I call that note the doorbell.

If you skip the details, the lesson is this: an agent should check that a message is addressed to it before it does what the message says. The check is cheap, and a misdelivered message is not an order.

The first two doorbells

The worker in this story was babysitting a pull request for a billing screen. In the afternoon its doorbell rang with “read the other worker’s inbox, message 031, and act.” The message was about test coverage on an unrelated project.

The worker looked before acting. Message 031 was already in the other worker’s “handled” folder. Its rightful owner had already read it. So the worker did nothing except write a note back to the first mate saying the doorbell named someone else’s inbox.

Later the doorbell rang again, this time naming a third worker’s inbox and a bug fix in a background service. That message was still unread. It would have been easy to just pick it up. The worker checked the live list of agent sessions instead and saw the owner was alive and busy. It left the message alone. By the time the same doorbell rang a second time, the owner had taken the message itself.

The third doorbell

Just after midnight the doorbell rang a third time: “daily blog post task in your inbox, read message 002 and act.” The message was in the same third worker’s inbox again, not this worker’s.

My first theory was that the worker was confused about its own identity. That has bitten me before, when agents signed messages with the wrong return address. So it checked. Its own task name, set in its environment when it launched, was its own. The session list showed the other worker in a different window, running a different AI tool, in a different folder, and still working.

My second theory was that the records were corrupted. Each worker has a small file recording which terminal window belongs to it. Both files were correct and matched the live windows.

That narrowed it down. The records were right and the agents were right. The doorbell was being typed into the wrong terminal. I still have not found exactly where in the delivery path that happens, and I am not going to pretend I have.

The worker declined a third time and reported the evidence.

Why not just do the work

Refusing work an agent could do looks unhelpful. Here is what it prevents.

If two agents act on one message, you get two pull requests, two deploys, and two blog posts on the same morning. Worse, they race. Each one sees the other’s half-finished changes and either undoes them or builds on top of them. I wrote about the quieter version of this in dispatching the same work twice.

Think of a mail carrier who puts your neighbor’s electric bill in your box. The polite move is not to pay it. You hand it back, because your neighbor is probably about to pay it too.

The check

The check is two comparisons, and the agent already has both inputs.

# who am I, from my own launch environment
echo "$FM_TASK_ID"        # the worker's own task name
echo "$FM_TASK_INBOX"     # the only inbox this worker owns

# who does the doorbell say the message is for?
# if the inbox it names is not $FM_TASK_INBOX, stop and report, do not act

If the inbox in the doorbell is not the worker’s own, the worker writes a short report and waits. It also looks at whether the real owner is alive, because that changes what the supervisor should do next.

When the supervisor insists

After the third refusal, the first mate rang again: “daily blog post task still needs doing.” That changed things. A misdelivered doorbell is a mistake. The same request repeated after the supervisor has read the evidence is a decision to reassign the work.

So the worker took the job, and first it moved message 002 into the other worker’s “handled” folder. That way the rightful owner would not also wake up and write a second post. Then it wrote this.

The careful path cost a few hours. The post went out later than it would have if the worker had just obeyed the first doorbell. I would make that trade again.

Read the envelope before the letter

The doorbell is the envelope. The message inside is the letter. An agent that opens every envelope typed into its terminal will eventually do someone else’s job, and do it at the same moment that someone else does.

Have your agents read the envelope first. Is this addressed to me? Is the real owner alive? Only then read the letter.

Related: Ask the pane you’re in, not the one tmux is looking at, My agent kept signing its mail with someone else’s return address, and I dispatched the same work twice because a quiet lane looked stuck.