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

105 lines
6.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# OpenSpec Change: network-plugin-server-bridge
- **Change ID**: network-plugin-server-bridge
- **Package**: `@suaveplan/network-plugin-server-bridge` (new)
- **Status**: PROPOSED
- **Type**: new-package
- **Date**: 2026-04-29
## Why
The mesh is designed to operate autonomously when the central server is offline, but it must also maintain a bidirectional relationship with the server when online. The server provides authority (signed tokens), persistence, global coordination, and administrative control. This plugin runs on Tier 0 hosts and manages the WebSocket connection to the central server: detecting online/offline transitions, buffering logs during outages, replaying them on reconnection, receiving server commands, and reconciling divergent state.
## What changes
- **ADDED**: `ServerBridgePlugin` class implementing `NetworkPlugin`.
- **ADDED**: `ServerGateway` — maintains a persistent WebSocket connection from the Tier 0 host to the central server. Heartbeat with configurable interval. Detects disconnect within 2× heartbeat interval.
- **ADDED**: `OfflineModeCoordinator` — when server disconnects: switches mesh to autonomous mode, extends token grace periods, pauses server-dependent operations (new session creation), and broadcasts `server:offline` on the bus.
- **ADDED**: `LogBuffer` — circular buffer of signed activity logs. When server is offline, logs are buffered locally on the Tier 0 host and replicated to sibling Tier 0 hosts (via `network-plugin-audit-mesh`). When server reconnects, buffered logs are replayed in sequence.
- **ADDED**: `ReconciliationProtocol` — on server reconnection: server sends its last known `meshEpoch` and `sessionSequenceNumbers`. The mesh host sends all logs from those points forward. Server validates signatures, detects conflicts, and broadcasts reconciled state.
- **ADDED**: `CommandDispatcher` — receives server commands: `kick-peer`, `merge-sessions`, `split-mesh`, `issue-token`, `broadcast-announcement`. Validates command signatures and dispatches to appropriate plugins via `NetworkBus`.
- **ADDED**: `HeartbeatMultiplexer` — instead of every peer opening a WebSocket to the server, only Tier 0 hosts connect. Peer heartbeats are aggregated by the Tier 0 host and forwarded to the server in batches.
- **ADDED**: `GracefulDegradationFsm` — `online → degrading → offline → recovering → online`. Uses `@suaveplan/fsm`.
- **ADDED**: `NETWORK_SB_CODES` — frozen error registry.
## Offline → Online state machine
```text
online
│ server heartbeat timeout
▼
degrading ──(retry with backoff)──► online
│ max retries exceeded
▼
offline ──(buffer logs, replicate to peers)──► [autonomous operation]
│ server heartbeat detected
▼
recovering ──(replay logs, reconcile)──► online
```
## Server command types
```typescript
type ServerCommand =
| { type: 'kick-peer'; targetPeerId: string; reason: string }
| { type: 'merge-sessions'; fromSessionId: string; toSessionId: string }
| { type: 'split-mesh'; meshId: string; newMeshId: string; peerIds: string[] }
| { type: 'issue-token'; tokenType: 'session' | 'mesh'; token: SignedToken }
| { type: 'broadcast'; message: string; scope: 'mesh' | 'all' }
| { type: 'shutdown-mesh'; meshId: string; deadlineMs: number };
```
All commands include a server Ed25519 signature. The plugin validates signatures before dispatch.
## Out of scope
- Server-side implementation → API gateway / game server packages.
- Persistent queue for log replay → `network-plugin-audit-mesh` handles cross-host replication; this plugin handles server-facing buffering.
- Multi-server federation (multiple central servers) → future scope.
## Source mapping
This is a **new design** — suaveplan has no equivalent server-mesh bridge.
### Requirements with no source line
| Requirement | Justification |
|---|---|
| Tier 0 host as server gateway | Prevents 1000s of peers from each opening a WebSocket to the server |
| Offline mode with autonomous operation | Mesh must continue functioning during server outages |
| Log buffering and replay | Server must reconstruct activity that occurred while offline |
| Reconciliation protocol | Detect and resolve conflicts between server state and mesh state |
| Server command dispatch | Admin must be able to control mesh remotely when online |
| Command signature validation | Prevents rogue server or man-in-the-middle attacks |
## Verification approach
- `src/gateway/gateway.spec-conformance.test.ts` — pins connect, disconnect, heartbeat, detection.
- `src/offline/offline.spec-conformance.test.ts` — pins autonomous mode, token grace extension.
- `src/buffer/buffer.spec-conformance.test.ts` — pins log buffering, replay ordering, deduplication.
- `src/reconciliation/reconciliation.spec-conformance.test.ts` — pins epoch sync, conflict detection.
- `src/command/command.spec-conformance.test.ts` — pins command validation, dispatch, rejection.
- `src/fsm/fsm.spec-conformance.test.ts` — pins state transitions, no invalid jumps.
- `src/error-codes.spec-conformance.test.ts` — frozen registry.
## Enhancement: Configurable Hosting Model
**Source**: `docs/old-network-planning/SERVER_FAILOVER.md` §4 Hosting Configurations
The server bridge currently assumes server-to-client failover (model #3). It should support 4 hosting configurations:
- `PURE_CLIENT` — no central server. Mesh operates entirely peer-to-peer. Token creation requires Byzantine quorum.
- `SERVER_BASED` — server is always top-tier host. Clients never promote. Fastest consistency but single point of failure.
- `SERVER_TO_CLIENT_FAILOVER` — server starts as host, fails over to clients on disconnect. Current default behavior.
- `CLIENT_WITH_SERVER_BACKUP` — clients host normally, server provides backup authority and reconciliation. Server can override client decisions when online.
`HostingModelConfig` — selectable at mesh creation time. Affects:
- Election behavior (whether clients can self-promote)
- Token authority (whether server tokens are required or quorum suffices)
- Reconciliation direction (server-wins vs client-wins on conflict)
## Migration impact
None — additive only.