218 lines
5.8 KiB
Markdown
218 lines
5.8 KiB
Markdown
# OpenSpec Change: enterprise-network-observability
|
||
|
||
- **Change ID**: enterprise-network-observability
|
||
- **Package**: `@suaveplan/network-observability`
|
||
- **Category**: universal/network
|
||
- **Target path**: `universal/network/network-observability`
|
||
- **Status**: SUPERSEDED-BY-GENESIS-WAVE
|
||
- **Date**: 2026-04-24
|
||
|
||
---
|
||
|
||
## Summary
|
||
|
||
Deliver `@suaveplan/network-observability` on the genesis branch from scratch at enterprise quality. The package provides network metrics collection and distributed tracing instrumentation: RTT measurements, bandwidth estimation, connection health scoring, packet loss tracking, span propagation across network hops, and structured event emission for network anomalies. Genesis adds structured errors via `@suaveplan/error`, Zod schemas for all metric types, deep OTel integration (this package is specifically about observability), `AbortSignal` on collection tasks, injectable `Clock` for measurement timestamps, and event-bus emission for threshold breaches.
|
||
|
||
---
|
||
|
||
## Current-state audit (genesis)
|
||
|
||
The package does not exist on genesis yet — this is a fresh build.
|
||
|
||
---
|
||
|
||
## Available workspace deps on genesis
|
||
|
||
| Package | Role |
|
||
|---|---|
|
||
| `@suaveplan/error` (`workspace:^`) | Base class for `NetworkObservabilityError`; stable error codes |
|
||
| `@suaveplan/types` (`workspace:^`) | `LoggerLike`, `Clock`, `EventBusLike` |
|
||
| `@suaveplan/events` (`workspace:^`) | Event bus for threshold breach notifications |
|
||
| `@suaveplan/logger` (`workspace:^`) | Structured logging |
|
||
| `@suaveplan/timing` (`workspace:^`) | Stopwatch and throttle for measurement intervals |
|
||
| `zod` (`catalog:forms`) | Zod schemas for all public metric types |
|
||
| `@opentelemetry/api` (`catalog:observability`) | Deep OTel integration — this package enriches OTel spans |
|
||
| `tslib` (`catalog:build`) | Runtime helpers |
|
||
|
||
Dev deps: `vitest`, `@vitest/coverage-istanbul`, `fast-check` (all `catalog:testing`).
|
||
|
||
---
|
||
|
||
## Public API surface
|
||
|
||
### Core
|
||
|
||
```ts
|
||
function createNetworkMonitor(options?: NetworkMonitorOptions): NetworkMonitor
|
||
|
||
interface NetworkMonitor {
|
||
start(signal?: AbortSignal): Promise<void>
|
||
stop(): void
|
||
snapshot(): NetworkSnapshot
|
||
history(limit?: number): ReadonlyArray<NetworkSnapshot>
|
||
on(event: NetworkEvent, handler: (data: NetworkSnapshot) => void): () => void
|
||
}
|
||
```
|
||
|
||
### Metric types
|
||
|
||
```ts
|
||
interface NetworkSnapshot {
|
||
readonly timestamp: number
|
||
readonly rtt: RttMetrics
|
||
readonly bandwidth: BandwidthMetrics
|
||
readonly packetLoss: PacketLossMetrics
|
||
readonly health: NetworkHealthScore
|
||
}
|
||
|
||
interface RttMetrics {
|
||
readonly current: number
|
||
readonly min: number
|
||
readonly max: number
|
||
readonly avg: number
|
||
readonly p50: number
|
||
readonly p95: number
|
||
readonly p99: number
|
||
readonly samples: number
|
||
}
|
||
|
||
interface BandwidthMetrics {
|
||
readonly downloadBps: number
|
||
readonly uploadBps?: number
|
||
readonly estimatedAt: number
|
||
}
|
||
|
||
interface PacketLossMetrics {
|
||
readonly rate: number // 0–1
|
||
readonly total: number
|
||
readonly lost: number
|
||
}
|
||
|
||
interface NetworkHealthScore {
|
||
readonly score: number // 0–100
|
||
readonly grade: 'excellent' | 'good' | 'fair' | 'poor' | 'critical'
|
||
readonly factors: ReadonlyArray<HealthFactor>
|
||
}
|
||
|
||
interface HealthFactor {
|
||
readonly name: string
|
||
readonly weight: number
|
||
readonly score: number
|
||
readonly impact: 'positive' | 'negative' | 'neutral'
|
||
}
|
||
```
|
||
|
||
### Span propagation
|
||
|
||
```ts
|
||
function injectTraceContext(headers: Record<string, string>): Record<string, string>
|
||
function extractTraceContext(headers: Record<string, string>): SpanContext | null
|
||
function withNetworkSpan<T>(name: string, fn: () => Promise<T>, attributes?: NetworkSpanAttributes): Promise<T>
|
||
|
||
interface NetworkSpanAttributes {
|
||
url?: string
|
||
method?: string
|
||
statusCode?: number
|
||
requestSize?: number
|
||
responseSize?: number
|
||
}
|
||
```
|
||
|
||
### Options
|
||
|
||
```ts
|
||
interface NetworkMonitorOptions {
|
||
measureIntervalMs?: number
|
||
historySize?: number
|
||
rttTargetUrl?: string
|
||
thresholds?: NetworkThresholds
|
||
logger?: LoggerLike
|
||
clock?: Clock
|
||
eventBus?: EventBusLike
|
||
}
|
||
|
||
interface NetworkThresholds {
|
||
maxRttMs?: number
|
||
minBandwidthBps?: number
|
||
maxPacketLossRate?: number
|
||
minHealthScore?: number
|
||
}
|
||
|
||
type NetworkEvent = 'snapshot' | 'threshold-breach' | 'recovery'
|
||
```
|
||
|
||
### Error codes
|
||
|
||
```ts
|
||
type NetworkObservabilityErrorCode =
|
||
| 'NET_OBS_MEASUREMENT_FAILED'
|
||
| 'NET_OBS_MONITOR_ALREADY_RUNNING'
|
||
| 'NET_OBS_ABORT'
|
||
|
||
function registerNetworkObservabilityErrorCodes(): void
|
||
```
|
||
|
||
---
|
||
|
||
## Genesis additions
|
||
|
||
1. **Structured `NetworkObservabilityError`** with stable `NET_OBS.*` codes
|
||
2. **Zod schemas** for all metric types and options
|
||
3. **Health scoring algorithm** — weighted composite of RTT, packet loss, bandwidth; grades A–F
|
||
4. **W3C Trace Context propagation** helpers (`injectTraceContext`, `extractTraceContext`)
|
||
5. **Threshold alerting** — emits event-bus events when thresholds are breached or recovered
|
||
6. **Injectable `Clock`** for deterministic timestamp tests
|
||
7. **OTel deep integration** — this package is the entry point for network-layer OTel spans
|
||
|
||
---
|
||
|
||
## File layout
|
||
|
||
```text
|
||
universal/network/network-observability/
|
||
package.json
|
||
tsconfig.json
|
||
vitest.config.ts
|
||
src/
|
||
index.ts
|
||
error-codes.ts
|
||
constants/
|
||
index.ts
|
||
types/
|
||
common.ts
|
||
common.md
|
||
core/
|
||
monitor/
|
||
monitor.ts
|
||
monitor.md
|
||
monitor.types.ts
|
||
monitor.test.ts
|
||
index.ts
|
||
health/
|
||
health.ts
|
||
health.md
|
||
health.test.ts
|
||
index.ts
|
||
tracing/
|
||
propagation.ts
|
||
propagation.md
|
||
propagation.test.ts
|
||
index.ts
|
||
metrics/
|
||
rtt.ts
|
||
rtt.md
|
||
rtt.test.ts
|
||
bandwidth.ts
|
||
bandwidth.md
|
||
bandwidth.test.ts
|
||
tests/
|
||
integration.test.ts
|
||
property.test.ts
|
||
```
|
||
|
||
---
|
||
|
||
## Impact
|
||
|
||
**Workspace dep prerequisites**: `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/events`, `@suaveplan/logger`, `@suaveplan/timing` must be published.
|