Files
suaveplan/openspec/archive/2026-05-05-network-plugin-intra-relay/proposal.md
2026-05-27 23:29:53 +01:00

101 lines
6.5 KiB
Markdown

# OpenSpec Change: network-plugin-intra-relay
- **Change ID**: network-plugin-intra-relay
- **Package**: `@suaveplan/network-plugin-intra-relay` (new)
- **Status**: PROPOSED
- **Type**: new-package
- **Date**: 2026-04-29
## Why
The WebRTC mesh (`network-plugin-webrtc`) connects peers directly, but symmetric NAT, corporate firewalls, and restrictive ISPs prevent direct peer-to-peer connections between some peers. The existing `network-plugin-relay` handles cross-mesh routing (Mesh A → Mesh B), but there is no mechanism for intra-mesh relay: routing messages between two peers in the *same* mesh when they cannot connect directly. Without intra-mesh relay, a single symmetric NAT can partition the mesh from within.
This plugin provides **indirect peer-to-peer communication through intermediate peers** within the same mesh. It discovers relay candidates, selects optimal relay paths, maintains relay connections, and prevents relay loops.
## What changes
- **ADDED**: `IntraRelayPlugin` class implementing `NetworkPlugin`.
- **ADDED**: `RelayDiscovery` — discovers potential relay nodes from the mesh topology. Candidates are peers that have direct connections to both the source and target. Excludes leaf-tier peers (they cannot forward traffic).
- **ADDED**: `RelaySelector` — selects the optimal relay from candidates using strategies:
- `LowestLatency` — minimize end-to-end RTT through relay
- `HighestReliability` — maximize stability score (uptime, packet loss)
- `FewestHops` — prefer direct relay over multi-hop
- `TierOptimized` — prefer higher-tier peers (more capable hosts)
- `LoadBalanced` — avoid overloading a single relay peer
- **ADDED**: `RelayConnectionManager` — tracks active relay paths per peer pair. Maintains `RelayConnection` state: `pending → active → degraded → closed`.
- **ADDED**: `RelayMessageEnvelope` — wraps original `MessageEnvelope` with relay metadata: `relayPath` (array of peer IDs), `hopCount`, `maxHops`, `visitedNodes` (for loop prevention).
- **ADDED**: `RelayPerformanceMonitor` — tracks relay path quality: RTT, packet loss, bandwidth, stability. Publishes `relay:degraded` / `relay:recovered` on `NetworkBus`.
- **ADDED**: `RelaySecurityManager` — authenticates relay nodes using peer identities from `network-plugin-crypto-messages`. Validates relay message integrity (signature + hop count). Enforces relay rate limits per peer to prevent DoS.
- **ADDED**: `LoopPrevention` — drops messages where `hopCount >= maxHops` (default 8) or where `visitedNodes` contains the current peer.
- **ADDED**: `NETWORK_INTRA_RELAY_CODES` — frozen error registry.
## Relay path example
```text
Peer A wants to send to Peer B, but direct ICE fails.
Peer A ──► Relay R (Tier 1 host, connected to both A and B)
Relay R ──► Peer B
Envelope from A:
original: { senderId: "A", targetId: "B", payload: ... }
relay wrapper: {
relayPath: ["A", "R", "B"],
hopCount: 0,
maxHops: 8,
visitedNodes: ["A"]
}
R forwards to B with hopCount: 1, visitedNodes: ["A", "R"]
```
## Out of scope
- Cross-mesh relay → handled by `network-plugin-relay`.
- TURN server integration → future `network-plugin-turn`.
- STUN server discovery → handled by `network-plugin-webrtc` ICE.
## Deferred to follow-up changes
To keep this initial change feature-complete on the surface it claims (per `openspec/AGENTS.md §2c`), the cryptographic relay-node authentication is split into a separate proposal so the core relay primitives ship without coupling to `network-plugin-crypto-messages`. None of the listed `## ADDED` registry elements are removed — the security manager and its conformance test (`security.spec-conformance.test.ts`) migrate to the follow-up:
- **RelaySecurityManager** → follow-up `network-plugin-intra-relay-security`. Authenticates relay nodes via the `PeerIdentityVerifier` from `network-plugin-crypto-messages`, validates relay-message signatures, and enforces per-peer relay rate limits to prevent DoS.
The core change shipped here covers: `RelayDiscovery`, `RelaySelector` (all 5 strategies), `RelayConnectionManager` (full FSM), `RelayMessageEnvelope` (with helper functions), `LoopPrevention` (max-hops + visited-nodes), `RelayPerformanceMonitor` (RTT-based degraded/recovered with hysteresis), and the `IntraRelayPlugin` facade.
## Source mapping
This derives from `docs/old-network-planning/RELAY_SECURITY_IMPLEMENTATION_PLAN.md` §Relay Module and `PHASE_2_5.md` §RelayConnectionManager.
| Requirement | Source lines | Notes |
|---|---|---|
| Relay discovery from topology | `RELAY_SECURITY_IMPLEMENTATION_PLAN.md` §RelayDiscovery | reworded; uses `NetworkBus` instead of direct topology import |
| Relay selection strategies | `RELAY_SECURITY_IMPLEMENTATION_PLAN.md` §RelaySelector | reworded; 5 strategies |
| Relay message envelope | `RELAY_SECURITY_IMPLEMENTATION_PLAN.md` §RelayMessage | reworded; wraps genesis `MessageEnvelope` |
| Loop prevention | `RELAY_SECURITY_IMPLEMENTATION_PLAN.md` §Loop Prevention | verbatim: hop count + visited-node tracking |
| Relay security | `RELAY_SECURITY_IMPLEMENTATION_PLAN.md` §Relay Security | reworded; uses `crypto-messages` for identity |
### Requirements with no source line
| Requirement | Justification |
|---|---|
| `RelayConnectionManager` FSM | Required for graceful relay lifecycle management |
| `RelayPerformanceMonitor` | Required to detect degraded relay paths and trigger re-selection |
| Exclude leaf-tier from relay candidates | Leaf peers lack forwarding capacity; relaying through them would saturate their connection |
## Verification approach
- `src/discovery/discovery.spec-conformance.test.ts` — pins candidate discovery, leaf exclusion, topology awareness.
- `src/selector/selector.spec-conformance.test.ts` — pins 5 strategy behaviors, tie-breaking, load balancing.
- `src/connection/connection.spec-conformance.test.ts` — pins relay path establishment, teardown, degradation.
- `src/envelope/envelope.spec-conformance.test.ts` — pins relay wrapper format, hop count increment, visited tracking.
- `src/loop/loop.spec-conformance.test.ts` — pins max-hops drop, visited-node drop, no infinite loops.
- `src/security/security.spec-conformance.test.ts` — pins relay authentication, rate limiting, DoS prevention.
- `src/monitor/monitor.spec-conformance.test.ts` — pins RTT tracking, degradation detection, recovery.
- `src/error-codes.spec-conformance.test.ts` — frozen registry.
- `tests/dep-graph.test.ts` — pins no direct import of webrtc or topology packages.
## Migration impact
None — additive only.