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

7.5 KiB

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

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

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

ADDED Requirements

Requirement: MonitorPlugin conforms to NetworkPlugin lifecycle

The package SHALL export a MonitorPlugin implements NetworkPlugin and SHALL provide an integrated metric collector, alert engine, tracer, history store, and sampler on install.

Scenario: install / uninstall lifecycle

  • WHEN a host installs then uninstalls the plugin
  • THEN the plugin reaches INSTALLED then UNINSTALLED and releases timers

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


Requirement: MetricCollector supports the four metric types

The package SHALL export MetricCollector, MetricCollectorConfig, and MetricDefinition. The collector SHALL support Counter, Gauge, Histogram, and Summary metric types and SHALL throw NetworkMonError(METRIC_NOT_FOUND) / METRIC_TYPE_MISMATCH on misuse.

Scenario: unknown metric raises typed error

  • WHEN collector.record("not-registered", 1) is called
  • THEN the call throws NetworkMonError with code === "NET_MON.METRIC_NOT_FOUND"

Verified by: src/collector/metric-collector.spec-conformance.test.ts::"throws METRIC_NOT_FOUND on unknown metric"


Requirement: AlertEngine enforces unique rule ids

The package SHALL export AlertEngine, AlertEngineConfig, and AlertBus. Adding two rules with the same id SHALL throw NetworkMonError(ALERT_RULE_DUPLICATE); operating on an unknown id SHALL throw NetworkMonError(ALERT_RULE_NOT_FOUND).

Scenario: duplicate rule id

  • WHEN engine.addRule({ id: "x", … }) is called twice
  • THEN the second call throws NetworkMonError(ALERT_RULE_DUPLICATE)

Verified by: src/alert/alert-engine.spec-conformance.test.ts::"throws ALERT_RULE_DUPLICATE on repeat id"


Requirement: GrafanaDashboardGenerator validates row titles with typed error

The package SHALL export GrafanaDashboardGenerator, GrafanaDashboardOptions, GrafanaDashboardOptionsSchema, DashboardJson, GrafanaPanelType, GridPos, and GridPosSchema. addRow(title) SHALL throw NetworkMonError(DASHBOARD_ROW_INVALID) when title is empty or whitespace-only. The class SHALL NOT throw bare Error.

Scenario: empty title raises typed error

  • WHEN generator.addRow("") is called
  • THEN the call throws NetworkMonError with code === "NET_MON.DASHBOARD_ROW_INVALID" and context.field === "title"

Verified by: src/grafana/dashboard-generator.spec-conformance.test.ts::"throws DASHBOARD_ROW_INVALID on empty title"


Requirement: BandwidthMonitor validates sample config with typed error

The package SHALL export BandwidthMonitor (in the quality module). The monitor SHALL throw NetworkMonError(BANDWIDTH_MONITOR_CONFIG_INVALID) whenever maxSamples is less than 1 or smoothingFactor is outside (0, 1]. The class SHALL NOT throw bare RangeError.

Scenario: invalid maxSamples

  • WHEN new BandwidthMonitor({ maxSamples: 0 }) is called
  • THEN the call throws NetworkMonError with code === "NET_MON.BANDWIDTH_MONITOR_CONFIG_INVALID" and context.field === "maxSamples"

Scenario: invalid smoothingFactor

  • WHEN new BandwidthMonitor({ smoothingFactor: 0 }) is called
  • THEN the call throws NetworkMonError with code === "NET_MON.BANDWIDTH_MONITOR_CONFIG_INVALID" and context.field === "smoothingFactor"

Verified by: src/quality/bandwidth-monitor.spec-conformance.test.ts::"throws BANDWIDTH_MONITOR_CONFIG_INVALID on maxSamples < 1" AND src/quality/bandwidth-monitor.spec-conformance.test.ts::"throws BANDWIDTH_MONITOR_CONFIG_INVALID on smoothingFactor out of range"


Requirement: DegradationManager validates hysteresis and window config with typed error

The package SHALL export DegradationManager (in the quality module). The manager SHALL throw NetworkMonError(DEGRADATION_CONFIG_INVALID) whenever hysteresisMs is negative or windowSize is less than 1.

Scenario: negative hysteresisMs

  • WHEN new DegradationManager({ hysteresisMs: -1 }) is called
  • THEN the call throws NetworkMonError with code === "NET_MON.DEGRADATION_CONFIG_INVALID" and context.field === "hysteresisMs"

Scenario: zero windowSize

  • WHEN new DegradationManager({ windowSize: 0 }) is called
  • THEN the call throws NetworkMonError with code === "NET_MON.DEGRADATION_CONFIG_INVALID" and context.field === "windowSize"

Verified by: src/quality/degradation-manager.spec-conformance.test.ts::"throws DEGRADATION_CONFIG_INVALID on negative hysteresisMs" AND src/quality/degradation-manager.spec-conformance.test.ts::"throws DEGRADATION_CONFIG_INVALID on zero windowSize"


Requirement: NetworkTracer propagates span context across mesh hops

The package SHALL export a tracer compatible with @opentelemetry/api. Operating on a closed span SHALL throw NetworkMonError(SPAN_NOT_OPEN).

Scenario: closed span raises typed error

  • WHEN tracer.addEvent(closedSpanId, …) is called
  • THEN the call throws NetworkMonError(SPAN_NOT_OPEN)

Verified by: src/tracer/network-tracer.spec-conformance.test.ts::"throws SPAN_NOT_OPEN on closed span"


Requirement: HistoricalDataStore enforces retention with typed error

The package SHALL export a historical store and an adaptive sampler. Invalid retention SHALL throw NetworkMonError(RETENTION_INVALID).

Scenario: invalid retention raises typed error

  • WHEN new HistoricalDataStore({ retentionMs: -1 }) is called
  • THEN the call throws NetworkMonError(RETENTION_INVALID)

Verified by: src/history/historical-data-store.spec-conformance.test.ts::"throws RETENTION_INVALID on negative retention"


Requirement: Error-code registry is frozen and namespaced NET_MON

NETWORK_MON_CODES SHALL be frozen under the NET_MON namespace and SHALL include at minimum: METRIC_NOT_FOUND, METRIC_TYPE_MISMATCH, ALERT_RULE_DUPLICATE, ALERT_RULE_NOT_FOUND, SPAN_NOT_OPEN, RETENTION_INVALID, and the new DASHBOARD_ROW_INVALID, BANDWIDTH_MONITOR_CONFIG_INVALID, DEGRADATION_CONFIG_INVALID.

Scenario: registry contains the three new codes

  • WHEN NETWORK_MON_CODES is inspected
  • THEN the three new codes map to their "NET_MON.<KEY>" values

Verified by: src/error-codes.spec-conformance.test.ts::"NETWORK_MON_CODES includes DASHBOARD_ROW_INVALID, BANDWIDTH_MONITOR_CONFIG_INVALID, DEGRADATION_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-monitor 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-monitor/README.md
  • THEN output is 1

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