Initial Commit
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
# OpenSpec Change: enterprise-browser-network-discovery-webtorrent
|
||||
|
||||
- **Change ID**: enterprise-browser-network-discovery-webtorrent
|
||||
- **Package**: `@suaveplan/network-discovery-webtorrent`
|
||||
- **Category**: browser
|
||||
- **Target path**: `browser/network/network-discovery-webtorrent`
|
||||
- **Status**: SUPERSEDED-BY-GENESIS-WAVE
|
||||
- **Date**: 2026-04-24
|
||||
- **Reference spec**: `/mnt/s/web/suaveplan/enterprise/network-discovery-webtorrent.md`
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
Deliver `@suaveplan/network-discovery-webtorrent` on the genesis branch at enterprise quality. The package wraps `p2pt` for WebTorrent-tracker-based WebRTC peer discovery, replacing the main-branch `describe.skip` stub with real unit tests and a Playwright E2E. Ships strict-mode (no public tracker defaults), a typed `P2PTPeer` interface, tracker health tracking + failover, OTel metrics, 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, `PeerInfo` |
|
||||
| `@suaveplan/events` (`workspace:^`) | `EventEmitter` base |
|
||||
| `@suaveplan/error` (`workspace:^`) | Typed errors |
|
||||
| `@suaveplan/types` (`workspace:^`) | `LoggerLike` |
|
||||
| `@suaveplan/crypto` (`workspace:^`) | Optional signed/encrypted announcements |
|
||||
| `@suaveplan/schema-registry` (`workspace:^`) | Register envelope schema |
|
||||
| `zod` (`catalog:forms`) | `P2PTPeer` + envelope Zod schemas |
|
||||
| `@opentelemetry/api` (`catalog:observability`) | Tracker/peer metrics |
|
||||
| `tslib` (`catalog:build`) | Runtime helpers |
|
||||
|
||||
External: `p2pt` (Bun catalog).
|
||||
|
||||
---
|
||||
|
||||
## Preserved public API surface
|
||||
|
||||
```ts
|
||||
class WebTorrentDiscovery extends EventEmitter<DiscoveryEvents> {
|
||||
constructor(config: WebTorrentDiscoveryConfig)
|
||||
start(): Promise<void>
|
||||
stop(): Promise<void>
|
||||
}
|
||||
|
||||
interface WebTorrentDiscoveryConfig {
|
||||
trackerUrls: string[] // Required; no public tracker defaults when strict: true
|
||||
announceId: string // Must include tenant/app hash; namespaced
|
||||
strict?: boolean // Default true
|
||||
encrypt?: boolean
|
||||
sign?: boolean
|
||||
}
|
||||
|
||||
interface P2PTPeer { id: string; address?: string }
|
||||
interface PeerInfo { id: PeerId; multiaddrs: Multiaddr[] }
|
||||
interface DiscoveryEvents { peer: (info: PeerInfo) => void; error: (err: Error) => void }
|
||||
// + PeerId, Multiaddr, Discovery interface
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## New additions for genesis
|
||||
|
||||
### 1. Real unit tests — no `describe.skip`
|
||||
|
||||
Vitest suites using a typed `P2PTP2PTAdapter` interface so `p2pt` can be driven without stubs (or with a typed adapter that implements the real interface for unit isolation).
|
||||
|
||||
### 2. Strict-mode tracker config
|
||||
|
||||
Refuses to start with the four default public WebTorrent trackers unless `strict: false`.
|
||||
|
||||
### 3. `announceId` namespacing enforcement
|
||||
|
||||
`announceId` must include a non-trivial prefix (≥8 chars); optionally hashed with a tenant salt.
|
||||
|
||||
### 4. Tracker health + failover
|
||||
|
||||
Per-tracker health bookkeeping; rotate away from trackers emitting `trackerwarning`.
|
||||
|
||||
### 5. Optional encryption + signed announcements
|
||||
|
||||
`config.encrypt: true` → AES-GCM wrap of peer messages via `@suaveplan/crypto`.
|
||||
`config.sign: true` → ed25519 signatures on announcements.
|
||||
|
||||
### 6. Error codes
|
||||
|
||||
`WEBTORRENT_TRACKER_UNREACHABLE`, `WEBTORRENT_ANNOUNCE_FAILED`.
|
||||
|
||||
### 7. OTel metrics
|
||||
|
||||
Counter `discovery.webtorrent.peers_seen_total`, histogram `discovery.webtorrent.tracker_rtt_ms`.
|
||||
|
||||
---
|
||||
|
||||
## File layout
|
||||
|
||||
```text
|
||||
browser/network/network-discovery-webtorrent/
|
||||
package.json
|
||||
tsconfig.json
|
||||
vitest.config.ts
|
||||
src/
|
||||
index.ts
|
||||
error-codes.ts
|
||||
lib/
|
||||
network-discovery-webtorrent/
|
||||
network-discovery-webtorrent.ts
|
||||
network-discovery-webtorrent.md
|
||||
network-discovery-webtorrent.types.ts
|
||||
network-discovery-webtorrent.test.ts
|
||||
index.ts
|
||||
p2pt-adapter/
|
||||
p2pt-adapter.ts (P2PTP2PTAdapter interface + real p2pt wrapper)
|
||||
p2pt-adapter.md
|
||||
p2pt-adapter.test.ts
|
||||
index.ts
|
||||
tracker-health/
|
||||
tracker-health.ts
|
||||
tracker-health.md
|
||||
tracker-health.test.ts
|
||||
index.ts
|
||||
schema/
|
||||
envelope-schema/
|
||||
envelope-schema.ts
|
||||
envelope-schema.md
|
||||
index.ts
|
||||
tests/
|
||||
integration.test.ts
|
||||
e2e/
|
||||
webtorrent-discovery.spec.ts (real WSS tracker)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Impact
|
||||
|
||||
**Downstream**: `@suaveplan/network-webrtc` (signalling example), `@suaveplan/network-discovery-hybrid`.
|
||||
|
||||
**Prerequisites**: `@suaveplan/network`, `@suaveplan/events`, `@suaveplan/error`, `@suaveplan/crypto` on Verdaccio.
|
||||
@@ -0,0 +1,81 @@
|
||||
# Tasks: enterprise-browser-network-discovery-webtorrent
|
||||
|
||||
**Change ID**: enterprise-browser-network-discovery-webtorrent
|
||||
**Package**: `@suaveplan/network-discovery-webtorrent`
|
||||
**Target path**: `browser/network/network-discovery-webtorrent`
|
||||
**Prerequisite packages on Verdaccio**: `@suaveplan/network`, `@suaveplan/events`, `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/crypto`
|
||||
|
||||
---
|
||||
|
||||
## 1. Scaffold
|
||||
|
||||
- [x] Create directory tree per `proposal.md`.
|
||||
- [x] `package.json` v0.0.0, `"sideEffects": false`.
|
||||
- `dependencies`: `@suaveplan/network workspace:^`, `@suaveplan/events workspace:^`, `@suaveplan/error workspace:^`, `@suaveplan/types workspace:^`, `@suaveplan/crypto workspace:^`, `p2pt`, `zod catalog:forms`, `@opentelemetry/api catalog:observability`, `tslib catalog:build`
|
||||
- `devDependencies`: `vitest catalog:testing`, `@vitest/coverage-istanbul catalog:testing`, `@playwright/test catalog:testing`, `@suaveplan/testing workspace:^`
|
||||
- [x] `tsconfig.json`, `vitest.config.ts` (pool: forks).
|
||||
|
||||
---
|
||||
|
||||
## 2. Error codes + schema
|
||||
|
||||
- [x] `WEBTORRENT_TRACKER_UNREACHABLE`, `WEBTORRENT_ANNOUNCE_FAILED`. Register eagerly.
|
||||
- [x] `P2PTPeerSchema`, `EnvelopeSchema` (Zod); register envelope in `@suaveplan/schema-registry`.
|
||||
|
||||
---
|
||||
|
||||
## 3. `P2PTAdapter` interface (`src/lib/p2pt-adapter/`)
|
||||
|
||||
- [x] Define `P2PTAdapter` interface mirroring `p2pt`'s public API surface.
|
||||
- [x] Implement `RealP2PTAdapter` wrapping `new P2PT(...)`.
|
||||
- [x] This adapter is the seam for unit tests — inject it rather than stubbing globals.
|
||||
- [x] Write `p2pt-adapter.test.ts`, `p2pt-adapter.md`.
|
||||
|
||||
---
|
||||
|
||||
## 4. `TrackerHealth` (`src/lib/tracker-health/`)
|
||||
|
||||
- [x] Track per-tracker `warningCount`, `lastWarning`, `healthy` flag.
|
||||
- [x] On `trackerwarning` event, increment warning count; mark unhealthy above threshold.
|
||||
- [x] Round-robin to next healthy tracker.
|
||||
- [x] Write `tracker-health.test.ts`, `tracker-health.md`.
|
||||
|
||||
---
|
||||
|
||||
## 5. `WebTorrentDiscovery` (`src/lib/network-discovery-webtorrent/`)
|
||||
|
||||
- [x] No `describe.skip` — real tests.
|
||||
- [x] Strict-mode: reject four default public trackers.
|
||||
- [x] `announceId` must be ≥8 chars; optionally tenant-hashed.
|
||||
- [x] Optional encryption: AES-GCM wrap messages.
|
||||
- [x] Optional signed announcements: ed25519 via `@suaveplan/crypto`.
|
||||
- [x] Wire `TrackerHealth` failover.
|
||||
- [x] Wire OTel metrics.
|
||||
- [x] Write `network-discovery-webtorrent.test.ts` (config, tracker selection, peer dedup, error propagation via `P2PTAdapter`), `network-discovery-webtorrent.md`, `network-discovery-webtorrent.types.ts`.
|
||||
|
||||
---
|
||||
|
||||
## 6. Integration test (`tests/integration.test.ts`)
|
||||
|
||||
- [x] Strict-mode rejects public trackers.
|
||||
- [x] `announceId` too short throws typed error.
|
||||
- [x] Tracker failover: simulate `trackerwarning` events and verify rotation.
|
||||
|
||||
---
|
||||
|
||||
## 7. Playwright E2E (`e2e/webtorrent-discovery.spec.ts`)
|
||||
|
||||
- [x] Chromium browser context connects to a real WSS WebTorrent tracker.
|
||||
- [x] Second peer announces; first peer discovers it and emits `peer` event.
|
||||
|
||||
---
|
||||
|
||||
## 8. Docs + verify
|
||||
|
||||
- [x] Write `.md` per module; `README.md` with tracker threat model, enterprise deployment, strict-mode guidance.
|
||||
- [x] `bunx turbo lint typecheck test --filter=@suaveplan/network-discovery-webtorrent` — green.
|
||||
- [x] `bunx turbo test:coverage` — 100%.
|
||||
- [x] No `describe.skip`, no `vi.stubGlobal`.
|
||||
- [x] Playwright E2E discovers a real peer.
|
||||
- [x] `bun scripts/publish.ts --package @suaveplan/network-discovery-webtorrent`.
|
||||
- [x] Archive to `openspec/archive/2026-04-24-enterprise-browser-network-discovery-webtorrent/`.
|
||||
Reference in New Issue
Block a user