4.5 KiB
OpenSpec Change: network-quality-consolidation
- Change ID: network-quality-consolidation
- Affects:
@suaveplan/network-plugin-monitor✅ (extended) OR new@suaveplan/network-plugin-quality@suaveplan/network-quality(upstream — folded or migrated)
- Category: universal
- Status: ARCHIVED 2026-05-12 — Option A executed
- Date: 2026-05-11
- Parent:
network-transport-family(2026-05-11) — Wave 6 - Migration source:
../suaveplan/packages/universal/network-quality+../suaveplan/enterprise/network-quality.md
Summary
Mirror change of network-observability-consolidation but for @suaveplan/network-quality — upstream's network-quality-monitoring layer. The shipped @suaveplan/network-plugin-monitor ✅ already scores per-peer quality; upstream network-quality likely overlaps. Resolve via fold or split.
Decision required
Same fold-vs-split decision as network-observability-consolidation. See that proposal for the framing.
Recommendation: Fold into network-plugin-monitor (Option A) unless audit reveals quality-specific abstractions (e.g. MOS scoring, QoE estimation, packet-pacing analyzers) that warrant a dedicated plugin.
Current-state audit (perform at execution time)
Upstream coverage: 98.88%. Investigate:
ls ../suaveplan/packages/universal/network-quality/src/
diff <(grep -rh "^export" ../suaveplan/packages/universal/network-quality/src/) \
<(grep -rh "^export" packages/network/network-plugin-monitor/src/)
Parity Checklist (FINAL — audit complete 2026-05-12)
Decision: Option A — fold into @suaveplan/network-plugin-monitor.
Audit confirmed zero overlap with the shipped network-plugin-monitor exports — none of BandwidthMonitor, DegradationManager, or createQualityMiddleware have analogues in monitor's existing collector/alert/sampler/tracer surface:
| Capability | Upstream | Existing (monitor) |
Verdict |
|---|---|---|---|
| Per-peer RTT raw metric | 🚫 | ✅ (MetricCollector) |
already covered |
| Loss / jitter raw metrics | 🚫 | ✅ (NetworkMonitor) |
already covered |
| Alert thresholds on raw metrics | 🚫 | ✅ (AlertEngine) |
already covered |
| EMA-smoothed bandwidth/RTT/loss recorder | ✅ BandwidthMonitor (122 LOC) |
🚫 | ⬆️ folded as quality/bandwidth-monitor |
| 4-rung quality-class classifier with hysteresis + one-step transitions | ✅ DegradationManager (207 LOC) |
🚫 | ⬆️ folded as quality/degradation-manager |
| Per-source outgoing-message throttling middleware | ✅ createQualityMiddleware (95 LOC) |
🚫 | ⬆️ folded as quality/quality-middleware |
| MOS / QoE scoring | 🚫 not in upstream src | 🚫 | n/a — not present |
| Packet-pacing analyzers | 🚫 not in upstream src | 🚫 | n/a — not present |
QualityPlugin NetworkPlugin-wrapper driving periodic evaluate() via setInterval |
✅ (120 LOC) | n/a | ❌ NOT folded — monitor already exposes MonitorPlugin; consumers wanting auto-evaluation wire BandwidthMonitor + DegradationManager behind their own scheduler |
Why fold and not split: upstream is 707 LOC, only ~430 LOC of which is portable after dropping QualityPlugin. After filtering, the three remaining modules consume each other in a tight loop (BandwidthMonitor → DegradationManager → createQualityMiddleware) and share a single QualityLevel/BandwidthSample types layer — same fold pattern as Wave 6.1's prometheus/grafana.
API rewrites at fold: upstream BandwidthMonitor/DegradationManager both extended @suaveplan/events's EventEmitter<TMap>, but genesis's events package is now bus-based. Replaced with callback-handler subscriptions returning unsubscribe functions — same observable surface, zero monolithic-EE coupling. hysteresisMs: 0 newly commits same-call so the policy is usable synchronously. QualityLevel rewritten as a const object + value-union to drop TypeScript enum reverse-mapping. Every public shape gained Zod validation (BandwidthSampleSchema, QualityThresholdsSchema, LevelThresholdSchema).
Acceptance gate
Identical to network-observability-consolidation:
- Audit + decision.
- Implementation under chosen option.
STATUS.mdrow removed; supersession table updated.bunx turbo lint typecheck test+test:coverage100% on affected packages.
Out of scope
- Audio/video MOS scoring (separate
@suaveplan/audio-qualityif needed).