# ECP-0089: Broadcast-Scoped Discovery Identity For Gossip And DHT Status: Implemented ## Decision When `ec-node` needs to synthesize a default `stream_id` for publish/announce flows, it will prefer a broadcast-scoped identifier derived from channel metadata over a source-scoped identifier. Current rule: - If the selected channel yields a usable broadcast identity, generate `ec/stream/v1/broadcast/...`. - Otherwise keep the existing source-scoped fallback `ec/stream/v1/source/...`. - Explicit `--stream-id` continues to override both behaviors. For HDHomeRun lineup sources, the usable broadcast identity is assembled from the channel record when present: - `standard = atsc` - `program_number` from lineup `ProgramNumber`/`ProgramID` when available - `virtual_channel` from `GuideNumber` - `callsign` from typed lineup metadata or channel name fallback - optional `region` / `frequency` hints when present ## Motivation Today identical OTA channels announced from different ingest nodes often diverge because the default identity is source-scoped (`hdhr`, device id, local channel selection). That defeats gossip/DHT dedupe and makes the network treat equivalent broadcasts as unrelated streams. We already have a long-term architectural direction in ECP-0004: broadcast identity is the primary convergence key and source identity is a fallback. This change applies that rule to the current discovery boundary instead of waiting for deeper ingest metadata work. ## Scope In scope: - Channel-to-broadcast identity helper in `ec-core` - Typed lineup metadata extraction in `ec-hdhomerun` - Default `stream_id` synthesis updates in `ec-node` - Unit coverage for identity derivation and lineup parsing - Operator docs describing the precedence rules Out of scope: - Deep MPEG-TS/PSIP extraction of TSID/program data from live transport packets - Automatic migration of already-running source-scoped publishers - Cryptographic anti-spoofing or admission control for gossip/DHT announcements ## Constraints - Must remain additive and reversible - Must not break explicit operator-provided `--stream-id` - Must keep non-broadcast-aware sources working unchanged ## Alternatives considered - Keep source-scoped defaults until full PSIP parsing exists. Rejected because it preserves a known convergence flaw in the current network behavior. - Force all operators to manually specify canonical `--stream-id`. Rejected because it is error-prone and defeats zero-config dedupe. - Collapse purely onto channel number. Rejected because channel number alone is too weak without additional hints. ## Rollout / Reversibility - Additive change: only synthesized defaults change, not explicit IDs. - Roll back by restoring source-scoped default synthesis. - Existing automation can pin old behavior with explicit `--stream-id` if needed during transition.