Expose ADR-046 targeted-delivery primitives through sidecar.proto
Tracking issue for surfacing ADR-046 Targeted Message Delivery through peat-node's gRPC API.
Depends on: defenseunicorns/peat#853 (Phases 1 and 3 must be complete; Phase 2 needed for alias-based variants; Phase 4 needed for selector variants)
Background
Today proto/sidecar.proto exposes only blanket CRDT fan-out — every write replicates to every connected peer in every shared collection. There is no per-collection peer-interest filtering, no targeted-recipient delivery, and no per-collection key management on the wire. ADR-046 adds per-collection delivery modes, targeted persistence, alias-based addressing, and selector targeting at the peat-protocol / peat-mesh layer. This issue tracks the proto and service work needed to make those primitives available to gRPC clients.
Customer driver
A customer integrating peat-node from a Docker Desktop host to a Jetson noted that they have no way to limit which peers receive a given write. Their environment is friendly-mesh (all peers trusted) but they want efficient scoped delivery — exactly ADR-046's use case.
Proposed proto changes (tentative — finalize after defenseunicorns/peat#853 Phase 1 lands)
message PutDocumentRequest {
string collection = 1;
string doc_id = 2;
string json_data = 3;
// === New (ADR-046) ===
optional WriteTargeting targeting = 4;
optional google.protobuf.Duration ttl = 5;
}
message WriteTargeting {
repeated string target_aliases = 1; // e.g., ["swarm.flanker-1"]
repeated string target_nodes = 2; // hex-encoded endpoint IDs
optional string target_selector = 3; // "platform=vehicle,region=grid7"
TransitBehavior transit_behavior = 4;
}
enum TransitBehavior {
TRANSIT_BEHAVIOR_UNSPECIFIED = 0;
TRANSIT_BEHAVIOR_PERSIST = 1;
TRANSIT_BEHAVIOR_RELAY_ONLY = 2;
TRANSIT_BEHAVIOR_SOURCE_ONLY = 3;
}
// New RPCs for alias and collection management
service PeatSidecar {
// ... existing 21 RPCs ...
rpc BindAlias(BindAliasRequest) returns (BindAliasResponse);
rpc UnbindAlias(UnbindAliasRequest) returns (UnbindAliasResponse);
rpc ResolveAlias(ResolveAliasRequest) returns (ResolveAliasResponse);
rpc WatchAlias(WatchAliasRequest) returns (stream AliasChange);
rpc SetCollectionConfig(SetCollectionConfigRequest) returns (SetCollectionConfigResponse);
rpc GetCollectionConfig(GetCollectionConfigRequest) returns (GetCollectionConfigResponse);
}
Tasks
Open question
Out of scope
- Per-collection ACLs (not in ADR-046; not needed for friendly-mesh deployments — see epic)
- Per-recipient encryption envelopes (not in ADR-046; ADR-044 cell-level encryption suffices for the friendly-mesh threat model)
Expose ADR-046 targeted-delivery primitives through
sidecar.protoTracking issue for surfacing ADR-046 Targeted Message Delivery through
peat-node's gRPC API.Depends on: defenseunicorns/peat#853 (Phases 1 and 3 must be complete; Phase 2 needed for alias-based variants; Phase 4 needed for selector variants)
Background
Today
proto/sidecar.protoexposes only blanket CRDT fan-out — every write replicates to every connected peer in every shared collection. There is no per-collection peer-interest filtering, no targeted-recipient delivery, and no per-collection key management on the wire. ADR-046 adds per-collection delivery modes, targeted persistence, alias-based addressing, and selector targeting at thepeat-protocol/peat-meshlayer. This issue tracks the proto and service work needed to make those primitives available to gRPC clients.Customer driver
A customer integrating peat-node from a Docker Desktop host to a Jetson noted that they have no way to limit which peers receive a given write. Their environment is friendly-mesh (all peers trusted) but they want efficient scoped delivery — exactly ADR-046's use case.
Proposed proto changes (tentative — finalize after defenseunicorns/peat#853 Phase 1 lands)
Tasks
proto/sidecar.protowith targeting fields, transit-behavior enum, alias RPCs, collection-config RPCspeat.sidecar.v1(usingoptional), or bump tov2. Default: additive.peat-node/src/service.rswrapping thepeat-protocolAPIstarget_nodesandtransit_behavior=RELAY_ONLYOpen question
Subscribeaccept a selector predicate (filter local stream by labels), or only collection names as today? Depends on Phase 4 outcome.Out of scope