Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,125 @@
<!-- markdownlint-disable MD024 -->
# Capability Spec Delta: network-plugin-state (complete-network-plugins)
**Package**: `@suaveplan/network-plugin-state`
**Status**: PROPOSED
> Every requirement below carries a `**Verified by:**` line at authoring time.
## ADDED Requirements
### Requirement: StatePlugin conforms to NetworkPlugin lifecycle
The package SHALL export `StatePlugin implements NetworkPlugin` and `StatePluginConfig`. The plugin SHALL manage state synchronization, delta compression, history pruning, and reconciliation against peer states.
#### Scenario: install / uninstall lifecycle
- **WHEN** a host installs then uninstalls the plugin
- **THEN** the plugin reaches `INSTALLED` then `UNINSTALLED` cleanly
**Verified by:** `src/plugin/state-plugin.spec-conformance.test.ts::"install / uninstall lifecycle is clean"`
---
### Requirement: BloomFilter and BloomFilterComparator detect divergence
The package SHALL export `BloomFilter`, `BloomFilterComparator`, and `BloomFilterConfig`. The comparator SHALL diff two bit-vectors of equal byte-length and return the set of suspected divergent slots.
#### Scenario: comparator finds divergent slots
- **WHEN** two filters of the same configuration are compared
- **THEN** the result identifies slots set in one and unset in the other
**Verified by:** `src/bloom/bloom-filter-comparator.spec-conformance.test.ts::"diff identifies divergent slots"`
---
### Requirement: BloomFilterComparator rejects length-mismatch with typed error
`BloomFilterComparator` SHALL throw `NetworkStateError` with `code === "NET_STATE.BLOOM_LENGTH_MISMATCH"` and a `context` payload carrying both byte lengths whenever the two filters' byte arrays have different sizes. The class SHALL NOT throw bare `Error`.
#### Scenario: byte-length mismatch
- **WHEN** two bloom filters of byte lengths 8 and 16 are compared
- **THEN** the call throws `NetworkStateError` with `code === "NET_STATE.BLOOM_LENGTH_MISMATCH"` and `context === { left: 8, right: 16 }`
**Verified by:** `src/bloom/bloom-filter-comparator.spec-conformance.test.ts::"throws BLOOM_LENGTH_MISMATCH on byte-length mismatch"`
---
### Requirement: DeltaCompressor produces and applies state diffs
The package SHALL export `DeltaCompressor` that takes prior and next state snapshots and produces a compact delta that, when applied to the prior, reconstructs the next.
#### Scenario: delta round-trip reconstructs next state
- **WHEN** `apply(prev, compress(prev, next))` is computed
- **THEN** the result is structurally equal to `next`
**Verified by:** `src/delta/delta-compressor.spec-conformance.test.ts::"compress / apply round-trip"`
---
### Requirement: Reconciler deepMerge merges peer-state branches
The package SHALL export `deepMerge` and a reconciler abstraction that merges two state branches under a configurable strategy. Missing strategy keys SHALL raise `NetworkStateError(STRATEGY_MISSING_MERGE)`.
#### Scenario: missing strategy raises typed error
- **WHEN** a reconciler is run with no strategy registered for the key in conflict
- **THEN** the call throws `NetworkStateError` with `code === "NET_STATE.STRATEGY_MISSING_MERGE"`
**Verified by:** `src/reconciler/reconciler.spec-conformance.test.ts::"throws STRATEGY_MISSING_MERGE when no strategy registered"`
---
### Requirement: StateHistoryPruner enforces retention policy
The package SHALL export `StateHistoryPruner` and `StateHistoryPrunerConfig`. The pruner SHALL drop history entries older than the configured retention window and SHALL raise `NetworkStateError(PRUNE_INVALID_RETENTION)` on invalid retention configuration.
#### Scenario: invalid retention raises typed error
- **WHEN** `new StateHistoryPruner({ retentionMs: -1 })` is called
- **THEN** the call throws `NetworkStateError` with `code === "NET_STATE.PRUNE_INVALID_RETENTION"`
**Verified by:** `src/pruner/state-history-pruner.spec-conformance.test.ts::"throws PRUNE_INVALID_RETENTION on negative window"`
---
### Requirement: Error-code registry is frozen and namespaced NET_STATE
`NETWORK_STATE_CODES` SHALL be frozen under the `NET_STATE` namespace and SHALL include at minimum: `PATH_INVALID`, `STRATEGY_MISSING_MERGE`, `DELTA_OUT_OF_ORDER`, `RESOURCE_PROFILE_UNKNOWN`, `PRUNE_INVALID_RETENTION`, and the new `BLOOM_LENGTH_MISMATCH`.
#### Scenario: registry contains BLOOM_LENGTH_MISMATCH
- **WHEN** `NETWORK_STATE_CODES` is inspected
- **THEN** `BLOOM_LENGTH_MISMATCH` maps to `"NET_STATE.BLOOM_LENGTH_MISMATCH"`
**Verified by:** `src/error-codes.spec-conformance.test.ts::"NETWORK_STATE_CODES includes BLOOM_LENGTH_MISMATCH"`
---
### Requirement: No bare-Error throws in production code
`src/` SHALL contain zero bare `throw new (Error|TypeError|RangeError|SyntaxError)\(` sites outside test files.
#### Scenario: source grep returns zero hits
- **WHEN** `grep -rnE "throw new (Error|TypeError|RangeError|SyntaxError)\(" packages/network/network-plugin-state/src/ --include="*.ts"` excluding tests
- **THEN** the output is empty
**Verified by:** `tests/no-bare-throws.test.ts::"network-plugin-state src/ has no bare Error throws"`
---
### Requirement: README is auto-docs idempotent
The package `README.md` SHALL contain exactly one balanced auto-docs block; the generator SHALL produce a byte-identical file on a second run.
#### Scenario: marker count is exactly one
- **WHEN** `grep -c "begin:auto-docs" packages/network/network-plugin-state/README.md`
- **THEN** output is `1`
**Verified by:** `scripts/generate-package-module-tree.test.ts::"README regen is idempotent for network-plugin-state"`