4.1 KiB
Capability Spec Delta: network-plugin-partition (complete-network-plugins)
Package: @suaveplan/network-plugin-partition
Status: PROPOSED
Every requirement below carries a
**Verified by:**line at authoring time. First canonical spec for this package.
ADDED Requirements
Requirement: PartitionDetector identifies split-brain network conditions
The package SHALL export PartitionDetector, PartitionDetectorConfig, and PartitionView. The detector SHALL emit a split-brain view when the observed peer graph splits into two or more disjoint components and SHALL throw PartitionError(SPLIT_BRAIN_DETECTED) from any operation that depends on a unified view while the split persists.
Scenario: graph splits into two components
- WHEN the detector observes two disjoint reachability components for at least
confirmationMs - THEN the next
view()call returns aPartitionViewwithkind === "split-brain"and two component sets
Verified by: src/detector/detector.spec-conformance.test.ts::"detects split-brain when graph splits"
Requirement: QuorumResolver picks a winning component under configurable strategy
The package SHALL export QuorumResolver, QuorumResolverConfig, and a QuorumStrategy union "size" | "performance" | "age" | "hybrid". The resolver SHALL return a single winning component per split, deterministically, given the same inputs. If no component qualifies, the resolver SHALL throw PartitionError(QUORUM_UNRESOLVED).
Scenario: size strategy prefers larger component
- WHEN strategy is
"size"and components have sizes 5 and 3 - THEN the resolver returns the 5-node component as the winner
Scenario: no component qualifies
- WHEN no component meets the configured threshold
- THEN the call throws
PartitionError(QUORUM_UNRESOLVED)
Verified by: src/quorum/quorum.spec-conformance.test.ts::"size strategy returns larger component" AND src/quorum/quorum.spec-conformance.test.ts::"throws QUORUM_UNRESOLVED when no component qualifies"
Requirement: MergeProtocol reconciles divergent component states
The package SHALL export MergeProtocol, MergeProtocolConfig, MergeResult, and a generic Reconciler<T> interface. The protocol SHALL invoke the registered reconciler per state key during a heal event and SHALL throw PartitionError(MERGE_FAILED) when the reconciler reports an unresolvable conflict.
Scenario: reconciler reports unresolvable conflict
- WHEN a reconciler returns a conflict indicator for a key during merge
- THEN the call throws
PartitionError(MERGE_FAILED)withcontext.keypopulated
Verified by: src/merge/merge.spec-conformance.test.ts::"throws MERGE_FAILED on unresolvable conflict"
Requirement: Error-code registry is frozen and namespaced NET_PART
PARTITION_CODES SHALL be frozen under the NET_PART namespace and SHALL include exactly: SPLIT_BRAIN_DETECTED, QUORUM_UNRESOLVED, MERGE_FAILED. Every code SHALL be reachable from a production throw site.
Scenario: registry membership
- WHEN
PARTITION_CODESis inspected - THEN every key maps to a value of the form
"NET_PART.<KEY>"
Verified by: src/error-codes.spec-conformance.test.ts::"PARTITION_CODES is frozen and prefixed NET_PART"
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 the grep is run
- THEN the output is empty
Verified by: tests/no-bare-throws.test.ts::"network-plugin-partition 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-partition/README.md - THEN output is
1
Verified by: scripts/generate-package-module-tree.test.ts::"README regen is idempotent for network-plugin-partition"