Files
suaveplan/openspec/archive/2026-05-12-enterprise-browser-network-discovery-hybrid/proposal.md
2026-05-27 23:29:53 +01:00

5.3 KiB

OpenSpec Change: enterprise-browser-network-discovery-hybrid

  • Change ID: enterprise-browser-network-discovery-hybrid
  • Package: @suaveplan/network-discovery-hybrid
  • Category: browser
  • Target path: browser/network/network-discovery-hybrid
  • Status: SUPERSEDED-BY-GENESIS-WAVE
  • Date: 2026-04-24
  • Reference spec: /mnt/s/web/suaveplan/enterprise/network-discovery-hybrid.md

Summary

Deliver @suaveplan/network-discovery-hybrid on the genesis branch at enterprise quality. The package composes any subset of the sibling discovery strategies into a single HybridDiscoveryManager with priority-based peer selection, health tracking per strategy, automatic fallback, and de-duplicated peer sets. No __mocks__/ directory, no vi.stubGlobal, no any — tests exercise real DiscoveryStrategy implementations from sibling packages installed as devDependencies.


Current-state audit (genesis)

Fresh build — does not exist on genesis yet.


Available workspace deps on genesis

Package Role
@suaveplan/network (workspace:^) DiscoveryStrategy interface
@suaveplan/error (workspace:^) Typed hybrid errors
@suaveplan/types (workspace:^) LoggerLike
@suaveplan/schema-registry (workspace:^) Config schema registration
zod (catalog:forms) HybridDiscoveryConfig schema
@opentelemetry/api (catalog:observability) Strategy health metrics
tslib (catalog:build) Runtime helpers

Optional peer deps (devDependencies for tests): @suaveplan/network-discovery-peerjs, @suaveplan/network-discovery-trystero, @suaveplan/network-discovery-webtorrent, @suaveplan/network-discovery-crdt, @suaveplan/network-discovery-gundb.

Dev: vitest, @vitest/coverage-istanbul, @suaveplan/testing. React in devDeps for story.


Preserved public API surface (from main branch)

class HybridDiscoveryManager {
  constructor(config: HybridDiscoveryConfig)
  start(): Promise<void>
  stop(): Promise<void>
  getPeers(): PeerInfo[]
  getStrategyHealth(): Record<string, StrategyHealth>
  addStrategy(config: StrategyConfig): void
  removeStrategy(id: string): void
  on(event: HybridDiscoveryEvent, handler: Function): void

  static presets: {
    browserP2P(): HybridDiscoveryConfig
  }
}

interface HybridDiscoveryConfig {
  strategies: StrategyConfig[]
  fallbackOrder?: string[]
  deduplicatePeers?: boolean
}
interface StrategyConfig { id: string; strategy: DiscoveryStrategy; priority: StrategyPriority; enabled?: boolean }
interface StrategyHealth { status: 'healthy' | 'degraded' | 'failed'; peersDiscovered: number; lastError?: Error }
type StrategyPriority = 'high' | 'medium' | 'low' | number
type HybridDiscoveryEvent = 'peer:discovered' | 'peer:left' | 'strategy:health:change' | 'strategy:failover' | 'error'
// + PeerSource, HybridManagerStatus

New additions for genesis

1. No __mocks__/ — real implementations

Tests install sibling discovery packages as devDependencies and instantiate real DiscoveryStrategy objects. A minimal in-tree MemoryDiscoveryStrategy (implements the real interface, not duck-typed) is provided for unit tests.

2. HybridDiscoveryConfig Zod schema

Full config validation; registered in @suaveplan/schema-registry.

3. Typed StrategyLoadError

When a peer-dep strategy is missing, strategy-loader.ts returns a typed STRATEGY_LOAD_FAILED error — never fails silently.

4. Deterministic priority tie-breaking

Equal-priority strategies are ranked alphabetically by id.

5. Back-pressure

Configurable maxPeerEventsPerSecond per strategy; excess events queued or dropped with counter metric.

6. HybridDiscoveryManager.presets.browserP2P()

One-liner wiring PeerJS + Trystero with sensible defaults.

7. Error codes

STRATEGY_LOAD_FAILED, STRATEGY_UNAVAILABLE, HYBRID_NO_HEALTHY_STRATEGY.

8. OTel metrics

Counter discovery.hybrid.strategy_healthy, counter discovery.hybrid.strategy_degraded, counter discovery.hybrid.strategy_failed; histogram discovery.hybrid.failover_ms.


File layout

browser/network/network-discovery-hybrid/
  package.json
  tsconfig.json
  vitest.config.ts
  src/
    index.ts
    error-codes.ts
    hybrid-discovery-manager/
      hybrid-discovery-manager.ts
      hybrid-discovery-manager.md
      hybrid-discovery-manager.types.ts
      hybrid-discovery-manager.test.ts
      index.ts
    strategy-manager/
      strategy-manager.ts
      strategy-manager.md
      strategy-manager.test.ts
      index.ts
    strategy-loader/
      strategy-loader.ts
      strategy-loader.md
      strategy-loader.test.ts
      index.ts
    lifecycle/
      lifecycle.ts
      lifecycle.md
      lifecycle.test.ts
      index.ts
    peer-tracker/
      peer-tracker.ts
      peer-tracker.md
      peer-tracker.test.ts
      index.ts
    presets/
      presets.ts
      presets.md
      index.ts
    internal/
      memory-discovery-strategy.ts   (test double implementing real interface)
  tests/
    config.test.ts
    config-advanced.test.ts
    runtime.test.ts                  (split ≤500 lines)
    runtime-failover.test.ts

Impact

Downstream: top-level P2P networking clients.

Prerequisites: @suaveplan/network, @suaveplan/error on Verdaccio; sibling discovery packages as devDeps.