Peat mesh sidecar — a Rust binary that runs alongside applications in Kubernetes pods, participates as a full CRDT mesh node (Automerge + Iroh QUIC), and exposes a gRPC API for co-located apps to read/write shared state that syncs across clusters.
Primary integration target: UDS Fleet Management — provides the DDIL-resilient transport layer between edge agents and the Fleet Command Hub.
graph TB
subgraph pod["Kubernetes Pod"]
app["Your Application<br/>(any language)"]
subgraph sidecar["peat-node"]
grpc["gRPC API :50051<br/>21 RPCs: documents, peers,<br/>subscriptions, sync control"]
crdt["CRDT Store<br/>(Automerge)"]
transport["P2P Transport<br/>(Iroh QUIC)"]
grpc --> crdt --> transport
end
app -- "gRPC client" --> grpc
end
transport -. "Iroh QUIC<br/>(relay or direct)" .-> other["Other peat-node<br/>instances on<br/>other clusters"]
Documents written on one cluster automatically sync to all connected peers via Automerge CRDT — no central server, works through network partitions, eventually consistent.
When deployed alongside UDS Remote Agent, the sidecar's agent watcher polls the agent's existing Connect RPC APIs and syncs fleet state across clusters:
graph TB
subgraph alpha["Edge Cluster Alpha"]
agentA["UDS Remote Agent :8080"]
sidecarA["peat-node :50051<br/>Polls /status, ListPackages<br/>Writes to CRDT store"]
sidecarA -- "Connect RPC<br/>(same as CLI/UI)" --> agentA
end
subgraph bravo["Edge Cluster Bravo"]
agentB["UDS Remote Agent :8080"]
sidecarB["peat-node :50051<br/>Polls /status, ListPackages<br/>Writes to CRDT store"]
sidecarB -- "Connect RPC<br/>(same as CLI/UI)" --> agentB
end
sidecarA <-- "Iroh QUIC<br/>CRDT sync" --> sidecarB
Query either sidecar to see fleet-wide agent state from both clusters.
Zero modifications to UDS Remote Agent required. The watcher uses the same Connect RPC protocol (connect.WithGRPC() over HTTP/2) as the uds-agent-cli and web UI.
| Data | CRDT Collection | Source API |
|---|---|---|
| Agent health, K8s version, architecture | platforms/{agent-id} |
GET /status |
| Deployed packages (name, version, status) | deployments/{agent-id}:{pkg} |
ListPackages |
| Pulled/cached packages | packages/{agent-id}:{ref} |
ListPulledPackages |
- Agent settings (registry credentials) — security boundary
- Active pod status — cluster-local, from K8s informers
- In-flight deployment progress — transient
| Test | Result |
|---|---|
| Single sidecar smoke test (put/get/delete/subscribe) | Pass |
| Two-node bidirectional CRDT sync | Pass (sub-second sync) |
| Real UDS Remote Agent + watcher + mesh sync (local processes) | Pass |
| Two k3d clusters, each with UDS Remote Agent + peat-node sidecar | Pass |
| In-cluster Helm deployment watching agent via cluster DNS | Pass |
# Build
cargo build --release
# Run standalone
./target/release/peat-node \
--listen tcp://0.0.0.0:50051 \
--data-dir /tmp/peat-node \
--node-id my-node \
--auto-sync
# Run with agent watcher (watches local UDS Remote Agent)
./target/release/peat-node \
--listen tcp://0.0.0.0:50051 \
--agent-addr http://localhost:8080 \
--agent-poll-interval 10 \
--auto-syncThe sidecar exposes peat.sidecar.v1.PeatSidecar with 21 RPCs:
| Category | RPCs |
|---|---|
| Lifecycle | GetStatus |
| Peers | ConnectPeer, DisconnectPeer, ListPeers |
| Documents | PutDocument, GetDocument, DeleteDocument, ListDocuments |
| Typed Collections | PutPlatform, GetPlatforms, PutCell, GetCells, PutTrack, GetTracks, PutCommand, GetCommands |
| Subscriptions | Subscribe (server-streaming) |
| Sync Control | StartSync, StopSync, GetSyncStats |
Proto definition: proto/sidecar.proto
docker build -t peat-node:latest .
docker run -p 50051:50051 peat-node:latest --listen tcp://0.0.0.0:50051helm install peat-node chart/peat-node/ \
--namespace peat-system --create-namespace \
--set listen=tcp://0.0.0.0:50051# Deploy peat-node watching the agent via cluster DNS
helm install peat-node chart/peat-node/ \
--namespace peat-system --create-namespace \
--set listen=tcp://0.0.0.0:50051 \
--set agentAddr=http://uds-remote-agent-svc.zarf.svc.cluster.local:8080 \
--set agentPollInterval=10The chart provides injectable templates for adding peat-node as a container in any pod:
# In a parent chart's deployment.yaml:
containers:
- name: my-app
...
{{- include "peat-node.container" .Subcharts.peat-node | nindent 8 }}
volumes:
{{- include "peat-node.volumes" .Subcharts.peat-node | nindent 8 }}# Build the Zarf package
zarf package create .
# Deploy to a UDS cluster
zarf package deploy zarf-package-peat-node-*.tar.zst --confirmThe UDS bundle enables the UDS Package CR (NetworkPolicies for Iroh QUIC mesh traffic):
cd bundle && uds create . && uds deploy uds-bundle-peat-node-*.tar.zst --confirmAll flags can be set via environment variables with PEAT_NODE_ prefix:
| Flag | Env Var | Default | Description |
|---|---|---|---|
--listen |
PEAT_NODE_LISTEN |
tcp://0.0.0.0:50051 |
gRPC listen address |
--data-dir |
PEAT_NODE_DATA_DIR |
/data/peat-node |
Persistent data directory |
--node-id |
PEAT_NODE_NODE_ID |
Random UUID | Node identifier |
--app-id |
PEAT_NODE_APP_ID |
peat-default |
Formation/group ID |
--shared-key |
PEAT_NODE_SHARED_KEY |
Base64 shared key | |
--peer |
PEAT_NODE_PEERS |
Peer endpoint IDs (comma-separated) | |
--auto-sync |
PEAT_NODE_AUTO_SYNC |
true |
Start sync on boot |
--agent-addr |
PEAT_NODE_AGENT_ADDR |
Service to watch (e.g. http://localhost:8080) |
|
--agent-poll-interval |
PEAT_NODE_AGENT_POLL_INTERVAL |
10 |
Poll interval (seconds) |
See docs/DESIGN.md for:
- Relationship to UDS Fleet Management architecture
- How Peat provides the DDIL-resilient transport layer
- Agent watcher design (maps heartbeat data to CRDT collections)
- Connected vs DDIL operation modes
- Fleet state propagation options (A through D)
- Air-gap / tablet mesh bridge scenario
| Path | Description |
|---|---|
proto/sidecar.proto |
gRPC service definition |
src/main.rs |
CLI + server bootstrap |
src/node.rs |
SidecarNode (Automerge + Iroh mesh stack) |
src/service.rs |
gRPC service implementation |
src/watcher.rs |
Agent watcher (Connect RPC poller) |
chart/peat-node/ |
Helm chart (deployment, service, UDS Package CR, injectable sidecar templates) |
bundle/uds-bundle.yaml |
UDS bundle |
zarf.yaml |
Zarf package config |
Dockerfile |
Multi-stage build (debian:bookworm-slim) |
docs/DESIGN.md |
Architecture and integration design |
test/go/ |
Go client library + integration tests (smoketest, synctest, watchertest, query, cluster e2e) |
| Project | Description |
|---|---|
| peat | Decentralized mesh protocol (Rust) |
| test/go/ | Go client library + integration tests (in this repo) |
| uds-remote-agent | UDS Remote Agent (primary integration target) |
| peat-registry | OCI registry sync (validates the sidecar pattern) |
| Issue | Description |
|---|---|
| peat#747 | peat-node umbrella |
| peat#748 | Agent watcher |
| peat#750 | Cluster-to-cluster test |
| peat#751 | Fleet state propagation design |
| uds-remote-agent#533 | FleetService (future agent-side APIs) |
