99 lines
5.3 KiB
Markdown
99 lines
5.3 KiB
Markdown
# OpenSpec Change: network-discovery-hybrid
|
|
|
|
- **Change ID**: network-discovery-hybrid
|
|
- **Package**: `@suaveplan/network-discovery-hybrid`
|
|
- **Category**: browser
|
|
- **Target path**: `packages/network/network-discovery-hybrid`
|
|
- **Status**: PROPOSED
|
|
- **Date**: 2026-05-11
|
|
- **Parent**: `network-transport-family` (2026-05-11) — Wave 2 (last)
|
|
- **Migration source**: `../suaveplan/packages/browser/network-discovery-hybrid` + `../suaveplan/enterprise/network-discovery-hybrid.md`
|
|
|
|
---
|
|
|
|
## Summary
|
|
|
|
Migrate `@suaveplan/network-discovery-hybrid` as the multi-strategy orchestrator that composes any subset of the other five Wave-2 discovery strategies (`peerjs`, `crdt`, `trystero`, `webtorrent`, `gundb`) into a single `HybridDiscoveryManager` with priority-based peer selection, per-strategy health tracking, automatic fallback when a strategy degrades, de-duplicated peer sets, and unified lifecycle. **Last package of Wave 2** because it has hard peer-deps on the other five.
|
|
|
|
---
|
|
|
|
## Why this is last in Wave 2
|
|
|
|
`HybridDiscoveryManager` cannot be meaningfully tested without at least two concrete strategies registered. Landing it after all five sibling packages means integration tests run against the real implementations rather than mocks (which AGENTS.md §0a explicitly bans).
|
|
|
|
---
|
|
|
|
## Current-state audit
|
|
|
|
Upstream source layout (`../suaveplan/packages/browser/network-discovery-hybrid/src/`):
|
|
|
|
- `hybrid-discovery-manager.ts` (217 L) — top-level orchestrator
|
|
- `strategy-manager.ts` (250 L) — health + priority bookkeeping
|
|
- `types.ts` (258 L)
|
|
- `lifecycle.ts` (164 L) — start/stop + transitions
|
|
- `peer-tracker.ts` (145 L) — deduped peer set with sources
|
|
- `strategy-loader.ts` — dynamic strategy loading
|
|
- `__mocks__/strategy-mock.ts` ❌ — direct CLAUDE.md no-mocks violation
|
|
|
|
Upstream coverage: 4 test files (config-advanced, config, integration, runtime). React story without React dep.
|
|
|
|
---
|
|
|
|
## Parity Checklist
|
|
|
|
| Capability | Upstream | Migrated | Notes |
|
|
|---|---|---|---|
|
|
| `HybridDiscoveryManager` composer | ✅ | ✅ | |
|
|
| Priority-based peer selection | ✅ | ✅ | |
|
|
| Per-strategy `StrategyHealth` tracking | ✅ | ✅ | |
|
|
| Automatic fallback on degradation | ✅ | ✅ | |
|
|
| De-duplicated peer set with `PeerSource` provenance | ✅ | ✅ | |
|
|
| Unified lifecycle (start/stop) | ✅ | ✅ | |
|
|
| Dynamic strategy loading | ✅ | ✅ | |
|
|
| `__mocks__/strategy-mock.ts` | ❌ (violates no-mocks rule) | 🚫 | DROPPED. Replaced with a real in-package `TestStrategy` fixture that implements `DiscoveryStrategy` deterministically — no `vi.mock` / `jest.mock`. |
|
|
| `: any` usage in mocks | ❌ | 🚫 | Eliminated as a consequence of the above. |
|
|
| Optional peer-deps on 5 siblings | ✅ | ✅ | `peerDependenciesMeta.{...}.optional: true` per upstream. |
|
|
| Structured errors | 🚫 | ⬆️ | `defineCodes("NET_DISC_HYBRID", [...])`: `NO_STRATEGIES`, `ALL_STRATEGIES_DEGRADED`, `STRATEGY_LOAD_FAILED`, `DUPLICATE_STRATEGY`, `INVALID_OPTIONS`. |
|
|
| Zod boundary validation | 🚫 | ⬆️ | `HybridDiscoveryConfig`, `StrategyConfig`, `StrategyPriority`. |
|
|
| OTel instrumentation | 🚫 | ⬆️ | Counter `hybrid.peer_sources_total{strategy}`, histogram `hybrid.strategy_health_score{strategy}`, gauge `hybrid.active_strategies`. |
|
|
| AbortSignal | 🚫 | ⬆️ | Threaded through every async path. |
|
|
| `export *` barrels | check | ⬆️ | Convert to explicit named exports per §6a. |
|
|
| Test-runner imports | direct vitest | ⬆️ | Rewrite to `@suaveplan/testing/runner` per §7. |
|
|
| 100% test coverage | 🚫 | ⬆️ | Bring to 100/100/100/100 — integration test uses real Wave-2 siblings. |
|
|
| React Storybook story | ✅ (no declared dep) | 🚫 | Dropped — out of scope for headless discovery package. |
|
|
|
|
---
|
|
|
|
## Available workspace deps on genesis
|
|
|
|
- `@suaveplan/network` ✅
|
|
- `@suaveplan/network-bootstrap` ⬅ Wave 1
|
|
- `@suaveplan/service-discovery` ⬅ Wave 1
|
|
- `@suaveplan/network-discovery-peerjs` ⬅ Wave 2 (peer-dep, optional)
|
|
- `@suaveplan/network-discovery-crdt` ⬅ Wave 2 (peer-dep, optional)
|
|
- `@suaveplan/network-discovery-trystero` ⬅ Wave 2 (peer-dep, optional)
|
|
- `@suaveplan/network-discovery-webtorrent` ⬅ Wave 2 (peer-dep, optional)
|
|
- `@suaveplan/network-discovery-gundb` ⬅ Wave 2 (peer-dep, optional)
|
|
- `@suaveplan/types`, `@suaveplan/error`, `@suaveplan/events`, `@suaveplan/timing` ✅
|
|
- `@suaveplan/testing` ✅
|
|
|
|
**Blocking note.** Implementation MUST wait until all five sibling discovery strategies are shipped on genesis (per AGENTS.md §0b — pending dependencies must be migrated first). This proposal is approved but cannot start.
|
|
|
|
---
|
|
|
|
## Acceptance gate
|
|
|
|
1. `bunx turbo lint typecheck test --filter=@suaveplan/network-discovery-hybrid` green.
|
|
2. `bunx turbo test:coverage --filter=@suaveplan/network-discovery-hybrid` 100/100/100/100.
|
|
3. `bun run docs:check` green.
|
|
4. `STATUS.md` row flipped.
|
|
5. Integration test: register all five sibling strategies in a `HybridDiscoveryManager`, verify peer dedup, simulate strategy degradation, observe fallback. **No mocks** — the test uses real strategies against real (loopback) signaling.
|
|
6. Spec: `openspec/specs/network-discovery-hybrid/spec.md` with `## ADDED Requirements`.
|
|
|
|
---
|
|
|
|
## Out of scope
|
|
|
|
- Adding NEW concrete strategies beyond the Wave-2 set (future Wave-9 work).
|
|
- Cross-network federation across multiple hybrid managers (separate proposal).
|