Initial Commit
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
<!-- markdownlint-disable MD024 -->
|
||||
|
||||
# Capability Spec Delta: network-plugin-qos (complete-network-plugins)
|
||||
|
||||
**Package**: `@suaveplan/network-plugin-qos`
|
||||
**Status**: PROPOSED
|
||||
|
||||
> Every requirement below carries a `**Verified by:**` line at authoring time. First canonical spec for this package.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: MessagePriorityClassifier classifies messages into a fixed QoS lattice
|
||||
|
||||
The package SHALL export `MessagePriorityClassifier`, `MessagePriorityClassifierConfig`, `ClassificationRule`, and a `QoSClass` union `"URGENT" | "CONTROL" | "DATA" | "BULK"`. The classifier SHALL evaluate registered rules in priority order and SHALL return a deterministic `QoSClass` for every input.
|
||||
|
||||
#### Scenario: first matching rule wins
|
||||
|
||||
- **WHEN** two rules match an input and the first is registered with higher priority
|
||||
- **THEN** the classifier returns the class assigned by the first rule
|
||||
|
||||
**Verified by:** `src/classifier/classifier.spec-conformance.test.ts::"first matching rule wins"`
|
||||
|
||||
---
|
||||
|
||||
### Requirement: BandwidthQuotaEnforcer applies per-class quota with typed overflow
|
||||
|
||||
The package SHALL export `BandwidthQuotaEnforcer` and `BandwidthQuotaEnforcerConfig`. The enforcer SHALL maintain a token-bucket per `QoSClass` and SHALL throw `QosError(QUOTA_EXCEEDED)` when a send attempt would exhaust the bucket for the message's class.
|
||||
|
||||
#### Scenario: quota exhausted
|
||||
|
||||
- **WHEN** the bucket for `"BULK"` is empty and a `"BULK"` message of size > 0 is offered
|
||||
- **THEN** the call throws `QosError` with `code === "NET_QOS.QUOTA_EXCEEDED"` and `context.class === "BULK"`
|
||||
|
||||
**Verified by:** `src/enforcer/enforcer.spec-conformance.test.ts::"throws QUOTA_EXCEEDED when bucket is empty"`
|
||||
|
||||
---
|
||||
|
||||
### Requirement: CongestionMonitor reports a binary congestion state to listeners
|
||||
|
||||
The package SHALL export `CongestionMonitor`, `CongestionMonitorConfig`, and a `CongestionListener` type. The monitor SHALL emit `"congested"` when sustained backpressure crosses the configured threshold and `"recovered"` when it falls back.
|
||||
|
||||
#### Scenario: threshold transition
|
||||
|
||||
- **WHEN** measured backlog rises above the threshold for the dwell time
|
||||
- **THEN** every registered listener receives `"congested"`
|
||||
|
||||
**Verified by:** `src/monitor/congestion-monitor.spec-conformance.test.ts::"emits congested on sustained backpressure"`
|
||||
|
||||
---
|
||||
|
||||
### Requirement: QoSRouter decides per-message action under load
|
||||
|
||||
The package SHALL export `QoSRouter`, `QoSRouterConfig`, a `QoSAction` union `"bypass" | "send" | "queue" | "drop" | "defer"`, and a `QoSDecision` record. The router SHALL combine the classifier's `QoSClass` with the enforcer's quota state and the monitor's congestion state to produce a deterministic `QoSDecision` per message.
|
||||
|
||||
#### Scenario: congested + over-quota bulk message is dropped
|
||||
|
||||
- **WHEN** the monitor reports `"congested"` and the bulk bucket is empty
|
||||
- **THEN** `router.decide(msg)` returns `{ action: "drop", class: "BULK", reason }`
|
||||
|
||||
**Verified by:** `src/router/qos-router.spec-conformance.test.ts::"drops bulk message when congested and over quota"`
|
||||
|
||||
---
|
||||
|
||||
### Requirement: Error-code registry is frozen and namespaced NET_QOS
|
||||
|
||||
`QOS_CODES` SHALL be frozen under the `NET_QOS` namespace and SHALL include at minimum `QUOTA_EXCEEDED`. Every code SHALL be reachable from a production throw site.
|
||||
|
||||
#### Scenario: registry membership
|
||||
|
||||
- **WHEN** `QOS_CODES` is inspected
|
||||
- **THEN** every key maps to a value of the form `"NET_QOS.<KEY>"`
|
||||
|
||||
**Verified by:** `src/error-codes.spec-conformance.test.ts::"QOS_CODES is frozen and prefixed NET_QOS"`
|
||||
|
||||
---
|
||||
|
||||
### 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-qos 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-qos/README.md`
|
||||
- **THEN** output is `1`
|
||||
|
||||
**Verified by:** `scripts/generate-package-module-tree.test.ts::"README regen is idempotent for network-plugin-qos"`
|
||||
Reference in New Issue
Block a user