Skip to content

Real-time CSI introspection (ADR-099): v0.8.0 capabilities, measured baseline, path to 10× D8 #556

@ruvnet

Description

@ruvnet

Companion to PR #554 (feat: ADR-099 midstream introspection tap). This issue surfaces what's measured, what the new capabilities are, and what's still needed to hit ADR-099's stretch goal.

Capability surface added in v0.8.0

Endpoint Format Default Notes
GET /ws/introspection NDJSON, streamed at CSI frame rate off (--introspection) Live attractor + regime + signature-match stream
GET /api/v1/introspection/snapshot single-shot JSON off (--introspection) Auth-gated when RUVIEW_API_TOKEN is set; orchestrator-friendly

Each snapshot field: frame_count, timestamp_ns, regime (Idle / Periodic / Transient / Chaotic / Unknown), lyapunov_exponent, attractor_dim, attractor_confidence, regime_changed (boolean — flips on first frame after a regime transition), top_k_similarity[] (with above_threshold).

Measured baseline (this release)

tests/introspection_latency.rs — 200-frame noise warm-up → 5-frame motion-ramp signature, host-side L1 stand-in scoring on a 1-D mean-amplitude feature:

Signal Frames Ratio vs event-path floor (16) Status
top_k_similarity[0].above_threshold 5 3.20× Real, repeatable
regime_changed did not fire in motion window See "Open" below
Per-frame update() p99 0.041 ms ~24× under D4's 1 ms ✅ Meets budget

Workspace validation: 1,656 passed, 0 failed, 8 ignored. Python proof VERDICT PASS.

Open questions / follow-up work

1. Closing ADR-099 D8 (10× faster than event-path floor)

The 3.20× ratio is the architectural ceiling on 1-D scalar features — the noise band of a single mean-amplitude scalar overlaps a motion signature too much to discriminate in 1–2 frames. Closing this gap is not a tuning problem; it's a feature-dimensionality problem. Path:

  • Land ADR-208 Phase 2 (Hailo NPU vec128 embeddings).
  • Wire those embeddings into Signature.window (currently Vec<f64> — would become Vec<Embedding>).
  • Reassess D8 once partial matches can score on 128-D cosine instead of 1-D L1.

2. regime_changed did not fire in the 10-frame motion window

The 200-frame noise trajectory dominates Lyapunov classification — a 10-frame perturbation doesn't shift the regime fast enough on a scalar feature. Same root cause as (1). Options:

  • Multi-dim features (covered by (1)).
  • Adaptive Lyapunov windowing — shorter trailing window when amplitude variance spikes.
  • Both.

3. Side finding: midstream's temporal-compare::dtw() is symbolic-only

temporal-compare::dtw() uses discrete equality cost (designed for LLM tokens) — 0 if seq1[i].value == seq2[j].value, else 1. On f64 amplitude values that's strictly worse than the L1 stand-in this PR uses. Swapping in midstream DTW is not the path to closing D8.

  • Open question: hand-roll a numeric DTW in wifi-densepose-sensing-server::introspection, or contribute one upstream to midstreamer-temporal-compare?

4. Documentation

  • Add an --introspection section to docs/user-guide.md once the feature exits "off by default" status.

Links

  • ADR-099 (this PR): docs/adr/ADR-099-midstream-introspection-tap.md
  • ADR-098 (rejected midstream as a replacement): docs/adr/ADR-098-evaluate-midstream-fit.md
  • ADR-208 (Hailo NPU integration plan — Phase 2 unblocks D8)
  • midstream: https://github.com/ruvnet/midstream

🤖 Generated with claude-flow

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions