Initial Commit
This commit is contained in:
96
openspec/archive/2026-05-04-network-plugin-state/proposal.md
Normal file
96
openspec/archive/2026-05-04-network-plugin-state/proposal.md
Normal file
@@ -0,0 +1,96 @@
|
||||
# OpenSpec Change: network-plugin-state
|
||||
|
||||
- **Change ID**: network-plugin-state
|
||||
- **Package**: `@suaveplan/network-plugin-state` (new)
|
||||
- **Status**: PROPOSED
|
||||
- **Type**: new-package
|
||||
- **Date**: 2026-04-29
|
||||
|
||||
## Why
|
||||
|
||||
Multiplayer games and collaborative applications require synchronized state across all peers in a mesh. Without a dedicated state synchronization layer, each application must implement its own conflict resolution, delta compression, and reconnection handling. This leads to inconsistent state, bandwidth waste, and race conditions. The genesis `bitpacker` package provides efficient binary delta compression, and `serialize` provides schemas. This plugin implements a mesh-wide state store with automatic conflict resolution.
|
||||
|
||||
This plugin implements **synchronized state with delta compression, path-specific conflict resolution, and Bloom filter comparison** for efficient sync.
|
||||
|
||||
## What changes
|
||||
|
||||
- **ADDED**: `StatePlugin` class implementing `NetworkPlugin`.
|
||||
- **ADDED**: `StateManager` — maintains a versioned local state store with path-based access (`get(path)`, `set(path, value)`). Tracks state history with sequence numbers. Supports subscriptions per path.
|
||||
- **ADDED**: `DeltaCompressor` — computes deltas between state versions using `@suaveplan/bitpacker`. Only changed properties are transmitted. Supports schema-aware compression for typed data.
|
||||
- **ADDED**: `StateReconciler` — resolves conflicts between concurrent state updates with 5 strategies:
|
||||
- `latest-wins` — highest timestamp wins
|
||||
- `remote-wins` — always accept remote state
|
||||
- `local-wins` — always keep local state
|
||||
- `deep-merge` — combine non-conflicting properties recursively
|
||||
- `custom` — application-provided merge function
|
||||
- **ADDED**: `PathStrategyRegistry` — applies different reconciliation strategies per state path. Example: `game/positions` uses `latest-wins`, `game/inventory` uses `deep-merge`, `game/achievements` uses `remote-wins`.
|
||||
- **ADDED**: `BloomFilterComparator` — uses Bloom filters for efficient state comparison. Peers exchange compact Bloom filter summaries to detect divergence without transmitting full state.
|
||||
- **ADDED**: `StateSyncEngine` — orchestrates sync: detect divergence (Bloom filter), request delta, apply delta, resolve conflicts, notify subscribers. Supports full-state sync for new peers and delta sync for existing peers.
|
||||
- **ADDED**: `ResourceAdapter` — adapts sync behavior based on device profile:
|
||||
- `EDGE` — minimal history, aggressive compression, low sync frequency
|
||||
- `MOBILE` — balanced compression, medium sync frequency, battery-aware
|
||||
- `DESKTOP` — full history, fast sync, high responsiveness
|
||||
- `CLOUD` — maximum throughput, aggressive batching
|
||||
- **ADDED**: `StateHistoryPruner` — prunes old history based on memory constraints and policy. Configurable retention window.
|
||||
- **ADDED**: `NETWORK_STATE_CODES` — frozen error registry.
|
||||
|
||||
## State sync flow
|
||||
|
||||
```text
|
||||
Peer A changes state at path "game/positions/player1"
|
||||
↓
|
||||
StateManager records change with sequence + timestamp
|
||||
↓
|
||||
DeltaCompressor computes delta from previous version
|
||||
↓
|
||||
StateSyncEngine broadcasts delta to mesh peers
|
||||
↓
|
||||
Peer B receives delta
|
||||
↓
|
||||
StateReconciler applies strategy for "game/positions/*" (latest-wins)
|
||||
↓
|
||||
StateManager updates local state, notifies subscribers
|
||||
```
|
||||
|
||||
## Out of scope
|
||||
|
||||
- Game-specific entity replication (ECS) → `gaming-ecs`, `gaming-r3f-networking`.
|
||||
- Persistent state storage → future `network-plugin-state-persistence`.
|
||||
- CRDT implementations → future `network-plugin-state-crdt`.
|
||||
|
||||
## Source mapping
|
||||
|
||||
This derives from `docs/old-network-planning/PHASE_7.md` §State Management and `PLAN_ENHANCED_PHASE_7.md`.
|
||||
|
||||
| Requirement | Source lines | Notes |
|
||||
|---|---|---|
|
||||
| State history tracking | `PHASE_7.md` §StateManager | reworded; path-based instead of object-based |
|
||||
| Delta compression | `PHASE_7.md` §BitPackerCompressor | reworded; uses `@suaveplan/bitpacker` |
|
||||
| Reconciliation strategies | `PHASE_7.md` §StateReconciler | verbatim: 5 strategies |
|
||||
| Path-specific resolution | `PHASE_7.md` §Path-specific Resolution | verbatim |
|
||||
| Bloom filter comparison | `ADAPT_3.md` §Performance Optimizations | reworded; for state divergence detection |
|
||||
| Resource profiles | `PLAN_ENHANCED_PHASE_7.md` §Resource Profiles | reworded; 4 profiles |
|
||||
|
||||
### Requirements with no source line
|
||||
|
||||
| Requirement | Justification |
|
||||
|---|---|
|
||||
| `StateSyncEngine` orchestration | Required to automate the full sync pipeline |
|
||||
| `StateHistoryPruner` | Required to prevent unbounded memory growth |
|
||||
| Subscriptions per path | Required for reactive UI updates |
|
||||
|
||||
## Verification approach
|
||||
|
||||
- `src/state/state.spec-conformance.test.ts` — pins get/set, path access, history, subscriptions.
|
||||
- `src/delta/delta.spec-conformance.test.ts` — pins delta computation, roundtrip, schema encoding.
|
||||
- `src/reconciler/reconciler.spec-conformance.test.ts` — pins all 5 strategies, path-specific application.
|
||||
- `src/sync/sync.spec-conformance.test.ts` — pins divergence detection, delta request, full-state sync.
|
||||
- `src/bloom/bloom.spec-conformance.test.ts` — pins filter comparison, false-positive tolerance.
|
||||
- `src/resource/resource.spec-conformance.test.ts` — pins profile adaptation, compression level, sync frequency.
|
||||
- `src/pruner/pruner.spec-conformance.test.ts` — pins retention window, memory bounds.
|
||||
- `src/error-codes.spec-conformance.test.ts` — frozen registry.
|
||||
- `tests/dep-graph.test.ts` — pins direct import of `@suaveplan/bitpacker`.
|
||||
|
||||
## Migration impact
|
||||
|
||||
None — additive only.
|
||||
96
openspec/archive/2026-05-04-network-plugin-state/tasks.md
Normal file
96
openspec/archive/2026-05-04-network-plugin-state/tasks.md
Normal file
@@ -0,0 +1,96 @@
|
||||
# Tasks — network-plugin-state
|
||||
|
||||
> Blocked on: `network-core`, `network-plugin-registry`.
|
||||
|
||||
## 1. Scaffold
|
||||
|
||||
- [x] 1.1 `packages/network/network-plugin-state/` with `package.json` (`@suaveplan/network-plugin-state@0.0.0`), `tsconfig.json`, `vitest.config.ts`, `README.md`.
|
||||
- [x] 1.2 Workspace deps: `@suaveplan/network`, `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/events`, `@suaveplan/bitpacker`, `@suaveplan/serialize`, `@suaveplan/timing`, `@opentelemetry/api`, `zod`.
|
||||
- [x] 1.3 `sideEffects: false`.
|
||||
|
||||
## 2. Types
|
||||
|
||||
- [x] 2.1 `src/types/state.types.ts` — `StateValue`, `StatePath`, `StateSequence`, `StateSnapshot`.
|
||||
- [x] 2.2 `src/types/reconciliation.types.ts` — `ReconciliationStrategy`, `ConflictResolution`, `PathStrategy`.
|
||||
- [x] 2.3 `src/types/sync.types.ts` — `SyncMode`, `DeltaMessage`, `FullSyncMessage`.
|
||||
- [x] 2.4 `src/error-codes.ts` — `defineCodes("NET_STATE", [...])`.
|
||||
|
||||
## 3. State manager
|
||||
|
||||
- [x] 3.1 `src/state/state-manager.ts` — `StateManager`.
|
||||
- [x] 3.2 Path-based access: `get(path)`, `set(path, value)`, `delete(path)`.
|
||||
- [x] 3.3 Versioned history with sequence numbers and timestamps.
|
||||
- [x] 3.4 Per-path subscriptions: `subscribe(path, callback)`.
|
||||
|
||||
## 4. Delta compressor
|
||||
|
||||
- [x] 4.1 `src/delta/delta-compressor.ts` — `DeltaCompressor`.
|
||||
- [x] 4.2 Computes deltas using `@suaveplan/bitpacker`.
|
||||
- [x] 4.3 Schema-aware compression for typed data.
|
||||
- [x] 4.4 Roundtrip encode/decode verification.
|
||||
|
||||
## 5. State reconciler
|
||||
|
||||
- [x] 5.1 `src/reconciler/state-reconciler.ts` — `StateReconciler`.
|
||||
- [x] 5.2 Strategies: `latest-wins`, `remote-wins`, `local-wins`, `deep-merge`, `custom`.
|
||||
- [x] 5.3 Deterministic outcomes for same inputs.
|
||||
- [x] 5.4 Reports conflicts with path, local value, remote value.
|
||||
|
||||
## 6. Path strategy registry
|
||||
|
||||
- [x] 6.1 `src/strategy/path-strategy-registry.ts` — `PathStrategyRegistry`.
|
||||
- [x] 6.2 Maps glob/regex patterns to reconciliation strategies.
|
||||
- [x] 6.3 Examples: `game/positions/*` → `latest-wins`, `game/inventory/*` → `deep-merge`.
|
||||
|
||||
## 7. Bloom filter comparator
|
||||
|
||||
- [x] 7.1 `src/bloom/bloom-filter-comparator.ts` — `BloomFilterComparator`.
|
||||
- [x] 7.2 Generates compact Bloom filter from state paths.
|
||||
- [x] 7.3 Detects divergence with configurable false-positive rate (default 1%).
|
||||
|
||||
## 8. State sync engine
|
||||
|
||||
- [x] 8.1 `src/sync/state-sync-engine.ts` — `StateSyncEngine`.
|
||||
- [x] 8.2 Full-state sync for new peers.
|
||||
- [x] 8.3 Delta sync for existing peers (Bloom filter divergence detection).
|
||||
- [x] 8.4 Conflict resolution via `StateReconciler`.
|
||||
- [x] 8.5 Notifies subscribers after sync.
|
||||
|
||||
## 9. Resource adapter
|
||||
|
||||
- [x] 9.1 `src/resource/resource-adapter.ts` — `ResourceAdapter`.
|
||||
- [x] 9.2 Profiles: `EDGE`, `MOBILE`, `DESKTOP`, `CLOUD`.
|
||||
- [x] 9.3 Adjusts compression level, history retention, sync frequency per profile.
|
||||
|
||||
## 10. State history pruner
|
||||
|
||||
- [x] 10.1 `src/pruner/state-history-pruner.ts` — `StateHistoryPruner`.
|
||||
- [x] 10.2 Configurable retention window (default: 5 minutes).
|
||||
- [x] 10.3 Memory-bound pruning: drops oldest when memory threshold exceeded.
|
||||
|
||||
## 11. Plugin wrapper
|
||||
|
||||
- [x] 11.1 `src/plugin/state-plugin.ts` — `StatePlugin` implements `NetworkPlugin`.
|
||||
- [x] 11.2 Installs state manager, sync engine, pruner on `install()`.
|
||||
- [x] 11.3 Subscribes to `peer:joined` for full-state sync, `peer:left` for cleanup.
|
||||
|
||||
## 12. Spec
|
||||
|
||||
- [x] 12.1 Update `openspec/specs/network/spec.md` with `NET-42`.
|
||||
|
||||
## 13. Conformance tests
|
||||
|
||||
- [x] 13.1 `src/state/state.spec-conformance.test.ts` — get/set, paths, history, subscriptions.
|
||||
- [x] 13.2 `src/delta/delta.spec-conformance.test.ts` — delta compute, roundtrip, schema.
|
||||
- [x] 13.3 `src/reconciler/reconciler.spec-conformance.test.ts` — 5 strategies, path-specific.
|
||||
- [x] 13.4 `src/sync/sync.spec-conformance.test.ts` — divergence, delta request, full sync.
|
||||
- [x] 13.5 `src/bloom/bloom.spec-conformance.test.ts` — filter comparison, false-positive tolerance.
|
||||
- [x] 13.6 `src/resource/resource.spec-conformance.test.ts` — profile adaptation.
|
||||
- [x] 13.7 `src/pruner/pruner.spec-conformance.test.ts` — retention, memory bounds.
|
||||
- [x] 13.8 `src/error-codes.spec-conformance.test.ts` — frozen registry.
|
||||
|
||||
## 14. Verify
|
||||
|
||||
- [x] 14.1 `bunx turbo lint typecheck test --filter=@suaveplan/network-plugin-state` green.
|
||||
- [x] 14.2 `bunx turbo test:coverage --filter=@suaveplan/network-plugin-state` 100/100/100/100.
|
||||
- [x] 14.3 `bun scripts/openspec-conformance.ts @suaveplan/network-plugin-state` PASS.
|
||||
Reference in New Issue
Block a user