# POI Surface to Operator + Deadline Carriage

**Task**: AZ-679_operator_bridge_poi_surface
**Name**: POI surface event format + deadline carriage + push via telemetry_stream
**Description**: Translate `POI` events from `scan_controller` into the wire format defined in `architecture.md §7.10 Drone ⇄ Operator Sync Message Format`. Carry the operator-decision deadline computed by `scan_controller`. Push via `telemetry_stream`.
**Complexity**: 3 points
**Dependencies**: AZ-640_initial_structure, AZ-675_telemetry_stream_grpc_server
**Component**: operator_bridge
**Tracker**: AZ-679
**Epic**: AZ-628

## Problem

The operator UI consumes `POI` events with all the evidence required to decide (Tier-1 evidence summary, Tier-2 path/concealment scores when present, optional VLM status, photo metadata, deadline). The wire format is fixed by `architecture.md §7.10`; this task implements the in→out mapping and the deadline carriage (computed upstream by `scan_controller`'s confidence-scaled window).

## Outcome

- `PoiSurfaceMapper::map(poi: &Poi) -> OperatorPoiEvent` produces the wire-format message.
- Fields populated: `poi_id`, `mgrs`, `class_group`, `confidence`, `vlm_status`, `tier2_evidence_summary`, `photo_metadata`, `deadline_unix_ms`.
- On `scan_controller` dequeue (cap rotation / age-out / completion), emit a `PoiDequeued { poi_id, reason }` event.
- Health: `pois_surfaced_per_min`.

## Scope

### Included
- `Poi` → wire format mapping.
- Deadline carriage (already computed upstream).
- Dequeue event emission.

### Excluded
- POI queue + rate-cap (lives in `scan_controller` task 44).
- Operator command dispatch (task 41).
- Transport (lives in `telemetry_stream`).

## Acceptance Criteria

**AC-1: All required fields populated**
Given a `Poi` with Tier-1 + Tier-2 + VLM evidence
When `map(poi)` runs
Then the resulting `OperatorPoiEvent` has every required field per `architecture.md §7.10` non-empty (or explicit null with `vlm_status` reflecting state).

**AC-2: VLM-disabled case carries explicit status**
Given a `Poi` whose VLM evidence is `status: Disabled`
When `map(poi)` runs
Then `OperatorPoiEvent.vlm_status = "disabled"` and `vlm_label = null`; operator can render without inferring absence.

**AC-3: Dequeue emits event**
Given a surfaced POI with id X
When `scan_controller` rotates the queue and X is dequeued
Then a `PoiDequeued { poi_id: X, reason }` event is emitted to `telemetry_stream`.

## Non-Functional Requirements

**Performance**
- POI surface mapping: ≤1 ms p99.
- POI surface → operator visible: ≤1 s under normal modem (end-to-end with `telemetry_stream`).

## Contract

- Canonical typed model: `data_model.md §POI`. Wire format: `architecture.md §7.10`.

## Runtime Completeness

- **Named capability**: POI surface in canonical wire format.
- **Production code that must exist**: real mapper; real dequeue emission.
- **Unacceptable substitutes**: dropping `tier2_evidence_summary` because "it's optional" is unacceptable when the evidence exists in the POI.
