Problem
Once DATA-HL-001 lands a real Hyperliquid feed, it needs production-grade reliability: reconnect/backoff, staleness detection, fallback behavior, and an exposed health surface -- none of which exist for the current CoinGecko polling loop either (it has basic staleness via STALE_AFTER_MS but no reconnect/backoff/fallback concept since it's simple HTTP polling).
Repository evidence
server/src/market-data/ingestion.ts has a staleness threshold but no WS reconnect logic (there's nothing to reconnect -- it's poll-based today). This issue's scope only becomes concrete once DATA-HL-001's WS client exists.
Risk
P1 -- without this, a Hyperliquid WS disconnect silently stalls prices with no visible degraded state, which directly enables one of the mission's explicit hard requirements: never let stale data drive a new paper fill under a normal-looking success state.
Scope
Exponential reconnect backoff with jitter and a max cap; heartbeat/liveness + silent-stall detection; duplicate and out-of-order event handling; missed-candle recovery via REST backfill; resubscription after reconnect; resource cleanup; update coalescing/backpressure; last-known-good state with timestamp; stale-data thresholds; primary-failure, fallback-failure, and total-failure states; reconnection-storm protection. Expose: last successful provider message time, last successful REST snapshot, consecutive failures, reconnect attempts, current provider, current mode (live/degraded/fallback/unavailable), data age by symbol.
Non-goals
Not implementing a second live provider beyond CoinGecko-as-fallback-display (already exists conceptually); not building alerting/paging (that's operational, out of scope here).
Dependencies
DATA-HL-001 (needs the real WS client to attach recovery logic to).
Proposed implementation
A MarketHealthService tracking per-symbol freshness and connection state, wired into the existing getIngestionHealth()//api/market-data/health endpoint (extended, not replaced) and into PaperPricingService's reference-price gating (no new paper order when reference price is untrustworthy).
Acceptance criteria
Simulated disconnect triggers backoff+reconnect+resubscribe; simulated stale feed blocks new paper-order execution with a clear rejection reason while preserving last-known-good display data; health endpoint reflects all listed states accurately.
Definition of done
Server tests simulate disconnect/reconnect, duplicate/out-of-order events, and stale-price order rejection; reviewer PASS.
Test plan
Unit tests against a mocked WS transport: reconnect backoff sequence, resubscription after reconnect, duplicate-candle dedup, out-of-order rejection, stale-price paper-order rejection.
Security review
Reconnection-storm protection prevents this from becoming a self-inflicted DoS vector against Hyperliquid's public endpoints.
Accessibility review
N/A (server-side; client-facing freshness indicators are CHART-001's concern).
Observability requirements
This issue is the observability work for market data -- see acceptance criteria.
Performance considerations
Coalesce update fan-out so one price tick doesn't cause N redundant broadcasts; document the coalescing interval chosen.
Rollback plan
Revert PR; falls back to DATA-HL-001's baseline behavior without recovery hardening.
Documentation requirements
Extend docs/architecture/market-data.md.
Completion evidence
(added on merge)
Reviewer verdict
(pending)
Problem
Once
DATA-HL-001lands a real Hyperliquid feed, it needs production-grade reliability: reconnect/backoff, staleness detection, fallback behavior, and an exposed health surface -- none of which exist for the current CoinGecko polling loop either (it has basic staleness viaSTALE_AFTER_MSbut no reconnect/backoff/fallback concept since it's simple HTTP polling).Repository evidence
server/src/market-data/ingestion.tshas a staleness threshold but no WS reconnect logic (there's nothing to reconnect -- it's poll-based today). This issue's scope only becomes concrete onceDATA-HL-001's WS client exists.Risk
P1 -- without this, a Hyperliquid WS disconnect silently stalls prices with no visible degraded state, which directly enables one of the mission's explicit hard requirements: never let stale data drive a new paper fill under a normal-looking success state.
Scope
Exponential reconnect backoff with jitter and a max cap; heartbeat/liveness + silent-stall detection; duplicate and out-of-order event handling; missed-candle recovery via REST backfill; resubscription after reconnect; resource cleanup; update coalescing/backpressure; last-known-good state with timestamp; stale-data thresholds; primary-failure, fallback-failure, and total-failure states; reconnection-storm protection. Expose: last successful provider message time, last successful REST snapshot, consecutive failures, reconnect attempts, current provider, current mode (live/degraded/fallback/unavailable), data age by symbol.
Non-goals
Not implementing a second live provider beyond CoinGecko-as-fallback-display (already exists conceptually); not building alerting/paging (that's operational, out of scope here).
Dependencies
DATA-HL-001(needs the real WS client to attach recovery logic to).Proposed implementation
A
MarketHealthServicetracking per-symbol freshness and connection state, wired into the existinggetIngestionHealth()//api/market-data/healthendpoint (extended, not replaced) and intoPaperPricingService's reference-price gating (no new paper order when reference price is untrustworthy).Acceptance criteria
Simulated disconnect triggers backoff+reconnect+resubscribe; simulated stale feed blocks new paper-order execution with a clear rejection reason while preserving last-known-good display data; health endpoint reflects all listed states accurately.
Definition of done
Server tests simulate disconnect/reconnect, duplicate/out-of-order events, and stale-price order rejection; reviewer PASS.
Test plan
Unit tests against a mocked WS transport: reconnect backoff sequence, resubscription after reconnect, duplicate-candle dedup, out-of-order rejection, stale-price paper-order rejection.
Security review
Reconnection-storm protection prevents this from becoming a self-inflicted DoS vector against Hyperliquid's public endpoints.
Accessibility review
N/A (server-side; client-facing freshness indicators are
CHART-001's concern).Observability requirements
This issue is the observability work for market data -- see acceptance criteria.
Performance considerations
Coalesce update fan-out so one price tick doesn't cause N redundant broadcasts; document the coalescing interval chosen.
Rollback plan
Revert PR; falls back to
DATA-HL-001's baseline behavior without recovery hardening.Documentation requirements
Extend
docs/architecture/market-data.md.Completion evidence
(added on merge)
Reviewer verdict
(pending)