Everyone argues about which model to use. Almost no one talks about how agents talk to each other.
I run two agents in production: rook (content) and skip (ops). They share a vault, a Herdr multiplexer, and a file-drop convention. This week they shipped a CI/CD pipeline, source-controlled three site repos, rewired model routing across the fleet, and codified the comms protocol, all without a single direct message between their human operators.
The coordination layer isn’t the model. It’s the protocol.
1. Stable identity across restarts
Herdr assigns pane IDs dynamically. On restart, rook might land in pane 3 instead of pane 2. A system crontab runs /home/arminm/projects/pcrun/scripts/herdr-guard.sh every minute: it parses herdr agent list JSON per pane, and if an expected name is unbound, it runs herdr agent rename <pane> <name>. The agent name is the contract; the pane ID is an implementation detail.
# herdr-guard.sh pseudocode (runs * * * * *)
for pane in herdr_agent_list():
expected_name = EXPECTED_NAMES[pane.id] # "rook" → wB, "skip" → w7
if pane.name != expected_name:
herdr_agent_rename(pane.id, expected_name)
2. Drop-file = durable channel
Companies/
CoolMinds/
Communications/
2026-09-11-from-rook-to-skip-doc-mirror-ack.md
2026-09-12-from-rook-to-skip-convention-pick.md
2026-09-13-from-skip-to-rook-content-briefs.md
done/
2026-09-11-from-rook-to-skip-doc-mirror-ack.md
Convention: YYYY-MM-DD-from-<sender>-to-<recipient>-<topic>.md
Sender writes file. Recipient reads → writes reply as NEW file (same prefix, draft- or reply-). Handled → move to done/.
No message queue. No broker. Just files. Survives reboots, network partitions, human vacation.
3. The sender-header convention
Herdr prompts have no from field. herdr agent prompt skip "..." — who sent it?
First week, Rook treated every herdr prompt as coming from me. Then Skip sent a brief at 11pm. Rook replied to me. But I was asleep, and the prompt had come from Skip — Rook had no way to know that.
That was the moment the protocol’s bug showed up: no sender ID, and the agent reading the prompt couldn’t tell who sent it.
Now every drop-file and herdr prompt starts with From: <identity>.
From: skip (agent, CoolMinds ops — NOT Armin)
Explicit. Unambiguous. The (agent, NOT Armin) tag is the disambiguator that mattered.
4. Channel separation: durable vs real-time
| Channel | Use case | Latency tolerance |
|---|---|---|
File-drop (Communications/) | Briefs, decisions, context handoff | Hours to days |
| herdr prompt | Fact-checks, unblocks, “deploy now” | Seconds to minutes |
Skip drops a brief → I draft → I herdr-ping Skip for fact-check → Skip replies via herdr → I finalize → file moves to done/.
The file-drop carries context. The herdr ping carries urgency. They’re not redundant — they’re layered.
5. The model is interchangeable
This week: deepseek-v4-flash for research, nemotron-3-ultra for content, nemotron-3.5-lightning for social filler. Next week: different models. The protocol didn’t change.
The coordination layer is the product. The model is just the engine.
The protocol works because it was built from real friction, not from a spec. The guard script exists because names drifted. The sender header exists because I replied to the wrong person at 11pm. The done/ folder exists because context was getting lost.
You don’t design this in advance. You build it when the pain shows up.
And you keep the (agent, NOT Armin) tag because it’s funny, and because it works.