# Pre-Flight MapObjects Snapshot + In-Flight Diffs + Reconnect Resync

**Task**: AZ-677_telemetry_stream_mapobjects_snapshot
**Name**: MapObjects bundle: pre-flight snapshot + in-flight diff stream + reconnect re-snapshot
**Description**: Emit a full `MapObjectsBundle` snapshot on operator client connect/reconnect, then stream diff messages as the store appends new observations / ignored items. On client reconnect after disconnect, emit a fresh snapshot rather than trying to replay diffs.
**Complexity**: 3 points
**Dependencies**: AZ-640_initial_structure, AZ-675_telemetry_stream_grpc_server, AZ-667_mapobjects_store_hydrate_and_pending
**Component**: telemetry_stream
**Tracker**: AZ-677
**Epic**: AZ-637

## Problem

The operator views the live map state. Sending the entire `MapObjectsBundle` on every change is wasteful, but streaming diffs without a baseline forces the operator to recover from missing state on reconnect. The pattern: snapshot on connect, then diffs while connected. On disconnect-then-reconnect, treat as fresh client → re-snapshot. No best-effort gap-filling.

## Outcome

- On client subscribe to `MapObjectsBundle` topic: read current store state via `MapObjectsStore::snapshot()`; emit one `MapObjectsBundleSnapshot` message.
- During the session: subscribe to the store's append log (pending_observations + pending_ignored streams); emit `MapObjectsDiff { added: [...], moved: [...], removed_candidates: [...], ignored: [...] }` messages.
- On client disconnect: drop the subscriber.
- On reconnect: treat as new subscribe; emit a fresh snapshot. NO diff replay.
- Health: `mapobjects_snapshot_bytes`, `mapobjects_diff_count`, `mapobjects_resnap_count`.

## Scope

### Included
- Snapshot emission on subscribe.
- Diff stream from store append log.
- Re-snapshot on reconnect.

### Excluded
- Store implementation (task 28).
- Per-client subscriber state machine (task 36).

## Acceptance Criteria

**AC-1: First subscribe receives snapshot**
Given a store with 50 MapObjects + 10 IgnoredItems hydrated
When a client subscribes to the MapObjectsBundle topic
Then it receives exactly one `MapObjectsBundleSnapshot` containing 50 + 10 entries.

**AC-2: In-flight changes emit diffs**
Given a connected client
When 3 new observations and 1 ignored item are appended to the store
Then the client receives one or more `MapObjectsDiff` messages whose combined contents = `{added: 3, ignored: 1}`.

**AC-3: Reconnect re-snapshots**
Given a client disconnected mid-session and the store grew by 5 entries while disconnected
When the client reconnects
Then the client receives a fresh `MapObjectsBundleSnapshot` reflecting the current state; NO diff replay.

## Non-Functional Requirements

**Performance**
- Snapshot serialization: ≤200 ms p99 for ≤10 000 MapObjects.
- Diff fan-out: ≤2 ms p99 per append.

## Runtime Completeness

- **Named capability**: snapshot + diff transport for MapObjects.
- **Production code that must exist**: real snapshot emission; real diff streaming; real re-snapshot on reconnect.
- **Unacceptable substitutes**: emitting full snapshots on every change (bandwidth) or replaying diffs across reconnect (consistency hazard) are both unacceptable.
