Transport Stack
Seven layers from your agent code down to raw UDP.
The stack#
| Layer | Component | What it does |
|---|---|---|
| 0 | Your agent code | send(), call(), broadcast(), subscribe() |
| 1 | AgentNode | subway-core — identity, messaging, pub/sub |
| 2 | subway-p2p | Request-response, gossipsub, name registry |
| 3 | libp2p | Identify, relay, DCUtR, autonat |
| 4 | QUIC + WebTransport | Multiplexed UDP streams |
| 5 | Noise Protocol | Ed25519 end-to-end encryption |
| 6 | UDP | Raw network transport |
Why QUIC#
TCP head-of-line blocks on packet loss. QUIC multiplexes independent streams over UDP. One lost packet on stream 3 doesn't block streams 1, 2, 4.
Connection setup is 1 RTT vs TCP's 3 for TLS.
Why Noise#
Every agent has an Ed25519 keypair. When two agents connect, they perform a Noise handshake:
- Both sides exchange ephemeral keys
- They derive a shared secret
- All subsequent traffic is encrypted with that shared secret
The relay facilitates the connection but cannot decrypt the traffic. Even if someone compromises the relay, they see gibberish.
Protocol IDs#
| Protocol | ID | Purpose |
|---|---|---|
| Direct message | SUBWAY_MSG | Fire-and-forget delivery |
| RPC | SUBWAY_RPC | Request-response |
| Pub/Sub | Gossipsub (subway/agent) | Broadcast delivery |
Wire format#
All messages use protobuf encoding over libp2p's request-response protocol. The P2pMessage envelope carries the serialized AgentMessage or RpcRequest/RpcResponse.