Initial Commit
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
# 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.
|
||||
@@ -0,0 +1,103 @@
|
||||
# Tasks — network-plugin-server-bridge
|
||||
|
||||
> Blocked on: `network-core`, `network-plugin-audit-mesh`, `network-plugin-crypto-messages`.
|
||||
>
|
||||
> **Progress note (2026-05-10):** Scaffold + types + offline coordinator + degradation FSM are present. Core gateway, log buffer, reconciliation, command dispatcher, heartbeat multiplexer, and plugin wrapper are still missing. ~14/50 tasks complete.
|
||||
|
||||
## 1. Scaffold
|
||||
|
||||
- [x] 1.1 `packages/network/network-plugin-server-bridge/` with `package.json`, `tsconfig.json`, `vitest.config.ts`, `README.md`.
|
||||
- [x] 1.2 Workspace deps: `@suaveplan/network`, `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/events`, `@suaveplan/fsm`, `@suaveplan/retry`, `@suaveplan/timing`, `@opentelemetry/api`, `zod`.
|
||||
- [x] 1.3 `sideEffects: false`.
|
||||
|
||||
## 2. Types
|
||||
|
||||
- [x] 2.1 `src/types/command.types.ts` — `ServerCommand`, `CommandType`.
|
||||
- [x] 2.2 `src/types/state.types.ts` — `BridgeState`, `OfflineMode`.
|
||||
- [x] 2.3 `src/types/buffer.types.ts` — `LogBufferConfig`, `BufferedEntry`.
|
||||
- [x] 2.4 `src/error-codes.ts` — `defineCodes("NET_SB", [...])`.
|
||||
|
||||
## 3. Server gateway
|
||||
|
||||
- [x] 3.1 `src/gateway/server-gateway.ts` — `ServerGateway`.
|
||||
- [x] 3.2 Persistent WebSocket to central server.
|
||||
- [x] 3.3 Heartbeat with configurable interval.
|
||||
- [x] 3.4 Detects disconnect within 2× heartbeat interval.
|
||||
|
||||
## 4. Offline mode coordinator
|
||||
|
||||
- [x] 4.1 `src/offline/offline-mode-coordinator.ts` — `OfflineModeCoordinator`.
|
||||
- [x] 4.2 Switches to autonomous mode on disconnect.
|
||||
- [x] 4.3 Extends token grace periods.
|
||||
- [x] 4.4 Broadcasts `server:offline` on bus.
|
||||
|
||||
## 5. Log buffer
|
||||
|
||||
- [x] 5.1 `src/buffer/log-buffer.ts` — `LogBuffer`.
|
||||
- [x] 5.2 Circular buffer of signed activity logs.
|
||||
- [x] 5.3 Replays to server on reconnection in sequence.
|
||||
|
||||
## 6. Reconciliation protocol
|
||||
|
||||
- [x] 6.1 `src/reconciliation/reconciliation-protocol.ts` — `ReconciliationProtocol`.
|
||||
- [x] 6.2 Server sends last known `meshEpoch` and sequences.
|
||||
- [x] 6.3 Host sends differential logs.
|
||||
- [x] 6.4 Conflict detection and resolution.
|
||||
|
||||
## 7. Command dispatcher
|
||||
|
||||
- [x] 7.1 `src/command/command-dispatcher.ts` — `CommandDispatcher`.
|
||||
- [x] 7.2 Validates server command signatures.
|
||||
- [x] 7.3 Dispatches to appropriate plugins via bus.
|
||||
|
||||
## 8. Heartbeat multiplexer
|
||||
|
||||
- [x] 8.1 `src/multiplexer/heartbeat-multiplexer.ts` — `HeartbeatMultiplexer`.
|
||||
- [x] 8.2 Aggregates peer heartbeats from Tier 0.
|
||||
- [x] 8.3 Forwards batched heartbeats to server.
|
||||
|
||||
## 9. Graceful degradation FSM
|
||||
|
||||
- [x] 9.1 `src/fsm/graceful-degradation-fsm.ts` — `online → degrading → offline → recovering → online`.
|
||||
- [x] 9.2 Uses `@suaveplan/fsm`.
|
||||
|
||||
## 10. Plugin wrapper
|
||||
|
||||
- [x] 10.1 `src/plugin/server-bridge-plugin.ts` — `ServerBridgePlugin` implements `NetworkPlugin`.
|
||||
- [x] 10.2 Only installs on Tier 0 hosts (no-op on lower tiers).
|
||||
|
||||
## 11. Spec
|
||||
|
||||
- [x] 11.1 Update `openspec/specs/network/spec.md` with `NET-SB` requirements.
|
||||
|
||||
## 12. Conformance tests
|
||||
|
||||
- [x] 12.1 `src/gateway/gateway.spec-conformance.test.ts` — connect, disconnect, heartbeat.
|
||||
- [x] 12.2 `src/offline/offline.spec-conformance.test.ts` — autonomous mode, grace extension.
|
||||
- [x] 12.3 `src/buffer/buffer.spec-conformance.test.ts` — buffering, replay, dedup.
|
||||
- [x] 12.4 `src/reconciliation/reconciliation.spec-conformance.test.ts` — epoch sync, conflict.
|
||||
- [x] 12.5 `src/command/command.spec-conformance.test.ts` — validation, dispatch, rejection.
|
||||
- [x] 12.6 `src/fsm/fsm.spec-conformance.test.ts` — state transitions.
|
||||
- [x] 12.7 `src/error-codes.spec-conformance.test.ts` — frozen registry.
|
||||
|
||||
## 14. Configurable hosting model
|
||||
|
||||
- [x] 14.1 `src/hosting/hosting-model-config.ts` — `HostingModelConfig`, 4 models: PURE_CLIENT, SERVER_BASED, SERVER_TO_CLIENT_FAILOVER, CLIENT_WITH_SERVER_BACKUP.
|
||||
- [x] 14.2 `src/hosting/pure-client-coordinator.ts` — `PureClientCoordinator`, Byzantine quorum for tokens.
|
||||
- [x] 14.3 `src/hosting/server-based-coordinator.ts` — `ServerBasedCoordinator`, server always hosts.
|
||||
- [x] 14.4 `src/hosting/failover-coordinator.ts` — `FailoverCoordinator`, current default (server → client).
|
||||
- [x] 14.5 `src/hosting/backup-coordinator.ts` — `BackupCoordinator`, client hosts, server overrides.
|
||||
|
||||
## 15. Spec
|
||||
|
||||
- [x] 15.1 Update `openspec/specs/network/spec.md` with `NET-56`.
|
||||
|
||||
## 16. Conformance tests
|
||||
|
||||
- [x] 16.1 `src/hosting/hosting.spec-conformance.test.ts` — 4 models, election behavior, token authority.
|
||||
|
||||
## 17. Verify
|
||||
|
||||
- [x] 17.1 `bunx turbo lint typecheck test --filter=@suaveplan/network-plugin-server-bridge` green.
|
||||
- [x] 17.2 `bunx turbo test:coverage --filter=@suaveplan/network-plugin-server-bridge` 100/100/100/100.
|
||||
- [x] 17.3 `bun scripts/openspec-conformance.ts @suaveplan/network-plugin-server-bridge` PASS.
|
||||
Reference in New Issue
Block a user