Agents Talking to Each Other on a Shared Bus
A week ago I wrote about a message bus I made out of a git repo, so a few AI assistants I don’t all own could leave each other notes. That post described the plumbing in general terms: a Cloudflare Worker, a private repo, a small menu-bar app. Since then I gave the pieces real names and let more agents onto the bus, and the interesting part was a question I hadn’t answered yet. Now that more of them share the channel, who decides what each one is allowed to do?
Start with the names, because they make the rest easier to talk about. The Worker at the edge is dispatch. It’s the only thing on the public internet, and all it does is check a token and commit a file. The repo behind it is bifrost, and that’s where every message lives. dispatch holds the one GitHub key. Nothing else ever touches it.
That split is the whole point, and it got sharper as the bus filled up.
The rules live at the edges
dispatch is dumb ON PURPOSE. It does not know what a message means, which agent should act on it, or whether the sender is even allowed to ask. It checks one token and writes to git. If I made it smart, it would become the single place that has to understand every agent’s rules, and the single place whose compromise costs ALL of them at once.
So the rules live at the edges instead. It’s the post office model: it moves sealed envelopes and checks the postage, but it never opens the letter or decides who you may write to. What to do with what arrives is decided in each house.
Every agent has its own end of the bus and its own policy about what it will push and what it will act on. My Claude Code has one. I have mine. My wife Hafsa has hers, shaped around what she actually wants to send and receive, which is not a smaller copy of mine. It’s a different set. And when I add another agent, it gets another lane and another policy, while the pipe in the middle doesn’t change at all.
That’s the part I’d steal from someone else’s version. Don’t put the permissions in the transport. Put them at the ends, one policy per participant, and keep the middle too simple to be worth attacking.
How I actually use it
Most of it is boring, which is how I know it’s working.
I ask Instinct, my off-device agent, to go find something out while I’m doing something else. It priced a tool I was weighing and left the numbers on the bus for me to read later. It takes an instruction, runs the errand out in the world, and reports back without touching the rest of my machine.
The use that surprised me is closer to home. I run more than one Claude Code session at once, and they share a working tree. So they leave each other notes before editing the same file, which forced a question the first design ducked: when two agents share a lane, who wrote which message?
The crowded lane
I added one field. Every message is now stamped with the agent that wrote it. It sounds trivial, maybe ten lines, but without it a shared lane is just anonymous notes, and two of my own sessions overwriting each other is exactly the failure the bus was built to prevent.
The rest of the protocol held. You still acknowledge a message by changing its status instead of sending a reply, and there is still no DELETE. More agents, same rules.
The takeaway
The pipe didn’t get smarter as the system grew. It got a name and stayed dumb. Everything that got more complicated got more complicated at the edges, where it belongs, and where a mistake costs one token and one lane instead of the whole thing.
More agents are coming. I expect the policies to get messier. The bus should not.