6.6 KiB
Capability Spec: network-plugin-devtools
Capability: network-plugin-devtools
Status: ACTIVE
Every requirement below carries a
**Verified by:**line at authoring time. No exceptions. (Seeopenspec/AGENTS.md§13.)
ADDED Requirements
Requirement: NET_DEV-01 — NetworkVisualizer produces a stable IR and supports three modes
The package SHALL export a NetworkVisualizer class whose start({ mode, refreshRate }) Zod-validates input (rejecting unknown modes with VISUALIZER_INVALID_MODE), whose render() produces a VisualizerScene IR carrying nodes, edges, heat, width, height, and an optional focus field, and whose three modes (hierarchy, flow, heat) drive distinct edge / heat collection paths from the injected TopologyAdapter and MessageStreamAdapter. render() SHALL surface VISUALIZER_EMPTY_TOPOLOGY when the active filter eliminates every node, and render() and mode() SHALL throw VISUALIZER_NOT_STARTED before start().
Verified by: src/visualizer/visualizer.spec-conformance.test.ts
Scenario: Mode switches the edge source
- WHEN
start({ mode: "flow", refreshRate: 30 })is called and the stream returns three flow edges - THEN
render().edges.length === 3
Requirement: NET_DEV-02 — Visualizer export delegates to the injected Renderer with format checking
NetworkVisualizer.export(format) SHALL accept only "svg" or "png", reject any other format with VISUALIZER_INVALID_MODE, surface renderer exceptions as VISUALIZER_RENDERER_FAILED (with the original error preserved as cause), and reject any renderer that returns an output whose format field does not match the requested format. The bundled SvgRenderer SHALL satisfy the Renderer contract and produce deterministic UTF-8 SVG bytes with mimeType === "image/svg+xml". PNG support SHALL be delivered via injected Renderer (no built-in encoder dependency).
Verified by: src/visualizer/visualizer.spec-conformance.test.ts
Scenario: Renderer format mismatch rejected
- WHEN a renderer is injected that returns
{ format: "png" }while the consumer asked for"svg" - THEN
export("svg")throwsVISUALIZER_RENDERER_FAILED
Requirement: NET_DEV-03 — StateInspector records, inspects, scrubs, and diffs per path
The package SHALL export a StateInspector class with a configurable per-path ring buffer (default 256), record(StateSnapshot) Zod boundary surfacing INSPECTOR_DIFF_FAILED on invalid input, inspect(path) returning StateView (throws INSPECTOR_PATH_NOT_FOUND when absent), diff(path, fromVersion, toVersion) producing DiffView with added / removed / changed JSON Pointers and a numeric summary (throws INSPECTOR_INVALID_RANGE when versions match or are missing), scrub(path, atVersion) returning the latest snapshot ≤ atVersion (throws INSPECTOR_HISTORY_EMPTY when none satisfies the cap), and search(filter) AND-combining populated pathContains / peerId / sessionId / minVersion / maxVersion filters.
Verified by: src/inspector/inspector.spec-conformance.test.ts
Scenario: Diff classifies added / removed / changed paths
- WHEN two snapshots are recorded with
{ a: 1 }and{ b: 2 }at versions 1 and 2 - THEN
diff(path, 1, 2)reportsremoved: ["/a"]ANDadded: ["/b"]
Requirement: NET_DEV-04 — SimulationConfigTool builds, records, plays, and round-trips scenarios
The package SHALL export a SimulationConfigTool class with peer / link / condition / event editors, startRecording / stopRecording (throws SIMULATOR_RECORDING_INACTIVE on stop without start), loadPlayback enforcing scenario-id match (throws SIMULATOR_SCENARIO_INVALID on mismatch), playback() grouping events by atMs (throws SIMULATOR_PLAYBACK_INACTIVE before load), exportJson() / importJson(json) round-trip with full Zod validation (parse errors and schema errors both surface as SIMULATOR_SCENARIO_INVALID), addPeer rejecting duplicates with SIMULATOR_PEER_DUPLICATE, and addLink rejecting unknown endpoints with SIMULATOR_PEER_NOT_FOUND.
Verified by: src/simulator/simulator.spec-conformance.test.ts
Scenario: Playback groups concurrent events
- WHEN three events at
atMs: 100and one atatMs: 200are recorded and replayed - THEN
playback()returns two ticks of length 3 and 1 inatMsorder
Requirement: NET_DEV-05 — PerformanceProfiler distributes, baselines, regresses, and suggests
The package SHALL export a PerformanceProfiler class that records latency / throughput / plugin-overhead / memory samples into bounded rings, exposes p50 / p95 / p99 / min / max / mean / count distributions per path, supports named baselines (captureBaseline rejects duplicates with PROFILER_BASELINE_DUPLICATE), compare(baselineId) produces a Regression[] ranked by Z-score across p50 / p95 / p99 latency and message-throughput drops (throws PROFILER_NO_BASELINE when missing), and suggestions() emits category-tagged OptimizationSuggestions. Constructor SHALL throw PROFILER_INVALID_THRESHOLD on non-positive windowSize / regressionZScore / regressionWarnPct.
Verified by: src/profiler/profiler.spec-conformance.test.ts
Scenario: Tail-latency suggestion fires
- WHEN latency samples produce
p50 = 50andp99 = 200 - THEN
suggestions()includes acategory: "latency"entry whose subject is the path
Requirement: NET_DEV-06 — DevToolsPlugin facade exposes subsystems with a tier gate
DevToolsPlugin SHALL expose visualizer, inspector, simulator, profiler as public fields, evaluate the injected tierGate at install() time, record PLUGIN_TIER_GATE_REJECTED as tierRejection() when the gate returns false, expose requireActive() raising PLUGIN_DEV_DISABLED when the gate rejected activation, and expose idempotent stop() / dispose() lifecycles.
Verified by: src/plugin/devtools-plugin.spec-conformance.test.ts
Scenario: Production gate inert
- WHEN
tierGate: () => falseis supplied andinstallthenstartare called - THEN
isStarted()is true,isActive()is false,requireActive()throwsPLUGIN_DEV_DISABLED
Requirement: NET_DEV-07 — Frozen NETWORK_DEV_CODES registry
NETWORK_DEV_CODES SHALL be frozen (Object.isFrozen() === true), every value SHALL be prefixed NET_DEV., and the registry SHALL include every code consumed by visualizer, inspector, simulator, profiler, and plugin facade modules. Removing a code is a major-version change.
Verified by: src/error-codes.spec-conformance.test.ts