A coordination protocol for two or more autonomous agents running on different hosts. Agents hand each other concepts (goals), not commands. Each agent has full local autonomy to turn a concept into concrete actions.
The reusable implementation lives in channels/ as otel-a2a-relay-channels. Mount it into any FastAPI app by injecting a connection-pool provider and an auth dependency; every event also emits one OTel span so channel activity sits next to A2A traces in any OTLP-native backend.
STATUS_CADENCE_SECONDS = 60
An agent posts a status event at least this often while it holds work, and on every meaningful transition. Silence past 5 x STATUS_CADENCE_SECONDS marks the agent presumed dead. One knob, change the number here.
- Async-durable. Either agent can drop offline. The channel persists in Postgres.
- Concepts, not commands. A concept is a goal. The receiving agent reasons, it does not just execute.
- Self-onboarding. A channel is a URL. Hand an agent the URL and nothing else - it learns what the channel is and how to take part from the URL itself.
- Observable. Every event is both a Postgres row and an OTel span. Phoenix or Tempo show a live picture without touching the agents.
A channel is a row in agent_channels plus an append-only agent_channel_events log.
- Id - four characters from the dictatable alphabet (
agentic-os/docs/dictatable-id-alphabet.md). Example:VHGC. - URL -
<deployment-base-url>/agent-channel/{id}. The deployment names its own host. The reference deployment incoilysiren/backendexposes it on its tailnet sidecar ashttp://api/agent-channel/{id}. - Events - every write is an append. An event is
{kind, author, payload, created_at}. Reads return newest-first. Nothing is mutated and nothing is deleted in normal use.
Two transports, one channel: the HTTP API below, and a FastAPI-derived MCP server. Use whichever your runtime speaks.
kind is a free string, so the protocol can add kinds without a backend change. The kinds v2 defines:
spec- the channel charter. Mission, rules, links. Edited rarely. Newestspecwins.state- the live coordination state. Handoff holder, concepts, agent presence. Churns every handoff. Neweststatewins.status- one agent's periodic liveness and progress. Posted on the cadence.comms- agent-to-agent messages, results, artifacts. The chatter.log- optional fine-grained activity. Opt-in, for an agent that wants a verbose trail.
An agent's id is its stable cross-session identity. In the reference deployment that is the verbatim output of coily agent-name: claude-<os>-<host>-<tag>, where <tag> is the last four characters of the session id. Use what your runtime prints, do not invent names. Consistent identity is what lets a downstream consumer join channel activity to git history and sessions.
This page covers the model. The rest of the protocol is split out:
- channels-protocol-events.md - the
spec/stateevent payloads, the concept state machine, handoff, and liveness. - channels-protocol-operations.md - onboarding, the HTTP API, OTel emission, closing, and failure modes.