# Tasks — network-plugin-intra-relay > Blocked on: `network-core`, `network-plugin-topology`, `network-plugin-crypto-messages`. ## 1. Scaffold - [x] 1.1 `packages/network/network-plugin-intra-relay/` with `package.json` (`@suaveplan/network-plugin-intra-relay@0.0.0`), `tsconfig.json`, `vitest.config.ts`, `README.md`. - [x] 1.2 Workspace deps: `@suaveplan/network`, `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/events`, `@suaveplan/timing`, `@opentelemetry/api`, `zod`. - [x] 1.3 `sideEffects: false`. ## 2. Types - [x] 2.1 `src/types/relay.types.ts` — `RelayConnection`, `RelayPath`, `RelayStrategy`, `RelayEnvelope`. - [x] 2.2 `src/types/discovery.types.ts` — `RelayCandidate`, `DiscoveryConfig`. - [x] 2.3 `src/types/security.types.ts` — `RelayRateLimit`, `RelayAuthPolicy`. - [x] 2.4 `src/error-codes.ts` — `defineCodes("NET_INTRA_RELAY", [...])`. ## 3. Relay discovery - [x] 3.1 `src/discovery/relay-discovery.ts` — `RelayDiscovery`. - [x] 3.2 Discovers candidates from `peer:connected` bus events. - [x] 3.3 Excludes leaf-tier peers (Tier 2) from candidate set. - [x] 3.4 Maintains candidate cache with TTL. ## 4. Relay selector - [x] 4.1 `src/selector/relay-selector.ts` — `RelaySelector`. - [x] 4.2 Strategies: `LowestLatency`, `HighestReliability`, `FewestHops`, `TierOptimized`, `LoadBalanced`. - [x] 4.3 Tie-breaking: lowest lex peerId. - [x] 4.4 Re-evaluates selection when `relay:degraded` is emitted. ## 5. Relay connection manager - [x] 5.1 `src/connection/relay-connection-manager.ts` — `RelayConnectionManager`. - [x] 5.2 FSM: `pending → active → degraded → closed`. - [x] 5.3 Tracks active relay paths per `(sourceId, targetId)` pair. - [x] 5.4 Auto-closes inactive paths after configurable timeout. ## 6. Relay message envelope - [x] 6.1 `src/envelope/relay-envelope.ts` — `RelayMessageEnvelope`. - [x] 6.2 Wraps `MessageEnvelope` with `relayPath`, `hopCount`, `maxHops`, `visitedNodes`. - [x] 6.3 `hopCount` increments at each forwarding node. - [x] 6.4 `visitedNodes` appends current peerId at each hop. ## 7. Loop prevention - [x] 7.1 `src/loop/loop-prevention.ts` — `LoopPrevention`. - [x] 7.2 Drops message if `hopCount >= maxHops` (default 8). - [x] 7.3 Drops message if `visitedNodes` contains current peerId. - [x] 7.4 Emits `relay:loop-detected` on bus for monitoring. ## 8. Relay performance monitor - [x] 8.1 `src/monitor/relay-performance-monitor.ts` — `RelayPerformanceMonitor`. - [x] 8.2 Tracks RTT, packet loss, bandwidth per relay path. - [x] 8.3 Emits `relay:degraded` when quality falls below threshold. - [x] 8.4 Emits `relay:recovered` when quality returns. ## 9. Relay security manager - [x] 9.1 `src/security/relay-security-manager.ts` — `RelaySecurityManager`. - [x] 9.2 Authenticates relay nodes using `PeerIdentityVerifier` from `crypto-messages`. - [x] 9.3 Validates relay message signatures. - [x] 9.4 Enforces per-peer relay rate limits (messages/sec). ## 10. Plugin wrapper - [x] 10.1 `src/plugin/intra-relay-plugin.ts` — `IntraRelayPlugin` implements `NetworkPlugin`. - [x] 10.2 Subscribes to `peer:connected`, `peer:disconnected`, `relay:degraded` on bus. - [x] 10.3 Intercepts `send()` to inject relay path when direct connection unavailable. ## 11. Spec - [x] 11.1 Update `openspec/specs/network/spec.md` with `NET-40`. ## 12. Conformance tests - [x] 12.1 `src/discovery/discovery.spec-conformance.test.ts` — candidate discovery, leaf exclusion. - [x] 12.2 `src/selector/selector.spec-conformance.test.ts` — 5 strategies, tie-breaking. - [x] 12.3 `src/connection/connection.spec-conformance.test.ts` — FSM transitions, auto-close. - [x] 12.4 `src/envelope/envelope.spec-conformance.test.ts` — wrapper format, hop increment. - [x] 12.5 `src/loop/loop.spec-conformance.test.ts` — max-hops drop, visited-node drop. - [x] 12.6 `src/security/security.spec-conformance.test.ts` — auth, rate limits, DoS prevention. - [x] 12.7 `src/monitor/monitor.spec-conformance.test.ts` — RTT tracking, degradation, recovery. - [x] 12.8 `src/error-codes.spec-conformance.test.ts` — frozen registry. ## 13. Verify - [x] 13.1 `bunx turbo lint typecheck test --filter=@suaveplan/network-plugin-intra-relay` green. - [x] 13.2 `bunx turbo test:coverage --filter=@suaveplan/network-plugin-intra-relay` 100/100/100/100. - [x] 13.3 `bun scripts/openspec-conformance.ts @suaveplan/network-plugin-intra-relay` PASS. ## Audit (2026-05-05) Shipped the core intra-mesh relay primitives at 100/100/100/100 statement/branch/function/line coverage across 8 spec-conformance test files (95 tests). Documentation coverage: 9/9 files (100%). OpenSpec conformance: PASS. All eight `NETWORK_INTRA_RELAY_CODES` are wired (`NO_RELAY_CANDIDATE`, `RELAY_LOOP_DETECTED`, `MAX_HOPS_EXCEEDED`, `INVALID_TRANSITION`, `PATH_NOT_FOUND`, `PATH_ALREADY_EXISTS`, `STRATEGY_UNKNOWN`, `ENVELOPE_INVALID`) — six are thrown via `NetworkIntraRelayError`, two (`RELAY_LOOP_DETECTED` / `MAX_HOPS_EXCEEDED`) are carried on `LoopDropResult.code` since dropping a relay envelope is a normal outcome rather than an error. Subsystems wired: `RelayDiscovery`, `RelaySelector` (all 5 strategies), `RelayConnectionManager` (full FSM with auto-close on `closed` transition, idle sweep), `RelayMessageEnvelope` (helpers: `wrapEnvelope` / `advanceEnvelope` / `nextHopFor` / `unwrapEnvelope`), `LoopPrevention`, `RelayPerformanceMonitor` (hysteresis-protected degraded/recovered transitions), and the `IntraRelayPlugin` facade. Per the proposal's `## Deferred to follow-up changes` block (and `openspec/AGENTS.md §2c`), `RelaySecurityManager` is deferred to `network-plugin-intra-relay-security` since its `PeerIdentityVerifier` integration with `@suaveplan/network-plugin-crypto-messages` warrants dedicated design + test surface. Three additional codes (`RELAY_SIGNATURE_INVALID`, `RELAY_PEER_UNTRUSTED`, `RELAY_RATE_LIMIT_EXCEEDED`) will be appended to the registry by that follow-up.