# Component — `detection_client` **Layer**: Perception (data plane in) **Status**: forward-looking design (Rust) ## 1. Purpose Bi-directional gRPC client to the external `../detections` service. Streams frames out, receives bounding-box detections back. Same bboxes are reused by `semantic_analyzer` (Tier 2 ROI selection) and by `telemetry_stream` (operator overlay). This is the only component in autopilot that talks to `../detections`. ## 2. Inputs | Input | Source | Cadence | Notes | |---|---|---|---| | `Frame` | `frame_ingest` | up to 30 fps | Skipped when `ai_locked` is set. | | Tier-1 service config | startup config | once | gRPC endpoint, TLS settings, request budget, max concurrent streams. | ## 3. Outputs | Output | Consumer | Shape | |---|---|---| | `DetectionBatch` | `scan_controller`, `semantic_analyzer`, `telemetry_stream` | `{ frame_seq: u64, detections: Vec, latency_ms, model_version }` | | Health metric | health aggregator | gRPC connection state, `requests_in_flight`, `latency_p50/p99`, `errors_by_kind`, `model_version`. | `Detection` mirrors the `../detections` contract: `{ class_id, class_name, confidence, bbox_normalized, optional_mask_or_polyline, source_frame_seq }`. ## 4. Key Responsibilities - Maintain a single bi-directional gRPC stream to `../detections`. Reconnect on stream loss with bounded exponential backoff. - Frame budgeting: respect the Tier-1 ≤100 ms/frame target by dropping older in-flight frames if a new frame arrives before the previous response (configurable). - Validate the response payload against the schema version the client was built against. Surface a hard error on schema mismatch; do not silently downcast. - Tag each `DetectionBatch` with the source frame's monotonic timestamp so downstream consumers can compute end-to-end latency. ## 5. Internal State - gRPC channel, stream handle, reconnect state. - Sliding window of in-flight frame sequence numbers. - Last-known model version (echoed by `../detections` on each response or on stream init). State is in-process only. ## 6. Failure Modes | Failure | Detection | Behaviour | |---|---|---| | `../detections` unreachable | gRPC connect error | Bounded exponential backoff; health → red after threshold; `scan_controller` continues but the `detection_client` health flag is red. | | Mid-stream cancellation by server | stream error | Reopen stream; do not lose frames in flight (best-effort retry on the latest only). | | Schema mismatch | response decode error | Hard error to the health aggregator; reject the response; alert. | | Model version change at runtime | new `model_version` on the stream | Log it; if the change implies new classes, surface to `scan_controller` so per-class thresholds can be reloaded. | | Consistent latency above budget | `latency_p99 > 100 ms` over a sliding window | Health → yellow; `scan_controller` may degrade to alternate-frame inference. | ## 7. Dependencies **In-process**: `frame_ingest` (input), `scan_controller` / `semantic_analyzer` / `telemetry_stream` (output). **External**: - `../detections` gRPC service. Contract owner: `../_docs/03_detections.md`. Bi-directional streaming. ## 8. Non-Functional Targets | Concern | Target | |---|---| | Per-frame round-trip latency | ≤100 ms (Tier-1 NFR; mostly owned by `../detections`, autopilot's call budget respects it) | | Reconnect latency | ≤2 s after `../detections` returns | | Throughput | up to 30 fps at 1080p | | Backpressure | drop oldest in-flight rather than queue indefinitely | ## 9. Open Questions - Versioning strategy of the gRPC contract (covered in `architecture.md §8 Q4`). ## 10. References - `architecture.md §1`, `§3`, `§7.6`. - `system-flows.md §F1`. - `../_docs/03_detections.md`. - `data_model.md §Detection`, `§DetectionBatch`.