Initial Commit
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
# OpenSpec Change: enterprise-browser-network-discovery-trystero
|
||||
|
||||
- **Change ID**: enterprise-browser-network-discovery-trystero
|
||||
- **Package**: `@suaveplan/network-discovery-trystero`
|
||||
- **Category**: browser
|
||||
- **Target path**: `browser/network/network-discovery-trystero`
|
||||
- **Status**: SUPERSEDED-BY-GENESIS-WAVE
|
||||
- **Date**: 2026-04-24
|
||||
- **Reference spec**: `/mnt/s/web/suaveplan/enterprise/network-discovery-trystero.md`
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
Deliver `@suaveplan/network-discovery-trystero` on the genesis branch at enterprise quality. The package wraps Trystero to provide serverless WebRTC peer discovery over four transports: BitTorrent, Nostr, MQTT, and IPFS. Ships `TrysteroDiscovery` with strict-mode, Zod-validated messages, per-strategy OTel metrics, curated relay-pool bundles, and optional encrypted/signed announcements.
|
||||
|
||||
---
|
||||
|
||||
## 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 Trystero errors |
|
||||
| `@suaveplan/types` (`workspace:^`) | `LoggerLike` |
|
||||
| `@suaveplan/crypto` (`workspace:^`) | Optional encrypted rooms + signed announcements |
|
||||
| `@suaveplan/schema-registry` (`workspace:^`) | Message schema registration |
|
||||
| `zod` (`catalog:forms`) | `TrysteroMessage` Zod schemas |
|
||||
| `@opentelemetry/api` (`catalog:observability`) | Per-strategy health metrics |
|
||||
| `tslib` (`catalog:build`) | Runtime helpers |
|
||||
|
||||
External: `trystero` (Bun catalog). React in devDeps for story.
|
||||
|
||||
---
|
||||
|
||||
## Preserved public API surface
|
||||
|
||||
```ts
|
||||
class TrysteroDiscovery implements DiscoveryStrategy {
|
||||
constructor(config: TrysteroDiscoveryConfig)
|
||||
start(): Promise<void>
|
||||
stop(): Promise<void>
|
||||
getPeers(): PeerInfo[]
|
||||
on(event: string, handler: Function): void
|
||||
}
|
||||
|
||||
interface TrysteroDiscoveryConfig {
|
||||
strategy: TrysteroStrategy
|
||||
roomId: string
|
||||
torrent?: TorrentConfig
|
||||
nostr?: NostrRelayConfig
|
||||
mqtt?: MqttConfig
|
||||
ipfs?: IpfsConfig
|
||||
encrypt?: { password: string } // AES-GCM via @suaveplan/crypto
|
||||
sign?: boolean // ed25519 signed announcements
|
||||
strict?: boolean // Default true; rejects public defaults
|
||||
}
|
||||
type TrysteroStrategy = 'torrent' | 'nostr' | 'mqtt' | 'ipfs'
|
||||
interface TorrentConfig { trackerUrls: string[] }
|
||||
interface NostrRelayConfig { relayUrls: string[] }
|
||||
interface MqttConfig { brokerUrl: string; topic?: string }
|
||||
interface IpfsConfig { swarmAddrs?: string[] }
|
||||
// + TrysteroConnectionStatus, TrysteroMessage, TrysteroMessageType, TrysteroPeerMetadata
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## New additions for genesis
|
||||
|
||||
### 1. Strict-mode relay gate
|
||||
|
||||
Requires explicit relay/tracker/broker per strategy; rejects known public defaults without explicit `strict: false`.
|
||||
|
||||
### 2. Zod-validated messages
|
||||
|
||||
`TrysteroMessageSchema` variants; validated in `message-handlers.ts`; malformed dropped with metric.
|
||||
|
||||
### 3. Encrypted rooms
|
||||
|
||||
`config.encrypt.password` → AES-GCM wrap via `@suaveplan/crypto`; messages unreadable without password.
|
||||
|
||||
### 4. Signed announcements
|
||||
|
||||
`config.sign: true` → ed25519 signatures on peer metadata via `@suaveplan/crypto`.
|
||||
|
||||
### 5. Curated relay-pool bundles (`src/presets/`)
|
||||
|
||||
`TORRENT_TRACKERS`, `NOSTR_RELAYS` exported with freshness metadata; no public defaults used unless opted in via presets import.
|
||||
|
||||
### 6. Fallback via `@suaveplan/retry`
|
||||
|
||||
Replace ad-hoc `fallback.ts` with `@suaveplan/retry` exponential backoff for strategy transitions.
|
||||
|
||||
### 7. Error codes
|
||||
|
||||
`TRYSTERO_RELAY_UNREACHABLE`, `TRYSTERO_ROOM_JOIN_FAILED`.
|
||||
|
||||
### 8. OTel metrics
|
||||
|
||||
Counter `discovery.trystero.peers_seen_total{strategy}`, counter `discovery.trystero.fallback_total{from,to}`, histogram `discovery.trystero.join_ms{strategy}`.
|
||||
|
||||
---
|
||||
|
||||
## File layout
|
||||
|
||||
```text
|
||||
browser/network/network-discovery-trystero/
|
||||
package.json
|
||||
tsconfig.json
|
||||
vitest.config.ts
|
||||
src/
|
||||
index.ts
|
||||
error-codes.ts
|
||||
trystero-discovery/
|
||||
trystero-discovery.ts
|
||||
trystero-discovery.md
|
||||
trystero-discovery.types.ts
|
||||
trystero-discovery.test.ts
|
||||
index.ts
|
||||
message-handlers/
|
||||
message-handlers.ts
|
||||
message-handlers.md
|
||||
message-handlers.test.ts
|
||||
index.ts
|
||||
room-config/
|
||||
room-config.ts
|
||||
room-config.md
|
||||
room-config.test.ts
|
||||
index.ts
|
||||
trystero-room-manager/
|
||||
trystero-room-manager.ts
|
||||
trystero-room-manager.md
|
||||
trystero-room-manager.test.ts
|
||||
index.ts
|
||||
intervals/
|
||||
intervals.ts
|
||||
intervals.md
|
||||
intervals.test.ts
|
||||
index.ts
|
||||
event-emitter/
|
||||
event-emitter.ts
|
||||
event-emitter.md
|
||||
event-emitter.test.ts
|
||||
index.ts
|
||||
presets/
|
||||
presets.ts (TORRENT_TRACKERS, NOSTR_RELAYS with freshness metadata)
|
||||
presets.md
|
||||
index.ts
|
||||
schema/
|
||||
trystero-schema/
|
||||
trystero-schema.ts
|
||||
trystero-schema.md
|
||||
index.ts
|
||||
tests/
|
||||
core.test.ts
|
||||
messaging.test.ts
|
||||
messaging-advanced.test.ts
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Impact
|
||||
|
||||
**Downstream**: `@suaveplan/network-discovery-hybrid`.
|
||||
|
||||
**Prerequisites**: `@suaveplan/network`, `@suaveplan/error`, `@suaveplan/crypto`, `@suaveplan/retry` on Verdaccio.
|
||||
@@ -0,0 +1,76 @@
|
||||
# Tasks: enterprise-browser-network-discovery-trystero
|
||||
|
||||
**Change ID**: enterprise-browser-network-discovery-trystero
|
||||
**Package**: `@suaveplan/network-discovery-trystero`
|
||||
**Target path**: `browser/network/network-discovery-trystero`
|
||||
**Prerequisite packages on Verdaccio**: `@suaveplan/network`, `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/crypto`, `@suaveplan/retry`
|
||||
|
||||
---
|
||||
|
||||
## 1. Scaffold
|
||||
|
||||
- [x] Create directory tree per `proposal.md`.
|
||||
- [x] `package.json` v0.0.0, `"sideEffects": false`.
|
||||
- `dependencies`: `@suaveplan/network workspace:^`, `@suaveplan/error workspace:^`, `@suaveplan/types workspace:^`, `@suaveplan/crypto workspace:^`, `@suaveplan/retry workspace:^`, `trystero`, `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 + schema
|
||||
|
||||
- [x] `TRYSTERO_RELAY_UNREACHABLE`, `TRYSTERO_ROOM_JOIN_FAILED`. Register eagerly.
|
||||
- [x] `TrysteroMessageSchema` per variant; register in `@suaveplan/schema-registry`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Supporting modules
|
||||
|
||||
For `event-emitter`, `intervals`, `room-config`, `trystero-room-manager`, `message-handlers`:
|
||||
|
||||
- [x] Implement each module; validate messages with Zod in `message-handlers`.
|
||||
- [x] Write `*.test.ts` and `*.md`.
|
||||
|
||||
---
|
||||
|
||||
## 4. Presets (`src/presets/`)
|
||||
|
||||
- [x] Export `TORRENT_TRACKERS`, `NOSTR_RELAYS` with `{ url, addedAt, lastVerified }` freshness metadata.
|
||||
- [x] Write `presets.md`.
|
||||
|
||||
---
|
||||
|
||||
## 5. TrysteroDiscovery (`src/trystero-discovery/`)
|
||||
|
||||
- [x] Strict-mode: reject public default relay lists without `strict: false`.
|
||||
- [x] Encrypted rooms: if `config.encrypt`, wrap messages with `@suaveplan/crypto` AES-GCM.
|
||||
- [x] Signed announcements: if `config.sign`, sign metadata with `@suaveplan/crypto` ed25519.
|
||||
- [x] Fallback via `@suaveplan/retry` (replace any ad-hoc fallback logic).
|
||||
- [x] Wire OTel metrics per strategy.
|
||||
- [x] Write `trystero-discovery.test.ts`, `trystero-discovery.md`, `trystero-discovery.types.ts`.
|
||||
|
||||
---
|
||||
|
||||
## 6. Story
|
||||
|
||||
- [x] `src/trystero-discovery/trystero-discovery.stories.tsx` with React devDep.
|
||||
|
||||
---
|
||||
|
||||
## 7. Tests (≤500 lines each)
|
||||
|
||||
- [x] `tests/core.test.ts` — config, strict-mode, start/stop.
|
||||
- [x] `tests/messaging.test.ts` — message send/receive per strategy, Zod validation.
|
||||
- [x] `tests/messaging-advanced.test.ts` — encrypted round-trip, signed announcement verification.
|
||||
|
||||
---
|
||||
|
||||
## 8. Verify + publish
|
||||
|
||||
- [x] `bunx turbo lint typecheck test --filter=@suaveplan/network-discovery-trystero` — green.
|
||||
- [x] `bunx turbo test:coverage` — 100%.
|
||||
- [x] Strict-mode blocks public defaults.
|
||||
- [x] Encrypted-room round trip verified.
|
||||
- [x] Fallback transition produces typed event with `from`/`to`.
|
||||
- [x] `bun scripts/publish.ts --package @suaveplan/network-discovery-trystero`.
|
||||
- [x] Archive to `openspec/archive/2026-04-24-enterprise-browser-network-discovery-trystero/`.
|
||||
Reference in New Issue
Block a user