Initial Commit
This commit is contained in:
@@ -0,0 +1,232 @@
|
||||
# OpenSpec Change: enterprise-browser-drive-webrtc
|
||||
|
||||
- **Change ID**: enterprise-browser-drive-webrtc
|
||||
- **Package**: `@suaveplan/drive-webrtc`
|
||||
- **Category**: browser
|
||||
- **Target path**: `packages/drive/drive-webrtc`
|
||||
- **Status**: IN PROGRESS
|
||||
- **Date**: 2026-04-24
|
||||
- **Reference spec**: `/mnt/s/web/suaveplan/enterprise/drive-webrtc.md`
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
Deliver `@suaveplan/drive-webrtc` on the genesis branch from scratch at enterprise quality. The package provides a WebRTC peer-to-peer mesh plugin for `@suaveplan/drive`, shipping the full pipeline to distribute content chunks browser-to-browser: `WebRTCClient` (signalling + RTC lifecycle), `SignalingClient` (WebSocket transport), `PeerManager` + `PeerBandwidthTracker`, `DataChannelManager`, `ChunkDiscoveryManager` + `WebRTCChunkSource`, `SubChunkSplitter` / `SubChunkReassembler`, `ChunkIntegrityManager` (hash verify + **real** signature verification via `@suaveplan/crypto`), `LRUCache`, `RateLimiter`, and `WebRTCDrivePlugin`. No `vi.stubGlobal` — WebSocket/RTC paths exercised via Playwright.
|
||||
|
||||
---
|
||||
|
||||
## Current-state audit (genesis)
|
||||
|
||||
The package does not exist on genesis yet — fresh build.
|
||||
|
||||
---
|
||||
|
||||
## Available workspace deps on genesis
|
||||
|
||||
| Package | Role |
|
||||
|---|---|
|
||||
| `@suaveplan/drive` (`workspace:^`) | `DrivePlugin` interface, `ChunkSource` contract |
|
||||
| `@suaveplan/crypto` (`workspace:^`) | `crypto.subtle`-based chunk signature verification |
|
||||
| `@suaveplan/events` (`workspace:^`) | `TypedEventEmitter` for peer/chunk events |
|
||||
| `@suaveplan/error` (`workspace:^`) | Typed errors for signalling, peer handshake, chunk integrity |
|
||||
| `@suaveplan/types` (`workspace:^`) | `LoggerLike` |
|
||||
| `@suaveplan/packer` (`workspace:^`) | Chunk format / packing helpers |
|
||||
| `@suaveplan/schema-registry` (`workspace:^`) | Register signalling Zod schemas |
|
||||
| `zod` (`catalog:forms`) | Schemas for `SignalingMessage` family, `WebRTCPluginConfig` |
|
||||
| `@opentelemetry/api` (`catalog:observability`) | Peer/chunk metrics |
|
||||
| `tslib` (`catalog:build`) | Runtime helpers |
|
||||
|
||||
No external runtime deps — uses only native Web APIs.
|
||||
|
||||
Dev deps: `vitest`, `@vitest/coverage-istanbul`, `@playwright/test` (`catalog:testing`), `@suaveplan/testing workspace:^`.
|
||||
|
||||
---
|
||||
|
||||
## Preserved public API surface (from main branch)
|
||||
|
||||
All eleven subpath exports preserved:
|
||||
|
||||
- `WebRTCChunkSource` + `ChunkSourceOptions`
|
||||
- `WebRTCClient` + `WebRTCClientOptions` + `resolveConfig`
|
||||
- `DataChannelManager`
|
||||
- `ChunkDiscoveryManager`
|
||||
- `TypedEventEmitter`
|
||||
- `ChunkIntegrityManager` + `computeChunkHash` + `verifyChunkIntegrity` + `ChunkMetadata`
|
||||
- `LRUCache` + `LRUCacheOptions`
|
||||
- `PeerBandwidthTracker` + config/metrics types
|
||||
- `PeerManager`
|
||||
- `WebRTCDrivePlugin`
|
||||
- `RateLimiter` + `RateLimiterOptions`
|
||||
- Plus: `generateSecurePeerId`, `generateSecureRequestId`, `validatePeerSecurity`, `validateSignalingUrl`, `SignalingClient`, `SubChunkReassembler`, `sendSubChunks`, `splitIntoSubChunks`, `encodeToBase64`, `decodeFromBase64`, all config/event/message/peer/stats types
|
||||
|
||||
---
|
||||
|
||||
## New additions for genesis
|
||||
|
||||
### 1. Real chunk signature verification
|
||||
|
||||
`ChunkIntegrityManager.verifySignature(chunk, key)` implemented using `crypto.subtle.verify` + `@suaveplan/crypto` — no "forward-looking placeholder" wording anywhere.
|
||||
|
||||
### 2. Structured errors via `@suaveplan/error`
|
||||
|
||||
Error codes: `SIGNALING_UNREACHABLE`, `PEER_HANDSHAKE_FAILED`, `CHUNK_INTEGRITY_FAILED`, `ICE_FAILED`, `PEER_BANDWIDTH_EXCEEDED`, `RATE_LIMIT_EXCEEDED`.
|
||||
|
||||
### 3. ICE-restart policy
|
||||
|
||||
`WebRTCClient` detects `iceConnectionState === 'failed'` and triggers ICE restart; surfaces via typed `'ice:restart'` event.
|
||||
|
||||
### 4. TURN / STUN configuration
|
||||
|
||||
First-class `iceServers` config in `WebRTCClientOptions` with Zod validation; documented ops guide for `turn://user:cred@host:port?transport=udp|tcp`.
|
||||
|
||||
### 5. OTel metrics
|
||||
|
||||
Counters `drive.webrtc.peers_connected_total`, `drive.webrtc.chunks_served_total`, `drive.webrtc.chunks_rejected_total{reason}`; histograms `drive.webrtc.peer_rtt_ms`, `drive.webrtc.chunk_transfer_ms`, `drive.webrtc.signaling_reconnect_ms`.
|
||||
|
||||
### 6. Signalling Zod schemas
|
||||
|
||||
`SignalingMessageSchema` family (offer/answer/ICE/chunk-request/chunk-response) registered in `@suaveplan/schema-registry`.
|
||||
|
||||
### 7. Topology strategies
|
||||
|
||||
`TopologyStrategy` interface with `FullMesh`, `SuperPeer`, and `HubAndSpoke` implementations in `src/peer-manager/topology/`.
|
||||
|
||||
### 8. Per-subpath bundle-size snapshots
|
||||
|
||||
Eleven snapshot tests asserting tree-shake isolation across all entry points.
|
||||
|
||||
---
|
||||
|
||||
## File layout
|
||||
|
||||
```text
|
||||
packages/drive/drive-webrtc/
|
||||
package.json
|
||||
tsconfig.json
|
||||
vitest.config.ts
|
||||
src/
|
||||
index.ts
|
||||
error-codes.ts
|
||||
client/
|
||||
client/
|
||||
client.ts
|
||||
client.md
|
||||
client.test.ts
|
||||
index.ts
|
||||
offer-answer/
|
||||
offer-answer.ts
|
||||
offer-answer.md
|
||||
offer-answer.test.ts
|
||||
index.ts
|
||||
ice/
|
||||
ice.ts
|
||||
ice.md
|
||||
ice.test.ts
|
||||
index.ts
|
||||
reconnect/
|
||||
reconnect.ts
|
||||
reconnect.md
|
||||
reconnect.test.ts
|
||||
index.ts
|
||||
signaling/
|
||||
signaling-client/
|
||||
signaling-client.ts
|
||||
signaling-client.md
|
||||
signaling-client.test.ts
|
||||
index.ts
|
||||
data-channel/
|
||||
data-channel-manager/
|
||||
data-channel-manager.ts
|
||||
data-channel-manager.md
|
||||
data-channel-manager.test.ts
|
||||
index.ts
|
||||
discovery/
|
||||
chunk-discovery-manager/
|
||||
chunk-discovery-manager.ts
|
||||
chunk-discovery-manager.md
|
||||
chunk-discovery-manager.test.ts
|
||||
index.ts
|
||||
chunk-source/
|
||||
chunk-source/
|
||||
chunk-source.ts
|
||||
chunk-source.md
|
||||
chunk-source.test.ts
|
||||
index.ts
|
||||
integrity/
|
||||
chunk-integrity/
|
||||
chunk-integrity.ts (includes real signature verification)
|
||||
chunk-integrity.md
|
||||
chunk-integrity.types.ts
|
||||
chunk-integrity.test.ts
|
||||
index.ts
|
||||
peer-manager/
|
||||
peer-manager/
|
||||
peer-manager.ts
|
||||
peer-manager.md
|
||||
peer-manager.test.ts
|
||||
index.ts
|
||||
peer-bandwidth-tracker/
|
||||
peer-bandwidth-tracker.ts
|
||||
peer-bandwidth-tracker.md
|
||||
peer-bandwidth-tracker.test.ts
|
||||
index.ts
|
||||
topology/
|
||||
topology-strategy.ts
|
||||
full-mesh.ts
|
||||
super-peer.ts
|
||||
hub-and-spoke.ts
|
||||
plugin/
|
||||
webrtc-plugin/
|
||||
webrtc-plugin.ts
|
||||
webrtc-plugin.md
|
||||
webrtc-plugin.test.ts
|
||||
index.ts
|
||||
sub-chunk/
|
||||
sub-chunk/
|
||||
sub-chunk-splitter.ts
|
||||
sub-chunk-reassembler.ts
|
||||
sub-chunk.md
|
||||
sub-chunk.test.ts
|
||||
index.ts
|
||||
lru-cache/
|
||||
lru-cache/
|
||||
lru-cache.ts
|
||||
lru-cache.md
|
||||
lru-cache.test.ts
|
||||
index.ts
|
||||
rate-limiter/
|
||||
rate-limiter/
|
||||
rate-limiter.ts
|
||||
rate-limiter.md
|
||||
rate-limiter.test.ts
|
||||
index.ts
|
||||
security/
|
||||
security-validator/
|
||||
security-validator.ts
|
||||
security-validator.md
|
||||
security-validator.test.ts
|
||||
index.ts
|
||||
events/
|
||||
typed-event-emitter/
|
||||
typed-event-emitter.ts
|
||||
typed-event-emitter.md
|
||||
typed-event-emitter.test.ts
|
||||
index.ts
|
||||
types/
|
||||
(config, events, messages, peer, stats, drive type modules)
|
||||
tests/
|
||||
integration.test.ts
|
||||
bundle-size/
|
||||
(eleven snapshot tests)
|
||||
e2e/
|
||||
drive-webrtc.spec.ts (two browsers, signalling, ICE, data-channel, chunk exchange)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Impact
|
||||
|
||||
**Downstream**: `@suaveplan/drive`, real-time P2P content distribution.
|
||||
|
||||
**Prerequisites**: `@suaveplan/drive`, `@suaveplan/crypto`, `@suaveplan/events`, `@suaveplan/packer`, `@suaveplan/error` on Verdaccio.
|
||||
@@ -0,0 +1,156 @@
|
||||
# Tasks: enterprise-browser-drive-webrtc
|
||||
|
||||
**Change ID**: enterprise-browser-drive-webrtc
|
||||
**Package**: `@suaveplan/drive-webrtc`
|
||||
**Target path**: `packages/drive/drive-webrtc`
|
||||
**Prerequisite packages on Verdaccio**: `@suaveplan/drive`, `@suaveplan/crypto`, `@suaveplan/events`, `@suaveplan/packer`, `@suaveplan/error`, `@suaveplan/types`
|
||||
|
||||
---
|
||||
|
||||
## 1. Scaffold
|
||||
|
||||
- [ ] Create `packages/drive/drive-webrtc/` directory tree per layout in `proposal.md`.
|
||||
- [ ] Write `package.json` at version `0.1.0`:
|
||||
- `"sideEffects": false`
|
||||
- Eleven subpath exports (see `proposal.md`)
|
||||
- `dependencies`: `@suaveplan/drive workspace:^`, `@suaveplan/crypto workspace:^`, `@suaveplan/events workspace:^`, `@suaveplan/packer workspace:^`, `@suaveplan/error workspace:^`, `@suaveplan/types workspace:^`, `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:^`
|
||||
- [ ] Write `tsconfig.json` and `vitest.config.ts` (pool: forks).
|
||||
|
||||
---
|
||||
|
||||
## 2. Error codes (`src/error-codes.ts`)
|
||||
|
||||
- [ ] Define `DriveWebRTCErrorCode`: `SIGNALING_UNREACHABLE`, `PEER_HANDSHAKE_FAILED`, `CHUNK_INTEGRITY_FAILED`, `ICE_FAILED`, `PEER_BANDWIDTH_EXCEEDED`, `RATE_LIMIT_EXCEEDED`.
|
||||
- [ ] Export `registerDriveWebRTCErrorCodes()` and call eagerly.
|
||||
|
||||
---
|
||||
|
||||
## 3. Typed event emitter (`src/events/typed-event-emitter/`)
|
||||
|
||||
- [ ] Implement `TypedEventEmitter<T>` wrapping `@suaveplan/events` `EventEmitter` with typed event map `T`.
|
||||
- [ ] Write `typed-event-emitter.test.ts`, `typed-event-emitter.md`.
|
||||
|
||||
---
|
||||
|
||||
## 4. Utility modules
|
||||
|
||||
- [ ] `lru-cache`: LRU implementation with `get`/`set`/`delete`/`clear`, configurable max size. Tests + md.
|
||||
- [ ] `rate-limiter`: token-bucket rate limiter with `consume`/`refill`, configurable window. Tests + md.
|
||||
- [ ] `security-validator`: `generateSecurePeerId`, `generateSecureRequestId`, `validatePeerSecurity`, `validateSignalingUrl`. Tests + md.
|
||||
- [ ] `sub-chunk`: `splitIntoSubChunks`, `sendSubChunks`, `SubChunkReassembler`. Tests + md.
|
||||
|
||||
---
|
||||
|
||||
## 5. Chunk integrity (`src/integrity/chunk-integrity/`)
|
||||
|
||||
- [ ] Implement `computeChunkHash(data)` using `crypto.subtle.digest('SHA-256', data)`.
|
||||
- [ ] Implement `verifyChunkIntegrity(chunk, expectedHash)` — real comparison, no placeholder.
|
||||
- [ ] Implement `ChunkIntegrityManager.verifySignature(chunk, key)` using `crypto.subtle.verify` + `@suaveplan/crypto` ed25519.
|
||||
- [ ] Remove any "forward-looking placeholder" language; the method is fully implemented.
|
||||
- [ ] Write `chunk-integrity.test.ts` with real `crypto.subtle` keys (no stubs), `chunk-integrity.md`, `chunk-integrity.types.ts`.
|
||||
|
||||
---
|
||||
|
||||
## 6. Signalling client (`src/signaling/signaling-client/`)
|
||||
|
||||
- [ ] Implement `SignalingClient` WebSocket wrapper: connect/reconnect with backoff, send/receive typed messages.
|
||||
- [ ] Validate incoming messages with Zod `SignalingMessageSchema`.
|
||||
- [ ] Wire OTel histogram `drive.webrtc.signaling_reconnect_ms`.
|
||||
- [ ] Write `signaling-client.test.ts` using real WebSocket server (no `vi.stubGlobal`), `signaling-client.md`.
|
||||
|
||||
---
|
||||
|
||||
## 7. WebRTC client (`src/client/`)
|
||||
|
||||
- [ ] `offer-answer/offer-answer.ts`: `createOffer`, `handleAnswer`, `handleOffer` via `RTCPeerConnection`.
|
||||
- [ ] `ice/ice.ts`: ICE candidate handling + ICE-restart on `iceConnectionState === 'failed'`.
|
||||
- [ ] `reconnect/reconnect.ts`: reconnect policy with backoff.
|
||||
- [ ] `client/client.ts`: `WebRTCClient` orchestrating the above; `resolveConfig` with TURN/STUN validation.
|
||||
- [ ] No `vi.stubGlobal` — real RTCPeerConnection via Playwright E2E for end-to-end path; unit tests using MemorySignalingChannel + programmatic ICE injection.
|
||||
- [ ] Write tests per sub-module, `.md` per module.
|
||||
|
||||
---
|
||||
|
||||
## 8. Data channel manager (`src/data-channel/data-channel-manager/`)
|
||||
|
||||
- [ ] Implement `DataChannelManager`: create/close data channels, route messages by label.
|
||||
- [ ] Write `data-channel-manager.test.ts`, `data-channel-manager.md`.
|
||||
|
||||
---
|
||||
|
||||
## 9. Discovery + chunk source (`src/discovery/`, `src/chunk-source/`)
|
||||
|
||||
- [ ] `ChunkDiscoveryManager`: request chunks from peers, de-duplicate in-flight requests.
|
||||
- [ ] `WebRTCChunkSource`: implements `ChunkSource` interface from `@suaveplan/drive`.
|
||||
- [ ] Write tests per module, `.md` per module.
|
||||
|
||||
---
|
||||
|
||||
## 10. Peer manager + topology (`src/peer-manager/`)
|
||||
|
||||
- [ ] `PeerManager`: admit, score, evict peers; integrate with `PeerBandwidthTracker`.
|
||||
- [ ] `PeerBandwidthTracker`: track per-peer RTT and bytes.
|
||||
- [ ] `TopologyStrategy` interface + `FullMesh`, `SuperPeer`, `HubAndSpoke` implementations.
|
||||
- [ ] Wire OTel `drive.webrtc.peers_connected_total`, `drive.webrtc.peer_rtt_ms`.
|
||||
- [ ] Write tests per module, `.md` per module.
|
||||
|
||||
---
|
||||
|
||||
## 11. Drive plugin (`src/plugin/webrtc-plugin/`)
|
||||
|
||||
- [ ] Implement `WebRTCDrivePlugin` implementing `DrivePlugin` interface; wire all sub-components.
|
||||
- [ ] Wire OTel counters for chunks served/rejected.
|
||||
- [ ] Write `webrtc-plugin.test.ts`, `webrtc-plugin.md`.
|
||||
|
||||
---
|
||||
|
||||
## 12. Zod schemas
|
||||
|
||||
- [ ] Define `SignalingMessageSchema` family (offer/answer/ICE-candidate/chunk-request/chunk-response/peer-announce); validate in `signaling-client.ts`.
|
||||
- [ ] Define `WebRTCPluginConfigSchema`; validate in `WebRTCClient.resolveConfig`.
|
||||
- [ ] Register all in `@suaveplan/schema-registry`.
|
||||
|
||||
---
|
||||
|
||||
## 13. Bundle-size snapshots (`tests/bundle-size/`)
|
||||
|
||||
- [ ] One snapshot test per subpath export (eleven total); assert that importing one entry does not pull in other plugin sub-trees.
|
||||
|
||||
---
|
||||
|
||||
## 14. Integration test (`tests/integration.test.ts`)
|
||||
|
||||
- [ ] `ChunkIntegrityManager.verifySignature` with real ed25519 keys (no stubs).
|
||||
- [ ] `PeerManager` admit/evict cycle.
|
||||
- [ ] `SubChunkSplitter` + `SubChunkReassembler` round-trip.
|
||||
- [ ] `LRUCache` eviction at capacity.
|
||||
|
||||
---
|
||||
|
||||
## 15. Playwright E2E (`e2e/drive-webrtc.spec.ts`)
|
||||
|
||||
- [ ] Two Chromium browser contexts + local WebSocket signalling server.
|
||||
- [ ] Assert: peer discovery, ICE, data-channel open, chunk request/response, `ChunkIntegrityManager.verifyChunkIntegrity` passes.
|
||||
- [ ] ICE-restart: simulate `iceConnectionState = 'failed'`; verify recovery.
|
||||
|
||||
---
|
||||
|
||||
## 16. Docs
|
||||
|
||||
- [ ] Write `.md` per module (≥200 words, API reference, examples).
|
||||
- [ ] Write `README.md` with ICE/TURN ops guidance, subpath table, topology-strategy guide.
|
||||
|
||||
---
|
||||
|
||||
## 17. Verify and publish
|
||||
|
||||
- [ ] `bunx turbo lint typecheck test --filter=@suaveplan/drive-webrtc` — green.
|
||||
- [ ] `bunx turbo test:coverage --filter=@suaveplan/drive-webrtc` — 100%.
|
||||
- [ ] `bun run docs:check --filter=@suaveplan/drive-webrtc` — zero errors.
|
||||
- [ ] No `vi.stubGlobal`, `vi.mock`, placeholder wording, `any`, `ts-ignore`, `.skip`.
|
||||
- [ ] `ChunkIntegrityManager.verifySignature` implemented and tested with real WebCrypto keys.
|
||||
- [ ] All eleven bundle-size snapshots green.
|
||||
- [ ] Playwright E2E passes.
|
||||
- [ ] `bun scripts/publish.ts --package @suaveplan/drive-webrtc`.
|
||||
- [ ] Archive to `openspec/archive/2026-04-24-enterprise-browser-drive-webrtc/`.
|
||||
Reference in New Issue
Block a user