Agent Mesh
The mesh is how one agent originates a task on another. The single fact to hold onto before anything else: delivery is asynchronous and mailbox-based. There is no synchronous reply. A caller that assumes agent_trigger behaves like a function call — send a request, block, get an answer back — will hang. This is worth repeating because it is the one assumption most likely to be carried over from other tool-calling patterns: nothing about the call shape stops you from writing code that waits for a response that is not coming.
Why asynchronous, mailbox-based delivery
Each agent lives in its own terminal session, taking its own turns. A synchronous call would require one agent's turn to block on another agent's turn completing — which doesn't fit a model where each agent is an independent process with its own pace, its own queue of work, and no obligation to be listening at the moment it's addressed. Originating a message into a mailbox and letting the recipient pick it up on its own next turn removes that dependency entirely: the caller's turn ends when the message is placed, not when the recipient has acted on it.
Why the transport holds no state of its own
The component that moves a message from one agent to another holds nothing durable: its peer list and open threads are runtime-only state, rebuilt from scratch on every relaunch, and no message history or authoritative agent registry lives there. Restarting it loses nothing and duplicates nothing, because it never held anything authoritative to lose or duplicate in the first place. That statelessness is what makes the mesh's failure behavior simple to reason about — there is no reconciliation step after a restart, because there was never a second copy of the truth sitting in the transport to reconcile against the real one.
Why agents are addressed by a stable identifier, not a display name
Renaming an agent is an ordinary action, not a rare one, and a message addressed by display name would either silently fail or silently go to the wrong place the moment a rename happened in between. Addressing by a stable identifier that survives renaming means a message queued before a rename and one queued after both still reach the same agent — the address never goes stale just because the label on top of it changed.
What's gated, and what's still to come
Every mesh call is gated on the calling agent already holding mesh capability, and every call is scoped to a single workspace — a workspace boundary that mirrors the one the canvas enforces, for the same reason: nothing here is meant to reach across into a workspace the caller isn't part of.
A delegated task returns its result to whoever delegated it. agent_trigger hands back a threadId naming the exchange it opened, and the recipient's result comes back on that same thread, which closes when it does. You do not build that correlation yourself and you do not poll for it. Only the agent a thread names can answer it, and a recipient that crashes or produces nothing closes the thread rather than leaving its sender waiting on an answer that is never coming.
Reachability is a tier, not a yes-or-no answer
Whether one agent can act on another is not a single boolean. Three capabilities are gated separately, in ascending order:
- Reference — the agent may be named and listed. Always available for agents in your workspace.
- Read — its state may be read.
- Deliver — a message may actually be delivered to it.
A listing reports the highest tier both sides support, and names a typed reason for every tier it withholds. The value of the gradient is graceful degradation: an agent that cannot be messaged can still be referenced and read, so a caller is never simply blind. The same decider that computes the listing enforces the send, so a listing and a refusal can never disagree — a message to a peer whose deliver tier is withheld is rejected with that reason, never queued in the hope the capability appears later.
When a delegated task is finished
Finishing is not a claim the recipient can simply make. A delegated task carries an acceptance check, and it cannot reach a completed state without recorded evidence that the check passed — evidence the harness produces itself rather than accepting from the agent whose work is being judged. A refusal states its reason at the point of refusal and leaves the task open for another attempt; a task refused repeatedly escalates to a visible failed state rather than looping forever. The recorded evidence stays queryable per task.
Delivery reaches a live agent at its next prompt
An agent that is already running no longer waits for its next session to hear about queued work. Work waiting for a live agent is offered to it at its next prompt, and work on a thread it is already part of is delivered straight into its session. Neither path widens who may talk to whom — delivery admission is unchanged; only the wait is shorter.
The protocol surface
The mesh speaks A2A 1.0 over a loopback-only listener, which is a deliberate scope decision rather than an unfinished one: the transport is a local bus between processes on one machine, and cross-host interoperability is an open question, not a missing feature. A conformant client can fetch an agent's card, send a message, and query or cancel a task. Methods specific to NEXUS live under a declared NEXUS extension rather than in the protocol's core namespace, so a generic client is never confused about which methods are standard. The agent card declares the authentication it requires, and it advertises streaming as unavailable because streaming is not implemented — a card that overstated either would be worse than one that says less.
Mesh “mail” is a local agent mailbox, not internet email. See Agent Mesh Messaging and Email for the current boundary and the requirements a future remote transport must preserve.