# 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.
