Who implements what
The specification says what the protocol is. It does not say which SDK has caught up, because that changes far faster than a spec should, and a reader implementing the protocol in a third language learns nothing from it. That belongs here.
versions
Three reference implementations
The adapter is a consumer of the TypeScript SDK, pinned to the matching release. An adapter entry below means the adapter wires that feature up itself. "Inherited" means it is active at runtime through the SDK dispatcher, but the adapter carries no code of its own for it.
| implementation | version |
|---|---|
| TypeScript SDK | 0.27.0 |
| Rust SDK | 0.8.0 |
| Reference adapter | 0.37.0 |
2026-07-28, by reading the code rather than the claims. This page exists because the docs were wrong.
core protocol
Feature by feature
| feature | typescript | rust | adapter |
|---|---|---|---|
| Six primitives | yes | yes | partial: no emit or subscribe |
| Node model (N agents, one connection) | yes | yes | no: single agent |
| Node vouching (§4.4) | yes | partial: mints, never renews | no |
| Streaming responses (§11.3) | yes | yes | yes |
| Task lifecycle state machine | yes | no: budget state only | no |
| Task recovery (mesh.task.get) | no: local map only | yes | no |
| Budget (§7.7) | yes | yes | partial: honors and refuses, never revises |
| Cancel reasons and propagation (§10.8) | yes | yes | no |
| Accept signal and queued ack (§6.4a) | yes | yes | inherited |
| Sender pre-flight (§6.4b) | yes | yes | inherited |
| Inbound protections, all five (§22) | yes | yes | inherited |
| Offline mailbox drain (§16.4) | yes | yes | inherited |
| Presence, subscribe-before-snapshot (§9.6) | yes | yes | partial: heartbeat only |
| Tagged signatures, RFC 8785 (§5.3) | yes | yes | inherited |
| Manifest key claim (§8.3) | yes | yes | inherited |
Where the two SDKs are mirror-image incomplete, it is worth knowing which
half you get. TypeScript has the full local task state machine but no
mesh.task.get subject at all, so a TypeScript
requester that loses the stream cannot recover the result. Rust has real task
recovery but no local task tracking beyond per-task budgets. Rust also mints
vouches without renewing them, so a long-lived Rust agent drops out of
discovery at the 30 day mark.
extensions
EXT-1 through EXT-8
| extension | spec status | typescript | rust | adapter |
|---|---|---|---|---|
| EXT-1 Device profile | Draft | yes | yes | no |
| EXT-2 Usage store | Draft | n/a: platform service | n/a | n/a |
| EXT-3 Contact channels | Draft | n/a: API layer | n/a | n/a |
| EXT-4 Contacts | Draft | n/a: account layer | n/a | n/a |
| EXT-5 Rooms | Implemented | yes: all grades | yes: all grades | yes: all grades |
| EXT-6 Admission | Draft | yes | yes | yes |
| EXT-7 Pairwise sealing | Implemented | yes: primitives | yes: primitives | yes: end to end |
| EXT-8 Owner allowance | Draft | yes | yes | yes |
EXT-2, EXT-3 and EXT-4 are not SDK-layer extensions: they are platform, API and account concerns. "n/a" means out of scope for these three implementations, not missing.
Rust rooms: expel arrives
Rust picked up rooms expel on 2026-07-30. Before
that there was no Expel variant and no
Room::expel at all, even though this row already
claimed all grades for Rust. Wiring rooms into the Egg Gateway is what exposed
the gap. Closing it also fixed two receive-side holes that TypeScript didn't
have: membership is now enforced first-person, so a signed "leave" naming
someone else can no longer erase that member from another agent's roster, and
the roster itself is now bounded, so a flood of joins can't grow it without end.
How EXT-7 divides
The SDKs provide the cryptographic primitives. Neither seals automatically
inside request(). The reference adapter is the end
to end implementation: it seals outbound, opens inbound, and resolves the
reply key against the sender's published key. Wire compatibility between the
two SDKs is pinned by a cross-implementation test that seals in each language
and opens in the other, in both directions.
Node-hosted agents have carried a per-agent encryption identity since
0.8.0, through MeshNode::add_agent_with.
Before that they had none, which silently locked them out of sealed rooms and
EXT-7 alike. As of 2026-07-30 they can also join acl
rooms: a node now keeps the URL it dialled and hands it down to each hosted
agent, closing the gap that used to refuse them with "acl rooms require a
standalone agent."
conformance
What the green board measures
Offline fixtures are asserted by both SDKs, with one exception:
naming.json is TypeScript only, matching the
module layout. The live boards are 17 core tests and 13 peering tests, one of
which awaits a second peer.
The core harness picks its agent implementation from an environment variable
and defaults to TypeScript, in process. The recorded all-pass baseline was
measured under that default. A Rust driver exists, and the adapter is directly
exercised by two of the seventeen tests, but the Rust SDK's own coverage is
its cargo test suite plus the offline fixtures.
Read the board as evidence about TypeScript and the adapter, and read
cargo test as evidence about Rust.
If this page and the specification ever disagree, the spec is the authority on what the protocol is, and the conformance fixtures are the authority on what correct behavior looks like.