# Phase 7: Heartbeat Unified Per-Symbol View - Context

**Gathered:** 2026-03-25
**Status:** Ready for planning
**Source:** AskUserQuestion flow in conversation

<domain>
## Phase Boundary

Merge the Yesterday and Junction sections of the heartbeat Telegram message into a single exception-only display. Expand yesterday check from hardcoded BTC/ETH to all enabled Binance spot symbols (dynamically from `symbols.toml`). Replace raw TID dumps in junction with delta-only computation.

</domain>

<decisions>
## Implementation Decisions

### Layout: Exception-only display

- When ALL symbols are clean (yesterday=no gaps, junction delta=0): show one summary line like `✅ 16/16 symbols clean (0 gaps, 0 overlaps)`
- When issues exist: show summary count + expand only the problematic symbols with detail
- Example: `⚠️ 14/16 clean, 2 issues:\n  ❌ XRPUSDT: yest gap=1 (tid 697869399)\n  ⚠️ BCHUSDT: junction gap=42 trades`

### Junction: TID delta only

- Compute `delta = ws_first_tid - rest_last_tid - 1` per symbol
- delta=0 means zero-gap handoff (clean)
- Only show raw TIDs when delta != 0 (for debugging)
- Remove the current wall of raw TID numbers entirely

### Symbol scope: Dynamic from registry

- Use `get_heartbeat_symbols()` (already in heartbeat config.py, queries `symbols.toml`)
- No hardcoded symbol lists — respects SSoT
- Exness forex symbols excluded (no `agg_trade_id`, can't do Stathera)

### Claude's Discretion

- Section naming in the formatter (e.g., "Yesterday + Junction" vs "Per-Symbol Health")
- How to handle the case where junction data is unavailable (sidecar just started, no junction yet)
- Whether to keep the current separate Freshness section or fold freshness age into the per-symbol line

</decisions>

<canonical_refs>

## Canonical References

### Heartbeat check modules

- `scripts/heartbeat/checks/yesterday.py` — current yesterday completion check (BTC/ETH only)
- `scripts/heartbeat/checks/junction.py` — current junction check (raw TID display)
- `scripts/heartbeat/formatter.py` — message formatting with section layout
- `scripts/heartbeat/config.py` — `get_heartbeat_symbols()`, health level keys

### Registry SSoT

- `python/opendeviationbar/data/symbols.toml` — symbol registry

</canonical_refs>

<specifics>
## Specific Ideas

- The heartbeat already has `get_heartbeat_symbols()` returning all enabled Binance spot symbols (v5.0 Phase 4)
- Yesterday check currently only runs for BTC/ETH (hardcoded in `yesterday.py`) — needs to use `get_heartbeat_symbols()`
- Junction check currently dumps raw TIDs from sidecar `/status` endpoint — needs delta computation
- Both checks write to the shared `results` dict which the formatter reads

</specifics>

<deferred>
## Deferred Ideas

- Folding Freshness section into the per-symbol view (keep separate for now)
- Adding historical trend (e.g., "clean for 3 days") to the summary line

</deferred>

---

_Phase: 07-heartbeat-unified-per-symbol-view_
_Context gathered: 2026-03-25 via AskUserQuestion flow_
