diff --git a/docs/adr/ADR-030-ruvsense-persistent-field-model.md b/docs/adr/ADR-030-ruvsense-persistent-field-model.md new file mode 100644 index 0000000..52cccb8 --- /dev/null +++ b/docs/adr/ADR-030-ruvsense-persistent-field-model.md @@ -0,0 +1,364 @@ +# ADR-030: RuvSense Persistent Field Model — Longitudinal Drift Detection and Exotic Sensing Tiers + +| Field | Value | +|-------|-------| +| **Status** | Proposed | +| **Date** | 2026-03-02 | +| **Deciders** | ruv | +| **Codename** | **RuvSense Field** — Persistent Electromagnetic World Model | +| **Relates to** | ADR-029 (RuvSense Multistatic), ADR-005 (SONA Self-Learning), ADR-024 (AETHER Embeddings), ADR-016 (RuVector Integration), ADR-026 (Survivor Track Lifecycle), ADR-027 (MERIDIAN Generalization) | + +--- + +## 1. Context + +### 1.1 Beyond Pose Estimation + +ADR-029 establishes RuvSense as a sensing-first multistatic mesh achieving 20 Hz DensePose with <30mm jitter. That treats WiFi as a **momentary pose estimator**. The next leap: treat the electromagnetic field as a **persistent world model** that remembers, predicts, and explains. + +The most exotic capabilities come from this shift in abstraction level: +- The room is the model, not the person +- People are structured perturbations to a baseline +- Changes are deltas from a known state, not raw measurements +- Time is a first-class dimension — the system remembers days, not frames + +### 1.2 The Seven Capability Tiers + +| Tier | Capability | Foundation | +|------|-----------|-----------| +| 1 | **Field Normal Modes** — Room electromagnetic eigenstructure | Baseline calibration + SVD | +| 2 | **Coarse RF Tomography** — 3D occupancy volume from link attenuations | Sparse tomographic inversion | +| 3 | **Intention Lead Signals** — Pre-movement prediction (200-500ms lead) | Temporal embedding trajectory analysis | +| 4 | **Longitudinal Biomechanics Drift** — Personal baseline deviation over days | Welford statistics + HNSW memory | +| 5 | **Cross-Room Continuity** — Identity persistence across spaces without optics | Environment fingerprinting + transition graph | +| 6 | **Invisible Interaction Layer** — Multi-user gesture control through walls/darkness | Per-person CSI perturbation classification | +| 7 | **Adversarial Detection** — Physically impossible signal identification | Multi-link consistency + field model constraints | + +### 1.3 Signals, Not Diagnoses + +RF sensing detects **biophysical proxies**, not medical conditions: + +| Detectable Signal | Not Detectable | +|-------------------|---------------| +| Breathing rate variability | COPD diagnosis | +| Gait asymmetry shift (18% over 14 days) | Parkinson's disease | +| Posture instability increase | Neurological condition | +| Micro-tremor onset | Specific tremor etiology | +| Activity level decline | Depression or pain diagnosis | + +The output is: "Your movement symmetry has shifted 18 percent over 14 days." That is actionable without being diagnostic. The evidence chain (stored embeddings, drift statistics, coherence scores) is fully traceable. + +### 1.4 Acceptance Tests + +**Tier 0 (ADR-029):** Two people, 20 Hz, 10 min stable tracks, zero ID swaps, <30mm torso jitter. + +**Tier 1-4 (this ADR):** Seven-day run, no manual tuning. System flags one real environmental change and one real human drift event, produces traceable explanation using stored embeddings plus graph constraints. + +**Tier 5-7 (appliance):** Thirty-day local run, no camera. Detects meaningful drift with <5% false alarm rate. + +--- + +## 2. Decision + +### 2.1 Implement Field Normal Modes as the Foundation + +Add a `field_model` module to `wifi-densepose-signal/src/ruvsense/` that learns the room's electromagnetic baseline during unoccupied periods and decomposes all subsequent observations into environmental drift + body perturbation. + +``` +wifi-densepose-signal/src/ruvsense/ +├── mod.rs // (existing, extend) +├── field_model.rs // NEW: Field normal mode computation + perturbation extraction +├── tomography.rs // NEW: Coarse RF tomography from link attenuations +├── longitudinal.rs // NEW: Personal baseline + drift detection +├── intention.rs // NEW: Pre-movement lead signal detector +├── cross_room.rs // NEW: Cross-room identity continuity +├── gesture.rs // NEW: Gesture classification from CSI perturbations +├── adversarial.rs // NEW: Physically impossible signal detection +└── (existing files...) +``` + +### 2.2 Core Architecture: The Persistent Field Model + +``` + Time + │ + ▼ + ┌────────────────────────────────┐ + │ Field Normal Modes (Tier 1) │ + │ Room baseline + SVD modes │ + │ ruvector-solver │ + └────────────┬───────────────────┘ + │ Body perturbation (environmental drift removed) + │ + ┌───────┴───────┐ + │ │ + ▼ ▼ + ┌──────────┐ ┌──────────────┐ + │ Pose │ │ RF Tomography│ + │ (ADR-029)│ │ (Tier 2) │ + │ 20 Hz │ │ Occupancy vol│ + └────┬─────┘ └──────────────┘ + │ + ▼ + ┌──────────────────────────────┐ + │ AETHER Embedding (ADR-024) │ + │ 128-dim contrastive vector │ + └────────────┬─────────────────┘ + │ + ┌───────┼───────┐ + │ │ │ + ▼ ▼ ▼ + ┌────────┐ ┌─────┐ ┌──────────┐ + │Intention│ │Track│ │Cross-Room│ + │Lead │ │Re-ID│ │Continuity│ + │(Tier 3)│ │ │ │(Tier 5) │ + └────────┘ └──┬──┘ └──────────┘ + │ + ▼ + ┌──────────────────────────────┐ + │ RuVector Longitudinal Memory │ + │ HNSW + graph + Welford stats│ + │ (Tier 4) │ + └──────────────┬───────────────┘ + │ + ┌───────┴───────┐ + │ │ + ▼ ▼ + ┌──────────────┐ ┌──────────────┐ + │ Drift Reports│ │ Adversarial │ + │ (Level 1-3) │ │ Detection │ + │ │ │ (Tier 7) │ + └──────────────┘ └──────────────┘ +``` + +### 2.3 Field Normal Modes (Tier 1) + +**What it is:** The room's electromagnetic eigenstructure — the stable propagation paths, reflection coefficients, and interference patterns when nobody is present. + +**How it works:** +1. During quiet periods (empty room, overnight), collect 10 minutes of CSI across all links +2. Compute per-link baseline (mean CSI vector) +3. Compute environmental variation modes via SVD (temperature, humidity, time-of-day effects) +4. Store top-K modes (K=3-5 typically captures >95% of environmental variance) +5. At runtime: subtract baseline, project out environmental modes, keep body perturbation + +```rust +pub struct FieldNormalMode { + pub baseline: Vec>>, // [n_links × n_subcarriers] + pub environmental_modes: Vec>, // [n_modes × n_subcarriers] + pub mode_energies: Vec, // eigenvalues + pub calibrated_at: u64, + pub geometry_hash: u64, +} +``` + +**RuVector integration:** +- `ruvector-solver` → Low-rank SVD for mode extraction +- `ruvector-temporal-tensor` → Compressed baseline history storage +- `ruvector-attn-mincut` → Identify which subcarriers belong to which mode + +### 2.4 Longitudinal Drift Detection (Tier 4) + +**The defensible pipeline:** + +``` +RF → AETHER contrastive embedding + → RuVector longitudinal memory (HNSW + graph) + → Coherence-gated drift detection (Welford statistics) + → Risk flag with traceable evidence +``` + +**Three monitoring levels:** + +| Level | Signal Type | Example Output | +|-------|------------|----------------| +| **1: Physiological** | Raw biophysical metrics | "Breathing rate: 18.3 BPM today, 7-day avg: 16.1" | +| **2: Drift** | Personal baseline deviation | "Gait symmetry shifted 18% over 14 days" | +| **3: Risk correlation** | Pattern-matched concern | "Pattern consistent with increased fall risk" | + +**Storage model:** + +```rust +pub struct PersonalBaseline { + pub person_id: PersonId, + pub gait_symmetry: WelfordStats, + pub stability_index: WelfordStats, + pub breathing_regularity: WelfordStats, + pub micro_tremor: WelfordStats, + pub activity_level: WelfordStats, + pub embedding_centroid: Vec, // [128] + pub observation_days: u32, + pub updated_at: u64, +} +``` + +**RuVector integration:** +- `ruvector-temporal-tensor` → Compressed daily summaries (50-75% memory savings) +- HNSW → Embedding similarity search across longitudinal record +- `ruvector-attention` → Per-metric drift significance weighting +- `ruvector-mincut` → Temporal segmentation (detect changepoints in metric series) + +### 2.5 Regulatory Classification + +| Classification | What You Claim | Regulatory Path | +|---------------|---------------|-----------------| +| **Consumer wellness** (recommended first) | Activity metrics, breathing rate, stability score | Self-certification, FCC Part 15 | +| **Clinical decision support** (future) | Fall risk alert, respiratory pattern concern | FDA Class II 510(k) or De Novo | +| **Regulated medical device** (requires clinical partner) | Diagnostic claims for specific conditions | FDA Class II/III + clinical trials | + +**Decision: Start as consumer wellness.** Build 12+ months of real-world longitudinal data. The dataset itself becomes the asset for future regulatory submissions. + +--- + +## 3. Appliance Product Categories + +### 3.1 Invisible Guardian + +Wall-mounted wellness monitor for elderly care and independent living. No camera, no microphone, no reconstructable data. Stores embeddings and structural deltas only. + +| Spec | Value | +|------|-------| +| Nodes | 4 ESP32-S3 pucks per room | +| Processing | Central hub (RPi 5 or x86) | +| Power | PoE or USB-C | +| Output | Risk flags, drift alerts, occupancy timeline | +| BOM | $73-91 (ESP32 mesh) + $35-80 (hub) | +| Validation | 30-day autonomous run, <5% false alarm rate | + +### 3.2 Spatial Digital Twin Node + +Live electromagnetic room model for smart buildings and workplace analytics. + +| Spec | Value | +|------|-------| +| Output | Occupancy heatmap, flow vectors, dwell time, anomaly events | +| Integration | MQTT/REST API for BMS and CAFM | +| Retention | 30-day rolling, GDPR-compliant | +| Vertical | Smart buildings, retail, workspace optimization | + +### 3.3 RF Interaction Surface + +Multi-user gesture interface. No cameras. Works in darkness, smoke, through clothing. + +| Spec | Value | +|------|-------| +| Gestures | Wave, point, beckon, push, circle + custom | +| Users | Up to 4 simultaneous | +| Latency | <100ms gesture recognition | +| Vertical | Smart home, hospitality, accessibility | + +### 3.4 Pre-Incident Drift Monitor + +Longitudinal biomechanics tracker for rehabilitation and occupational health. + +| Spec | Value | +|------|-------| +| Baseline | 7-day calibration per person | +| Alert | Metric drift >2sigma for >3 days | +| Evidence | Stored embedding trajectory + statistical report | +| Vertical | Elderly care, rehab, occupational health | + +### 3.5 Vertical Recommendation for First Hardware SKU + +**Invisible Guardian** — the elderly care wellness monitor. Rationale: +1. Largest addressable market with immediate revenue (aging population, care facility demand) +2. Lowest regulatory bar (consumer wellness, no diagnostic claims) +3. Privacy advantage over cameras is a selling point, not a limitation +4. 30-day autonomous operation validates all tiers (field model, drift detection, coherence gating) +5. $108-171 BOM allows $299-499 retail with healthy margins + +--- + +## 4. RuVector Integration Map (Extended) + +All five crates are exercised across the exotic tiers: + +| Tier | Crate | API | Role | +|------|-------|-----|------| +| 1 (Field) | `ruvector-solver` | `NeumannSolver` + SVD | Environmental mode decomposition | +| 1 (Field) | `ruvector-temporal-tensor` | `TemporalTensorCompressor` | Baseline history storage | +| 1 (Field) | `ruvector-attn-mincut` | `attn_mincut` | Mode-subcarrier assignment | +| 2 (Tomo) | `ruvector-solver` | `NeumannSolver` (L1) | Sparse tomographic inversion | +| 3 (Intent) | `ruvector-attention` | `ScaledDotProductAttention` | Temporal trajectory weighting | +| 3 (Intent) | `ruvector-temporal-tensor` | `CompressedCsiBuffer` | 2-second embedding history | +| 4 (Drift) | `ruvector-temporal-tensor` | `TemporalTensorCompressor` | Daily summary compression | +| 4 (Drift) | `ruvector-attention` | `ScaledDotProductAttention` | Metric drift significance | +| 4 (Drift) | `ruvector-mincut` | `DynamicMinCut` | Temporal changepoint detection | +| 5 (Cross-Room) | `ruvector-attention` | HNSW | Room and person fingerprint matching | +| 5 (Cross-Room) | `ruvector-mincut` | `MinCutBuilder` | Transition graph partitioning | +| 6 (Gesture) | `ruvector-attention` | `ScaledDotProductAttention` | Gesture template matching | +| 7 (Adversarial) | `ruvector-solver` | `NeumannSolver` | Physical plausibility verification | +| 7 (Adversarial) | `ruvector-attn-mincut` | `attn_mincut` | Multi-link consistency check | + +--- + +## 5. Implementation Priority + +| Priority | Tier | Module | Weeks | Dependency | +|----------|------|--------|-------|------------| +| P0 | 1 | `field_model.rs` | 2 | ADR-029 multistatic mesh operational | +| P0 | 4 | `longitudinal.rs` | 2 | Tier 1 baseline + AETHER embeddings | +| P1 | 2 | `tomography.rs` | 1 | Tier 1 perturbation extraction | +| P1 | 3 | `intention.rs` | 2 | Tier 1 + temporal embedding history | +| P2 | 5 | `cross_room.rs` | 2 | Tier 4 person profiles + multi-room deployment | +| P2 | 6 | `gesture.rs` | 1 | Tier 1 perturbation + per-person separation | +| P3 | 7 | `adversarial.rs` | 1 | Tier 1 field model + multi-link consistency | + +**Total exotic tier: ~11 weeks after ADR-029 acceptance test passes.** + +--- + +## 6. Consequences + +### 6.1 Positive + +- **Room becomes self-sensing**: Field normal modes provide a persistent baseline that explains change as structured deltas +- **7-day autonomous operation**: Coherence gating + SONA adaptation + longitudinal memory eliminate manual tuning +- **Privacy by design**: No images, no audio, no reconstructable data — only embeddings and statistical summaries +- **Traceable evidence**: Every drift alert links to stored embeddings, timestamps, and graph constraints +- **Multiple product categories**: Same software stack, different packaging — Guardian, Twin, Interaction, Drift Monitor +- **Regulatory clarity**: Consumer wellness first, clinical decision support later with accumulated dataset +- **Security primitive**: Coherence gating detects adversarial injection, not just quality issues + +### 6.2 Negative + +- **7-day calibration** required for personal baselines (system is less useful during initial period) +- **Empty-room calibration** needed for field normal modes (may not always be available) +- **Storage growth**: Longitudinal memory grows ~1 KB/person/day (manageable but non-zero) +- **Statistical power**: Drift detection requires 14+ days of data for meaningful z-scores +- **Multi-room**: Cross-room continuity requires hardware in all rooms (cost scales linearly) + +### 6.3 Risks + +| Risk | Probability | Impact | Mitigation | +|------|-------------|--------|------------| +| Field modes drift faster than expected | Medium | False perturbation detections | Reduce mode update interval from 24h to 4h | +| Personal baselines too variable | Medium | High false alarm rate for drift | Widen sigma threshold from 2σ to 3σ; require 5+ days | +| Cross-room matching fails for similar body types | Low | Identity confusion | Require temporal proximity (<60s) plus spatial adjacency | +| Gesture recognition insufficient SNR | Medium | <80% accuracy | Restrict to near-field (<2m) initially | +| Adversarial injection via coordinated WiFi injection | Very Low | Spoofed occupancy | Multi-link consistency check makes single-link spoofing detectable | + +--- + +## 7. Related ADRs + +| ADR | Relationship | +|-----|-------------| +| ADR-029 | **Prerequisite**: Multistatic mesh is the sensing substrate for all exotic tiers | +| ADR-005 (SONA) | **Extended**: SONA recalibration triggered by coherence gate → now also by drift events | +| ADR-016 (RuVector) | **Extended**: All 5 crates exercised across 7 exotic tiers | +| ADR-024 (AETHER) | **Critical dependency**: Embeddings are the representation for all longitudinal memory | +| ADR-026 (Tracking) | **Extended**: Track lifecycle now spans days (not minutes) for drift detection | +| ADR-027 (MERIDIAN) | **Used**: Room geometry encoding for field normal mode conditioning | + +--- + +## 8. References + +1. IEEE 802.11bf-2024. "WLAN Sensing." IEEE Standards Association. +2. FDA. "General Wellness: Policy for Low Risk Devices." Guidance Document, 2019. +3. EU MDR 2017/745. "Medical Device Regulation." Official Journal of the European Union. +4. Welford, B.P. (1962). "Note on a Method for Calculating Corrected Sums of Squares." Technometrics. +5. Chen, L. et al. (2026). "PerceptAlign: Geometry-Aware WiFi Sensing." arXiv:2601.12252. +6. AM-FM (2026). "A Foundation Model for Ambient Intelligence Through WiFi." arXiv:2602.11200. +7. Geng, J. et al. (2023). "DensePose From WiFi." arXiv:2301.00250. diff --git a/docs/ddd/ruvsense-domain-model.md b/docs/ddd/ruvsense-domain-model.md index 372d8db..f6cc9f9 100644 --- a/docs/ddd/ruvsense-domain-model.md +++ b/docs/ddd/ruvsense-domain-model.md @@ -591,3 +591,437 @@ pub trait MeshRepository { - Re-ID window: Lost tracks eligible for re-identification for 5 seconds - Embedding EMA decay: 0.95 (slow adaptation preserves identity across environmental changes) - Joint assignment cost must use both position (60%) and embedding (40%) terms + +--- + +## Part II: Persistent Field Model Bounded Contexts (ADR-030) + +### Ubiquitous Language (Extended) + +| Term | Definition | +|------|------------| +| **Field Normal Mode** | The room's electromagnetic eigenstructure — stable propagation baseline when unoccupied | +| **Body Perturbation** | Structured change to field caused by a person, after environmental drift is removed | +| **Environmental Mode** | Principal component of baseline variation due to temperature, humidity, time-of-day | +| **Personal Baseline** | Per-person rolling statistical profile of biophysical proxies over days/weeks | +| **Drift Event** | Statistically significant deviation from personal baseline (>2sigma for >3 days) | +| **Drift Report** | Traceable evidence package: z-score, direction, window, supporting embeddings | +| **Risk Signal** | Actionable observation about biophysical change — not a diagnosis | +| **Intention Lead Signal** | Pre-movement dynamics (lean, weight shift) detected 200-500ms before visible motion | +| **Occupancy Volume** | Low-resolution 3D probabilistic density field from RF tomography | +| **Room Fingerprint** | HNSW-indexed embedding characterizing a room's electromagnetic identity | +| **Transition Event** | Person exiting one room and entering another, matched by embedding similarity | + +--- + +### 4. Field Model Context + +**Responsibility:** Learn and maintain the room's electromagnetic baseline. Decompose all CSI observations into environmental drift, body perturbation, and anomalies. Provide the foundation for all downstream exotic capabilities. + +``` +┌──────────────────────────────────────────────────────────┐ +│ Field Model Context │ +├──────────────────────────────────────────────────────────┤ +│ │ +│ ┌───────────────┐ ┌───────────────┐ │ +│ │ Calibration │ │ Mode │ │ +│ │ Collector │ │ Extractor │ │ +│ │ (empty-room │ │ (SVD on │ │ +│ │ CSI frames) │ │ baseline) │ │ +│ └───────┬───────┘ └───────┬───────┘ │ +│ │ │ │ +│ └────────┬───────────┘ │ +│ ▼ │ +│ ┌────────────────┐ │ +│ │ Perturbation │ │ +│ │ Extractor │ │ +│ │ (subtract │ │ +│ │ baseline + │──▶ BodyPerturbation │ +│ │ project out │ │ +│ │ env modes) │ │ +│ └────────┬───────┘ │ +│ │ │ +│ ┌────────▼───────┐ │ +│ │ RF Tomographer│ │ +│ │ (sparse 3D │──▶ OccupancyVolume │ +│ │ inversion) │ │ +│ └────────────────┘ │ +│ │ +└──────────────────────────────────────────────────────────┘ +``` + +**Aggregates:** +- `FieldNormalMode` (Aggregate Root) + +**Value Objects:** +- `BodyPerturbation` — Per-link CSI residual after baseline + environmental mode removal +- `EnvironmentalMode` — One principal component of baseline variation +- `OccupancyVolume` — 3D voxel grid of estimated mass density +- `CalibrationStatus` — Fresh / Stale / Expired (based on time since last empty-room) + +**Domain Services:** +- `CalibrationService` — Detects empty-room windows, collects calibration data +- `ModeExtractionService` — SVD computation for environmental modes +- `PerturbationService` — Baseline subtraction + mode projection +- `TomographyService` — Sparse L1 inversion for occupancy volume + +**RuVector Integration:** +- `ruvector-solver` → SVD for mode extraction; L1 for tomographic inversion +- `ruvector-temporal-tensor` → Baseline history compression +- `ruvector-attn-mincut` → Mode-subcarrier assignment partitioning + +--- + +### 5. Longitudinal Monitoring Context + +**Responsibility:** Maintain per-person biophysical baselines over days/weeks. Detect meaningful drift. Produce traceable evidence reports. Enforce the signals-not-diagnoses boundary. + +``` +┌──────────────────────────────────────────────────────────┐ +│ Longitudinal Monitoring Context │ +├──────────────────────────────────────────────────────────┤ +│ │ +│ ┌───────────────┐ ┌───────────────┐ │ +│ │ Metric │ │ Baseline │ │ +│ │ Extractor │ │ Updater │ │ +│ │ (pose → gait,│ │ (Welford │ │ +│ │ stability, │ │ online │ │ +│ │ breathing) │ │ statistics) │ │ +│ └───────┬───────┘ └───────┬───────┘ │ +│ │ │ │ +│ └────────┬───────────┘ │ +│ ▼ │ +│ ┌────────────────┐ │ +│ │ Drift Detector│ │ +│ │ (z-score vs │ │ +│ │ personal │ │ +│ │ baseline) │ │ +│ └────────┬───────┘ │ +│ ▼ │ +│ ┌────────────────┐ │ +│ │ Evidence │ │ +│ │ Assembler │──▶ DriftReport │ +│ │ (embeddings + │ │ +│ │ timestamps + │ │ +│ │ graph links) │ │ +│ └────────────────┘ │ +│ │ +└──────────────────────────────────────────────────────────┘ +``` + +**Aggregates:** +- `PersonalBaseline` (Aggregate Root) + +**Entities:** +- `DailyMetricSummary` — One day's worth of compressed metric statistics per person + +**Value Objects:** +- `DriftReport` — Evidence package with z-score, direction, window, embeddings +- `DriftMetric` — GaitSymmetry / StabilityIndex / BreathingRegularity / MicroTremor / ActivityLevel +- `DriftDirection` — Increasing / Decreasing +- `MonitoringLevel` — Physiological (Level 1) / Drift (Level 2) / RiskCorrelation (Level 3) +- `WelfordStats` — Online mean/variance accumulator (count, mean, M2) + +**Domain Services:** +- `MetricExtractionService` — Extract biomechanical proxies from pose tracks +- `BaselineUpdateService` — Update Welford statistics with daily observations +- `DriftDetectionService` — Compute z-scores, identify significant deviations +- `EvidenceAssemblyService` — Package supporting embeddings and graph constraints + +**RuVector Integration:** +- `ruvector-temporal-tensor` → Compressed daily summary storage +- `ruvector-attention` → Weight metric significance in drift score +- `ruvector-mincut` → Temporal changepoint detection in metric series +- HNSW → Similarity search across longitudinal embedding record + +**Invariants:** +- Baseline requires 7+ observation days before drift detection activates +- Drift alert requires >2sigma deviation sustained for >3 consecutive days +- Evidence chain must include start/end embeddings bracketing the drift window +- System never outputs diagnostic language — only metric values and deviations +- Personal baseline decay: Welford stats use full history (no windowing) for stability + +--- + +### 6. Spatial Identity Context + +**Responsibility:** Maintain cross-room identity continuity via environment fingerprinting and transition graphs. Track who is where across spaces without storing images. + +``` +┌──────────────────────────────────────────────────────────┐ +│ Spatial Identity Context │ +├──────────────────────────────────────────────────────────┤ +│ │ +│ ┌───────────────┐ ┌───────────────┐ │ +│ │ Room │ │ Transition │ │ +│ │ Fingerprint │ │ Detector │ │ +│ │ Index (HNSW) │ │ (exit/entry │ │ +│ └───────┬───────┘ │ events) │ │ +│ │ └───────┬───────┘ │ +│ │ │ │ +│ └────────┬───────────┘ │ +│ ▼ │ +│ ┌────────────────┐ │ +│ │ Cross-Room │ │ +│ │ Matcher │ │ +│ │ (exit embed ↔ │──▶ TransitionEvent │ +│ │ entry embed) │ │ +│ └────────┬───────┘ │ +│ │ │ +│ ┌────────▼───────┐ │ +│ │ Transition │ │ +│ │ Graph │ │ +│ │ (rooms, │ │ +│ │ persons, │ │ +│ │ timestamps) │ │ +│ └────────────────┘ │ +│ │ +└──────────────────────────────────────────────────────────┘ +``` + +**Aggregates:** +- `SpatialIdentityGraph` (Aggregate Root) + +**Entities:** +- `RoomProfile` — HNSW-indexed electromagnetic fingerprint of a room +- `PersonSpatialRecord` — Which rooms a person has visited, in order + +**Value Objects:** +- `TransitionEvent` — Person, from_room, to_room, timestamps, embedding similarity +- `RoomFingerprint` — 128-dim AETHER embedding of the room's CSI profile +- `SpatialContinuity` — Confidence score for cross-room identity chain + +**Domain Services:** +- `RoomFingerprintService` — Compute and index room electromagnetic profiles +- `TransitionDetectionService` — Detect exits (track lost near boundary) and entries (new track) +- `CrossRoomMatchingService` — HNSW similarity between exit and entry embeddings +- `TransitionGraphService` — Build and query the room-person-time graph + +**RuVector Integration:** +- HNSW → Room and person fingerprint similarity search +- `ruvector-mincut` → Transition graph partitioning for occupancy analysis + +**Invariants:** +- Cross-room match requires >0.80 cosine similarity AND <60s temporal gap +- Room fingerprint must be recalculated if mesh topology changes +- Transition graph edges are immutable once created (append-only audit trail) +- No image data stored — only 128-dim embeddings and structural events + +--- + +### Domain Events (Extended) + +#### Field Model Events + +```rust +pub enum FieldModelEvent { + /// Baseline calibration completed (empty room detected and measured) + BaselineCalibrated { + room_id: RoomId, + n_modes: usize, + variance_explained: f32, // fraction of total variance captured + timestamp_us: u64, + }, + + /// Environmental drift detected (baseline shift without body cause) + EnvironmentalDriftDetected { + room_id: RoomId, + magnitude: f32, + drift_type: DriftProfile, + timestamp_us: u64, + }, + + /// Anomalous perturbation detected (does not match body or environment) + AnomalousPerturbation { + room_id: RoomId, + anomaly_score: f32, + affected_links: Vec, + timestamp_us: u64, + }, + + /// Occupancy volume updated + OccupancyUpdated { + room_id: RoomId, + occupied_voxels: usize, + total_voxels: usize, + timestamp_us: u64, + }, +} +``` + +#### Longitudinal Monitoring Events + +```rust +pub enum LongitudinalEvent { + /// Personal baseline established (7-day calibration complete) + BaselineEstablished { + person_id: PersonId, + observation_days: u32, + metrics_tracked: Vec, + timestamp_us: u64, + }, + + /// Drift detected — biophysical metric significantly changed + DriftDetected { + person_id: PersonId, + report: DriftReport, + timestamp_us: u64, + }, + + /// Drift resolved — metric returned to baseline range + DriftResolved { + person_id: PersonId, + metric: DriftMetric, + resolution_days: u32, + timestamp_us: u64, + }, + + /// Daily summary computed for a person + DailySummaryComputed { + person_id: PersonId, + date: u64, // day timestamp + metrics: Vec<(DriftMetric, f32)>, // metric, today's value + timestamp_us: u64, + }, +} +``` + +#### Spatial Identity Events + +```rust +pub enum SpatialEvent { + /// New room fingerprinted + RoomFingerprinted { + room_id: RoomId, + fingerprint_dims: usize, + timestamp_us: u64, + }, + + /// Person transitioned between rooms + PersonTransitioned { + person_id: PersonId, + from_room: RoomId, + to_room: RoomId, + similarity: f32, + gap_duration_ms: u64, + timestamp_us: u64, + }, + + /// Cross-room match failed (new person in destination room) + CrossRoomMatchFailed { + entry_room: RoomId, + entry_embedding: Vec, + candidates_checked: usize, + best_similarity: f32, + timestamp_us: u64, + }, +} +``` + +--- + +### Extended Context Map + +``` +┌──────────────────────────────────────────────────────────────────────┐ +│ RuvSense Full System (ADR-029 + ADR-030) │ +├──────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌───────────────┐ FusedFrame ┌──────────────┐ │ +│ │ Multistatic │────────────▶│ Pose Tracking │ │ +│ │ Sensing │ │ Context │ │ +│ └───────┬───────┘ └───────┬───────┘ │ +│ │ │ │ +│ │ │ TrackedPose │ +│ │ │ │ +│ ▼ ┌───────▼───────┐ │ +│ ┌───────────────┐ │ Longitudinal │ │ +│ │ Coherence │ │ Monitoring │ │ +│ │ Context │ │ Context │ │ +│ └───────┬───────┘ └───────┬───────┘ │ +│ │ Gates │ DriftReport │ +│ │ │ │ +│ ▼ ▼ │ +│ ┌───────────────┐ ┌───────────────┐ │ +│ │ Field Model │ │ Spatial │ │ +│ │ Context │ │ Identity │ │ +│ │ (baseline, │ │ Context │ │ +│ │ modes, │ │ (cross-room, │ │ +│ │ tomography) │ │ transitions)│ │ +│ └───────────────┘ └───────────────┘ │ +│ │ +│ ──────────────── Event Bus ────────────────── │ +│ SensingEvent | CoherenceEvent | TrackingEvent | │ +│ FieldModelEvent | LongitudinalEvent | SpatialEvent │ +│ │ +├──────────────────────────────────────────────────────────────────────┤ +│ UPSTREAM: wifi-densepose-{hardware, nn, signal} │ +│ SIBLINGS: AETHER (embeddings) | MERIDIAN (geometry) | MAT (triage) │ +└──────────────────────────────────────────────────────────────────────┘ +``` + +**New Relationship Types:** +- Multistatic Sensing → Field Model: **Partnership** (sensing provides raw CSI; field model provides perturbation extraction) +- Pose Tracking → Longitudinal Monitoring: **Customer/Supplier** (tracking provides daily pose metrics; monitoring builds baselines) +- Pose Tracking → Spatial Identity: **Customer/Supplier** (tracking provides track exit/entry events; spatial maintains transition graph) +- Coherence → Field Model: **Subscriber** (coherence events inform baseline recalibration) +- Longitudinal Monitoring → Spatial Identity: **Partnership** (person profiles shared for cross-room matching) + +--- + +### Extended Repository Interfaces + +```rust +/// Persists field normal modes and calibration history +pub trait FieldModelRepository { + fn save_baseline(&self, room_id: RoomId, mode: &FieldNormalMode); + fn load_baseline(&self, room_id: RoomId) -> Option; + fn list_rooms(&self) -> Vec; + fn save_occupancy_snapshot(&self, room_id: RoomId, volume: &OccupancyVolume, timestamp_us: u64); +} + +/// Persists personal baselines and drift history +pub trait LongitudinalRepository { + fn save_baseline(&self, baseline: &PersonalBaseline); + fn load_baseline(&self, person_id: &PersonId) -> Option; + fn save_daily_summary(&self, person_id: &PersonId, summary: &DailyMetricSummary); + fn load_summaries(&self, person_id: &PersonId, days: u32) -> Vec; + fn save_drift_report(&self, report: &DriftReport); + fn load_drift_history(&self, person_id: &PersonId) -> Vec; +} + +/// Persists room fingerprints and transition graphs +pub trait SpatialIdentityRepository { + fn save_room_fingerprint(&self, room_id: RoomId, fingerprint: &RoomFingerprint); + fn load_room_fingerprint(&self, room_id: RoomId) -> Option; + fn save_transition(&self, transition: &TransitionEvent); + fn load_transitions(&self, person_id: &PersonId, window_ms: u64) -> Vec; + fn load_room_occupancy(&self, room_id: RoomId) -> Vec; +} +``` + +--- + +### Extended Invariants + +#### Field Model +- Baseline calibration requires ≥10 minutes of empty-room CSI (≥12,000 frames at 20 Hz) +- Environmental modes capped at K=5 (more modes overfit to noise) +- Tomographic inversion only valid with ≥8 links (4 nodes minimum) +- Baseline expires after 24 hours if not refreshed during quiet period +- Perturbation energy must be non-negative (enforced by magnitude computation) + +#### Longitudinal Monitoring +- Personal baseline requires ≥7 observation days before drift detection activates +- Drift alert requires >2sigma deviation sustained for ≥3 consecutive days +- Evidence chain must include embedding pairs bracketing the drift window +- Output must never use diagnostic language — only metric values and statistical deviations +- Daily summaries stored for ≥90 days (rolling retention policy) +- Welford statistics use full history (no windowing) for maximum stability + +#### Spatial Identity +- Cross-room match requires >0.80 cosine similarity AND <60s temporal gap +- Room fingerprint recalculated when mesh topology changes (node added/removed/moved) +- Transition graph is append-only (immutable audit trail) +- No image data stored — only 128-dim embeddings and structural events +- Maximum 100 rooms indexed per deployment (HNSW scaling constraint) diff --git a/docs/research/ruvsense-multistatic-fidelity-architecture.md b/docs/research/ruvsense-multistatic-fidelity-architecture.md index a08f4bb..34b5594 100644 --- a/docs/research/ruvsense-multistatic-fidelity-architecture.md +++ b/docs/research/ruvsense-multistatic-fidelity-architecture.md @@ -875,3 +875,621 @@ RuvSense achieves high-fidelity WiFi DensePose by exploiting three physical leve The architecture is incrementally deployable: start with 2 nodes for basic improvement, scale to 4+ for full multistatic sensing. The same software stack runs on ESP32 mesh or Cognitum hardware, with only the CSI input interface changing. **The winning move is not inventing new WiFi. It is making existing WiFi see better.** + +--- + +## Part II: The Persistent Field Model + +*The most exotic capabilities come from treating RF as a persistent world model, not a momentary pose estimate.* + +--- + +## 16. Beyond Pose: RF as Spatial Intelligence + +Sections 1-15 treat WiFi as a pose estimator. That is the floor. The ceiling is treating the electromagnetic field as a **persistent, self-updating model of the physical world** — a model that remembers, predicts, and explains. + +The shift: instead of asking "where are the keypoints right now?", ask "how has this room changed since yesterday, and what does that change mean?" + +This requires three architectural upgrades: +1. **Field normal modes**: Model the room itself, not just the people in it +2. **Longitudinal memory**: Store structured embeddings over days/weeks via RuVector +3. **Coherence as reasoning**: Use coherence gating not just for quality control, but as a semantic signal — when coherence breaks, something meaningful happened + +--- + +## 17. The Seven Exotic Capability Tiers + +### Tier 1: Field Normal Modes + +The room becomes the thing you model. You learn the stable electromagnetic baseline — the set of propagation paths, reflection coefficients, and interference patterns that exist when nobody is present. This is the **field normal mode**: the eigenstructure of the empty room's channel transfer function. + +People and objects become **structured perturbations** to this baseline. A person entering the room does not create a new signal — they perturb existing modes. The perturbation has structure: it is spatially localized (the person is somewhere), spectrally colored (different body parts affect different subcarriers), and temporally smooth (people move continuously). + +```rust +/// Field Normal Mode — the room's electromagnetic eigenstructure +pub struct FieldNormalMode { + /// Baseline CSI per link (measured during empty-room calibration) + pub baseline: Vec>>, // [n_links × n_subcarriers] + /// Principal components of baseline variation (temperature, humidity) + pub environmental_modes: Vec>, // [n_modes × n_subcarriers] + /// Eigenvalues: how much variance each mode explains + pub mode_energies: Vec, + /// Timestamp of last baseline update + pub calibrated_at: u64, + /// Room geometry hash (invalidate if nodes move) + pub geometry_hash: u64, +} + +impl FieldNormalMode { + /// Compute perturbation: subtract baseline, project out environmental modes. + /// What remains is body-caused change. + pub fn extract_perturbation( + &self, + current_csi: &[Vec>], + ) -> Vec> { + current_csi.iter().zip(self.baseline.iter()).map(|(curr, base)| { + let delta: Vec = curr.iter().zip(base.iter()) + .map(|(c, b)| (c - b).norm()) + .collect(); + + // Project out environmental modes (slow drift) + let mut residual = delta.clone(); + for mode in &self.environmental_modes { + let projection: f32 = residual.iter().zip(mode.iter()) + .map(|(r, m)| r * m).sum(); + for (r, m) in residual.iter_mut().zip(mode.iter()) { + *r -= projection * m; + } + } + residual // Pure body perturbation + }).collect() + } +} +``` + +**Why this matters:** The field normal mode enables a building that **senses itself**. Changes are explained as deltas from baseline. A new chair is a permanent mode shift. A person walking is a transient perturbation. A door opening changes specific path coefficients. The system does not need to be told what changed — it can decompose the change into structural categories. + +**RuVector integration:** `ruvector-solver` fits the environmental mode matrix via low-rank SVD. `ruvector-temporal-tensor` stores the baseline history with adaptive quantization. + +### Tier 2: Coarse RF Tomography + +With multiple viewpoints, you can infer a low-resolution 3D occupancy volume, not just skeleton keypoints. + +``` + Node A + ╱ ╲ + ╱ ╲ Link A→B passes through voxel (2,3) + ╱ ╲ Link A→C passes through voxels (2,3), (3,4) + ╱ ┌─────┐ ╲ Link B→D passes through voxel (3,3) + ╱ │ occ │ ╲ +Node B │upa- │ Node C From 12 link attenuations, + ╲ │ ncy │ ╱ solve for voxel occupancy + ╲ └─────┘ ╱ using ruvector-solver (L1) + ╲ ╱ + ╲ ╱ + ╲ ╱ + Node D +``` + +This is not a camera. It is a **probabilistic density field** that tells you where mass is, not what it looks like. It stays useful in darkness, smoke, occlusion, and clutter. + +```rust +/// Coarse RF tomography — 3D occupancy from link attenuations +pub struct RfTomographer { + /// 3D voxel grid dimensions + pub grid_dims: [usize; 3], // e.g., [8, 10, 4] for 4m × 5m × 2m at 0.5m resolution + /// Voxel size in metres + pub voxel_size: f32, // 0.5m + /// Projection matrix: which voxels does each link pass through + /// Shape: [n_links × n_voxels], sparse + pub projection: Vec>, // (voxel_idx, path_weight) + /// Regularization strength (sparsity prior) + pub lambda: f32, // default: 0.01 +} + +impl RfTomographer { + /// Reconstruct occupancy volume from link perturbation magnitudes. + /// Uses ruvector-solver for L1-regularized least squares. + pub fn reconstruct( + &self, + link_perturbations: &[f32], // [n_links], magnitude of body perturbation + ) -> Vec { + // Sparse tomographic inversion: find occupancy x such that + // ||Ax - b||₂ + λ||x||₁ → min + // where A is projection matrix, b is link perturbations + let n_voxels = self.grid_dims.iter().product(); + let solver = NeumannSolver::new(n_voxels, self.lambda); + solver.solve_sparse(&self.projection, link_perturbations) + } +} +``` + +**Resolution:** With 4 nodes (12 links) and 0.5m voxels, the tomographic grid is 8×10×4 = 320 voxels. 12 measurements for 320 unknowns is severely underdetermined, but L1 regularization exploits sparsity — typically only 5-15 voxels are occupied by a person. At 8+ nodes (56 links), resolution improves to ~0.25m. + +### Tier 3: Intention Lead Signals + +Subtle pre-movement dynamics appear **before visible motion**. Lean, weight shift, arm tension, center-of-mass displacement. These are not noise — they are the body's preparatory phase for action. + +With contrastive embeddings plus temporal memory, you can **predict action onset** early enough to drive safety and robotics applications. + +```rust +/// Intention lead signal detector. +/// Monitors the embedding trajectory for pre-movement patterns. +pub struct IntentionDetector { + /// Temporal window of AETHER embeddings (last 2 seconds at 20 Hz = 40 frames) + pub embedding_history: VecDeque>, // [40 × 128] + /// Trained classifiers for pre-movement signatures + pub lean_classifier: MicroClassifier, + pub weight_shift_classifier: MicroClassifier, + pub reach_intent_classifier: MicroClassifier, + /// Lead time budget: how far ahead we predict (ms) + pub max_lead_ms: u32, // default: 500ms +} + +impl IntentionDetector { + /// Detect pre-movement intention from embedding trajectory. + /// Returns predicted action and time-to-onset. + pub fn detect(&self) -> Option { + let trajectory = self.compute_trajectory_features(); + + // Pre-movement signatures: + // 1. Embedding velocity increases before visible motion + // 2. Embedding curvature changes (trajectory bends toward action cluster) + // 3. Subcarrier variance pattern matches stored pre-action templates + + let lean = self.lean_classifier.score(&trajectory); + let shift = self.weight_shift_classifier.score(&trajectory); + let reach = self.reach_intent_classifier.score(&trajectory); + + let best = [ + (lean, IntentionType::Lean), + (shift, IntentionType::WeightShift), + (reach, IntentionType::Reach), + ].iter().max_by(|a, b| a.0.partial_cmp(&b.0).unwrap())?; + + if best.0 > 0.7 { + Some(IntentionSignal { + intent_type: best.1, + confidence: best.0, + estimated_lead_ms: self.estimate_lead_time(&trajectory), + }) + } else { + None + } + } +} +``` + +**How much lead time is realistic?** Research on anticipatory postural adjustments shows 200-500ms of preparatory muscle activation before voluntary movement. At 20 Hz with 2-second embedding history, we observe 4-10 frames of pre-movement dynamics. Contrastive pre-training teaches the encoder to separate pre-movement from noise. + +### Tier 4: Longitudinal Biomechanics Drift + +Not diagnosis. **Drift.** You build a personal baseline for gait symmetry, stability, breathing regularity, and micro-tremor, then detect meaningful deviation over days. + +RuVector is the memory and the audit trail. + +```rust +/// Personal biomechanics baseline — stores longitudinal embedding statistics +pub struct PersonalBaseline { + pub person_id: PersonId, + /// Per-metric rolling statistics (Welford online algorithm) + pub gait_symmetry: WelfordStats, // left-right step ratio + pub stability_index: WelfordStats, // center-of-mass sway area + pub breathing_regularity: WelfordStats, // coefficient of variation of breath interval + pub micro_tremor: WelfordStats, // high-frequency (4-12 Hz) limb oscillation power + pub activity_level: WelfordStats, // average movement energy per hour + /// Embedding centroid (EMA, 128-dim) + pub embedding_centroid: Vec, + /// Days of data accumulated + pub observation_days: u32, + /// Last update timestamp + pub updated_at: u64, +} + +/// Drift detection result +pub struct DriftReport { + pub person_id: PersonId, + pub metric: DriftMetric, + /// How many standard deviations from personal baseline + pub z_score: f32, + /// Direction of change + pub direction: DriftDirection, // Increasing / Decreasing + /// Duration over which drift occurred + pub window_days: u32, + /// Confidence that this is a real change (not noise) + pub confidence: f32, + /// Supporting evidence: stored embeddings bracketing the change + pub evidence_embeddings: Vec<(u64, Vec)>, +} + +pub enum DriftMetric { + GaitSymmetry, + StabilityIndex, + BreathingRegularity, + MicroTremor, + ActivityLevel, +} +``` + +**What can be detected (signals, not diagnoses):** + +| Signal | Physiological Proxy | Detectable Via | +|--------|---------------------|---------------| +| Gait symmetry shift | Asymmetric loading, injury compensation | Left-right step timing ratio from pose tracks | +| Stability decrease | Balance degradation | CoM sway area increase (static standing) | +| Breathing irregularity | Respiratory pattern change | Coefficient of variation in breath interval | +| Micro-tremor onset | Involuntary oscillation | 4-12 Hz power in limb keypoint FFT | +| Activity decline | Reduced mobility | Hourly movement energy integral | + +**The output:** "Your movement symmetry has shifted 18 percent over 14 days." That is actionable without being diagnostic. + +**RuVector integration:** `ruvector-temporal-tensor` stores compressed daily summaries. HNSW indexes embeddings for fast similarity search across the longitudinal record. `ruvector-attention` weights which metrics contribute to the overall drift score. + +### Tier 5: Cross-Room Continuity Without Optics + +Environment fingerprints plus track graphs let you carry identity continuity across spaces. You can know who moved where without storing images. + +```rust +/// Cross-room identity continuity via environment fingerprinting +pub struct CrossRoomTracker { + /// Per-room AETHER environment fingerprints (HNSW indexed) + pub room_index: HnswIndex, + /// Per-person embedding profiles (HNSW indexed) + pub person_index: HnswIndex, + /// Transition graph: room_a → room_b with timestamps + pub transitions: Vec, + /// Active tracks per room + pub active_tracks: HashMap>, +} + +pub struct RoomTransition { + pub person_id: PersonId, + pub from_room: RoomId, + pub to_room: RoomId, + pub exit_time: u64, + pub entry_time: u64, + /// Embedding at exit (for matching at entry) + pub exit_embedding: Vec, +} + +impl CrossRoomTracker { + /// When a person appears in a new room, match against recent exits. + pub fn match_entry( + &self, + room_id: RoomId, + entry_embedding: &[f32], + entry_time: u64, + ) -> Option { + // Search recent exits (within 60 seconds) from adjacent rooms + let candidates: Vec<_> = self.transitions.iter() + .filter(|t| entry_time - t.exit_time < 60_000_000) // 60s window + .collect(); + + // HNSW similarity match + let best = candidates.iter() + .map(|t| { + let sim = cosine_similarity(&t.exit_embedding, entry_embedding); + (t, sim) + }) + .max_by(|a, b| a.1.partial_cmp(&b.1).unwrap()); + + match best { + Some((transition, sim)) if sim > 0.80 => Some(transition.person_id), + _ => None, + } + } +} +``` + +**Privacy advantage:** No images are stored. The system stores 128-dimensional embeddings (not reconstructable to appearance) and structural transition events. Identity is established by **behavioral consistency**, not visual recognition. + +### Tier 6: Invisible Interaction Layer + +A room becomes an interface. Multi-user gesture control that works through clothing, in darkness, with line-of-sight blocked. + +The key insight: the same multistatic CSI pipeline that estimates pose can detect **gestural micro-patterns** when the pose is held relatively still. A hand wave, a pointing gesture, a beckoning motion — all produce characteristic CSI perturbation signatures that are person-localized (thanks to the multi-person separator) and geometry-invariant (thanks to MERIDIAN conditioning). + +```rust +/// Gesture recognition from multistatic CSI +pub struct GestureRecognizer { + /// Per-gesture template embeddings (trained contrastively) + pub gesture_templates: HashMap>, // [128-dim each] + /// Temporal window for gesture detection + pub window_frames: usize, // 20 frames = 1 second at 20 Hz + /// Minimum confidence for gesture trigger + pub trigger_threshold: f32, // default: 0.8 +} + +pub enum GestureType { + Wave, + Point, + Beckon, + PushAway, + CircularMotion, + StandUp, + SitDown, + Custom(String), +} +``` + +**Multi-user:** Because person separation (§5.4) already isolates each person's CSI contribution, gesture detection runs independently per person. Two people can gesture simultaneously without interference. + +### Tier 7: Adversarial and Spoofing Detection + +You can detect when the signal looks **physically impossible** given the room model. Coherence gating becomes a **security primitive**, not just a quality check. + +```rust +/// Adversarial signal detector — identifies physically impossible CSI +pub struct AdversarialDetector { + /// Room field normal modes (baseline) + pub field_model: FieldNormalMode, + /// Physical constraints: maximum possible CSI change per frame + pub max_delta_per_frame: f32, // based on max human velocity + /// Subcarrier correlation structure (from room geometry) + pub expected_correlation: Vec>, // [n_sub × n_sub] +} + +impl AdversarialDetector { + /// Check if a CSI frame is physically plausible. + pub fn check(&self, frame: &[Complex], prev_frame: &[Complex]) -> SecurityVerdict { + // 1. Rate-of-change check: no human can cause faster CSI change + let delta = frame_delta_magnitude(frame, prev_frame); + if delta > self.max_delta_per_frame { + return SecurityVerdict::RateViolation(delta); + } + + // 2. Correlation structure check: body perturbations have specific + // cross-subcarrier correlation patterns (from Fresnel zone geometry). + // Injected signals typically lack this structure. + let observed_corr = compute_correlation(frame); + let structure_score = correlation_similarity(&observed_corr, &self.expected_correlation); + if structure_score < 0.5 { + return SecurityVerdict::StructureViolation(structure_score); + } + + // 3. Multi-link consistency: a real body affects multiple links + // consistently with its position. A spoofed signal on one link + // will be inconsistent with other links. + // (Handled at the aggregator level, not per-frame) + + SecurityVerdict::Plausible + } +} + +pub enum SecurityVerdict { + Plausible, + RateViolation(f32), + StructureViolation(f32), + MultiLinkInconsistency(Vec), // which links disagree +} +``` + +**Why multistatic helps security:** To spoof a single-link system, an attacker injects a signal into one receiver. To spoof a multistatic mesh, the attacker must simultaneously inject consistent signals into all receivers — signals that are geometrically consistent with a fake body position. This is physically difficult because each receiver sees a different projection. + +--- + +## 18. Signals, Not Diagnoses + +### 18.1 The Regulatory Boundary + +RF sensing can capture **biophysical proxies**: +- Breathing rate variability +- Gait asymmetry +- Posture instability +- Micro-tremor +- Activity level drift +- Sleep movement patterns + +**Diagnosis** requires: +1. Clinical gold standard validation +2. Controlled datasets with IRB approval +3. Regulatory approval (FDA Class II or III) +4. Extremely low false positive and false negative rates + +Without that, you are in **"risk signal detection"**, not medical diagnosis. + +### 18.2 The Three Levels + +| Level | What It Is | What It Says | Regulatory Load | +|-------|-----------|-------------|-----------------| +| **Level 1: Physiological Monitoring** | Respiratory rate trends, movement stability index, fall likelihood score | "Your breathing rate averaged 18.3 BPM today" | Consumer wellness (low) | +| **Level 2: Drift Detection** | Change from personal baseline, early anomaly detection | "Your gait symmetry shifted 18% over 14 days" | Consumer wellness (low) | +| **Level 3: Condition Risk Correlation** | Pattern consistent with respiratory distress, motor instability | "Pattern consistent with increased fall risk" | Clinical decision support (medium-high) | + +**What you never say:** +- "You have Parkinson's." +- "You have heart failure." +- "You have Alzheimer's." + +### 18.3 The Defensible Pipeline + +``` +RF (CSI) + → AETHER contrastive embedding + → RuVector longitudinal memory + → Coherence-gated drift detection + → Risk flag with traceable evidence +``` + +That gives you: *"Your movement symmetry has shifted 18 percent over 14 days."* + +That is actionable without being diagnostic. The evidence chain (stored embeddings, drift statistics, coherence scores) is fully traceable and auditable via RuVector's graph memory. + +### 18.4 Path to Regulated Claims + +If you ever want to make diagnostic claims: + +| Requirement | Status | Effort | +|-------------|--------|--------| +| IRB-approved clinical studies | Not started | 6-12 months | +| Clinically labeled datasets | Not started | Requires clinical partner | +| Statistical power analysis | Feasible once data exists | 1-2 months | +| FDA 510(k) or De Novo pathway | Not started | 12-24 months + legal | +| CE marking (EU MDR) | Not started | 12-18 months | + +The opportunity is massive, but the regulatory surface explodes the moment you use the word "diagnosis." + +### 18.5 The Decision: Device Classification + +| Class | Example | Regulatory Path | Time to Market | +|-------|---------|----------------|----------------| +| **Consumer wellness** | Breathing rate tracker, activity monitor | Self-certification, FCC Part 15 only | 3-6 months | +| **Clinical decision support** | Fall risk alert, respiratory distress pattern | FDA Class II 510(k) or De Novo | 12-24 months | +| **Regulated medical device** | Diagnostic tool for specific conditions | FDA Class II/III, clinical trials | 24-48 months | + +**Recommendation:** Start as consumer wellness device with Level 1-2 signals. Build longitudinal dataset. Pursue FDA pathway only after 12+ months of real-world data proves statistical power. + +--- + +## 19. Appliance Product Categories + +Treating RF spatial intelligence as a persistent field model enables appliances that were not possible before because they required cameras, wearables, or invasive sensors. + +### 19.1 Invisible Guardian + +**Wall-mounted unit that models gait, fall dynamics, and breathing baselines without optics.** + +| Attribute | Specification | +|-----------|--------------| +| Form factor | Wall puck, 80mm diameter | +| Nodes | 4 ESP32-S3 pucks per room | +| Processing | Central hub (RPi 5 or x86) | +| Power | PoE or USB-C | +| Storage | Embeddings + deltas only, no images | +| Privacy | No camera, no microphone, no reconstructable data | +| Output | Risk flags, drift alerts, occupancy timeline | +| Vertical | Elderly care, independent living, home health | + +**Acceptance test:** Runs locally for 30 days, no camera, detects meaningful environmental or behavioral drift with less than 5% false alarms. + +### 19.2 Spatial Digital Twin Node + +**Small appliance that builds a live electromagnetic twin of a room.** + +Tracks occupancy flow, environmental changes, and structural anomalies. Facilities teams get a time-indexed behavioral map of space usage without video storage risk. + +| Attribute | Specification | +|-----------|--------------| +| Output | Occupancy heatmap, flow vectors, dwell time, anomaly events | +| Data retention | 30-day rolling summary, GDPR-compliant | +| Integration | MQTT/REST API for BMS and CAFM systems | +| Vertical | Smart buildings, workplace analytics, retail | + +### 19.3 Collective Behavior Engine + +**Real-time crowd density, clustering, agitation patterns, and flow bottlenecks.** + +| Attribute | Specification | +|-----------|--------------| +| Scale | 10-100 people per zone | +| Metrics | Density, flow velocity, dwell clusters, evacuation rate | +| Latency | <1s for crowd-level metrics | +| Vertical | Fire safety, event management, transit, retail | + +### 19.4 RF Interaction Surface + +**Turn any room into a gesture interface. No cameras. Multi-user. Works in darkness or smoke.** + +Lighting, media, robotics respond to posture and intent. + +| Attribute | Specification | +|-----------|--------------| +| Gestures | Wave, point, beckon, push, circle + custom | +| Multi-user | Up to 4 simultaneous users | +| Latency | <100ms gesture recognition | +| Vertical | Smart home, hospitality, accessibility, gaming | + +### 19.5 Pre-Incident Drift Monitor + +**Detect subtle changes in movement patterns that precede falls or medical instability.** + +Not diagnosis. Early warning via longitudinal embedding drift. + +| Attribute | Specification | +|-----------|--------------| +| Metrics | Gait symmetry, stability index, breathing regularity, micro-tremor | +| Baseline | 7-day calibration period per person | +| Alert | When any metric drifts >2σ from personal baseline for >3 days | +| Evidence | Stored embedding trajectory + statistical report | +| Vertical | Elderly care, rehabilitation, occupational health | + +### 19.6 Cognitum Nervous System Appliance + +For the premium lane: always-on, local, coherence-gated, storing structured memory in RuVector. + +This appliance was never possible before because we did not have: +- Small edge embedding models (AETHER on ESP32-S3 or Cognitum) +- Persistent vector graph memory (RuVector with HNSW) +- Cheap multistatic RF (ESP32 mesh at $73-91) + +--- + +## 20. Extended Acceptance Tests + +### 20.1 Pose Fidelity (Tier 0 — ADR-029) + +Two people in a room, 20 Hz, stable tracks for 10 minutes with no identity swaps and low jitter in the torso keypoints. + +### 20.2 Longitudinal Stability (Tier 1-4) + +**Seven-day run, no manual tuning.** The system: +1. Flags one real environmental change (furniture moved, door state changed) +2. Flags one real human drift event (gait asymmetry shift, breathing pattern change) +3. Produces a traceable explanation using stored embeddings plus graph constraints +4. Zero false alarms on days with no real change + +### 20.3 Appliance Validation (Tier 5-7) + +**Thirty-day local run, no camera.** The system: +1. Detects meaningful environmental or behavioral drift +2. Less than 5% false alarm rate +3. Provides traceable evidence chain for every alert +4. Operates autonomously — no manual calibration after initial setup + +--- + +## 21. Decision Questions (Exotic Tier) + +### Q3: Which exotic tier first? + +**Recommendation: Field normal modes (Tier 1).** + +Rationale: +- It is the foundation for everything else. Without a room baseline, you cannot detect drift (Tier 4), cross-room transitions (Tier 5), or adversarial signals (Tier 7). +- It requires no new hardware — just a calibration phase during empty-room periods. +- It immediately improves pose quality by separating environmental from body-caused CSI variation. +- It uses `ruvector-solver` (SVD) and `ruvector-temporal-tensor` (baseline storage), both already integrated. + +Second priority: **Longitudinal biomechanics drift (Tier 4)**, because it unlocks the Invisible Guardian and Pre-Incident Drift Monitor appliance categories. + +Third priority: **Cross-room continuity (Tier 5)**, because it unlocks the Spatial Digital Twin Node. + +### Q4: Commodity ESP32 mesh only, or premium Cognitum lane too? + +**Recommendation: ESP32 mesh as the primary development and validation platform. Design the software abstraction layer so Cognitum can slot in as a premium SKU without code changes.** + +The ESP32 mesh ($73-91) proves the algorithms. The Cognitum lane ($500-1000) proves the fidelity ceiling. Both share the same RuvSense aggregator, AETHER embeddings, and RuVector memory. The only difference is the CSI input quality. + +### Q5: Consumer wellness, clinical decision support, or regulated medical device? + +**Recommendation: Consumer wellness device first.** Build the longitudinal dataset. Pursue clinical decision support after 12 months of real-world data proves statistical power. Do not attempt regulated medical device claims without a clinical partner and IRB approval. + +--- + +## 22. Conclusion (Extended) + +RuvSense is not a pose estimator. It is a **spatial intelligence platform** built on the insight that WiFi RF is a persistent, self-updating model of the physical world. + +The architecture decomposes into three layers: + +| Layer | Capability | Timeframe | +|-------|-----------|-----------| +| **Pose** (§1-15) | Multistatic DensePose at 20 Hz, <30mm jitter, zero ID swaps | 10 weeks | +| **Field** (§16-17) | Room modeling, drift detection, intention signals, tomography | +8 weeks | +| **Appliance** (§19) | Product categories: Guardian, Digital Twin, Interaction Surface | +12 weeks | + +Each layer builds on the one below. The complete stack — from ESP32 NDP injection to 30-day autonomous drift monitoring — uses no cameras, stores no images, and runs on $73-91 of commodity hardware. + +RuVector provides the algorithmic spine: solving, attention, graph partitioning, temporal compression, and coherence gating. AETHER provides the embedding space. MERIDIAN provides domain generalization. The result is a system that remembers rooms, recognizes people, detects drift, and explains change — all through WiFi. + +**You can detect signals, not diagnoses. That distinction matters legally, ethically, and technically. But the signals are rich enough to build products that were never possible before.**