// AZ-675 telemetry_stream — operator-bound gRPC contract. // // One service, one bi-directional Subscribe RPC. Client opens a stream // declaring which topics it wants; server pushes messages for those // topics until the client disconnects. // // The server enforces per-client back-pressure: when a client cannot // keep up the oldest message in *that client's* queue is dropped and // a per-(client, topic) drop counter is incremented. Other clients // are unaffected. // // AZ-676 will add the video path (separate RPC, server-streamed binary // frames). AZ-677 will add the MapObjectsBundle snapshot RPC. Keep // those concerns out of this contract. syntax = "proto3"; package autopilot.telemetry.v1; // Topics a client can subscribe to. Repeated in SubscribeRequest so a // single stream multiplexes whichever subset the client cares about. enum Topic { TOPIC_UNSPECIFIED = 0; TOPIC_TELEMETRY_SAMPLE = 1; TOPIC_GIMBAL_STATE = 2; TOPIC_DETECTION_EVENT = 3; TOPIC_MOVEMENT_CANDIDATE = 4; TOPIC_MAP_OBJECTS_BUNDLE = 5; } message SubscribeRequest { // Operator/client identifier. Plumbed into per-client drop counters // and log lines. Free-form for AZ-675; AZ-678 (operator command // auth) will tighten the format. string client_id = 1; repeated Topic topics = 2; } // Each message carries the topic tag + an opaque JSON payload. We // don't pin schemas per topic in proto here because the canonical // payload shapes are already authoritative in `crates/shared/models` // (TelemetrySample, GimbalState, DetectionEvent, MovementCandidate, // MapObjectsBundle). Using JSON keeps the wire honest with what the // rest of the system already serializes; if a topic later needs // schema enforcement, add a typed message variant in a future bump. message TelemetryMessage { Topic topic = 1; // Monotonic nanoseconds since the autopilot process started. Used // by the operator for ordering and latency measurement. uint64 monotonic_ts_ns = 2; // Server-side per-client sequence number. Strictly increases per // (client, topic) stream; gaps imply drops. uint64 sequence = 3; // Serialized JSON payload (utf-8). Topic determines the shape. bytes payload_json = 4; } service TelemetryStream { // Server-streaming subscribe. The client sends ONE SubscribeRequest; // the server pushes TelemetryMessage values until the client cancels // the stream or the server shuts down. The server applies per- // client drop-oldest back-pressure if the client cannot keep up. rpc Subscribe(SubscribeRequest) returns (stream TelemetryMessage); }