Companion documents: rvCSI Platform PRD · ADR-095 — rvCSI Edge RF Sensing Platform
Camera-free RF spatial sensing from WiFi Channel State Information (CSI).
RF field interpretation. rvCSI converts noisy radio channel measurements into validated events and temporal embeddings that represent changes in physical space. CSI is treated as a temporal delta stream against learned baselines — not as exact vision.
Hardware adapter management · packet parsing · signal processing · calibration · event extraction · temporal memory · agent integration · replay and audit.
Logging · configuration · CLI parsing · WebSocket streaming · package publishing · dashboard visualization.
| Term | Definition |
|---|---|
| CSI | Channel State Information — per-subcarrier complex channel response measured by a WiFi receiver |
| Source | A physical or replayed producer of CSI frames (a NIC, an ESP32 node, a PCAP file, a recorded capture) |
| Adapter | A software module that knows how to receive and decode source-specific CSI and normalize it into a CsiFrame |
| Frame | One CSI observation at a timestamp — the unit of ingestion |
| Window | A bounded sequence of frames from one source/session, used for analysis |
| Baseline | The learned normal RF-field state for a space |
| Delta | The measured difference of the current field from baseline |
| Event | A semantic interpretation of one or more windows (presence started, motion detected, anomaly, …) |
| Quality score | Confidence, in [0, 1], that a signal/frame/window is usable |
| Calibration | The process of learning a stable baseline for a space |
| Room signature | A vector representation of a space under normal conditions |
| Drift | Slow movement of the field away from baseline |
| Anomaly | A significant, unexplained deviation from baseline |
| RF memory | Persisted temporal vectors and events for a physical space (stored in RuVector) |
| Coherence | Consistency among sources, windows, and learned baselines |
| Quarantine | A holding store for rejected/corrupt frames, kept for audit rather than discarded |
| Adapter profile | A capability descriptor for a source (chip, firmware/driver versions, supported channels/bandwidths, expected subcarrier counts, capture/injection/monitor-mode support) |
| Calibration version | An immutable identifier for a particular learned baseline; every event references the calibration version it was detected against |
| Evidence window set | The set of WindowIds an event references as its justification — an event with no evidence is invalid |
┌─────────────┐ ┌──────────────┐ ┌────────────┐ ┌──────────────┐
│ Capture │──▶│ Validation │──▶│ Signal │──▶│ Calibration │
│ context │ │ context │ │ context │ │ context │
└─────────────┘ └──────────────┘ └─────┬──────┘ └──────┬───────┘
│ │
▼ │
┌────────────┐ │
│ Event │◀──────────┘
│ context │
└─────┬──────┘
│
┌─────────────┴─────────────┐
▼ ▼
┌────────────┐ ┌────────────┐
│ Memory │ │ Agent │
│ context │ │ context │
└────────────┘ └────────────┘
- Capture upstreams raw input from sources.
- Validation protects every downstream context — nothing crosses into SDK/DSP/memory/agents unvalidated.
- Signal turns frames into windows.
- Calibration gives windows a room-specific baseline.
- Event converts deltas into meaning.
- Memory stores time, similarity, drift, and coherence (RuVector).
- Agent exposes safe actions and queries (MCP / TypeScript).
Responsibility: connect to CSI sources and produce raw frames.
┌──────────────────────────────────────────────────────────────┐
│ Capture Context │
├──────────────────────────────────────────────────────────────┤
│ ┌────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Source │ │ CaptureSession │ │ AdapterProfile │ │
│ │ (adapter │ │ (aggregate root)│ │ (capability │ │
│ │ plugin) │ │ │ │ descriptor) │ │
│ └────────────┘ └─────────────────┘ └─────────────────┘ │
│ │
│ CsiSource trait: open · start · next_frame · stop · health │
└──────────────────────────────────────────────────────────────┘
| Element | Kind | Notes |
|---|---|---|
Source |
Entity | A configured adapter instance bound to a device or file |
CaptureSession |
Entity / aggregate root | Owns exactly one AdapterProfile and one runtime configuration |
AdapterProfile |
Entity | Chip, firmware/driver versions, supported channels/bandwidths, expected subcarrier counts, capability flags |
Channel, Bandwidth, FirmwareVersion, DriverVersion |
Value objects | Immutable |
Commands: StartCapture · StopCapture · RestartCapture · InspectSource
Domain events: CaptureStarted · CaptureStopped · SourceDisconnected · AdapterUnsupported
Responsibility: make frames safe and trustworthy before any language-boundary crossing.
| Element | Kind | Notes |
|---|---|---|
ValidationPolicy |
Entity | Bounds, monotonicity rules, finiteness checks, quarantine on/off |
QuarantineStore |
Entity | Holds rejected/corrupt frames for audit |
ValidatedFrame |
Aggregate root | The frame once it has passed (or been degraded by) validation |
ValidationError, QualityScore, FrameBounds |
Value objects | QualityScore ∈ [0, 1] |
Commands: ValidateFrame · QuarantineFrame
Domain events: FrameAccepted · FrameRejected · QualityDropped
Responsibility: DSP and window features.
Frame stream ─▶ SignalPipeline ─▶ WindowBuffer ─▶ CsiWindow
(DC removal, phase unwrap, (mean amplitude,
smoothing, Hampel filter, phase variance,
variance, baseline subtraction, motion energy,
motion energy, presence score) presence/quality scores)
| Element | Kind | Notes |
|---|---|---|
SignalPipeline |
Entity | Ordered DSP stages; reuses wifi-densepose-signal primitives |
WindowBuffer |
Entity | Accumulates frames into bounded windows |
CsiWindow |
Aggregate root | Frames from exactly one source/session |
AmplitudeVector, PhaseVector, MotionEnergy, PresenceScore |
Value objects |
Commands: ProcessFrame · BuildWindow · EstimateBaselineDelta
Domain events: WindowReady · BaselineDeltaMeasured
Responsibility: learn and version the normal RF state and room signatures.
| Element | Kind | Notes |
|---|---|---|
CalibrationProfile |
Aggregate root | Linked to source, room, adapter profile, configuration |
RoomSignature |
Entity | Vector representation of a space under normal conditions |
BaselineModel |
Entity | Statistical model of the baseline field; carries version history |
CalibrationVersion, StabilityScore, RoomId |
Value objects | Calibration cannot complete if StabilityScore < threshold |
Commands: StartCalibration · CompleteCalibration · UpdateBaseline · RejectUnstableCalibration
Domain events: CalibrationStarted · CalibrationCompleted · CalibrationFailed · BaselineUpdated
Responsibility: semantic event extraction with confidence and evidence.
| Element | Kind | Notes |
|---|---|---|
EventDetector |
Entity | One per event family (presence, motion, breathing, anomaly, …) |
EventStateMachine |
Entity | Holds the per-source detection state; emits transitions |
CsiEvent |
Aggregate root | Must reference ≥ 1 evidence window; confidence ∈ [0, 1]; references calibration version |
Confidence, EvidenceWindowSet, EventKind |
Value objects |
Commands: DetectEvents · PublishEvent · SuppressEvent
Domain events (the CsiEventKind enum): PresenceStarted · PresenceEnded · MotionDetected · MotionSettled · BaselineChanged · SignalQualityDropped · DeviceDisconnected · BreathingCandidate · AnomalyDetected · CalibrationRequired
Responsibility: RuVector storage and retrieval — RF memory.
| Element | Kind | Notes |
|---|---|---|
RfMemoryCollection |
Entity | A RuVector collection scoped to a deployment |
TemporalEmbedding |
Entity | Frame / window / event embedding with timestamp |
SensorGraph |
Entity | Graph of sources and their topological relationships |
RoomMemory |
Aggregate root | Stored embeddings must be traceable to frame windows or event windows |
EmbeddingVector, DriftScore, CoherenceScore |
Value objects | DriftScore must include the baseline version |
Commands: StoreWindowEmbedding · StoreEventEmbedding · QuerySimilarWindows · ComputeDrift
Domain events: EmbeddingStored · DriftDetected · SimilarPatternFound
Data stored: frame embeddings · window embeddings · room baseline vectors · event vectors · drift snapshots · sensor-topology graph edges · source health records. Retention policy applies at collection level. No orphan embeddings.
Responsibility: MCP and TypeScript agent interaction — safe actions and queries.
| Element | Kind | Notes |
|---|---|---|
AgentSubscription |
Entity | An agent's filtered stream of events |
McpToolSession |
Entity | A tool invocation context with permissions |
AgentSession |
Aggregate root | |
ToolPermission, EventFilter, AgentIntent |
Value objects | ToolPermission distinguishes read vs. write-gated |
Commands: SubscribeToEvents · RequestStatus · RequestCalibration · QueryMemory
Domain events: AgentSubscribed · ToolExecuted · PermissionDenied
MCP tools (read by default; write-gated marked *): rvcsi_status · rvcsi_list_sources · rvcsi_start_capture * · rvcsi_stop_capture * · rvcsi_get_presence · rvcsi_get_recent_events · rvcsi_calibrate_room * · rvcsi_export_window * · rvcsi_query_ruvector · rvcsi_health_report.
| Upstream → Downstream | Relationship | ACL / contract |
|---|---|---|
| Capture → Validation | Customer/Supplier | Raw frames pass through ValidationPolicy; only Accepted/Degraded continue |
| Validation → Signal | Conformist (Signal accepts ValidatedFrame as-is) |
CsiFrame schema is the published language |
| Signal → Calibration | Customer/Supplier | Windows + baseline-delta measurements feed baseline modeling |
| Calibration → Event | Customer/Supplier | Detectors declare which CalibrationVersion they used |
| Signal/Event → Memory | Published Language (EmbeddingVector, event metadata) |
rvcsi-ruvector ACL translates to RuVector's API |
| Event → Agent | Open Host Service (event stream + MCP tools) | EventFilter + ToolPermission enforced at the boundary |
| Capture → Agent | Conformist (health/status only, via MCP read tools) | No raw frames cross to agents |
The CsiFrame schema is the shared kernel between Capture, Validation, Signal, and the language-boundary (napi-rs) layer. It is the FFI-safe object; nothing device-specific leaks past it.
Invariant: a capture session has exactly one source profile and one runtime configuration.
- A session cannot emit frames before it is started.
- A session cannot change channel without restart unless the adapter supports dynamic retune.
- A session must emit
SourceDisconnectedbefore stopping due to device loss.
Invariant: no frame crosses into SDK, DSP, memory, or agents unless its validation status is Accepted or Degraded.
- Rejected frames go to quarantine when quarantine is enabled.
- Degraded frames must carry quality-reason metadata.
- Missing optional hardware metadata must not invalidate a frame.
Invariant: a window contains frames from exactly one source and one session.
- Mixed-source windows are not allowed.
- Window start time must be strictly less than end time.
- Window quality is bounded in [0, 1].
Invariant: a calibration profile is linked to source, room, adapter profile, and configuration.
- Calibration cannot complete if
StabilityScoreis below threshold. - Baseline updates must preserve version history.
- Event detectors must declare which calibration version they used.
Invariant: an event must have evidence.
- Every event references at least one evidence window.
- Confidence is bounded in [0, 1].
- Event suppression must be explainable by policy.
Invariant: stored embeddings are traceable to frame windows or event windows.
- No orphan embeddings.
- Retention policy applies at collection level.
- Drift scores must include the baseline version.
pub struct CsiFrame {
pub frame_id: FrameId,
pub session_id: SessionId,
pub source_id: SourceId,
pub adapter_kind: AdapterKind,
pub timestamp_ns: u64,
pub channel: u16,
pub bandwidth_mhz: u16,
pub rssi_dbm: Option<i16>,
pub noise_floor_dbm: Option<i16>,
pub antenna_index: Option<u8>,
pub tx_chain: Option<u8>,
pub rx_chain: Option<u8>,
pub subcarrier_count: u16,
pub i_values: Vec<f32>,
pub q_values: Vec<f32>,
pub amplitude: Vec<f32>,
pub phase: Vec<f32>,
pub validation: ValidationStatus,
pub quality_score: f32,
pub calibration_version: Option<String>,
}
pub struct CsiWindow {
pub window_id: WindowId,
pub session_id: SessionId,
pub source_id: SourceId,
pub start_ns: u64,
pub end_ns: u64,
pub frame_count: u32,
pub mean_amplitude: Vec<f32>,
pub phase_variance: Vec<f32>,
pub motion_energy: f32,
pub presence_score: f32,
pub quality_score: f32,
}
pub enum CsiEventKind {
PresenceStarted,
PresenceEnded,
MotionDetected,
MotionSettled,
BaselineChanged,
SignalQualityDropped,
DeviceDisconnected,
BreathingCandidate,
AnomalyDetected,
CalibrationRequired,
}
pub struct CsiEvent {
pub event_id: EventId,
pub kind: CsiEventKind,
pub session_id: SessionId,
pub source_id: SourceId,
pub timestamp_ns: u64,
pub confidence: f32,
pub evidence_window_ids: Vec<WindowId>,
pub metadata_json: String,
}
pub struct AdapterProfile {
pub adapter_kind: AdapterKind,
pub chip: Option<String>,
pub firmware_version: Option<String>,
pub driver_version: Option<String>,
pub supported_channels: Vec<u16>,
pub supported_bandwidths_mhz: Vec<u16>,
pub expected_subcarrier_counts: Vec<u16>,
pub supports_live_capture: bool,
pub supports_injection: bool,
pub supports_monitor_mode: bool,
}
pub enum ValidationStatus { Accepted, Degraded, Rejected, Recovered }| Service | Input | Output | Responsibility |
|---|---|---|---|
FrameValidationService |
RawFrame, AdapterProfile, ValidationPolicy |
ValidatedFrame or RejectedFrame |
Enforce bounds, finiteness, monotonicity; assign initial QualityScore; route rejects to quarantine; emit structured errors |
SignalProcessingService |
ValidatedFrame stream |
CsiWindow stream |
Run the DSP pipeline; build bounded windows; compute motion energy, presence score, window quality |
BaselineDeltaService |
CsiWindow, BaselineModel |
BaselineDelta |
Subtract the calibrated baseline; measure deviation magnitude |
CalibrationService |
CsiWindow stream over a calibration window |
CalibrationProfile (new version) or CalibrationFailed |
Learn a stable baseline; compute StabilityScore; reject unstable calibrations; preserve version history |
EventDetectionService |
CsiWindow + BaselineDelta + CalibrationVersion |
CsiEvent stream |
Drive per-source state machines; attach confidence + evidence windows + calibration version; apply suppression policy |
EmbeddingService |
CsiWindow / CsiEvent |
TemporalEmbedding |
Produce frame/window/event vectors (v0: deterministic DSP feature vector; later: AETHER / on-device model) |
RfMemoryService |
TemporalEmbedding, query |
EmbeddingStored / similar windows / DriftScore |
Store to RuVector; similarity search; drift computation against a baseline version |
ReplayService |
A captured session bundle | A deterministic frame/window/event stream | Replay preserving timestamps, ordering, validation decisions, event output, calibration version, runtime config |
AdapterRegistryService |
— | List of available adapters + AdapterProfiles |
Discover sources (reuses ADR-049 interface detection); report health; flag unsupported firmware/driver state |
AgentGatewayService |
MCP tool call / SDK subscription | Tool result / filtered event stream | Enforce ToolPermission (read vs. write-gated), apply EventFilter, audit ToolExecuted / PermissionDenied |
- rvCSI Platform PRD — requirements, success criteria, scope
- ADR-095 — rvCSI Edge RF Sensing Platform — the fifteen architectural decisions
- RuvSense Domain Model — adjacent multistatic sensing context
- Signal Processing Domain Model — the DSP primitives
rvcsi-dspreuses - ADR Index