6.3 KiB
Capability Spec Delta: network-plugin-intra-relay (complete-network-plugins)
Package: @suaveplan/network-plugin-intra-relay
Status: PROPOSED
Every requirement below carries a
**Verified by:**line at authoring time.
ADDED Requirements
Requirement: IntraRelayPlugin conforms to NetworkPlugin lifecycle
The package SHALL export IntraRelayPlugin implements NetworkPlugin. The plugin SHALL manage relay-path discovery, connection lifecycle, envelope wrap/unwrap, and security on install.
Scenario: install / uninstall lifecycle
- WHEN a host installs then uninstalls the plugin
- THEN the plugin reaches
INSTALLEDthenUNINSTALLEDcleanly
Verified by: src/plugin/intra-relay-plugin.spec-conformance.test.ts::"install / uninstall lifecycle is clean"
Requirement: RelayEnvelope wraps and unwraps inner messages with hop tracking
The package SHALL export wrapEnvelope, unwrapEnvelope, advanceEnvelope, nextHopFor, WrapInput, InnerMessage, and DEFAULT_MAX_HOPS. Each hop SHALL increment a counter; the envelope SHALL throw NetworkIntraRelayError(MAX_HOPS_EXCEEDED) when the counter would exceed the configured limit.
Scenario: hop counter increments per advance
- WHEN
advanceEnvelopeis called twice on a fresh envelope - THEN the envelope's hop count is 2
Verified by: src/envelope/relay-envelope.spec-conformance.test.ts::"advance increments hop counter"
Requirement: RelayPerformanceMonitor validates hysteresis config with typed error
The package SHALL export RelayPerformanceMonitor. The class SHALL throw NetworkIntraRelayError(HYSTERESIS_CONFIG_INVALID) whenever hysteresis configuration is missing, negative, or non-finite. The class SHALL NOT throw bare Error.
Scenario: invalid hysteresis config raises typed error
- WHEN
new RelayPerformanceMonitor({ hysteresisMs: -1 })is called - THEN the call throws
NetworkIntraRelayErrorwithcode === "NET_INTRA_RELAY.HYSTERESIS_CONFIG_INVALID"
Verified by: src/monitor/relay-performance-monitor.spec-conformance.test.ts::"throws HYSTERESIS_CONFIG_INVALID on negative hysteresis"
Requirement: RelaySecurityManager validates rate-limit config with typed error
RelaySecurityManager SHALL throw NetworkIntraRelayError(RATE_LIMIT_CONFIG_INVALID) whenever refillRatePerSec or burstSize is zero, negative, or non-finite. The class SHALL NOT throw bare RangeError.
Scenario: zero burstSize raises typed error
- WHEN
new RelaySecurityManager({ rateLimit: { burstSize: 0, … } })is called - THEN the call throws
NetworkIntraRelayErrorwithcode === "NET_INTRA_RELAY.RATE_LIMIT_CONFIG_INVALID"andcontext.field === "burstSize"
Scenario: negative refillRatePerSec raises typed error
- WHEN
new RelaySecurityManager({ rateLimit: { refillRatePerSec: -1, … } })is called - THEN the call throws
NetworkIntraRelayErrorwithcode === "NET_INTRA_RELAY.RATE_LIMIT_CONFIG_INVALID"andcontext.field === "refillRatePerSec"
Verified by: src/security/relay-security-manager.spec-conformance.test.ts::"throws RATE_LIMIT_CONFIG_INVALID on zero burstSize" AND src/security/relay-security-manager.spec-conformance.test.ts::"throws RATE_LIMIT_CONFIG_INVALID on negative refillRatePerSec"
Requirement: RelayDiscovery surfaces candidates and tracks peer snapshots
The package SHALL export RelayDiscovery, RelayDiscoveryConfig, and PeerSnapshot. The discovery SHALL maintain a per-peer snapshot and SHALL throw NetworkIntraRelayError(NO_RELAY_CANDIDATE) when asked for a candidate and none qualify.
Scenario: no candidate available
- WHEN
discovery.pickCandidate()is called with no qualifying peers - THEN the call throws
NetworkIntraRelayError(NO_RELAY_CANDIDATE)
Verified by: src/discovery/relay-discovery.spec-conformance.test.ts::"throws NO_RELAY_CANDIDATE when no qualifying peers"
Requirement: RelayConnectionManager enforces a finite state machine
The package SHALL export RelayConnectionManager, RelayConnectionManagerConfig, and the RELAY_TRANSITIONS table. Illegal transitions SHALL throw NetworkIntraRelayError(INVALID_TRANSITION).
Scenario: illegal transition raises typed error
- WHEN the manager is asked to transition from
CLOSEDdirectly toSTREAMING - THEN the call throws
NetworkIntraRelayErrorwithcode === "NET_INTRA_RELAY.INVALID_TRANSITION"
Verified by: src/connection/relay-connection-manager.spec-conformance.test.ts::"throws INVALID_TRANSITION on illegal state move"
Requirement: Error-code registry is frozen and namespaced NET_INTRA_RELAY
NETWORK_INTRA_RELAY_CODES SHALL be frozen under the NET_INTRA_RELAY namespace and SHALL include at minimum: NO_RELAY_CANDIDATE, RELAY_LOOP_DETECTED, MAX_HOPS_EXCEEDED, INVALID_TRANSITION, PATH_NOT_FOUND, PATH_ALREADY_EXISTS, STRATEGY_UNKNOWN, ENVELOPE_INVALID, RELAY_SIGNATURE_INVALID, RELAY_PEER_UNTRUSTED, RELAY_RATE_LIMIT_EXCEEDED, and the new HYSTERESIS_CONFIG_INVALID, RATE_LIMIT_CONFIG_INVALID.
Scenario: registry contains the two new codes
- WHEN
NETWORK_INTRA_RELAY_CODESis inspected - THEN
HYSTERESIS_CONFIG_INVALIDandRATE_LIMIT_CONFIG_INVALIDmap to their"NET_INTRA_RELAY.<KEY>"values
Verified by: src/error-codes.spec-conformance.test.ts::"NETWORK_INTRA_RELAY_CODES includes HYSTERESIS_CONFIG_INVALID and RATE_LIMIT_CONFIG_INVALID"
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-intra-relay 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-intra-relay/README.md - THEN output is
1
Verified by: scripts/generate-package-module-tree.test.ts::"README regen is idempotent for network-plugin-intra-relay"