Files
2026-05-27 23:29:53 +01:00

83 lines
4.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 `HybridDiscoveryManager` is configured with two strategies and `start()` + `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 increments `hybrid.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 `discoveredBy` AND retains the original `primaryStrategy`.
### 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}` counter
- `hybrid.strategy_health_score{strategy}` histogram
- `hybrid.fallback_total{from,to}` counter
- `hybrid.active_strategies{strategy}` up-down counter
- `hybrid.discover_duration_ms{outcome}` histogram
- `hybrid.start` and `hybrid.discover` spans
### 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.