Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,141 @@
# 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)
```ts
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
```text
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.

View File

@@ -0,0 +1,85 @@
# Tasks: enterprise-browser-network-discovery-gundb
**Change ID**: enterprise-browser-network-discovery-gundb
**Package**: `@suaveplan/network-discovery-gundb`
**Target path**: `browser/network/network-discovery-gundb`
**Prerequisite packages on Verdaccio**: `@suaveplan/network`, `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/crypto`
---
## 1. Scaffold
- [x] Create directory tree per `proposal.md`.
- [x] `package.json` at version `0.1.0`; `sideEffects` accurately reflects Gun's import-time effects.
- `dependencies`: `@suaveplan/network workspace:^`, `@suaveplan/error workspace:^`, `@suaveplan/types workspace:^`, `@suaveplan/crypto workspace:^`, `gun`, `zod catalog:forms`, `@opentelemetry/api catalog:observability`, `tslib catalog:build`
- `devDependencies`: `vitest catalog:testing`, `@vitest/coverage-istanbul catalog:testing`, `@suaveplan/testing workspace:^`, `react catalog:browser`, `@types/react catalog:browser`
- [x] `tsconfig.json`, `vitest.config.ts` (pool: forks).
---
## 2. Error codes
- [x] Define `GunDBErrorCode`: `GUN_RELAY_UNREACHABLE`, `GUN_MESSAGE_REJECTED`, `GUN_SIGNATURE_INVALID`.
- [x] `registerGunDBErrorCodes()` — call eagerly.
---
## 3. GunDB schema (`src/schema/gundb-schema/`)
- [x] `GunDBMessageSchema` (Zod): `{ type: GunDBMessageType, peerId: string, metadata: GunDBPeerMetadata, signature?: string, timestamp: number }`.
- [x] `GunDBPeerMetadataSchema` (Zod): peer addresses, protocols, capabilities.
- [x] Register in `@suaveplan/schema-registry`.
- [x] Write `gundb-schema.md`.
---
## 4. GunNodeManager (`src/gun-node-manager/`)
- [x] Implement `GunNodeManager`: create Gun instance with explicit peer list; expose `get`/`put`/`on` wrappers.
- [x] Strict-mode: if `peers` empty and `strict: true`, throw `GUN_RELAY_UNREACHABLE` before Gun is created.
- [x] Write `gun-node-manager.test.ts` against a local Gun relay instance, `gun-node-manager.md`.
---
## 5. GunDBInitializer (`src/gundb-initializer/`)
- [x] Implement relay bootstrap and room namespace setup.
- [x] Write `gundb-initializer.test.ts`, `gundb-initializer.md`.
---
## 6. GunDBDiscovery (`src/gundb-discovery/`)
- [x] Implement `GunDBDiscovery`:
- On write: sign metadata with `@suaveplan/crypto` ed25519 when `config.sign: true`.
- On read: verify signature; drop with `GUN_SIGNATURE_INVALID` if invalid.
- Validate every incoming message with `GunDBMessageSchema`; drop + emit metric on failure.
- Rate limit: track updates per peer per second; drop excess.
- [x] Wire OTel metrics.
- [x] Write `gundb-discovery.test.ts` (sign/verify, strict-mode, malformed drop, rate limit), `gundb-discovery.md`, `gundb-discovery.types.ts`.
---
## 7. Story (`src/gundb-discovery/gundb-discovery.stories.tsx`)
- [x] Write Storybook story with `react` in devDeps — demonstrates live peer discovery against a local Gun relay.
---
## 8. Integration test (`tests/integration.test.ts`)
- [x] Two `GunDBDiscovery` instances against a local Gun relay; assert discovery event fires.
- [x] Strict-mode: empty `peers` throws typed error.
- [x] Signed metadata: a discovery instance without a matching key drops the peer.
---
## 9. Docs + verify
- [x] Write `.md` per module; `README.md` with strict-mode + relay-list deployment guidance.
- [x] `bunx turbo lint typecheck test --filter=@suaveplan/network-discovery-gundb` — green.
- [x] `bunx turbo test:coverage` — 100%.
- [x] `sideEffects` accurately declared (check Gun's effects; may need `["./dist/index.js"]`).
- [x] Story builds cleanly.
- [x] `bun scripts/publish.ts --package @suaveplan/network-discovery-gundb`.
- [x] Archive to `openspec/archive/2026-04-24-enterprise-browser-network-discovery-gundb/`.