# Phase 4: Combined WebSocket Streams - Context

**Gathered:** 2026-03-24
**Status:** Ready for planning

<domain>
## Phase Boundary

Migrate from per-symbol WS connections to Binance combined streams (2x9 hybrid architecture) with resilient reconnection maintaining Stathera continuity. This is a major infrastructure change requiring thorough validation, rollback capability, and iterative hardening.

**Critical user guidance:** This phase must include rollback recourse if combined streams don't perform as well as per-symbol connections. An additional follow-up phase is needed to wire up monit, Telegram notifications, heartbeat checks, and monitoring specifically for the new combined stream architecture.

</domain>

<decisions>
## Implementation Decisions

### D-01: Rollback-first design

The combined stream implementation must coexist with the existing per-symbol connection code. A configuration flag (env var or sidecar config) must allow switching between per-symbol and combined modes without code changes. This allows reverting in production if combined streams degrade quality.

### D-02: Follow-up phase for monitoring integration

After Phase 4 implements the core combined stream logic, a follow-up phase (Phase 4.1 or similar) should wire up:

- Monit watchdog checks for combined stream health
- Telegram notifications for stream reconnections
- Heartbeat checks for combined stream liveness per connection
- Connection count reporting in `/health` endpoint
- 24+ hour production validation period

### D-03: Thorough validation and iterative hardening

Phase 4 verification must include:

- A/B comparison: per-symbol vs combined stream Stathera continuity
- Ring buffer overflow check with all 18 symbols on 2 connections
- Reconnection behavior under simulated disconnects
- Multiple rounds of verification before declaring success

### Claude's Discretion

- Exact stream grouping strategy for the 2x9 split (by liquidity, alphabetical, etc.)
- Whether to use Rust-side or Python-side combined stream management
- Antaeus backoff parameters (base delay, max delay, jitter range)
- Feature flag mechanism (env var name, default behavior)

### Carrying forward

- Per-partition locks (Phase 1) — concurrent write safety
- Stathera continuity validation (Phase 2) — validates junction integrity
- Parquet-first catchup (Phase 3) — startup optimization still applies
- Existing Antaeus reconnection in `opendeviationbar-providers` — exponential backoff pattern

</decisions>

<canonical_refs>

## Canonical References

**Downstream agents MUST read these before planning or implementing.**

### WebSocket architecture

- `crates/opendeviationbar-providers/CLAUDE.md` — Binance WS architecture, spot-only policy, stream management
- `crates/opendeviationbar-streaming/` — Rust streaming crate
- `CLAUDE.md` §"Spot-Only Data Source Policy" — combined WS streams (`stream.binance.com`)

### Sidecar integration

- `python/opendeviationbar/sidecar/CLAUDE.md` — sidecar module map, WS lifecycle
- `python/opendeviationbar/sidecar/__init__.py` — WS start, main loop
- `src/stream_manager_bindings.rs` — StreamManager PyO3 bindings

### Existing spike

- `.claude/skills/full-symbol-streaming-spike/SKILL.md` — prior spike for combined streams (Phase 1 SOLUSDT POC, Phase 2 Rust combined, Phase 3 all 18 symbols)

### Monitoring (for follow-up phase reference)

- `deploy/CLAUDE.md` — monit watchdog config
- `scripts/heartbeat/CLAUDE.md` — heartbeat checks
- `python/opendeviationbar/notify/CLAUDE.md` — Telegram notifications

</canonical_refs>

<code_context>

## Existing Code Insights

### Reusable Assets

- `BinanceWebSocketStream` in providers crate — existing WS connection abstraction
- Antaeus reconnection logic — exponential backoff with jitter already implemented
- `StreamManager` — manages WS lifecycle from Python
- Full-symbol-streaming spike — prior investigation with approach options

### Established Patterns

- Sidecar WS lifecycle: start buffered → fill_from_rest → start streaming
- Combined stream URL: `wss://stream.binance.com/stream?streams=sym1@aggTrade/sym2@aggTrade/...`
- Binance limit: 200 streams per connection (18 symbols = well within 1 connection, 2x9 for redundancy)
- Per-symbol Argus liveness checks

### Integration Points

- `StreamManager` — Python↔Rust bridge for WS lifecycle
- Sidecar `__init__.py` — WS start call site
- `/health` endpoint — connection count reporting
- Heartbeat checks — per-symbol liveness

</code_context>

<specifics>
## Specific Ideas

- The full-symbol-streaming spike SKILL.md has detailed approach options — researcher should read it
- 2x9 split (not 1x18) provides redundancy: if one connection drops, 9 symbols briefly gap-fill while reconnecting, not all 18
- Feature flag should default to per-symbol (existing behavior) until combined is validated in production

</specifics>

<deferred>
## Deferred Ideas

### Phase 4.1: Combined WS Monitoring Integration

Wire up monit, Telegram notifications, heartbeat checks, and monitoring for combined stream architecture. Track connection count, per-connection symbol health, reconnection events. This is a separate phase from the core implementation to keep Phase 4 focused on the stream migration itself.

</deferred>

---

_Phase: 04-combined-websocket-streams_
_Context gathered: 2026-03-24_
