Files
2026-05-27 23:29:53 +01:00

5.8 KiB

Capability Spec Delta: network-plugin-protocol (complete-network-plugins)

Package: @suaveplan/network-plugin-protocol Status: PROPOSED

Every requirement below carries a **Verified by:** line at authoring time.

ADDED Requirements

Requirement: BinaryProtocol header carries version and routing metadata

The package SHALL export a BinaryProtocol class together with the constants PROTOCOL_VERSION and HEADER_SIZE defining the fixed-width header used on the wire. Headers SHALL be opaque to consumers and addressed only through the encoder / decoder pair.

Scenario: header round-trips through encoder / decoder

  • WHEN a MessageEnvelope is encoded with MessageEncoder and decoded with MessageDecoder
  • THEN the round-trip produces a structurally-equal envelope and the decoded header carries the same PROTOCOL_VERSION constant

Verified by: src/protocol/protocol.spec-conformance.test.ts::"BinaryProtocol round-trips an envelope"


Requirement: MessageDecoder throws structured errors on malformed input

MessageDecoder SHALL throw NetworkProtoError (subclass of SuaveplanError) with code === "NET_PROTO.DESERIALIZATION_FAILED" and a context payload identifying the failure cause whenever the input buffer is too short, the header is invalid, or deserialization fails. The package SHALL NOT throw bare Error / TypeError / RangeError from any production code path.

Scenario: incomplete buffer raises typed error

  • WHEN MessageDecoder.decode is called with a buffer whose length is less than HEADER_SIZE
  • THEN the call throws NetworkProtoError with code === "NET_PROTO.DESERIALIZATION_FAILED" and context.reason === "incomplete-message"

Verified by: src/decoder/decoder.spec-conformance.test.ts::"throws NetworkProtoError on incomplete buffer"


Requirement: ProtocolPipeline composes ordered stages with backpressure

The package SHALL export ProtocolPipeline with a PipelineStage interface that consumers register in order. The pipeline SHALL invoke stages in registration order on encode and in reverse on decode.

Scenario: stages run in registration order on encode and reverse on decode

  • WHEN stages A, B are registered in that order and a message flows through encode-then-decode
  • THEN the observed call sequence is A.encode, B.encode, B.decode, A.decode

Verified by: src/pipeline/pipeline.spec-conformance.test.ts::"runs stages in declared order"


Requirement: PriorityMessageQueue rejects overflow with QUEUE_FULL

The package SHALL export PriorityMessageQueue and MessageBatcher. The queue SHALL throw NetworkProtoError(QUEUE_FULL) when an insert would exceed the configured capacity.

Scenario: insert beyond capacity raises QUEUE_FULL

  • WHEN the queue holds capacity messages and a further enqueue is attempted
  • THEN the call throws NetworkProtoError with code === "NET_PROTO.QUEUE_FULL"

Verified by: src/queue/queue.spec-conformance.test.ts::"throws QUEUE_FULL on overflow"


Requirement: ProtocolPlugin conforms to NetworkPlugin lifecycle

The package SHALL export ProtocolPlugin implements NetworkPlugin and a ProtocolPluginOptions type. The plugin SHALL register itself against the host on install, register pluggable serializers via the options object, and tear down state on uninstall.

Scenario: install registers the plugin and exposes encoder/decoder via the host

  • WHEN a host calls await plugin.install(host) followed by await plugin.uninstall(host)
  • THEN the plugin enters INSTALLED then UNINSTALLED lifecycle states and does not leak resources

Verified by: src/protocol/protocol-plugin.spec-conformance.test.ts::"install / uninstall lifecycle is clean"


Requirement: Error-code registry is frozen and namespaced NET_PROTO

NETWORK_PROTO_CODES SHALL be a frozen registry under the NET_PROTO namespace exporting at minimum: INVALID_HEADER, PAYLOAD_TOO_LARGE, SERIALIZATION_FAILED, DESERIALIZATION_FAILED, UNSUPPORTED_SERIALIZER, QUEUE_FULL, TTL_EXPIRED, LOOP_DETECTED, DUPLICATE_MESSAGE. Every code SHALL be reachable from at least one production throw site.

Scenario: registry membership

  • WHEN NETWORK_PROTO_CODES is inspected
  • THEN every key maps to a value of the form "NET_PROTO.<KEY>"

Verified by: src/error-codes.spec-conformance.test.ts::"NETWORK_PROTO_CODES is frozen and prefixed NET_PROTO"


Requirement: No bare-Error throws in production code

The package SHALL NOT contain any throw new Error(...), throw new TypeError(...), throw new RangeError(...), or throw new SyntaxError(...) statement inside src/ (excluding *.test.ts and *.spec-conformance.test.ts). Every production failure path SHALL throw NetworkProtoError (or a SuaveplanError subclass from a transitive dependency).

Scenario: source grep returns zero hits

  • WHEN grep -rnE "throw new (Error|TypeError|RangeError|SyntaxError)\(" packages/network/network-plugin-protocol/src/ --include="*.ts" is run, excluding *.test.ts
  • THEN the output is empty

Verified by: tests/no-bare-throws.test.ts::"network-plugin-protocol src/ has no bare Error throws"


Requirement: README is auto-docs idempotent

The package README.md SHALL contain exactly one balanced <!-- begin:auto-docs --> … <!-- end:auto-docs --> block. Re-running bun scripts/generate-package-module-tree.ts SHALL produce a byte-identical file.

Scenario: marker count is exactly one

  • WHEN grep -c "begin:auto-docs" packages/network/network-plugin-protocol/README.md is run
  • THEN the output is 1

Verified by: scripts/generate-package-module-tree.test.ts::"README regen is idempotent for network-plugin-protocol"