4.3 KiB
Spec — network-discovery-hybrid
- Capability:
@suaveplan/network-discovery-hybrid - Tier: browser
- Status: SHIPPED 2026-05-11
- Genesis path:
packages/network/network-discovery-hybrid
ADDED Requirements
Requirement 1 — Multi-Strategy Composition
The package SHALL ship a HybridDiscoveryManager that composes any subset of the five Wave-2 sibling discovery strategies (peerjs / crdt / trystero / webtorrent / gundb) plus arbitrary caller-supplied strategies behind a single DiscoveryStrategy contract from @suaveplan/network-bootstrap.
Scenario 1: Composite Discovery
- WHEN a
HybridDiscoveryManageris configured with two strategies andstart()+discover(timeoutMs)is called - THEN the manager fans
discover()out across every active strategy and returns the merged + deduplicated peer set.
Requirement 2 — Priority-Based Strategy Selection
The orchestrator SHALL support a three-bucket strategy priority — primary, fallback, backup — and SHALL initialise strategies in priority order.
Scenario 1: Priority-Ordered Initialisation
- WHEN strategies are registered with mixed priorities
- THEN
initializeAll()runs every primary first, then every fallback, then every backup.
Requirement 3 — Per-Strategy Health Tracking
The orchestrator SHALL maintain a StrategyHealth record for every registered strategy with rolling success-rate (EMA, α = 0.3), consecutive-failure counter, last-error string, and active flag.
Requirement 4 — Automatic Fallback
The orchestrator SHALL, when autoFallback is enabled and a primary becomes unavailable, initialise the next dormant non-primary strategy in priority order.
Scenario 1: Fallback Promotion
- WHEN a primary strategy reports
isAvailable() === false - AND at least one non-primary strategy is dormant
- THEN the orchestrator initialises the dormant strategy AND emits
hybrid:fallback{from,to}AND incrementshybrid.fallback_total{from,to}.
Requirement 5 — Deduplicated Peer Set with PeerSource Provenance
The orchestrator SHALL maintain a deduplicated peer set keyed by PeerInfo.peerId with PeerSource.discoveredBy recording the ordered set of every strategy that has observed the peer.
Scenario 1: Append-Only Provenance
- WHEN the same peer is observed by two different strategies
- THEN the second observation appends to
discoveredByAND retains the originalprimaryStrategy.
Requirement 6 — Optional Peer-Deps with Graceful Degradation
The package SHALL declare every sibling discovery strategy as peerDependenciesMeta.<name>.optional: true. A StrategyConfig.factory whose dynamic import() rejects SHALL be recorded as STRATEGY_LOAD_FAILED and the strategy MUST be marked unhealthy WITHOUT aborting start() for the remaining strategies.
Requirement 7 — Lifecycle FSM
The orchestrator SHALL expose idempotent start(), stop(), and dispose() methods. After dispose() every method SHALL throw NetDiscHybridError(DISPOSED).
Requirement 8 — Error Registry
The package SHALL emit the six frozen codes NO_STRATEGIES, ALL_STRATEGIES_DEGRADED, STRATEGY_LOAD_FAILED, DUPLICATE_STRATEGY, INVALID_OPTIONS, DISPOSED via defineCodes("NET_DISC_HYBRID", [...]) and surface them through NetDiscHybridError extends SuaveplanError.
Requirement 9 — OpenTelemetry Instrumentation
The orchestrator SHALL emit the following instruments under tracer + meter name @suaveplan/network-discovery-hybrid:
hybrid.peer_sources_total{strategy}counterhybrid.strategy_health_score{strategy}histogramhybrid.fallback_total{from,to}counterhybrid.active_strategies{strategy}up-down counterhybrid.discover_duration_ms{outcome}histogramhybrid.startandhybrid.discoverspans
Requirement 10 — Test-Time Real-Implementation Fixture
The package SHALL ship a real-implementation TestStrategy fixture under tests/setup/test-strategy.ts that fully implements the DiscoveryStrategy contract deterministically.
The package SHALL NOT contain any vi.mock, jest.mock, __mocks__/ directory, or : any cast in production src/ code.
Requirement 11 — 100% Coverage
The package SHALL pass bunx turbo test:coverage --filter=@suaveplan/network-discovery-hybrid at 100% statements, branches, functions, and lines.