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.