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

4.2 KiB

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

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

Summary

Deliver @suaveplan/network-discovery-gundb on the genesis branch at enterprise quality. The package implements DiscoveryStrategy from @suaveplan/network using GunDB for gossip-based peer metadata. Ships GunDBDiscovery, GunNodeManager, and GunDBInitializer with strict-mode that refuses to start without explicit peer relay lists, signed metadata via @suaveplan/crypto, Zod validation on every inbound message, rate limiting, and full test coverage of all three modules.


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 GunDB errors
@suaveplan/types (workspace:^) LoggerLike
@suaveplan/crypto (workspace:^) ed25519 metadata signing + verification
@suaveplan/schema-registry (workspace:^) Register GunDBMessage Zod schemas
zod (catalog:forms) Message schemas
@opentelemetry/api (catalog:observability) Peer/message metrics
tslib (catalog:build) Runtime helpers

External: gun (Bun catalog).

Dev: vitest, @vitest/coverage-istanbul, @suaveplan/testing, react + @types/react for stories.


Preserved public API surface (from main branch)

class GunDBDiscovery implements DiscoveryStrategy {
  constructor(config: GunDBDiscoveryConfig)
  start(): Promise<void>
  stop(): Promise<void>
  getPeers(): PeerInfo[]
  on(event: 'peer:discovered' | 'peer:left' | 'error', handler: Function): void
}

interface GunDBDiscoveryConfig {
  peers: string[]          // Required; strict mode refuses empty list
  roomId: string
  sign?: boolean           // Default true; sign metadata with @suaveplan/crypto
  strict?: boolean         // Default true
}
// + GunDBConnectionStatus, GunDBMessage, GunDBMessageType, GunDBPeerMetadata

New additions for genesis

1. Strict-mode relay gate

GunDBDiscoveryConfig.peers must be non-empty when strict: true (default). Throws GUN_RELAY_UNREACHABLE at init if empty.

2. Signed metadata

On write: sign GunDBPeerMetadata using @suaveplan/crypto ed25519. On read: verify signature; drop unverified entries with GUN_SIGNATURE_INVALID.

3. Zod validation

GunDBMessageSchema + GunDBPeerMetadataSchema validated at boundary; malformed messages emit GUN_MESSAGE_REJECTED.

4. Rate limiting

Configurable max inbound metadata updates per second per peer; excess dropped with counter metric.

5. sideEffects audit

Gun has import-time effects; sideEffects in package.json accurately reflects Gun's behaviour.

6. Error codes

GUN_RELAY_UNREACHABLE, GUN_MESSAGE_REJECTED, GUN_SIGNATURE_INVALID.

7. OTel metrics

Counter discovery.gundb.peers_seen_total, counter discovery.gundb.messages_rejected_total{reason}, histogram discovery.gundb.sync_latency_ms.


File layout

browser/network/network-discovery-gundb/
  package.json
  tsconfig.json
  vitest.config.ts
  src/
    index.ts
    error-codes.ts
    gundb-discovery/
      gundb-discovery.ts
      gundb-discovery.md
      gundb-discovery.types.ts
      gundb-discovery.test.ts
      index.ts
    gun-node-manager/
      gun-node-manager.ts
      gun-node-manager.md
      gun-node-manager.test.ts
      index.ts
    gundb-initializer/
      gundb-initializer.ts
      gundb-initializer.md
      gundb-initializer.test.ts
      index.ts
    schema/
      gundb-schema/
        gundb-schema.ts
        gundb-schema.md
        index.ts
  tests/
    integration.test.ts

React in devDeps for gundb-discovery.stories.tsx.


Impact

Downstream: @suaveplan/network-discovery-hybrid (optional peer dep).

Prerequisites: @suaveplan/network, @suaveplan/error, @suaveplan/crypto on Verdaccio.