Files
suaveplan/openspec/archive/2026-05-12-network-observability-consolidation/proposal.md
2026-05-27 23:29:53 +01:00

5.9 KiB

OpenSpec Change: network-observability-consolidation

  • Change ID: network-observability-consolidation
  • Affects:
    • @suaveplan/network-plugin-monitor ✅ (shipped — extended)
    • @suaveplan/network-observability (upstream — folded in OR migrated as new plugin)
  • Category: universal
  • Status: PROPOSED (decision required at execution time)
  • Date: 2026-05-11
  • Parent: network-transport-family (2026-05-11) — Wave 6
  • Migration source: ../suaveplan/packages/universal/network-observability + ../suaveplan/enterprise/network-observability.md

Summary

Resolve the duplication between upstream @suaveplan/network-observability (application-monitoring observability layer for the mesh) and shipped @suaveplan/network-plugin-monitor ✅ (peer-quality + RTT/loss scorers + alert thresholds + OTel wiring across 12 modules). Both target the same problem space — network-tier telemetry.

This proposal does not write code. It captures the decision and the resulting work.


Decision required: fold vs. plugin

The shipped plugin already covers peer-quality scoring, RTT/loss, alert thresholds, and OTel. Upstream network-observability adds application-monitoring abstractions (probably topology metrics, event aggregation, dashboard primitives) — fold those into the shipped plugin as additional feature modules.

Pro: single canonical telemetry surface. Pro: no new package. Pro: consumers don't choose between two overlapping options.

Con: network-plugin-monitor grows. Mitigation: keep feature modules in their own subdirs, each ≤300 LOC.

Option B — Ship as separate @suaveplan/network-plugin-observability

Two plugins compose: monitor handles peer-quality, observability handles application-monitoring abstractions.

Pro: smaller plugins. Pro: tree-shake observability when not needed.

Con: consumers must wire both. Con: feature-creep boundary becomes blurry.

Recommendation: A. This proposal proceeds under A unless audit reveals upstream network-observability contains a fundamentally different abstraction (e.g. event-aggregation pipeline that doesn't fit the monitor plugin's per-peer model).


Current-state audit (perform at execution time)

Upstream coverage: 100%. Investigate what network-observability actually contains beyond what network-plugin-monitor ships:

ls ../suaveplan/packages/universal/network-observability/src/
diff <(grep -rh "^export" ../suaveplan/packages/universal/network-observability/src/) \
     <(grep -rh "^export" packages/network/network-plugin-monitor/src/)

Outcome of audit determines fold-or-split.


Parity Checklist (FINAL — audit complete 2026-05-12)

Decision: Option A — fold into @suaveplan/network-plugin-monitor.

Audit revealed upstream network-observability contains exactly three feature modules — all of them are output / export adapters for an external metric collector, not a fundamentally different application-monitoring abstraction:

Capability Upstream Existing (monitor) Verdict
Per-peer quality scoring 🚫 not present ✅ already covered
RTT / loss collectors 🚫 not present ✅ (MetricCollector, NetworkMonitor) already covered
Alert thresholds 🚫 not present ✅ (AlertEngine) already covered
OTel wiring (internal) 🚫 not present ✅ (@opentelemetry/api instruments across 12 modules) already covered
Prometheus exposition (text format) ✅ via prom-client 🚫 ⬆️ folded as prometheus/ (rewritten universal-tier, hand-rolled emitter; no prom-client dep)
Grafana dashboard JSON generator + presets ✅ 🚫 ⬆️ folded as grafana/ (pure data builder, injectable Rng)
OTel SDK exporter bridge ✅ via external SDK 🚫 (uses @opentelemetry/api directly per genesis convention) ❌ NOT folded — redundant; genesis monitor already emits via @opentelemetry/api so external SDKs pick up metrics natively
Application-monitoring abstractions 🚫 not present in upstream src n/a n/a
Event-aggregation pipeline 🚫 not present in upstream src n/a n/a
Topology metrics 🚫 not present in upstream src (handled by network-plugin-topology ✅) n/a

Why fold and not split: the upstream "package" is 1159 LOC total, only ~600 LOC of which is portable (prom-client and external @opentelemetry/sdk are deliberately not universal-tier and would taint a sibling). After portability filtering, only the Prometheus text emitter (~150 LOC) and Grafana JSON builder (~370 LOC) survive — too small for a sibling plugin, and they consume the existing monitor's MetricCollector.scrape() output directly. Folding makes a single canonical telemetry surface.

Why the OTel SDK exporter is dropped, not folded: the upstream otel-exporter.ts (293 LOC) is an adapter that wraps prom-client metrics into @opentelemetry/sdk-metrics observable instruments. Genesis's network-plugin-monitor already declares its instruments through @opentelemetry/api's MeterProvider — any externally-registered OTel SDK (@suaveplan/opentelemetry's NoopSdk/SdkFactory, or a user's NodeSDK) picks them up natively. The bridge is structurally redundant.


Acceptance gate

  1. Audit performed; Option A or B chosen with documented rationale.
  2. Bare @suaveplan/network-observability row removed from STATUS.md (becomes either folded-into-monitor or shipped as network-plugin-observability).
  3. bunx turbo lint typecheck test --filter='@suaveplan/network-plugin-monitor' (or new plugin) green.
  4. bunx turbo test:coverage 100/100/100/100 on the resulting package(s).
  5. STATUS.md updated; supersession table extended.

Out of scope

  • Cross-process observability federation (separate network-plugin-observability-otlp if needed).
  • Custom dashboard rendering (UI tier).