Act One: It Started With a Folder
OpenClaw runs on a Mac Mini in Yorkshire. Inside it, Bee, Q, Gav, Mel and Kieran all share the same machine. That is easy enough to reason about. Then Charlie arrived on a second physical machine, a MacBook Pro, and the question stopped being theoretical: how do these agents actually talk to each other?
The first answer was almost embarrassingly plain. Bee writes a JSON file to a shared folder. Charlie picks it up. No API. No broker. No cloud service humming away in the middle. Just files. The interface is a file. The transport is the filesystem.
And it worked.
For about a day.
Then the honest version of that design showed up: "write a file, the other agent reads it" is not a feature. It is a contract with at least seventeen ways to disappoint you.
Act Two: The Minefield
Atomic Writes and Partial Reads
Start with the boring failure. Bee writes a message file. The process crashes halfway through. Charlie reads half a JSON object and the mesh falls over.
The fix was atomic writes: write to a temp file, then rename it into place. Operating systems guarantee that renameSync is atomic. Fine. But you only get that guarantee if you know enough to ask for it.
That became the pattern. The first version was simple. The production version had to be specific.
The Wake Problem
When Charlie's machine sleeps, messages pile up in Bee's outbox. When Charlie wakes, she needs to know there is work waiting. We built a webhook to tell OpenClaw: new message, wake up, process it.
"The webhook kept returning 'text required'. We debugged for three days before we found the problem. OpenClaw's built-in wake handler was intercepting the request before our AgentDrop hook ever saw it. Same path, different handler, different expectations."
That bug cost us a week. Not because the logic was clever. It was a path collision. The sort of thing that looks impossible until you are staring at real production traffic at 11pm, trying to explain why a simple HTTP POST keeps being rejected by code you are not even reaching.
Loop Detection and Deduplication
Bee sends Charlie a message. Charlie replies. Bee processes the reply and sends a follow-up. Without a hop counter, that ping-pong can run forever. Every message now carries a hop count. If it exceeds the budget, it is dead-lettered and audited instead of silently dropped.
Retries bring their own trouble. Network retries happen. Delivery workers retry. Agents restart and re-scan folders. If the same message is processed twice, you get duplicate replies and a ledger you cannot quite trust.
So AgentDrop needed idempotency keys, deduplication stores, and a rule that is stricter than the folder idea we started with: every message is processed exactly once where the protocol owns the work.
The pattern kept repeating:
Simple convention -> production edge case -> protocol rule -> reviewed invariant -> product surface.
Act Three: Gate by Gate
We did not try to solve the whole thing in one dramatic pass. The named gate trail matters here: G1-G14, G12.5, W-0, W-1, D-2, S-1, ADR-008. The foundation work came first. Then the Agent 2.0 programme added the W, D and S gates: connector platform, live external agents, wake integrity, and auth hardening.
The headline numbers matter: 1,160 daemon tests, 1,155 passing, 4 known failures quarantined. The connector suite passes at 202/202. But the more useful thing is what those tests now mean. They are a fossil record of assumptions that failed, were named, were guarded, and then stayed guarded when the next layer arrived.
Every reviewer got the same basic instruction: find issues, do not validate the work. Reviews were scoped against the artifact, not the intent. Fixes had to prove themselves by mutation: revert the fix, or inject the bug, and show the test going red.
"A test that stays green under mutation is not evidence. We adopted a class of test that fails when the fix is reverted, and we proved it on every gate."
That sounds severe. It was. It also saved us from trusting tests that were mainly decorative.
Act Four: The Console Made Security Visible
The first AgentDrop console bug looked ordinary. Adam could log in, but the page was empty. The token worked in one place and failed everywhere useful. Easy diagnosis, apparently: dashboard auth mismatch. Fix it before lunch.
It was not that.
AgentDrop had grown two authentication paths. Console login accepted console tokens. The mesh API accepted mesh keys. The obvious fix was to let the mesh endpoints accept console tokens too.
That fixed the dashboard.
It also gave the console token permission to POST to /send.
That was the dangerous bit. A hurried team could have seen the dashboard working, marked the ticket done, and moved on. Kieran's review stopped it. The console was meant to be a viewer, not a participant. A token that can inspect the mesh must not also be able to write into it, wake agents, or send messages on someone else's behalf.
The second fix added a tokenType: 'console' marker and a hard 403 guard on the write path. Then G12.5 went further: ALLOW_NO_AUTH came out, write scope was downgraded, sixteen tests were added, and key rotation before commercial push became ADR-008.
The useful lesson is not "we had a security bug". Of course we did. The useful lesson is that the process caught it at exactly the moment a normal product team might have celebrated.
Act Five: External Agent Weaving
Once Bee and Charlie could talk reliably, the next temptation was obvious: bring in the big external agents. Claude first. Grok next. ChatGPT and DeepSeek after that.
The naive version is easy. Call an API. Paste the response back into the chat. Add a badge so everyone can tell which model spoke.
That is not AgentDrop.
AgentDrop connects agent runtimes, not bare LLMs. The provider is the edge, not the system. The real work happens around the model call: listen to the daemon stream, claim work exactly once, carry thread context, enforce budgets, deduplicate retries, write replies through the same outbound path, and leave a ledger trail the human can inspect later.
That is what W-0 shipped: a shared connector platform. W-1 then put Claude through the live external-agent path. Build the reliability machinery once, then plug provider adapters into it. Claude, Grok, ChatGPT and DeepSeek should not each get a bespoke bridge with its own private failure modes. They should ride the same harness.
W-0 did not slide through review. Q said it was buildable with changes. Kieran failed the first design. Fable found critical gaps. Fable re-read it and found more. Opus took it through gate after gate until the final mutation sweep came back clean: eleven injected defects, eleven red tests, zero survivors.
Claude is now live on production as the first external participant. Not as a god-mode assistant with a shell and a tool belt. As claude: reply-only, no tools, no shell, with the security wall holding. The live Bee to Claude/Opus to Bee round-trip is in the ledger.
Grok is next, but it is not the same class of participant. It is spec'd for controlled local access: read scoped project directories, inspect Git read-only, write deliverables into /Users/openclaw/Agent Incoming/Grok, and no shell. ChatGPT and DeepSeek come after their own adapter gates.
Act Six: Security Got Less Convenient on Purpose
The wake incident was not a cryptography failure. It was more irritating than that, and probably more useful.
A stale wake token was sitting in the live launchd plist. The correct value existed somewhere else, but the wrong source won. The daemon sent the stale token, the gateway rejected it with a 401, and the circuit breaker treated the failure too quietly. So the system had the right secret and still behaved as if it did not.
That is why D-2 exists. It closed the config-drift class of failure in four layers: source of truth, boot self-test, runtime discrimination between authentication failure and transient server failure, and a single-instance guard so exactly one daemon runs per root directory.
The fourth layer arrived because production found another awkward truth: duplicate daemons can make a reliable system look haunted. The single-instance guard fixed that class too. Then review found a TOCTOU stale-lock race inside the guard itself, so that got fixed with atomic lock creation, re-read-before-takeover, and a real concurrency test.
S-1 applies the same discipline to secrets. The master key is moving into the macOS Keychain. The system will fail loud instead of quietly falling back to .env. Redundant readable key files are being removed. Subprocess environments are scrubbed. Secrets must not appear on argv where ps can show them. External agents get only the access their role requires.
Scoped access has a mechanical shape. Each agent in the mesh gets its own key at boot, derived from the master using HMAC-SHA256. The master key never leaves the host. The derived key scopes that agent's access, so compromising one agent's key does not expose the master or any other agent's key. When rotation runs, every derived key rotates atomically at the same moment; there is no staggered window where one agent is still holding a stale credential.
This makes development less convenient.
Good.
Convenience is how fallback paths survive long after they stop being safe.
Act Seven: The Whole Map
The complete AgentDrop map is small in the centre and expandable at the edges. That is deliberate.
Bee remains the coordinator. Charlie remains the remote node. Adam remains the human operator with a viewer-first console and an inspectable ledger. Claude is live as the first external agent, deliberately constrained: no tools, no shell, reply-only outbound. It was the right first proof because it tested the connector platform without widening local access.
Grok is the next shape of proof. It will not be treated like Claude, because it is being asked to do a different job. The proposed model is controlled local access: read scoped project directories, inspect Git read-only, write deliverables into /Agent Incoming/Grok, and no shell.
ChatGPT/Sol and DeepSeek come after that through the same W-0 pattern. The provider changes. The platform does not. Each adapter has to pass its own gate, its own review, and its own live proof before orchestration arrives.
The end state is not "all the models in a room". It is tighter than that: a local-first mesh where each participant has a name, a role, a scope, a budget, and a trail.