RuView Documentation

Π RuView turns commodity WiFi signals into real-time spatial intelligence, vital sign monitoring, and presence detection — all without a single pixel of video.

RAW Doc

Docker & Self-Hosted Deployment Verified OCI

Deploy RuView on any server, homelab, or cloud container platform.

1-Click Terminal Command
bash (docker run)
docker run -d --name ruview -p 3000:3000 --restart always ruvnet/wifi-densepose:latest
Configured Services & Ports
⚙️ sensing-server
image: ruvnet/wifi-densepose:latest
🔌 Ports: 127.0.0.1:3000:3000, 127.0.0.1:3001:3001, 5005:5005/udp
⚙️ python-sensing
image: ruvnet/wifi-densepose:python
🔌 Ports: 127.0.0.1:8765:8765, 127.0.0.1:8080:8080
docker-compose.yml
yaml (docker-compose.yml)
services:
  sensing-server:
    build:
      context: ..
      dockerfile: docker/Dockerfile.rust
    image: ruvnet/wifi-densepose:latest
    # ESP32 CSI must accept LAN UDP; TCP APIs below remain loopback-only.
    # kics-scan ignore-line
    ports:
      - "127.0.0.1:3000:3000"   # REST API
      - "127.0.0.1:3001:3001"   # WebSocket
      # ESP32 UDP. On Linux/macOS this works with multiple ESP32 nodes out of
      # the box. On Docker Desktop for Windows, multi-source UDP is collapsed
      # to one source IP at the WSL/Hyper-V boundary, so all-but-one node's
      # frames are silently dropped (issue #374, #386).
      #
      # Windows workaround: change this to "5006:5005/udp" and run the host
      # relay so every datagram arrives from the same loopback source:
      #
      #   python scripts/udp-relay.py --listen-port 5005 --forward-port 5006
      #
      # See docs/TROUBLESHOOTING.md §9 for details.
      - "5005:5005/udp"
    environment:
      - RUST_LOG=info
      # CSI_SOURCE controls the data source for the sensing server.
      # Options: auto (default) — probe for ESP32 UDP then host WiFi; **fail
      #                           hard with exit 78 if neither is detected**.
      #                           Synthetic data is no longer a silent fallback
      #                           (issue #937 fix) — operators must opt in.
      #          esp32          — receive real CSI frames from an ESP32 on UDP port 5005
      #          wifi           — use host Wi-Fi RSSI/scan data (Windows netsh)
      #          simulated      — explicitly generate synthetic CSI for demo mode
      - CSI_SOURCE=${CSI_SOURCE:-auto}
      # MODELS_DIR controls where the server scans for .rvf model files.
      # Mount a host directory and set this to make models visible:
      #   volumes: ["/path/to/models:/app/models"]
      #   MODELS_DIR=/app/models
      - MODELS_DIR=${MODELS_DIR:-data/models}
      # Auth (issue #864). The entrypoint refuses to start (exit 64) unless
      # RUVIEW_API_TOKEN is set. Export it before `docker compose up`:
      #   export RUVIEW_API_TOKEN=$(openssl rand -hex 32)
      # Bare names pass the host value through only when it is set.
      - RUVIEW_API_TOKEN
      # ESP32 UDP ingest (ADR-296, issue #2089). The UDP receiver defaults to
      # 127.0.0.1, which cannot receive from the published 5005/udp port.
      # Set ONE source guard and the entrypoint binds 0.0.0.0:
      #   RUVIEW_UDP_ALLOW=  restrict sources (preferred)
      #   RUVIEW_UDP_INSECURE_LAN=true        accept the spoofing risk
      # Docker Desktop and OrbStack on macOS rewrite the source address to the
      # bridge gateway, so a LAN-subnet allowlist drops every frame. There,
      # allow the gateway instead:
      #   docker network inspect _default \
      #     --format '{{(index .IPAM.Config 0).Gateway}}'
      #   RUVIEW_UDP_ALLOW=/32
      # The gateway admits anything that reaches the published port, so keep
      # 5005/udp off untrusted networks.
      - RUVIEW_UDP_ALLOW
      - RUVIEW_UDP_INSECURE_LAN
      - RUVIEW_UDP_BIND
      # Browsing the UI from another machine also needs the host name or IP
      # in SENSING_ALLOWED_HOSTS (otherwise 421), and the TCP ports above
      # published beyond 127.0.0.1.
      - SENSING_ALLOWED_HOSTS
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL
    deploy:
      resources:
        limits:
          cpus: "2.0"
          memory: 1G
    healthcheck:
      test: ["CMD-SHELL", "kill -0 1"]
      interval: 30s
      timeout: 3s
      retries: 3
    # No explicit command needed — docker-entrypoint.sh uses CSI_SOURCE.
    # Override with: command: ["--source", "esp32", "--tick-ms", "500"]

  python-sensing:
    build:
      context: ..
      dockerfile: docker/Dockerfile.python
    image: ruvnet/wifi-densepose:python
    ports:
      - "127.0.0.1:8765:8765"   # WebSocket
      - "127.0.0.1:8080:8080"   # UI
    environment:
      - PYTHONUNBUFFERED=1
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL
    deploy:
      resources:
        limits:
          cpus: "1.0"
          memory: 512M
    healthcheck:
      test: ["CMD", "python", "-c", "import socket; socket.create_connection(('127.0.0.1', 8765), 2).close()"]
      interval: 30s
      timeout: 3s
      retries: 3

File: README.md

π RuView

**See through walls with WiFi**

Turn ordinary WiFi into a spatial intelligence / sensing system. Detect people, measure breathing and heart rate, track movement, and monitor rooms — through walls, in the dark, with no cameras or wearables. Just physics.

Works natively with the four major smart-home ecosystems: Home Assistant via the HA-DISCO MQTT publisher, Apple Home & HomePod as a discoverable HAP-1.1 bridge, Google Home + Amazon Alexa via the same HA bridge or a Matter endpoint. Siri, Google Assistant, and Alexa can voice presence and vitals by room with zero custom skills.

Drop into any Home Assistant install with one --mqtt flag. Or pair into Apple Home / Google Home / Alexa / SmartThings as a Matter Bridge. Ships 21 entities per node (11 raw signals + 10 inferred semantic states: someone-sleeping, possible-distress, room-active, elderly-inactivity-anomaly, meeting-in-progress, bathroom-occupied, fall-risk-elevated, bed-exit, no-movement, multi-room-transition) plus 3 starter HA Blueprints. See docs/integrations/home-assistant.md · ADR-115.

π RuView is a WiFi sensing platform that turns radio signals into spatial intelligence.

Every WiFi router already fills your space with radio waves. When people move, breathe, or even sit still, they disturb those waves in measurable ways. RuView captures these disturbances using Channel State Information (CSI) from low-cost ESP32 sensors and turns them into actionable data: who's there, what they're doing, and whether they're okay.

What it senses:

  • Presence and occupancy — detect people through walls, count them, track entries and exits
  • Vital signs — breathing rate and heart rate, contactless, while sleeping or sitting
  • Activity recognition — walking, sitting, gestures, falls — from temporal CSI patterns
  • Environment mapping — RF fingerprinting identifies rooms, detects moved furniture, spots new objects
  • Sleep quality — overnight monitoring with sleep stage classification and apnea screening

Also included:

  • Camera-free pose — estimate 17 body keypoints from WiFi CSI
  • Built-in model workflow — record CSI, train models, load RVF files, and switch LoRA profiles
  • Local automation — HOMECORE provides state, history, automations, signed Wasm plugins, voice hooks, and HomeKit support
  • Unified RF world model — combine WiFi CSI, radar, UWB, and cellular sensing in one privacy-bounded scene model; accuracy is still synthetic until real-data validation
  • Governed evidence — attach privacy policy, uncertainty, provenance, and witness records to sensing events
  • RuView MetaHarness — use an AI operator to onboard, calibrate, train, verify, and check sensing claims

RuView MetaHarness — guided operation for humans and AI agents

The RuView-specific metaharness we created is published as @ruvnet/ruview. It provides source-cited guidance, guarded Claude Code/Codex agents, deterministic verification, and an honesty check for accuracy claims.

bash
# Check the local setup and get source-cited guidance
npx @ruvnet/[email protected] doctor
npx @ruvnet/[email protected] guidance --topic sensing --query "model loading"

# Run a read-only RuView agent through Codex
npx @ruvnet/[email protected] agent run --host codex --repo . \
  --prompt "Find the nearest tests and cite the source files"

# Search or verify the reviewed contributor brain
npx @ruvnet/[email protected] brain search --query "calibration"
npx @ruvnet/[email protected] brain verify --repo .

# Check claims, replay the deterministic proof, or expose the MCP server
npx @ruvnet/[email protected] claim-check --file REPORT.md
npx @ruvnet/[email protected] verify
npx @ruvnet/[email protected] mcp start

Agent runs are read-only by default. Workspace writes require both --allow-write and --confirm; retrieved brain content is evidence, not authority.

Built on RuVector and Cognitum Seed, RuView runs entirely on edge hardware — an ESP32 mesh (as low as $9 per node) paired with a Cognitum Seed for persistent memory, cryptographic attestation, and AI integration. No cloud, no cameras, no internet required.

The system learns each environment locally using spiking neural networks that adapt in under 30 seconds, with multi-frequency mesh scanning across 6 WiFi channels that uses your neighbors' routers as free radar illuminators. Every measurement is cryptographically attested via an Ed25519 witness chain.

RuView turns ordinary WiFi into a contactless sensor. A $9 ESP32 board reads the radio reflections off the people in a room, and a small pretrained model — published on Hugging Face at ruvnet/wifi-densepose-pretrained — tells you who's there, how they're breathing, and how their heart rate is trending. The model fits in 8 KB (4-bit quantized) and runs in microseconds on a Raspberry Pi. (The v2 encoder reports an honest, label-free held-out temporal-triplet accuracy of 82.3% — up from 66.4% raw; the older "100% presence" figure was measured on a single-class recording and has been retracted in favor of this.) No cameras, no wearables, no app on the user's phone.

Built for low-power edge applications

Edge modules are small programs that run directly on the ESP32 sensor — no internet needed, no cloud fees, instant response.








What How Speed / scale
🫁 Breathing rate Bandpass 0.1–0.5 Hz on wrapped phase, circular variance, zero-crossing BPM (#593) 6–30 BPM, real-time
💓 Heart rate Bandpass 0.8–2.0 Hz, zero-crossing BPM 40–120 BPM, real-time
👤 Presence detection Trained head on Hugging Face (ruvnet/wifi-densepose-pretrained; v2 encoder = 82.3% held-out temporal-triplet acc, honestly re-benchmarked) + a phase-variance fallback that needs no model < 1 ms, ~30 s ambient calibration
🧬 CSI embeddings 128-dim contrastive encoder shipped on Hugging Face, 4-bit quantised variant fits in 8 KB 164,183 emb/s on M4 Pro
🦴 17-keypoint pose estimation cog-pose-estimation Cog v0.0.1 — signed aarch64 + x86_64 binaries on GCS, loads pose_v1.safetensors via Candle (the committed pose_v1 is a first-cut on-device model: PCK@20 = 3.0%, below the ADR-079 ≥35% target, and its runtime path is still a confidence=0 stub — see Model weights: what's real, what's not; the 82.69% figure below is the separate published MM-Fi benchmark, not this live cog). Train your own from paired data in 2.1 s on an RTX 5080 (ADR-101, benchmarks). SOTA on MM-Fi: ruvnet/wifi-densepose-mmfi-pose hits 82.69% torso-PCK@20 (ensemble 83.59%), beating MultiFormer (72.25%) and CSI2Pose (68.41%) on the matched MM-Fi random_split protocol — self-corrected and auditable on AetherArena 8.4 ms cold-start on a Pi 5
🚶 Motion / activity Motion-band power + phase acceleration Real-time
🤸 Fall detection Phase-acceleration threshold + 3-frame debounce + 5 s cooldown (#263) < 200 ms
🧮 Multi-person count Adaptive P95 normalisation + runtime-tunable dedup factor (/api/v1/config/dedup-factor, #491). Six specialised learned counters available as Cogs: occupancy-zones, elevator-count, queue-length, customer-flow, clean-room, person-matching Real-time, self-calibrating
🌍 World model prediction OccWorld TransVQVAE — 15-frame future occupancy prediction, 209 ms inference, 3.4 GB VRAM on RTX 5080; fine-tune on your space with occworld_retrain.py (ADR-147) 15 frames × 200×200×16 vox
🧱 Through-wall sensing Fresnel-zone geometry + multipath modeling Up to ~5 m, signal-dependent
🧠 Edge intelligence 105-cog catalog (ADR-102) live from app-registry.json — health, security, building, retail, industrial, research, AI, swarm, signal, network, and developer modules. Optional Cognitum Seed adds persistent vector store + kNN + witness chain $140 total BOM
🎯 Camera-free pre-training Self-supervised contrastive encoder, 12.2M training steps on 60K frames, shipped on Hugging Face 84 s/epoch retrain on M4 Pro
📷 Camera-supervised fine-tune MediaPipe + ESP32 CSI paired training, end-to-end Candle pipeline on RTX 5080 (ADR-079) 2.1 s for 400 epochs (~5 ms/epoch)
📡 Multi-frequency mesh Channel hopping across 6 bands, TDM slot scheduling (ADR-029) 3× sensing bandwidth
🌐 3D point cloud fusion Camera depth (MiDaS) + WiFi CSI + mmWave radar → unified spatial model 22 ms pipeline · 19K+ points/frame

Browse the full 105-module catalog (with practical descriptions, sizes, and difficulty) below in 🧩 Edge Module Catalog, or visit seed.cognitum.one/store.

🤗 Pretrained weights: download from ruvnet/wifi-densepose-pretrained — see Loading the pretrained model below for one-command setup.

Quick start options — Docker, ESP32-S3/C6, Cognitum Seed, and Python

text
/* Detailed source-code truncated for AI context efficiency. */

[!NOTE]
CSI-capable hardware recommended. Presence, vital signs, through-wall sensing, and all advanced capabilities require Channel State Information (CSI) from an ESP32-S3 ($9) or research NIC. The Docker image runs with simulated data for evaluation. Consumer WiFi laptops provide RSSI-only presence detection.

Hardware options for live CSI capture:

Option Hardware Cost Full CSI Capabilities
ESP32 + Cognitum Seed (recommended) ESP32-S3 + Cognitum Seed ~$140 Yes Presence, motion, breathing, heart rate, fall detection, multi-person counting, 17-keypoint pose (signed Cog binary — first-cut on-device model, see Model weights: what's real, what's not), 105-cog catalog, persistent vector store, kNN search, witness chain, MCP proxy
ESP32 Mesh 3-6× ESP32-S3 + WiFi router ~$54 Yes Same capabilities as above without the persistent-memory features
ESP32-C6 research node (ADR-110, witness, reviewer guide, firmware v0.7.0) ESP32-C6-DevKit ($6–10) ~$10 Yes (Wi-Fi 6 capable) Dual-target CSI with 99.56% measured ESP-NOW sync match and measured HE-LTF capture on IDF 5.5.2. TWT and ~5 µA operation still need hardware validation.
Research NIC Intel 5300 / Atheros AR9580 ~$50-100 Yes Full CSI with 3x3 MIMO
Qualcomm CSI beta (ADR-268) QCA9300 now; QCN9074/QCN9274 experimental ~$30-200 Simulator now; hardware adapter gated Rust QCS1 codec, deterministic replay, UDP/API integration; modern ath11k/ath12k profiles do not claim public CSI export
Vendor provider beta (ADR-270) Origin, Plume, Mist, NETGEAR, Electric Imp, RF Solutions, Luma, Nest, Linksys, Wifigarden Varies Capability-dependent Bounded Rust adapters and deterministic fixtures; telemetry/network-only/unsupported states cannot masquerade as CSI
Any WiFi Windows, macOS, or Linux laptop $0 No RSSI-only: coarse presence and motion (see tutorial #36)

No hardware? Verify the signal processing pipeline with the deterministic reference signal: python archive/v1/data/proof/verify.py


Real-time pose skeleton from WiFi CSI signals — no cameras, no wearables (demo visualization; the live CSI-only single-ESP32 17-keypoint model is still first-cut — see Model weights: what's real, what's not)

▶ Live Observatory Demo
 | 
▶ Dual-Modal Pose Fusion Demo
 | 
▶ Live 3D Point Cloud
 | 
▶ three.js Demos (5)

The server is optional for visualization and aggregation — the ESP32 runs independently for presence detection, vital signs, and fall alerts.

Live ESP32 pipeline: Connect an ESP32-S3 node → run the sensing server → open the pose fusion demo for real-time dual-modal pose estimation (webcam + WiFi CSI). See ADR-059. (The webcam supplies ground-truth pose in this dual-modal demo; the CSI-only on-device 17-keypoint model is still first-cut — see Model weights: what's real, what's not.)

three.js scene gallery at /three.js/ — five progressively richer ADR-097 demos: helpers, cinematic, GLTF skinned, FBX skinned, and a live MediaPipe→Mixamo retargeting feed driven by ESP32 CSI. Demos 04 and 05 require a local Mixamo X Bot.fbx (license boundary — not redistributed).

🤗 Pretrained model on Hugging Face

Pretrained CSI weights live at ruvnet/wifi-densepose-pretrained — 12.2M training steps on 60K frames / 610K contrastive triplets, 82.3% held-out temporal-triplet accuracy (up from 66.4% raw; the older "100% presence" figure was measured on a single-class recording and has been retracted), 4-bit quantized variant fits in 8 KB. The release includes a contrastive CSI encoder producing 128-dim embeddings (164,183 emb/s on M4 Pro) and a presence-detection head. Per-node LoRA adapters are included for environment-specific fine-tuning.

bash
# Download the model bundle
pip install huggingface_hub
huggingface-cli download ruvnet/wifi-densepose-pretrained --local-dir models/wifi-densepose-pretrained

What works today vs. what's pending wiring:

Consumer Format used Status
Python training / evaluation / embedding extraction model.safetensors ⚠️ The published file's header is NUL-padded, which the reference safetensors.torch.load_file rejects (issue #1522) — pending a corrected re-upload. csi-embed-v2.safetensors in the same repo is unaffected and loads normally.
Inspect / re-export the bundle model.rvf.jsonl (line-by-line JSON) ✅ Works — plain JSONL
Sensing-server --model flag native RVF, model.safetensors, or model.rvf.jsonl ✅ Native RVF loads directly; safetensors and JSONL auto-convert in memory

Loader scope: --model now accepts native RVF and auto-converts the published safetensors or JSONL files. The quantized model-q*.bin files still need a compatible reader, and loading weights does not supply the matching pose-decoder architecture or establish end-to-end pose accuracy.

Quantization choices (all in the HF repo): model-q2.bin (4 KB) · model-q4.bin ⭐ recommended (8 KB) · model-q8.bin (16 KB) · model.safetensors full (48 KB)

The separate 17-keypoint pose-estimation model is now published at ruvnet/wifi-densepose-mmfi-pose — 82.69% torso-PCK@20 on MM-Fi (single model) / 83.59% (3-model ensemble + TTA), beating the prior published SOTA MultiFormer (72.25%) and CSI2Pose (68.41%) on the matched random_split protocol. See Results & proof below.

Results & proof

See the measured benchmarks, witness records, and one-command reproducibility check.

View benchmark and proof details

What Where Numbers
MM-Fi pose model (SOTA) ruvnet/wifi-densepose-mmfi-pose 82.69% torso-PCK@20 (single) · 83.59% (ensemble+TTA) · 75K-param micro variant 74.30%
AetherArena benchmark Space ruvnet/aether-arena self-correcting, auditable MM-Fi leaderboard
Full MM-Fi study (honest picture) docs/benchmarks/mmfi-wifi-sensing-study.md pose + action; zero-shot cross-subject ~64%, +~30 s in-room calibration → 72.2%
Efficiency frontier docs/benchmarks/wifi-pose-efficiency-frontier.md SOTA-beating WiFi pose in a 20 KB int4 edge model
Pretrained encoder ruvnet/wifi-densepose-pretrained 82.3% held-out temporal-triplet, 8 KB int4
Reproducible proof (Trust Kill Switch) archive/v1/data/proof/verify.py + expected_features.sha256 one-command deterministic pipeline replay (SHA-256 of output vs published hash)
Benchmark-proof ADR ADR-168 how the numbers are produced and verified
Witness attestation docs/WITNESS-LOG-028.md 33-row capability attestation matrix with per-claim evidence
bash
# Reproduce the deterministic pipeline proof yourself (must print VERDICT: PASS):
python archive/v1/data/proof/verify.py

Tracked in #509; see ADR-079 phases P7–P9 for the camera-supervised fine-tune path.

Model weights: what's real, what's not

See which checkpoints are validated, experimental, or architecture-only.

View model maturity details

"WiFi → pose" means three different things in this repo, at three different maturity
levels. Read the label, not the headline (ADR-187):

Tier Checkpoint(s) Honest status
Real & validated ruvnet/wifi-densepose-pretrained (CSI encoder + presence head) · ruvnet/wifi-densepose-mmfi-pose (17-keypoint pose) · cog-person-count/count_v1 MEASURED / published. Presence = 82.3% held-out temporal-triplet accuracy (the old "100% presence" figure was retracted); MM-Fi pose = 82.69% torso-PCK@20 on the random_split protocol. These are the pose/presence numbers the project stands behind today.
Real but weak (honestly labeled) committed v2/crates/cog-pose-estimation/cog/artifacts/pose_v1.safetensors First-cut on-device model. PCK@20 = 3.0% / PCK@50 = 18.5% on a 217-sample holdout — below the ADR-079 target of ≥ 35%. Learns coarse structure (r_hip 77% PCK@50); distal/face joints near-random. Its runtime path in cog-pose-estimation/src/inference.rs is still a centred-skeleton stub returning confidence=0 — the weights are not yet wired in. Full disclosure in the cog README.
Architecture only, no weights archive/v1 DensePoseHead Random kaiming_normal_ init, no checkpoint of any kind (zero .pth/.onnx/.safetensors files under archive/v1/). Deprecated and superseded — see archive/v1/DEPRECATED.md. Do not expect real pose output from it.

On the ESP32-SISO question (#509): a
single-antenna, 56-subcarrier CSI stream at a 20-frame window does not carry the
fine-grained spatial information the multi-antenna NIC research relies on — the cog
measurements above show distal/face joints near-random. The shippable pose accuracy the
project can stand behind today is the MM-Fi benchmark number, not a live single-ESP32
number. The path to a first reproducible on-device baseline (PCK@20 ≥ 35%) is tracked in
ADR-079 / #645 — do not advertise the live single-ESP32 17-keypoint feature without the "first-cut, below-target, runtime-stub" caveat until that baseline is measured.

🧩 Edge Module Catalog

Add signed modules for health, security, buildings, industry, research, AI, and more.

Browse the full edge module catalog

Browse and install modules at seed.cognitum.one/store or on your appliance at http://<appliance>:9000/cogs. Each module is a small signed binary that runs beside the sensing stack. The appliance updates the catalog over the air and verifies every module before installation (ADR-100, ADR-102).

🫀 Health — 14 modules

ID What it does Size Difficulty
air-quality-index Track indoor air quality with CO2 and particle sensors 8 KB Easy
baby-cry Sustained mid-band energy detector for nursery / infant monitoring. Audio-only, no camera. 451 KB Easy
breathing-sync Detects when two people breathe in sync 10 KB Hard
cardiac-arrhythmia Spots irregular heartbeats and abnormal heart rhythms 8 KB Hard
cough-detect Acoustic transient + spectral cough detector with 30s cluster aggregation. Early-warning signal for respiratory illness. 451 KB Easy
dream-stage Tracks your sleep stages — light, deep, and dreaming 14 KB Hard
fall-detect Two-stage impact + stillness fall detector over ambient feature stream (ESP32 motion / mic). Optional ruview-mode for CSI-based pose reinforcement. 402 KB Easy
gait-analysis Detects walking problems and scores fall risk 12 KB Hard
health-monitor Contactless heart rate, breathing, sleep, and fall alerts 30 KB Med
respiratory-distress Alerts when breathing becomes labored or dangerously fast 10 KB Hard
seizure-detect Recognizes seizures and sends immediate alerts 10 KB Hard
sleep-apnea Detects when someone stops breathing during sleep 4 KB Easy
snore-monitor Periodic low-band energy tracker for sleep-quality / apnea-risk trending. Companion to sleep-apnea cog. 451 KB Easy
vital-trend Tracks breathing and heart rate trends over weeks 6 KB Med

🔒 Security — 14 modules

ID What it does Size Difficulty
audit-logger Record every action for compliance — tamper-proof log 8 KB Easy
behavioral-profiler Learns normal behavior and flags anything unusual 12 KB Hard
fleet-auth Manage device certificates and access across all seeds 12 KB Med
glass-break Two-phase bang + shatter acoustic detector. Distinguishes glass break from ordinary impulse noise. 451 KB Easy
gunshot-detect Saturating peak + exponential decay acoustic detector with optional ruview CSI motion-drop reinforcement. 451 KB Easy
intrusion Alerts when an unauthorized person enters a room 6 KB Med
intrusion-detect-ml Detect network attacks using machine learning 14 KB Hard
loitering Alerts when someone lingers too long in one spot 3 KB Easy
network-firewall Block unauthorized network access per cog 6 KB Easy
panic-motion Detects sudden panicked or erratic movement 6 KB Med
perimeter-breach Guards multiple zones and shows entry direction 10 KB Med
prompt-shield Blocks signal replay and injection attacks on the seed 10 KB Med
tailgating Catches when someone sneaks in behind a badge holder 6 KB Med
weapon-detect Detects concealed metal objects on a person 8 KB Hard

🏢 Building — 11 modules

ID What it does Size Difficulty
beehive-monitor Acoustic hive state classifier. Detects healthy / chaotic / queenless / swarming / robbing via hum-band energy + chaos + piping autocorr. 451 KB Easy
elevator-count Counts how many people are in an elevator 8 KB Med
energy-audit Learns your schedule and cuts wasted energy 6 KB Med
frost-warning Predicts frost 6 hours ahead via temperature trend + dewpoint-depression gate. Field/orchard agriculture. 451 KB Easy
hvac-presence Turns heating and cooling on when you arrive 3 KB Easy
lighting-zones Turns lights on and off as people move between rooms 4 KB Easy
meeting-room Shows if a meeting room is free or occupied 5 KB Easy
occupancy-zones Counts people in each room through walls 8 KB Med
predictive-maintenance Vibration harmonic analyzer for rotating equipment. Tracks F1 / 2×F1 / high-order / sideband energy to score degradation severity. 451 KB Easy
smoke-fire Multi-signal smoke and fire detector. Fuses acoustic crackle, thermal drift proxy, and optional ruview CSI plume signature. Not a UL-listed replacement for code-required smoke alarms. 451 KB Easy
water-leak Persistent low-amplitude hiss + periodic drip acoustic detector with multi-minute persistence gate. Two-stage likely → confirmed. 451 KB Easy

🛍️ Retail — 7 modules

ID What it does Size Difficulty
customer-flow Counts foot traffic in and out of each entrance 8 KB Med
dwell-heatmap Shows where customers spend the most time 6 KB Med
package-detect Sustained CSI-shift detector for porch / loading bay package arrivals and departures. Requires ESP32 CSI ruview input. 451 KB Easy
parking-occupancy Per-zone parking occupancy via ESP32 CSI subcarrier-amplitude shift. Tracks utilization and churn-per-hour. Requires ruview. 451 KB Easy
queue-length Estimates line length and wait time 6 KB Med
shelf-engagement Detects when customers interact with products 6 KB Med
table-turnover Tracks which restaurant tables are free or occupied 4 KB Easy

🏭 Industrial — 7 modules

ID What it does Size Difficulty
clean-room Enforces max headcount in controlled environments 4 KB Easy
confined-space Monitors workers in tight spaces for safety 5 KB Med
forklift-proximity Warns if a forklift gets too close to workers 10 KB Hard
livestock-monitor Monitors animals for distress, escape, or illness 6 KB Med
ppe-compliance Cog-composition layer: alerts when ruview-densepose detects presence in a restricted zone without an accompanying PPE-camera-cog confirmation vector. 387 KB Easy
slip-fall-zone Pre-fall risk detector. Fires when motion-variance drop, splash audio, and optional cautious-gait CSI all signal elevated slip risk. 451 KB Easy
structural-vibration Detects dangerous vibrations in buildings or machines 8 KB Hard

🔬 Research — 12 modules

ID What it does Size Difficulty
emotion-detect Reads stress and calm from body language and breathing 10 KB Hard
energy-harvester Optimize solar and battery for off-grid seed deployment 6 KB Med
gesture-language Recognizes sign language gestures in real time 12 KB Hard
ghost-hunter Finds unexplained environmental anomalies — for fun 10 KB Hard
happiness-score Estimates well-being from movement and mood signals 8 KB Med
hyperbolic-space Maps data into curved space for tree-like structures 12 KB Hard
music-conductor Reads a conductor's gestures for tempo and dynamics 12 KB Hard
plant-growth Tracks plant growth rate and day/night cycles 8 KB Med
rain-detect Detects when rain starts, stops, and how heavy it is 6 KB Med
ruview-densepose Full body pose tracking from WiFi — no cameras needed 50 KB Hard
sound-classifier Identify sounds like glass break, alarm, or baby cry 16 KB Hard
time-crystal Experiments with repeating time-pattern symmetry 12 KB Hard

🤖 Ai — 15 modules

ID What it does Size Difficulty
anomaly-attractor Learns what's normal and catches anything weird 10 KB Hard
cognitive-pipeline FastGRNN anomaly gate + SmolLM2 sparse-LLM inference for on-device Pi Zero 2W cognitive events 320 KB Hard
dtw-gesture-learn Teach custom hand gestures by showing examples 14 KB Med
ewc-lifelong Learns new things without forgetting old lessons 8 KB Hard
federated-learning Train AI across seeds without sharing raw data 18 KB Hard
goap-autonomy Plans and executes goals on its own 14 KB Hard
meta-adapt Automatically tunes itself for best performance 10 KB Hard
micro-hnsw Fast on-device fingerprinting and classification 12 KB Med
neural-trader Spot market patterns and trends from live data 20 KB Hard
pagerank-influence Finds the most influential person in a group 12 KB Med
pattern-sequence Detects daily routines and repeated habits 10 KB Med
rag-local Search your documents using AI — runs on the seed 14 KB Med
spiking-tracker Brain-inspired tracker that runs on tiny hardware 16 KB Hard
temporal-logic Enforces safety rules on live event streams 12 KB Hard
time-series-forecast Predict sensor trends using historical patterns 12 KB Med

🐝 Swarm — 11 modules

ID What it does Size Difficulty
swarm-backup-restore Auto-backup data to other seeds — one-click restore 8 KB Easy
swarm-cluster-monitor Live dashboard of every seed's health and status 6 KB Easy
swarm-consensus Seeds vote before making critical changes together 16 KB Hard
swarm-delta-sync Auto-sync data between seeds — only sends changes 8 KB Med
swarm-deploy Install or remove cogs on all seeds at once 10 KB Med
swarm-distributed-store Spread data across seeds and search them all at once 14 KB Hard
swarm-edge-orchestrator Manage all ESP32 sensor nodes from one place 14 KB Hard
swarm-load-balancer Spread queries across seeds so no single one overloads 10 KB Med
swarm-mesh-manager Find, connect, and monitor all seeds on your network 12 KB Easy
swarm-mqtt-bridge Share events between seeds over MQTT messaging 6 KB Easy
swarm-witness-federation Share tamper-proof audit trails across seeds 12 KB Hard

📡 Signal — 6 modules

ID What it does Size Difficulty
coherence-gate Filters out noisy signals and keeps clean ones 8 KB Med
flash-attention Focuses sensing on specific areas for better accuracy 12 KB Med
optimal-transport Measures motion using shape-aware signal comparison 12 KB Hard
person-matching Tells apart multiple people in the same room 18 KB Hard
sparse-recovery Recovers missing signal data from partial readings 16 KB Hard
temporal-compress Shrinks old data to save memory without losing meaning 14 KB Med

🌐 Network — 1 modules

ID What it does Size Difficulty
tailscale Reach the seed from anywhere via a private WireGuard mesh (Tailscale). Userspace mode — no root. 700 KB Med

🛠️ Developer — 7 modules

ID What it does Size Difficulty
adversarial Detects tampered or spoofed sensor signals 4 KB Easy
coherence Monitors signal quality across multiple channels 4 KB Easy
gesture Core gesture recognition building block for cogs 6 KB Med
interference-search Searches many possibilities at once for fast answers 14 KB Hard
psycho-symbolic Reasons over knowledge graphs with multiple styles 16 KB Hard
quantum-coherence Quantum-inspired model for advanced signal states 16 KB Hard
self-healing-mesh Keeps sensor mesh running even when nodes drop out 14 KB Hard

ℹ️ Build your own cog: see ADR-100 for the packaging spec. The first cog this repo ships into the catalog lives in v2/crates/cog-pose-estimation/ (17-keypoint WiFi pose, ADR-101).

🔬 How It Works

WiFi routers flood every room with radio waves. When a person moves — or even breathes — those waves scatter differently. WiFi DensePose reads that scattering pattern and reconstructs what happened:

text
WiFi Router → radio waves pass through room → hit human body → scatter
    ↓
ESP32 mesh (4-6 nodes) captures CSI on channels 1/6/11 via TDM protocol
    ↓
Multi-Band Fusion: 3 channels × 56 subcarriers = 168 virtual subcarriers per link
    ↓
Multistatic Fusion: N×(N-1) links → attention-weighted cross-viewpoint embedding
    ↓
Coherence Gate: accept/reject measurements → stable for days without tuning
    ↓
Signal Processing: Hampel, SpotFi, Fresnel, BVP, spectrogram → clean features
    ↓
AI Backbone (RuVector): attention, graph algorithms, compression, field model
    ↓
Signal-Line Protocol (CRV): 6-stage gestalt → sensory → topology → coherence → search → model
    ↓
Neural Network: processed signals → 17 body keypoints + vital signs + room model
    ↓
Output: real-time pose, breathing, heart rate, room fingerprint, drift alerts

No training cameras required — the Self-Learning system (ADR-024) bootstraps from raw WiFi data alone. MERIDIAN (ADR-027) ensures the model works in any room, not just the one it trained in.


🏢 Use Cases & Applications

WiFi sensing works anywhere WiFi exists. No new hardware in most cases — just software on existing access points or a $8 ESP32 add-on. Because there are no cameras, deployments avoid privacy regulations (GDPR video, HIPAA imaging) by design.

Scaling: Each AP distinguishes ~3-5 people (56 subcarriers). Multi-AP multiplies linearly — a 4-AP retail mesh covers ~15-20 occupants. No hard software limit; the practical ceiling is signal physics.

Why WiFi sensing wins Traditional alternative
🔒 No video, no GDPR/HIPAA imaging rules Cameras require consent, signage, data retention policies
🧱 Works through walls, shelving, debris Cameras need line-of-sight per room
🌙 Works in total darkness Cameras need IR or visible light
💰 $0-$8 per zone (existing WiFi or ESP32) Camera systems: $200-$2,000 per zone
🔌 WiFi already deployed everywhere PIR/radar sensors require new wiring per room

🏥 Everyday — Healthcare, retail, office, hospitality (commodity WiFi)

Use Case What It Does Hardware Key Metric Edge Module
Elderly care / assisted living Fall detection, nighttime activity monitoring, breathing rate during sleep — no wearable compliance needed 1 ESP32-S3 per room ($8) Fall alert <2s Sleep Apnea, Gait Analysis
Hospital patient monitoring Continuous breathing + heart rate for non-critical beds without wired sensors; nurse alert on anomaly 1-2 APs per ward Breathing: 6-30 BPM Respiratory Distress, Cardiac Arrhythmia
Emergency room triage Automated occupancy count + wait-time estimation; detect patient distress (abnormal breathing) in waiting areas Existing hospital WiFi Occupancy accuracy >95% Queue Length, Panic Motion
Retail occupancy & flow Real-time foot traffic, dwell time by zone, queue length — no cameras, no opt-in, GDPR-friendly Existing store WiFi + 1 ESP32 Dwell resolution ~1m Customer Flow, Dwell Heatmap
Office space utilization Which desks/rooms are actually occupied, meeting room no-shows, HVAC optimization based on real presence Existing enterprise WiFi Presence latency <1s Meeting Room, HVAC Presence
Hotel & hospitality Room occupancy without door sensors, minibar/bathroom usage patterns, energy savings on empty rooms Existing hotel WiFi 15-30% HVAC savings Energy Audit, Lighting Zones
Restaurants & food service Table turnover tracking, kitchen staff presence, restroom occupancy displays — no cameras in dining areas Existing WiFi Queue wait ±30s Table Turnover, Queue Length
Parking garages Pedestrian presence in stairwells and elevators where cameras have blind spots; security alert if someone lingers Existing WiFi Through-concrete walls Loitering, Elevator Count

🏟️ Specialized — Events, fitness, education, civic (CSI-capable hardware)

Use Case What It Does Hardware Key Metric Edge Module
Smart home automation Room-level presence triggers (lights, HVAC, music) that work through walls — no dead zones, no motion-sensor timeouts 2-3 ESP32-S3 nodes ($24) Through-wall range ~5m HVAC Presence, Lighting Zones
Fitness & sports Rep counting, posture correction, breathing cadence during exercise — no wearable, no camera in locker rooms 3+ ESP32-S3 mesh Pose: 17 keypoints Breathing Sync, Gait Analysis
Childcare & schools Naptime breathing monitoring, playground headcount, restricted-area alerts — privacy-safe for minors 2-4 ESP32-S3 per zone Breathing: ±1 BPM Sleep Apnea, Perimeter Breach
Event venues & concerts Crowd density mapping, crush-risk detection via breathing compression, emergency evacuation flow tracking Multi-AP mesh (4-8 APs) Density per m² Customer Flow, Panic Motion
Stadiums & arenas Section-level occupancy for dynamic pricing, concession staffing, emergency egress flow modeling Enterprise AP grid 15-20 per AP mesh Dwell Heatmap, Queue Length
Houses of worship Attendance counting without facial recognition — privacy-sensitive congregations, multi-room campus tracking Existing WiFi Zone-level accuracy Elevator Count, Energy Audit
Warehouse & logistics Worker safety zones, forklift proximity alerts, occupancy in hazardous areas — works through shelving and pallets Industrial AP mesh Alert latency <500ms Forklift Proximity, Confined Space
Civic infrastructure Public restroom occupancy (no cameras possible), subway platform crowding, shelter headcount during emergencies Municipal WiFi + ESP32 Real-time headcount Customer Flow, Loitering
Museums & galleries Visitor flow heatmaps, exhibit dwell time, crowd bottleneck alerts — no cameras near artwork (flash/theft risk) Existing WiFi Zone dwell ±5s Dwell Heatmap, Shelf Engagement

🤖 Robotics & Industrial — Autonomous systems, manufacturing, android spatial awareness

WiFi sensing gives robots and autonomous systems a spatial awareness layer that works where LIDAR and cameras fail — through dust, smoke, fog, and around corners. The CSI signal field acts as a "sixth sense" for detecting humans in the environment without requiring line-of-sight.

Use Case What It Does Hardware Key Metric Edge Module
Cobot safety zones Detect human presence near collaborative robots — auto-slow or stop before contact, even behind obstructions 2-3 ESP32-S3 per cell Presence latency <100ms Forklift Proximity, Perimeter Breach
Warehouse AMR navigation Autonomous mobile robots sense humans around blind corners, through shelving racks — no LIDAR occlusion ESP32 mesh along aisles Through-shelf detection Forklift Proximity, Loitering
Android / humanoid spatial awareness Ambient human pose sensing for social robots — detect gestures, approach direction, and personal space without cameras always on Onboard ESP32-S3 module 17-keypoint pose Gesture Language, Emotion Detection
Manufacturing line monitoring Worker presence at each station, ergonomic posture alerts, headcount for shift compliance — works through equipment Industrial AP per zone Pose + breathing Confined Space, Gait Analysis
Construction site safety Exclusion zone enforcement around heavy machinery, fall detection from scaffolding, personnel headcount Ruggedized ESP32 mesh Alert <2s, through-dust Panic Motion, Structural Vibration
Agricultural robotics Detect farm workers near autonomous harvesters in dusty/foggy field conditions where cameras are unreliable Weatherproof ESP32 nodes Range ~10m open field Forklift Proximity, Rain Detection
Drone landing zones Verify landing area is clear of humans — WiFi sensing works in rain, dust, and low light where downward cameras fail Ground ESP32 nodes Presence: >95% accuracy Perimeter Breach, Tailgating
Clean room monitoring Personnel tracking without cameras (particle contamination risk from camera fans) — gown compliance via pose Existing cleanroom WiFi No particulate emission Clean Room, Livestock Monitor

🔥 Extreme — Through-wall, disaster, defense, underground

These scenarios exploit WiFi's ability to penetrate solid materials — concrete, rubble, earth — where no optical or infrared sensor can reach. The WiFi-Mat disaster module (ADR-001) is specifically designed for this tier.

Use Case What It Does Hardware Key Metric Edge Module
Search & rescue (WiFi-Mat) Detect survivors through rubble/debris via breathing signature, START triage color classification, 3D localization Portable ESP32 mesh + laptop Through 30cm concrete Respiratory Distress, Seizure Detection
Firefighting Locate occupants through smoke and walls before entry; breathing detection confirms life signs remotely Portable mesh on truck Works in zero visibility Sleep Apnea, Panic Motion
Prison & secure facilities Cell occupancy verification, distress detection (abnormal vitals), perimeter sensing — no camera blind spots Dedicated AP infrastructure 24/7 vital signs Cardiac Arrhythmia, Loitering
Military / tactical Through-wall personnel detection, room clearing confirmation, hostage vital signs at standoff distance Directional WiFi + custom FW Range: 5m through wall Perimeter Breach, Weapon Detection
Border & perimeter security Detect human presence in tunnels, behind fences, in vehicles — passive sensing, no active illumination to reveal position Concealed ESP32 mesh Passive / covert Perimeter Breach, Tailgating
Mining & underground Worker presence in tunnels where GPS/cameras fail, breathing detection after collapse, headcount at safety points Ruggedized ESP32 mesh Through rock/earth Confined Space, Respiratory Distress
Maritime & naval Below-deck personnel tracking through steel bulkheads (limited range, requires tuning), man-overboard detection Ship WiFi + ESP32 Through 1-2 bulkheads Structural Vibration, Panic Motion
Wildlife research Non-invasive animal activity monitoring in enclosures or dens — no light pollution, no visual disturbance Weatherproof ESP32 nodes Zero light emission Livestock Monitor, Dream Stage

🧠 Self-Learning WiFi AI

Learn compact room fingerprints from raw CSI and adapt the model to each environment.

View self-learning architecture and commands

Every WiFi signal that passes through a room creates a unique fingerprint of that space. WiFi-DensePose already reads these fingerprints to track people, but until now it threw away the internal "understanding" after each reading. The Self-Learning WiFi AI captures and preserves that understanding as compact, reusable vectors — and continuously optimizes itself for each new environment.

What it does in plain terms:

  • Turns any WiFi signal into a 128-number "fingerprint" that uniquely describes what's happening in a room
  • Learns entirely on its own from raw WiFi data — no cameras, no labeling, no human supervision needed
  • Recognizes rooms, detects intruders, and classifies activities using only WiFi (named person-identity is an experimental, data-gated research capability — see below, not a shipped feature)
  • Runs on an $8 ESP32 chip (the entire model fits in 55 KB of memory)
  • Produces both body pose tracking AND environment fingerprints in a single computation

Key Capabilities

What How it works Why it matters
Self-supervised learning The model watches WiFi signals and teaches itself what "similar" and "different" look like, without any human-labeled data Deploy anywhere — just plug in a WiFi sensor and wait 10 minutes
Room identification Each room produces a distinct WiFi fingerprint pattern Know which room someone is in without GPS or beacons
Anomaly detection An unexpected person or event creates a fingerprint that doesn't match anything seen before Automatic intrusion and fall detection as a free byproduct
Person re-identification (experimental, research) A real per-channel similarity matcher (Soul Signature §3.6, wifi-densepose-bfld); measured result: on WiFi-only cardiac+respiratory channels alone two people are not separable (gap ~0.0005) Honest research capability — named identity is not claimed and is data-gated on enrollment with the decisive AETHER/body-resonance channel. See #1021
Environment adaptation MicroLoRA adapters (1,792 parameters per room) fine-tune the model for each new space Adapts to a new room with minimal data — 93% less than retraining from scratch
Memory preservation EWC++ regularization remembers what was learned during pretraining Switching to a new task doesn't erase prior knowledge
Hard-negative mining Training focuses on the most confusing examples to learn faster Better accuracy with the same amount of training data

Architecture

text
WiFi Signal [56 channels] → Transformer + Graph Neural Network
                                  ├→ 128-dim environment fingerprint (for search + identification)
                                  └→ 17-joint body pose (for human tracking)

Quick Start

bash
# Step 1: Learn from raw WiFi data (no labels needed)
cargo run -p wifi-densepose-sensing-server -- --pretrain --dataset data/csi/ --pretrain-epochs 50

# Step 2: Fine-tune with pose labels for full capability
cargo run -p wifi-densepose-sensing-server -- --train --dataset data/mmfi/ --epochs 100 --save-rvf model.rvf

# Step 3: Use the model — extract fingerprints from live WiFi
cargo run -p wifi-densepose-sensing-server -- --model model.rvf --embed

# Step 4: Search — find similar environments or detect anomalies
cargo run -p wifi-densepose-sensing-server -- --model model.rvf --build-index env

Training Modes

Mode What you need What you get
Self-Supervised Just raw WiFi data A model that understands WiFi signal structure
Supervised WiFi data + body pose labels Full pose tracking + environment fingerprints
Cross-Modal WiFi data + camera footage Fingerprints aligned with visual understanding

Fingerprint Index Types

Index What it stores Real-world use
env_fingerprint Average room fingerprint "Is this the kitchen or the bedroom?"
activity_pattern Activity boundaries "Is someone cooking, sleeping, or exercising?"
temporal_baseline Normal conditions "Something unusual just happened in this room"
person_track Individual movement signatures "Person A just entered the living room"

Model Size

Component Parameters Memory (on ESP32)
Transformer backbone ~28,000 28 KB
Embedding projection head ~25,000 25 KB
Per-room MicroLoRA adapter ~1,800 2 KB
Total ~55,000 55 KB (of 520 KB available)

The self-learning system builds on the AI Backbone (RuVector) signal-processing layer — attention, graph algorithms, and compression — adding contrastive learning on top.

See docs/adr/ADR-024-contrastive-csi-embedding-model.md for full architectural details.


🧩 Claude Code & Codex Plugin

Use the in-repo plugin for guided setup, sensing, training, and verification in Claude Code or Codex.

View plugin installation and commands

RuView's Claude Code plugin and Codex prompt mirror cover onboarding, ESP32 setup, sensing apps, model training, advanced sensing, CLI/API/WASM, mmWave radar, and witness verification. The source lives in plugins/ruview/; the marketplace manifest is .claude-plugin/marketplace.json.

bash
# In Claude Code — add this repo as a plugin marketplace, then install:
/plugin marketplace add ruvnet/RuView
/plugin install ruview@ruview

# Or try it for one session without installing (from a local clone of the repo):
claude --plugin-dir ./plugins/ruview

# Then, in Claude Code:
#   /ruview-start      → onboarding (Docker demo / repo build / live ESP32)
#   /ruview-flash      → build + flash ESP32 firmware
#   /ruview-provision  → provision WiFi creds, sink IP, channel/MAC, mesh slots
#   /ruview-app        → run a sensing application (presence / vitals / pose / sleep / MAT / point cloud)
#   /ruview-train      → train / evaluate / publish a model (incl. GPU on GCloud)
#   /ruview-advanced   → multistatic / tomography / cross-viewpoint / mesh-security
#   /ruview-verify     → tests + deterministic proof + witness bundle

Codex (OpenAI CLI): cp plugins/ruview/codex/prompts/*.md ~/.codex/prompts/ — the seven /ruview-* commands are mirrored as Codex prompts; plugins/ruview/codex/AGENTS.md carries the project rules. See plugins/ruview/codex/README.md.

Verify the plugin structure: bash plugins/ruview/scripts/smoke.sh. Full details: plugins/ruview/README.md.

For the portable RuView MetaHarness, use npx @ruvnet/[email protected]; the quick commands and fuller explanation are in the collapsed MetaHarness section near the top of this README and in harness/ruview/.


📖 Documentation

Start with the user, build, and calibration guides; expand for the full reference map.

Browse all documentation

Document Description
User Guide Step-by-step guide: installation, first run, API usage, hardware setup, training
Build Guide Building from source (Rust and Python)
Calibration & Room Training Guide What calibrate/enroll/train-room actually enforce: minimum frame counts, per-anchor quality gates, the pet/small-motion presence-detection caveat, and empty-room baseline conditions — grounded in the real code, not just ADR-135/151
Trust State & Engine Errors What engine_error_count and demoted mean on /api/v1/status, exact trigger conditions, the current diagnostic gap (no per-cause breakdown), the WDP_GUARD_INTERVAL_US recovery path, and why a converted Hugging Face model isn't shown to be the cause in code
Home Assistant + Matter Integration Works with Home Assistant via MQTT auto-discovery + Works with Matter (Apple Home / Google Home / Alexa / SmartThings) — full entity catalog, 3 starter blueprints, Lovelace dashboards, privacy mode, threshold tuning (ADR-115).
BFLD — Beamforming Feedback Layer for Detection New privacy-gated WiFi sensing layer that measures + structurally prevents identity leakage from 802.11ac/ax Beamforming Feedback Information. Three type-enforced invariants (raw BFI never exits node, identity embedding is in-RAM-only, cross-site correlation cryptographically impossible via per-site BLAKE3 keyed hash + daily rotation). Ships full operator surface (BfldPipeline, BfldPipelineHandle, the Soul Signature §3.6 per-channel matcher EnrolledMatcher/SoulMatchOracle — experimental; named identity is data-gated, measured as not-separable on WiFi-only channels alone), MQTT topic router + HA-DISCO + availability + LWT, 3 operator HA blueprints, two runnable examples, eclipse-mosquitto:2 CI service container. 327+ tests. ADR-118 umbrella + sub-ADRs 119/120/121/122/123. Research dossier: docs/research/BFLD/ (11 files, 13,544 words).
SENSE-BRIDGE — rvagent MCP server Dual-transport MCP server (@ruvnet/rvagent) bridging the RuView sensing stack to AI agents (Claude Code, Cursor, ruflo swarms). 6 tools wired: ruview.presence.now, ruview.vitals.get_{breathing,heart_rate,all}, ruview.bfld.last_scan, ruview.bfld.subscribe. stdio + Streamable HTTP (POST /mcp, Origin-validated, bearer-token auth, 127.0.0.1 bind). Full 20-tool Zod schema barrel + 5 RUVIEW-POLICY governance tools. 93 tests. ADR-124. Try: npx @ruvnet/rvagent stdio.
Semantic Primitives — Precision/Recall Per-primitive F1 on the held-out paired-capture set: someone-sleeping, possible-distress, room-active, elderly-inactivity-anomaly, meeting, bathroom, fall-risk, bed-exit, no-movement, multi-room.
Claude Code / Codex Plugin The ruview plugin + marketplace — skills, /ruview-* commands, agents, and the Codex prompt mirror
Portable harness — npx @ruvnet/ruview MetaHarness-minted, host-portable RuView operator harness — ruview.* MCP tools + the MEASURED-vs-CLAIMED honesty guardrail enforced in code (ADR-182). A lighter, multi-host companion to the in-repo plugin.
Architecture Decisions 205 ADRs — why each technical choice was made, organized by domain (hardware, signal processing, ML, platform, infrastructure)
Domain Models 8 DDD models (RuvSense, Signal Processing, Training Pipeline, Hardware Platform, Sensing Server, WiFi-Mat, CHCI, rvCSI) — bounded contexts, aggregates, domain events, and ubiquitous language
rvCSI — edge RF sensing runtime Rust-first / TypeScript-accessible / hardware-abstracted CSI runtime: multi-source ingestion (incl. real nexmon_csi .pcap from a Raspberry Pi 5 / Pi 4 / Pi 3B+ — CYW43455 / BCM43455c0) → validation → DSP → typed events → RuVector RF memory (ADR-095, ADR-096, domain model). Now its own repo — ruvnet/rvcsi — vendored here under vendor/rvcsi; 9 rvcsi-* crates on crates.io, @ruv/rvcsi on npm, plus a Claude Code plugin.
Desktop App WIP — Tauri v2 desktop app for node management, OTA updates, WASM deployment, and mesh visualization
ruview-swarm Drone swarm control system (ADR-148) — hierarchical-mesh topology, Raft consensus, MARL, CSI sensing payload, MAVLink/PX4/ArduPilot compatibility, Ruflo AI-agent integration
ruview-unified Unified RF spatial world model (ADR-273..277) — canonical RF tensor + hardware adapters (WiFi CSI / FMCW radar / UWB / 5G SRS), universal RF foundation encoder with ≤1% task adapters, RF-aware Gaussian spatial memory with channel-gain queries + inverse updates, physics-guided synthetic RF worlds, and an 802.11bf/ETSI-ISAC-aligned sensing policy plane (raw RF structurally unexportable). All accuracy numbers SYNTHETIC until real-data validation.
Medical Examples Contactless blood pressure, heart rate, breathing rate via 60 GHz mmWave radar — $15 hardware, no wearable
Extended Documentation Latest additions, key features, installation, quick start, signal processing, training, CLI, testing, deployment, and changelog

🚧 Beta software

Beta Software — Under active development. APIs and firmware may change. Known limitations:

  • ESP32-C3 and original ESP32 are not supported (single-core, insufficient for CSI DSP)
  • Single ESP32 deployments have limited spatial resolution — use 2+ nodes or add a Cognitum Seed for best results
  • Camera-free pose accuracy is limited (PCK@20 ≈ 2.5% with proxy labels) — camera ground-truth training targets 35%+ PCK@20; the pipeline is implemented, but the data-collection and evaluation phases (ADR-079 P7–P9) are still pending.

Contributions and bug reports welcome at Issues.

📄 License

MIT License — see LICENSE for details.

🤝 Creator Affiliate Program

For TikTok · Instagram · YouTube creators — earn 25% on every Cognitum sale you refer. The RuFlo, RuView, and RuVector videos you're already making have done millions of views; get paid for the orders they drive. Click-tracking activates instantly; commissions activate after a quick manual review (usually under 24 hours).

Apply now → cognitum.one/affiliate

📞 Support

GitHub Issues | Discussions | PyPI


WiFi DensePose — Privacy-preserving human pose estimation through WiFi signals.


File: docs/adr/ADR-001-wifi-mat-disaster-detection.md

ADR-001: WiFi-Mat Disaster Detection Architecture

Status

Accepted

Date

2026-01-13

Context

Natural disasters such as earthquakes, building collapses, avalanches, and floods trap victims under rubble or debris. Traditional search and rescue methods using visual inspection, thermal cameras, or acoustic devices have significant limitations:

  • Visual/Optical: Cannot penetrate rubble, debris, or collapsed structures
  • Thermal: Limited penetration depth, affected by ambient temperature
  • Acoustic: Requires victim to make sounds, high false positive rate
  • K9 Units: Limited availability, fatigue, environmental hazards

WiFi-based sensing offers a unique advantage: RF signals can penetrate non-metallic debris (concrete, wood, drywall) and detect subtle human movements including breathing patterns and heartbeats through Channel State Information (CSI) analysis.

Problem Statement

We need a modular extension to the WiFi-DensePose Rust implementation that:

  1. Detects human presence in disaster scenarios with high sensitivity
  2. Localizes survivors within rubble/debris fields
  3. Classifies victim status (conscious movement, breathing only, critical)
  4. Provides real-time alerts to rescue teams
  5. Operates in degraded/field conditions with portable hardware

Decision

We will create a new crate wifi-densepose-mat (Mass Casualty Assessment Tool) as a modular addition to the existing Rust workspace with the following architecture:

1. Domain-Driven Design (DDD) Approach

The module follows DDD principles with clear bounded contexts:

text
wifi-densepose-mat/
├── src/
│   ├── domain/           # Core domain entities and value objects
│   │   ├── survivor.rs   # Survivor entity with status tracking
│   │   ├── disaster_event.rs  # Disaster event aggregate root
│   │   ├── scan_zone.rs  # Geographic zone being scanned
│   │   └── alert.rs      # Alert value objects
│   ├── detection/        # Life sign detection bounded context
│   │   ├── breathing.rs  # Breathing pattern detection
│   │   ├── heartbeat.rs  # Micro-doppler heartbeat detection
│   │   ├── movement.rs   # Gross/fine movement classification
│   │   └── classifier.rs # Multi-modal victim classifier
│   ├── localization/     # Position estimation bounded context
│   │   ├── triangulation.rs  # Multi-AP triangulation
│   │   ├── fingerprinting.rs # CSI fingerprint matching
│   │   └── depth.rs      # Depth/layer estimation in rubble
│   ├── alerting/         # Notification bounded context
│   │   ├── priority.rs   # Triage priority calculation
│   │   ├── dispatcher.rs # Alert routing and dispatch
│   │   └── protocols.rs  # Emergency protocol integration
│   └── integration/      # Anti-corruption layer
│       ├── signal_adapter.rs  # Adapts wifi-densepose-signal
│       └── nn_adapter.rs      # Adapts wifi-densepose-nn

2. Core Architectural Decisions

2.1 Event-Driven Architecture

  • All survivor detections emit domain events
  • Events enable audit trails and replay for post-incident analysis
  • Supports distributed deployments with multiple scan teams

2.2 Configurable Detection Pipeline

rust
pub struct DetectionPipeline {
    breathing_detector: BreathingDetector,
    heartbeat_detector: HeartbeatDetector,
    movement_classifier: MovementClassifier,
    ensemble_classifier: EnsembleClassifier,
}

2.3 Triage Classification (START Protocol Compatible)

Status Detection Criteria Priority
Immediate (Red) Breathing detected, no movement P1
Delayed (Yellow) Movement + breathing, stable vitals P2
Minor (Green) Strong movement, responsive patterns P3
Deceased (Black) No vitals for >30 minutes continuous scan P4

2.4 Hardware Abstraction

Supports multiple deployment scenarios:

  • Portable: Single TX/RX with handheld device
  • Distributed: Multiple APs deployed around collapse site
  • Drone-mounted: UAV-based scanning for large areas
  • Vehicle-mounted: Mobile command post with array

3. Integration Strategy

The module integrates with existing crates through adapters:

text
┌─────────────────────────────────────────────────────────────┐
│                    wifi-densepose-mat                        │
├─────────────────────────────────────────────────────────────┤
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────┐  │
│  │  Detection  │  │ Localization│  │      Alerting       │  │
│  │  Context    │  │   Context   │  │      Context        │  │
│  └──────┬──────┘  └──────┬──────┘  └──────────┬──────────┘  │
│         │                │                     │             │
│         └────────────────┼─────────────────────┘             │
│                          │                                   │
│              ┌───────────▼───────────┐                       │
│              │   Integration Layer   │                       │
│              │  (Anti-Corruption)    │                       │
│              └───────────┬───────────┘                       │
└──────────────────────────┼───────────────────────────────────┘
                           │
        ┌──────────────────┼──────────────────┐
        │                  │                  │
        ▼                  ▼                  ▼
┌───────────────┐  ┌───────────────┐  ┌───────────────┐
│wifi-densepose │  │wifi-densepose │  │wifi-densepose │
│    -signal    │  │     -nn       │  │   -hardware   │
└───────────────┘  └───────────────┘  └───────────────┘

4. Performance Requirements

Metric Target Rationale
Detection Latency <500ms Real-time feedback for rescuers
False Positive Rate <5% Minimize wasted rescue efforts
False Negative Rate <1% Cannot miss survivors
Penetration Depth 3-5m Typical rubble pile depth
Battery Life (portable) >8 hours Full shift operation
Concurrent Zones 16+ Large disaster site coverage

5. Safety and Reliability

  • Fail-safe defaults: Always assume life present on ambiguous signals
  • Redundant detection: Multiple algorithms vote on presence
  • Continuous monitoring: Re-scan zones periodically
  • Offline operation: Full functionality without network
  • Audit logging: Complete trace of all detections

Consequences

Positive

  • Modular design allows independent development and testing
  • DDD ensures domain experts can validate logic
  • Event-driven enables distributed deployments
  • Adapters isolate from upstream changes
  • Compatible with existing WiFi-DensePose infrastructure

Negative

  • Additional complexity from event system
  • Learning curve for rescue teams
  • Requires calibration for different debris types
  • RF interference in disaster zones

Risks and Mitigations

Risk Mitigation
Metal debris blocking signals Multi-angle scanning, adaptive frequency
Environmental RF interference Spectral sensing, frequency hopping
False positives from animals Size/pattern classification
Power constraints in field Low-power modes, solar charging

References


File: docs/adr/ADR-002-ruvector-rvf-integration-strategy.md

ADR-002: RuVector RVF Integration Strategy

Status

Superseded by ADR-016 and ADR-017

Note: The vision in this ADR has been fully realized. ADR-016 integrates all 5 RuVector crates into the training pipeline. ADR-017 adds 7 signal + MAT integration points. The wifi-densepose-ruvector crate is published on crates.io. See also ADR-027 for how RuVector is extended with domain generalization.

Date

2026-02-28

Context

Current System Limitations

The WiFi-DensePose system processes Channel State Information (CSI) from WiFi signals to estimate human body poses. The current architecture (Python v1 + Rust port) has several areas where intelligence and performance could be significantly improved:

  1. No persistent vector storage: CSI feature vectors are processed transiently. Historical patterns, fingerprints, and learned representations are not persisted in a searchable vector database.

  2. Static inference models: The modality translation network (ModalityTranslationNetwork) and DensePose head use fixed weights loaded at startup. There is no online learning, adaptation, or self-optimization.

  3. Naive pattern matching: Human detection in CSIProcessor uses simple threshold-based confidence scoring (amplitude_indicator, phase_indicator, motion_indicator with fixed weights 0.4, 0.3, 0.3). No similarity search against known patterns.

  4. No cryptographic audit trail: Life-critical disaster detection (wifi-densepose-mat) lacks tamper-evident logging for survivor detections and triage classifications.

  5. Limited edge deployment: The WASM crate (wifi-densepose-wasm) provides basic bindings but lacks a self-contained runtime capable of offline operation with embedded models.

  6. Single-node architecture: Multi-AP deployments for disaster scenarios require distributed coordination, but no consensus mechanism exists for cross-node state management.

RuVector Capabilities

RuVector (github.com/ruvnet/ruvector) provides a comprehensive cognitive computing platform:

  • RVF (Cognitive Containers): Self-contained files with 25 segment types (VEC, INDEX, KERNEL, EBPF, WASM, COW_MAP, WITNESS, CRYPTO) that package vectors, models, and runtime into a single deployable artifact
  • HNSW Vector Search: Hierarchical Navigable Small World indexing with SIMD acceleration and Hyperbolic extensions for hierarchy-aware search
  • SONA: Self-Optimizing Neural Architecture providing <1ms adaptation via LoRA fine-tuning with EWC++ memory preservation
  • GNN Learning Layer: Graph Neural Networks that learn from every query through message passing, attention weighting, and representation updates
  • 46 Attention Mechanisms: Including Flash Attention, Linear Attention, Graph Attention, Hyperbolic Attention, Mincut-gated Attention
  • Post-Quantum Cryptography: ML-DSA-65, Ed25519, SLH-DSA-128s signatures with SHAKE-256 hashing
  • Witness Chains: Tamper-evident cryptographic hash-linked audit trails
  • Raft Consensus: Distributed coordination with multi-master replication and vector clocks
  • WASM Runtime: 5.5 KB runtime bootable in 125ms, deployable on servers, browsers, phones, IoT
  • Git-like Branching: Copy-on-write structure (1M vectors + 100 edits ≈ 2.5 MB branch)

Decision

We will integrate RuVector's RVF format and intelligence capabilities into the WiFi-DensePose system through a phased, modular approach across 9 integration domains, each detailed in subsequent ADRs (ADR-003 through ADR-010).

Integration Architecture Overview

text
/* Detailed source-code truncated for AI context efficiency. */

New Crate: `wifi-densepose-rvf`

A new workspace member crate will serve as the integration layer:

text
crates/wifi-densepose-rvf/
├── Cargo.toml
├── src/
│   ├── lib.rs                 # Public API surface
│   ├── container.rs           # RVF cognitive container management
│   ├── vector_store.rs        # HNSW-backed CSI vector storage
│   ├── search.rs              # Similarity search for fingerprinting
│   ├── learning.rs            # SONA integration for online learning
│   ├── gnn.rs                 # GNN pattern enhancement layer
│   ├── attention.rs           # Attention mechanism selection
│   ├── witness.rs             # Witness chain audit trails
│   ├── consensus.rs           # Raft consensus for multi-AP
│   ├── crypto.rs              # Post-quantum crypto wrappers
│   ├── edge.rs                # WASM edge runtime integration
│   └── adapters/
│       ├── mod.rs
│       ├── signal_adapter.rs  # Bridges wifi-densepose-signal
│       ├── nn_adapter.rs      # Bridges wifi-densepose-nn
│       └── mat_adapter.rs     # Bridges wifi-densepose-mat

Phased Rollout

Phase Timeline ADR Capability Priority
1 Weeks 1-3 ADR-003 RVF Cognitive Containers for CSI Data Critical
2 Weeks 2-4 ADR-004 HNSW Vector Search for Signal Fingerprinting Critical
3 Weeks 4-6 ADR-005 SONA Self-Learning for Pose Estimation High
4 Weeks 5-7 ADR-006 GNN-Enhanced CSI Pattern Recognition High
5 Weeks 6-8 ADR-007 Post-Quantum Cryptography for Secure Sensing Medium
6 Weeks 7-9 ADR-008 Distributed Consensus for Multi-AP Medium
7 Weeks 8-10 ADR-009 RVF WASM Runtime for Edge Deployment Medium
8 Weeks 9-11 ADR-010 Witness Chains for Audit Trail Integrity High (MAT)

Dependency Strategy

Verified published crates (crates.io, all at v2.0.4 as of 2026-02-28):

toml
# In Cargo.toml workspace dependencies
[workspace.dependencies]
ruvector-mincut = "2.0.4"           # Dynamic min-cut, O(n^1.5 log n) graph partitioning
ruvector-attn-mincut = "2.0.4"     # Attention + mincut gating in one pass
ruvector-temporal-tensor = "2.0.4"  # Tiered temporal compression (50-75% memory reduction)
ruvector-solver = "2.0.4"           # NeumannSolver — O(√n) Neumann series convergence
ruvector-attention = "2.0.4"        # ScaledDotProductAttention

Note (ADR-017 correction): Earlier versions of this ADR specified
ruvector-core, ruvector-data-framework, ruvector-consensus, and
ruvector-wasm at version "0.1". These crates do not exist at crates.io.
The five crates above are the verified published API surface at v2.0.4.
Capabilities such as RVF cognitive containers (ADR-003), HNSW search (ADR-004),
SONA (ADR-005), GNN patterns (ADR-006), post-quantum crypto (ADR-007),
Raft consensus (ADR-008), and WASM runtime (ADR-009) are internal capabilities
accessible through these five crates or remain as forward-looking architecture.
See ADR-017 for the corrected integration map.

Feature flags control which ruvector capabilities are compiled in:

toml
[features]
default = ["mincut-matching", "solver-interpolation"]
mincut-matching = ["ruvector-mincut"]
attn-mincut = ["ruvector-attn-mincut"]
temporal-compress = ["ruvector-temporal-tensor"]
solver-interpolation = ["ruvector-solver"]
attention = ["ruvector-attention"]
full = ["mincut-matching", "attn-mincut", "temporal-compress", "solver-interpolation", "attention"]

Consequences

Positive

  • 10-100x faster pattern lookup: HNSW replaces linear scan for CSI fingerprint matching
  • Continuous improvement: SONA enables online adaptation without full retraining
  • Self-contained deployment: RVF containers package everything needed for field operation
  • Tamper-evident records: Witness chains provide cryptographic proof for disaster response auditing
  • Future-proof security: Post-quantum signatures resist quantum computing attacks
  • Distributed operation: Raft consensus enables coordinated multi-AP sensing
  • Ultra-light edge: 5.5 KB WASM runtime enables browser and IoT deployment
  • Git-like versioning: COW branching enables experimental model variations with minimal storage

Negative

  • Increased binary size: Full feature set adds significant dependencies (~15-30 MB)
  • Complexity: 9 integration domains require careful coordination
  • Learning curve: Team must understand RuVector's cognitive container paradigm
  • API stability risk: RuVector is pre-1.0; APIs may change
  • Testing surface: Each integration point requires dedicated test suites

Risks and Mitigations

Risk Severity Mitigation
RuVector API breaking changes High Pin versions, adapter pattern isolates impact
Performance regression from abstraction layers Medium Benchmark each integration point, zero-cost abstractions
Feature flag combinatorial complexity Medium CI matrix testing for key feature combinations
Over-engineering for current use cases Medium Phased rollout, each phase independently valuable
Binary size bloat for edge targets Low Feature flags ensure only needed capabilities compile
  • ADR-001: WiFi-Mat Disaster Detection Architecture (existing)
  • ADR-003: RVF Cognitive Containers for CSI Data
  • ADR-004: HNSW Vector Search for Signal Fingerprinting
  • ADR-005: SONA Self-Learning for Pose Estimation
  • ADR-006: GNN-Enhanced CSI Pattern Recognition
  • ADR-007: Post-Quantum Cryptography for Secure Sensing
  • ADR-008: Distributed Consensus for Multi-AP Coordination
  • ADR-009: RVF WASM Runtime for Edge Deployment
  • ADR-010: Witness Chains for Audit Trail Integrity

References


File: docs/adr/ADR-003-rvf-cognitive-containers-csi.md

ADR-003: RVF Cognitive Containers for CSI Data

Status

Proposed

Date

2026-02-28

Context

Problem

WiFi-DensePose processes CSI (Channel State Information) data through a multi-stage pipeline: raw capture → preprocessing → feature extraction → neural inference → pose output. Each stage produces intermediate data that is currently ephemeral:

  1. Raw CSI measurements (CsiData): Amplitude matrices (num_antennas x num_subcarriers), phase arrays, SNR values, metadata. Stored only in a bounded VecDeque (max 500 entries in Python, similar in Rust).

  2. Extracted features (CsiFeatures): Amplitude mean/variance, phase differences, correlation matrices, Doppler shifts, power spectral density. Discarded after single-pass inference.

  3. Trained model weights: Static ONNX/PyTorch files loaded from disk. No mechanism to persist adapted weights or experimental variations.

  4. Detection results (HumanDetectionResult): Confidence scores, motion scores, detection booleans. Logged but not indexed for pattern retrieval.

  5. Environment fingerprints: Each physical space has a unique CSI signature affected by room geometry, furniture, building materials. No persistent fingerprint database exists.

Opportunity

RuVector's RVF (Cognitive Container) format provides a single-file packaging solution with 25 segment types that can encapsulate the entire WiFi-DensePose operational state:

text
RVF Cognitive Container Structure:
┌─────────────────────────────────────────────┐
│ HEADER    │ Magic, version, segment count   │
├───────────┼─────────────────────────────────┤
│ VEC       │ CSI feature vectors             │
│ INDEX     │ HNSW index over vectors         │
│ WASM      │ Inference runtime               │
│ COW_MAP   │ Copy-on-write branch state      │
│ WITNESS   │ Audit chain entries             │
│ CRYPTO    │ Signature keys, attestations    │
│ KERNEL    │ Bootable runtime (optional)     │
│ EBPF      │ Hardware-accelerated filters    │
│ ...       │ (25 total segment types)        │
└─────────────────────────────────────────────┘

Decision

We will adopt the RVF Cognitive Container format as the primary persistence and deployment unit for WiFi-DensePose operational data, implementing the following container types:

1. CSI Fingerprint Container (`.rvf.csi`)

Packages environment-specific CSI signatures for location recognition:

rust
/// CSI Fingerprint container storing environment signatures
pub struct CsiFingerprintContainer {
    /// Container metadata
    metadata: ContainerMetadata,

    /// VEC segment: Normalized CSI feature vectors
    /// Each vector = [amplitude_mean(N) | amplitude_var(N) | phase_diff(N-1) | doppler(10) | psd(128)]
    /// Typical dimensionality: 64 subcarriers → 64+64+63+10+128 = 329 dimensions
    fingerprint_vectors: VecSegment,

    /// INDEX segment: HNSW index for O(log n) nearest-neighbor lookup
    hnsw_index: IndexSegment,

    /// COW_MAP: Branches for different times-of-day, occupancy levels
    branches: CowMapSegment,

    /// Metadata per vector: room_id, timestamp, occupancy_count, furniture_hash
    annotations: AnnotationSegment,
}

Vector encoding: Each CSI snapshot is encoded as a fixed-dimension vector:

text
CSI Feature Vector (329-dim for 64 subcarriers):
┌──────────────────┬──────────────────┬─────────────────┬──────────┬─────────┐
│ amplitude_mean   │ amplitude_var    │ phase_diff      │ doppler  │ psd     │
│ [f32; 64]        │ [f32; 64]        │ [f32; 63]       │ [f32; 10]│ [f32;128│
└──────────────────┴──────────────────┴─────────────────┴──────────┴─────────┘

2. Model Container (`.rvf.model`)

Packages neural network weights with versioning:

rust
/// Model container with version tracking and A/B comparison
pub struct ModelContainer {
    /// Container metadata with model version history
    metadata: ContainerMetadata,

    /// Primary model weights (ONNX serialized)
    primary_weights: BlobSegment,

    /// SONA adaptation deltas (LoRA low-rank matrices)
    adaptation_deltas: VecSegment,

    /// COW branches for model experiments
    /// e.g., "baseline", "adapted-office-env", "adapted-warehouse"
    branches: CowMapSegment,

    /// Performance metrics per branch
    metrics: AnnotationSegment,

    /// Witness chain: every weight update recorded
    audit_trail: WitnessSegment,
}

3. Session Container (`.rvf.session`)

Captures a complete sensing session for replay and analysis:

rust
/// Session container for recording and replaying sensing sessions
pub struct SessionContainer {
    /// Session metadata (start time, duration, hardware config)
    metadata: ContainerMetadata,

    /// Time-series CSI vectors at capture rate
    csi_timeseries: VecSegment,

    /// Detection results aligned to CSI timestamps
    detections: AnnotationSegment,

    /// Pose estimation outputs
    poses: VecSegment,

    /// Index for temporal range queries
    temporal_index: IndexSegment,

    /// Cryptographic integrity proof
    witness_chain: WitnessSegment,
}

Container Lifecycle

text
┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐
  │  Create   │───▶│  Ingest  │───▶│  Query   │───▶│  Branch  │
  │ Container │    │ Vectors  │    │  (HNSW)  │    │  (COW)   │
  └──────────┘    └──────────┘    └──────────┘    └──────────┘
       │                                                │
       │         ┌──────────┐    ┌──────────┐          │
       │         │  Merge   │◀───│  Compare │◀─────────┘
       │         │ Branches │    │ Results  │
       │         └────┬─────┘    └──────────┘
       │              │
       ▼              ▼
  ┌──────────┐   ┌──────────┐
  │  Export   │   │  Deploy  │
  │  (.rvf)  │   │  (Edge)  │
  └──────────┘   └──────────┘

Integration with Existing Crates

The container system integrates through adapter traits:

rust
/// Trait for types that can be vectorized into RVF containers
pub trait RvfVectorizable {
    /// Encode self as a fixed-dimension f32 vector
    fn to_rvf_vector(&self) -> Vec<f32>;

    /// Reconstruct from an RVF vector
    fn from_rvf_vector(vec: &[f32]) -> Result<Self, RvfError> where Self: Sized;

    /// Vector dimensionality
    fn vector_dim() -> usize;
}

// Implementation for existing types
impl RvfVectorizable for CsiFeatures {
    fn to_rvf_vector(&self) -> Vec<f32> {
        let mut vec = Vec::with_capacity(Self::vector_dim());
        vec.extend(self.amplitude_mean.iter().map(|&x| x as f32));
        vec.extend(self.amplitude_variance.iter().map(|&x| x as f32));
        vec.extend(self.phase_difference.iter().map(|&x| x as f32));
        vec.extend(self.doppler_shift.iter().map(|&x| x as f32));
        vec.extend(self.power_spectral_density.iter().map(|&x| x as f32));
        vec
    }

    fn vector_dim() -> usize {
        // 64 + 64 + 63 + 10 + 128 = 329 (for 64 subcarriers)
        329
    }
    // ...
}

Storage Characteristics

Container Type Typical Size Vector Count Use Case
Fingerprint 5-50 MB 10K-100K Room/building fingerprint DB
Model 50-500 MB N/A (blob) Neural network deployment
Session 10-200 MB 50K-500K 1-hour recording at 100 Hz

COW Branching for Environment Adaptation

The copy-on-write mechanism enables zero-overhead experimentation:

text
main (office baseline: 50K vectors)
  ├── branch/morning (delta: 500 vectors, ~15 KB)
  ├── branch/afternoon (delta: 800 vectors, ~24 KB)
  ├── branch/occupied-10 (delta: 2K vectors, ~60 KB)
  └── branch/furniture-moved (delta: 5K vectors, ~150 KB)

Total overhead for 4 branches on a 50K-vector container: ~250 KB additional (0.5%).

Consequences

Positive

  • Single-file deployment: Move a fingerprint database between sites by copying one .rvf file
  • Versioned models: A/B test model variants without duplicating full weight sets
  • Session replay: Reproduce detection results from recorded CSI data
  • Atomic operations: Container writes are transactional; no partial state corruption
  • Cross-platform: Same container format works on server, WASM, and embedded
  • Storage efficient: COW branching avoids duplicating unchanged data

Negative

  • Format lock-in: RVF is not yet a widely-adopted standard
  • Serialization overhead: Converting between native types and RVF vectors adds latency (~0.1-0.5 ms per vector)
  • Learning curve: Team must understand segment types and container lifecycle
  • File size for sessions: High-rate CSI capture (1000 Hz) generates large session containers

Performance Targets

Operation Target Latency Notes
Container open <10 ms Memory-mapped I/O
Vector insert <0.1 ms Append to VEC segment
HNSW query (100K vectors) <1 ms See ADR-004
Branch create <1 ms COW metadata only
Branch merge <100 ms Delta application
Container export ~1 ms/MB Sequential write

References


File: docs/adr/ADR-004-hnsw-vector-search-fingerprinting.md

ADR-004: HNSW Vector Search for Signal Fingerprinting

Status

Partially realized by ADR-024; extended by ADR-027

Note: ADR-024 (AETHER) implements HNSW-compatible fingerprint indices with 4 index types. ADR-027 (MERIDIAN) extends this with domain-disentangled embeddings so fingerprints match across environments, not just within a single room.

Date

2026-02-28

Context

Current Signal Matching Limitations

The WiFi-DensePose system needs to match incoming CSI patterns against known signatures for:

  1. Environment recognition: Identifying which room/area the device is in based on CSI characteristics
  2. Activity classification: Matching current CSI patterns to known human activities (walking, sitting, falling)
  3. Anomaly detection: Determining whether current readings deviate significantly from baseline
  4. Survivor re-identification (MAT module): Tracking individual survivors across scan sessions

Current approach in CSIProcessor._calculate_detection_confidence():

python
# Fixed thresholds, no similarity search
amplitude_indicator = np.mean(features.amplitude_mean) > 0.1
phase_indicator = np.std(features.phase_difference) > 0.05
motion_indicator = motion_score > 0.3
confidence = (0.4 * amplitude_indicator + 0.3 * phase_indicator + 0.3 * motion_indicator)

This is a O(1) fixed-threshold check that:

  • Cannot learn from past observations
  • Has no concept of "similar patterns seen before"
  • Requires manual threshold tuning per environment
  • Produces binary indicators (above/below threshold) losing gradient information

What HNSW Provides

Hierarchical Navigable Small World (HNSW) graphs enable approximate nearest-neighbor search in high-dimensional vector spaces with:

  • O(log n) query time vs O(n) brute-force
  • High recall: >95% recall at 10x speed of exact search
  • Dynamic insertion: New vectors added without full rebuild
  • SIMD acceleration: RuVector's implementation uses AVX2/NEON for distance calculations

RuVector extends standard HNSW with:

  • Hyperbolic HNSW: Search in Poincaré ball space for hierarchy-aware results (e.g., "walking" is closer to "running" than to "sitting" in activity hierarchy)
  • GNN enhancement: Graph neural networks refine neighbor connections after queries
  • Tiered compression: 2-32x memory reduction through adaptive quantization

Decision

We will integrate RuVector's HNSW implementation as the primary similarity search engine for all CSI pattern matching operations, replacing fixed-threshold detection with similarity-based retrieval.

Architecture

text
┌─────────────────────────────────────────────────────────────────┐
│                    HNSW Search Pipeline                          │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  CSI Input     Feature           Vector         HNSW            │
│  ────────▶    Extraction   ────▶ Encode   ────▶ Search          │
│              (existing)        (new)          (new)             │
│                                                  │              │
│                                    ┌─────────────┤              │
│                                    ▼             ▼              │
│                              Top-K Results    Confidence        │
│                              [vec_id, dist,   Score from        │
│                               metadata]       Distance Dist.   │
│                                    │                            │
│                                    ▼                            │
│                              ┌────────────┐                     │
│                              │ Decision   │                     │
│                              │ Fusion     │                     │
│                              └────────────┘                     │
│                               Combines HNSW similarity with     │
│                               existing threshold-based logic    │
└─────────────────────────────────────────────────────────────────┘

Index Configuration

rust
/// HNSW configuration tuned for CSI vector characteristics
pub struct CsiHnswConfig {
    /// Vector dimensionality (matches CsiFeatures encoding)
    dim: usize,  // 329 for 64 subcarriers

    /// Maximum number of connections per node per layer
    /// Higher M = better recall, more memory
    /// CSI vectors are moderately dimensional; M=16 balances well
    m: usize,  // 16

    /// Size of dynamic candidate list during construction
    /// ef_construction = 200 gives >99% recall for 329-dim vectors
    ef_construction: usize,  // 200

    /// Size of dynamic candidate list during search
    /// ef_search = 64 gives >95% recall with <1ms latency at 100K vectors
    ef_search: usize,  // 64

    /// Distance metric
    /// Cosine similarity works best for normalized CSI features
    metric: DistanceMetric,  // Cosine

    /// Maximum elements (pre-allocated for performance)
    max_elements: usize,  // 1_000_000

    /// Enable SIMD acceleration
    simd: bool,  // true

    /// Quantization level for memory reduction
    quantization: Quantization,  // PQ8 (product quantization, 8-bit)
}

Multiple Index Strategy

Different use cases require different index configurations:

Index Name Vectors Dim Distance Use Case
env_fingerprint 10K-1M 329 Cosine Environment/room identification
activity_pattern 1K-50K 329 Euclidean Activity classification
temporal_pattern 10K-500K 329 Cosine Temporal anomaly detection
survivor_track 100-10K 329 Cosine MAT survivor re-identification

Similarity-Based Detection Enhancement

Replace fixed thresholds with distance-based confidence:

rust
/// Enhanced detection using HNSW similarity search
pub struct SimilarityDetector {
    /// HNSW index of known human-present CSI patterns
    human_patterns: HnswIndex,

    /// HNSW index of known empty-room CSI patterns
    empty_patterns: HnswIndex,

    /// Fusion weight between similarity and threshold methods
    fusion_alpha: f64,  // 0.7 = 70% similarity, 30% threshold
}

impl SimilarityDetector {
    /// Detect human presence using similarity search + threshold fusion
    pub fn detect(&self, features: &CsiFeatures) -> DetectionResult {
        let query_vec = features.to_rvf_vector();

        // Search both indices
        let human_neighbors = self.human_patterns.search(&query_vec, k=5);
        let empty_neighbors = self.empty_patterns.search(&query_vec, k=5);

        // Distance-based confidence
        let avg_human_dist = human_neighbors.mean_distance();
        let avg_empty_dist = empty_neighbors.mean_distance();

        // Similarity confidence: how much closer to human patterns vs empty
        let similarity_confidence = avg_empty_dist / (avg_human_dist + avg_empty_dist);

        // Fuse with traditional threshold-based confidence
        let threshold_confidence = self.traditional_threshold_detect(features);
        let fused_confidence = self.fusion_alpha * similarity_confidence
                             + (1.0 - self.fusion_alpha) * threshold_confidence;

        DetectionResult {
            human_detected: fused_confidence > 0.5,
            confidence: fused_confidence,
            similarity_confidence,
            threshold_confidence,
            nearest_human_pattern: human_neighbors[0].metadata.clone(),
            nearest_empty_pattern: empty_neighbors[0].metadata.clone(),
        }
    }
}

Incremental Learning Loop

Every confirmed detection enriches the index:

text
1. CSI captured → features extracted → vector encoded
2. HNSW search returns top-K neighbors + distances
3. Detection decision made (similarity + threshold fusion)
4. If confirmed (by temporal consistency or ground truth):
   a. Insert vector into appropriate index (human/empty)
   b. GNN layer updates neighbor relationships (ADR-006)
   c. SONA adapts fusion weights (ADR-005)
5. Periodically: prune stale vectors, rebuild index layers

Performance Analysis

Memory requirements (PQ8 quantization):

Vector Count Raw Size PQ8 Compressed HNSW Overhead Total
10,000 12.9 MB 1.6 MB 2.5 MB 4.1 MB
100,000 129 MB 16 MB 25 MB 41 MB
1,000,000 1.29 GB 160 MB 250 MB 410 MB

Latency expectations (329-dim vectors, ef_search=64):

Vector Count Brute Force HNSW Speedup
10,000 3.2 ms 0.08 ms 40x
100,000 32 ms 0.3 ms 107x
1,000,000 320 ms 0.9 ms 356x

Hyperbolic Extension for Activity Hierarchy

WiFi-sensed activities have natural hierarchy:

text
motion
                   /      \
              locomotion   stationary
              /    \         /    \
         walking  running  sitting  lying
         /    \
      normal  shuffling

Hyperbolic HNSW in Poincaré ball space preserves this hierarchy during search, so a query for "shuffling" returns "walking" before "sitting" even if Euclidean distances are similar.

rust
/// Hyperbolic HNSW for hierarchy-aware activity matching
pub struct HyperbolicActivityIndex {
    index: HnswIndex,
    curvature: f64,  // -1.0 for unit Poincaré ball
}

impl HyperbolicActivityIndex {
    pub fn search(&self, query: &[f32], k: usize) -> Vec<SearchResult> {
        // Uses Poincaré distance: d(u,v) = arcosh(1 + 2||u-v||²/((1-||u||²)(1-||v||²)))
        self.index.search_hyperbolic(query, k, self.curvature)
    }
}

Consequences

Positive

  • Adaptive detection: System improves with more data; no manual threshold tuning
  • Sub-millisecond search: HNSW provides <1ms queries even at 1M vectors
  • Memory efficient: PQ8 reduces storage 8x with <5% recall loss
  • Hierarchy-aware: Hyperbolic mode respects activity relationships
  • Incremental: New patterns added without full index rebuild
  • Explainable: "This detection matched pattern X from room Y at time Z"

Negative

  • Cold-start problem: Need initial fingerprint data before similarity search is useful
  • Index maintenance: Periodic pruning and layer rebalancing needed
  • Approximation: HNSW is approximate; may miss exact nearest neighbor (mitigated by high ef_search)
  • Memory for indices: HNSW graph structure adds 2.5x overhead on top of vectors

Migration Strategy

  1. Phase 1: Run HNSW search in parallel with existing threshold detection, log both results
  2. Phase 2: A/B test fusion weights (alpha parameter) on labeled data
  3. Phase 3: Gradually increase fusion_alpha from 0.0 (pure threshold) to 0.7 (primarily similarity)
  4. Phase 4: Threshold detection becomes fallback for cold-start/empty-index scenarios

References


File: docs/adr/ADR-005-sona-self-learning-pose-estimation.md

ADR-005: SONA Self-Learning for Pose Estimation

Status

Partially realized in ADR-023; extended by ADR-027

Note: ADR-023 implements SONA with MicroLoRA rank-4 adapters and EWC++ memory preservation. ADR-027 (MERIDIAN) extends SONA with unsupervised rapid adaptation: 10 seconds of unlabeled WiFi data in a new room automatically generates environment-specific LoRA weights via contrastive test-time training.

Date

2026-02-28

Context

Static Model Problem

The WiFi-DensePose modality translation network (ModalityTranslationNetwork in Python, ModalityTranslator in Rust) converts CSI features into visual-like feature maps that feed the DensePose head for body segmentation and UV coordinate estimation. These models are trained offline and deployed with frozen weights.

Critical limitations of static models:

  1. Environment drift: CSI characteristics change when furniture moves, new objects are introduced, or building occupancy changes. A model trained in Lab A degrades in Lab B without retraining.

  2. Hardware variance: Different WiFi chipsets (Intel AX200 vs Broadcom BCM4375 vs Qualcomm WCN6855) produce subtly different CSI patterns. Static models overfit to training hardware.

  3. Temporal drift: Even in the same environment, CSI patterns shift with temperature, humidity, and electromagnetic interference changes throughout the day.

  4. Population bias: Models trained on one demographic may underperform on body types, heights, or movement patterns not represented in training data.

Current mitigation: manual retraining with new data, which requires:

  • Collecting labeled data in the new environment
  • GPU-intensive training (hours to days)
  • Model export/deployment cycle
  • Downtime during switchover

SONA Opportunity

RuVector's Self-Optimizing Neural Architecture (SONA) provides <1ms online adaptation through:

  • LoRA (Low-Rank Adaptation): Instead of updating all weights (millions of parameters), LoRA injects small trainable rank decomposition matrices into frozen model layers. For a weight matrix W ∈ R^(d×k), LoRA learns A ∈ R^(d×r) and B ∈ R^(r×k) where r << min(d,k), so the adapted weight is W + AB.

  • EWC++ (Elastic Weight Consolidation): Prevents catastrophic forgetting by penalizing changes to parameters important for previously learned tasks. Each parameter has a Fisher information-weighted importance score.

  • Online gradient accumulation: Small batches of live data (as few as 1-10 samples) contribute to adaptation without full backward passes.

Decision

We will integrate SONA as the online learning engine for both the modality translation network and the DensePose head, enabling continuous environment-specific adaptation without offline retraining.

Adaptation Architecture

text
/* Detailed source-code truncated for AI context efficiency. */

LoRA Configuration per Layer

rust
/// SONA LoRA configuration for WiFi-DensePose
pub struct SonaConfig {
    /// LoRA rank (r): dimensionality of adaptation matrices
    /// r=4 for encoder layers (less variation needed)
    /// r=8 for decoder layers (more expression needed)
    /// r=16 for final output layers (maximum adaptability)
    lora_ranks: HashMap<String, usize>,

    /// Scaling factor alpha: controls adaptation strength
    /// Starts at 0.0 (pure frozen model), increases to target
    alpha: f64,  // Target: 0.3

    /// Alpha warmup steps before reaching target
    alpha_warmup_steps: usize,  // 100

    /// EWC++ regularization strength
    ewc_lambda: f64,  // 50.0

    /// Fisher information estimation samples
    fisher_samples: usize,  // 200

    /// Online learning rate (much smaller than offline training)
    online_lr: f64,  // 1e-5

    /// Gradient accumulation steps before applying update
    accumulation_steps: usize,  // 10

    /// Maximum adaptation delta (safety bound)
    max_delta_norm: f64,  // 0.1
}

Parameter budget:

Layer Original Params LoRA Rank LoRA Params Overhead
Encoder Conv1 (64→128) 73,728 4 768 1.0%
Encoder Conv2 (128→256) 294,912 4 1,536 0.5%
Encoder Conv3 (256→512) 1,179,648 4 3,072 0.3%
Decoder ConvT1 (512→256) 1,179,648 8 6,144 0.5%
Decoder ConvT2 (256→128) 294,912 8 3,072 1.0%
Output Conv (128→24) 27,648 16 2,432 8.8%
Total 3,050,496 - 17,024 0.56%

SONA adapts 0.56% of parameters while achieving 70-90% of the accuracy improvement of full fine-tuning.

Adaptation Trigger Conditions

rust
/// When to trigger SONA adaptation
pub enum AdaptationTrigger {
    /// Detection confidence drops below threshold over N samples
    ConfidenceDrop {
        threshold: f64,     // 0.6
        window_size: usize, // 50
    },

    /// CSI statistics drift beyond baseline (KL divergence)
    DistributionDrift {
        kl_threshold: f64,  // 0.5
        reference_window: usize, // 1000
    },

    /// New environment detected (no close HNSW matches)
    NewEnvironment {
        min_distance: f64,  // 0.8 (far from all known fingerprints)
    },

    /// Periodic adaptation (maintenance)
    Periodic {
        interval_samples: usize, // 10000
    },

    /// Manual trigger via API
    Manual,
}

Adaptation Feedback Sources

Since WiFi-DensePose lacks camera ground truth in deployment, adaptation uses self-supervised signals:

  1. Temporal consistency: Pose estimates should change smoothly between frames. Jerky transitions indicate prediction error.

    text
    L_temporal = ||pose(t) - pose(t-1)||² when Δt < 100ms
  2. Physical plausibility: Body part positions must satisfy skeletal constraints (limb lengths, joint angles).

    text
    L_skeleton = Σ max(0, |limb_length - expected_length| - tolerance)
  3. Multi-view agreement (multi-AP): Different APs observing the same person should produce consistent poses.

    text
    L_multiview = ||pose_AP1 - transform(pose_AP2)||²
  4. Detection stability: Confidence should be high when the environment is stable.

    text
    L_stability = -log(confidence) when variance(CSI_window) < threshold

Safety Mechanisms

rust
/// Safety bounds prevent adaptation from degrading the model
pub struct AdaptationSafety {
    /// Maximum parameter change per update step
    max_step_norm: f64,

    /// Rollback if validation loss increases by this factor
    rollback_threshold: f64,  // 1.5 (50% worse = rollback)

    /// Keep N checkpoints for rollback
    checkpoint_count: usize,  // 5

    /// Disable adaptation after N consecutive rollbacks
    max_consecutive_rollbacks: usize,  // 3

    /// Minimum samples between adaptations
    cooldown_samples: usize,  // 100
}

Persistence via RVF

Adaptation state is stored in the Model Container (ADR-003):

  • LoRA matrices A and B serialized to VEC segment
  • Fisher information matrix serialized alongside
  • Each adaptation creates a witness chain entry (ADR-010)
  • COW branching allows reverting to any previous adaptation state
text
model.rvf.model
  ├── main (frozen base weights)
  ├── branch/adapted-office-2024-01 (LoRA deltas)
  ├── branch/adapted-warehouse (LoRA deltas)
  └── branch/adapted-outdoor-disaster (LoRA deltas)

Consequences

Positive

  • Zero-downtime adaptation: Model improves continuously during operation
  • Tiny overhead: 17K parameters (0.56%) vs 3M full model; <1ms per adaptation step
  • No forgetting: EWC++ preserves performance on previously-seen environments
  • Portable adaptations: LoRA deltas are ~70 KB, easily shared between devices
  • Safe rollback: Checkpoint system prevents runaway degradation
  • Self-supervised: No labeled data needed during deployment

Negative

  • Bounded expressiveness: LoRA rank limits the degree of adaptation; extreme environment changes may require offline retraining
  • Feedback noise: Self-supervised signals are weaker than ground-truth labels; adaptation is slower and less precise
  • Compute on device: Even small gradient computations require tensor math on the inference device
  • Complexity: Debugging adapted models is harder than static models
  • Hyperparameter sensitivity: EWC lambda, LoRA rank, learning rate require tuning

Validation Plan

  1. Offline validation: Train base model on Environment A, test SONA adaptation to Environment B with known ground truth. Measure pose estimation MPJPE (Mean Per-Joint Position Error) improvement.
  2. A/B deployment: Run static model and SONA-adapted model in parallel on same CSI stream. Compare detection rates and pose consistency.
  3. Stress test: Rapidly change environments (simulated) and verify EWC++ prevents catastrophic forgetting.
  4. Edge latency: Benchmark adaptation step on target hardware (Raspberry Pi 4, Jetson Nano, browser WASM).

References


File: docs/adr/ADR-006-gnn-enhanced-csi-pattern-recognition.md

ADR-006: GNN-Enhanced CSI Pattern Recognition

Status

Partially realized in ADR-023; extended by ADR-027

Note: ADR-023 implements a 2-layer GCN on the COCO skeleton graph for spatial reasoning. ADR-027 (MERIDIAN) adds domain-adversarial regularization via a gradient reversal layer that forces the GCN to learn environment-invariant graph features, shedding room-specific multipath patterns.

Date

2026-02-28

Context

ADR-004 introduces HNSW-based similarity search for CSI pattern matching. While HNSW provides fast nearest-neighbor retrieval, it treats each vector independently. CSI patterns, however, have rich relational structure:

  1. Temporal adjacency: CSI frames captured 10ms apart are more related than frames 10s apart. Sequential patterns reveal motion trajectories.

  2. Spatial correlation: CSI readings from adjacent subcarriers are highly correlated due to frequency proximity. Antenna pairs capture different spatial perspectives.

  3. Cross-session similarity: The "walking to kitchen" pattern from Tuesday should inform Wednesday's recognition, but the environment baseline may have shifted.

  4. Multi-person entanglement: When multiple people are present, CSI patterns are superpositions. Disentangling requires understanding which pattern fragments co-occur.

Standard HNSW cannot capture these relationships. Each query returns neighbors based solely on vector distance, ignoring the graph structure of how patterns relate to each other.

RuVector's GNN Enhancement

RuVector implements a Graph Neural Network layer that sits on top of the HNSW index:

text
Standard HNSW: Query → Distance-based neighbors → Results
GNN-Enhanced:  Query → Distance-based neighbors → GNN refinement → Improved results

The GNN performs three operations in <1ms:

  1. Message passing: Each node aggregates information from its HNSW neighbors
  2. Attention weighting: Multi-head attention identifies which neighbors are most relevant for the current query context
  3. Representation update: Node embeddings are refined based on neighborhood context

Additionally, temporal learning tracks query sequences to discover:

  • Vectors that frequently appear together in sessions
  • Temporal ordering patterns (A usually precedes B)
  • Session context that changes relevance rankings

Decision

We will integrate RuVector's GNN layer to enhance CSI pattern recognition with three core capabilities: relational search, temporal sequence modeling, and multi-person disentanglement.

GNN Architecture for CSI

text
/* Detailed source-code truncated for AI context efficiency. */

Three Integration Modes

Mode 1: Query-Time Refinement (Default)

GNN refines HNSW results after retrieval. No modifications to stored vectors.

rust
pub struct GnnQueryRefiner {
    /// GNN weights (small: ~50K parameters)
    gnn_weights: GnnModel,

    /// Number of message passing rounds
    num_rounds: usize,  // 2

    /// Attention heads for neighbor weighting
    num_heads: usize,  // 4

    /// How many HNSW neighbors to consider in GNN
    neighborhood_size: usize,  // 20 (retrieve 20, GNN selects best 5)
}

impl GnnQueryRefiner {
    /// Refine HNSW results using graph context
    pub fn refine(&self, query: &[f32], hnsw_results: &[SearchResult]) -> Vec<SearchResult> {
        // Build local subgraph from query + HNSW results
        let subgraph = self.build_local_subgraph(query, hnsw_results);

        // Run message passing
        let refined = self.message_pass(&subgraph, self.num_rounds);

        // Re-rank based on refined representations
        self.rerank(query, &refined)
    }
}

Latency: +0.2ms on top of HNSW search (total <1.5ms for 100K vectors).

Mode 2: Temporal Sequence Recognition

Tracks CSI vector sequences to recognize activity patterns that span multiple frames:

rust
/// Temporal pattern recognizer using GNN edges
pub struct TemporalPatternRecognizer {
    /// Sliding window of recent query vectors
    window: VecDeque<TimestampedVector>,

    /// Maximum window size (in frames)
    max_window: usize,  // 100 (10 seconds at 10 Hz)

    /// Temporal edge decay factor
    decay: f64,  // 0.95 (edges weaken with time)

    /// Known activity sequences (learned from data)
    activity_templates: HashMap<String, Vec<Vec<f32>>>,
}

impl TemporalPatternRecognizer {
    /// Feed new CSI vector and check for activity pattern matches
    pub fn observe(&mut self, vector: &[f32], timestamp: f64) -> Vec<ActivityMatch> {
        self.window.push_back(TimestampedVector { vector: vector.to_vec(), timestamp });

        // Build temporal subgraph from window
        let temporal_graph = self.build_temporal_graph();

        // GNN aggregates temporal context
        let sequence_embedding = self.gnn_aggregate(&temporal_graph);

        // Match against known activity templates
        self.match_activities(&sequence_embedding)
    }
}

Activity patterns detectable:

Activity Frames Needed CSI Signature
Walking 10-30 Periodic Doppler oscillation
Falling 5-15 Sharp amplitude spike → stillness
Sitting down 10-20 Gradual descent in reflection height
Breathing (still) 30-100 Micro-periodic phase variation
Gesture (wave) 5-15 Localized high-frequency amplitude variation

Mode 3: Multi-Person Disentanglement

When N>1 people are present, CSI is a superposition. The GNN learns to cluster pattern fragments:

rust
/// Multi-person CSI disentanglement using GNN clustering
pub struct MultiPersonDisentangler {
    /// Maximum expected simultaneous persons
    max_persons: usize,  // 10

    /// GNN-based spectral clustering
    cluster_gnn: GnnModel,

    /// Per-person tracking state
    person_tracks: Vec,
}

impl MultiPersonDisentangler {
    /// Separate CSI features into per-person components
    pub fn disentangle(&mut self, features: &CsiFeatures) -> Vec {
        // Decompose CSI into subcarrier groups using GNN attention
        let subcarrier_graph = self.build_subcarrier_graph(features);

        // GNN clusters subcarriers by person contribution
        let clusters = self.cluster_gnn.cluster(&subcarrier_graph, self.max_persons);

        // Extract per-person features from clustered subcarriers
        clusters.iter().map(|c| self.extract_person_features(features, c)).collect()
    }
}

GNN Learning Loop

The GNN improves with every query through RuVector's built-in learning:

text
Query → HNSW retrieval → GNN refinement → User action (click/confirm/reject)
                                              │
                                              ▼
                                    Update GNN weights via:
                                    1. Positive: confirmed results get higher attention
                                    2. Negative: rejected results get lower attention
                                    3. Temporal: successful sequences reinforce edges

For WiFi-DensePose, "user action" is replaced by:

  • Temporal consistency: If frame N+1 confirms frame N's detection, reinforce
  • Multi-AP agreement: If two APs agree on detection, reinforce both
  • Physical plausibility: If pose satisfies skeletal constraints, reinforce

Performance Budget

Component Parameters Memory Latency (per query)
GNN weights (2 layers, 4 heads) 52K 208 KB 0.15 ms
Temporal graph (100-frame window) N/A ~130 KB 0.05 ms
Multi-person clustering 18K 72 KB 0.3 ms
Total GNN overhead 70K 410 KB 0.5 ms

Consequences

Positive

  • Context-aware search: Results account for temporal and spatial relationships, not just vector distance
  • Activity recognition: Temporal GNN enables sequence-level pattern matching
  • Multi-person support: GNN clustering separates overlapping CSI patterns
  • Self-improving: Every query provides learning signal to refine attention weights
  • Lightweight: 70K parameters, 410 KB memory, 0.5ms latency overhead

Negative

  • Training data needed: GNN weights require initial training on CSI pattern graphs
  • Complexity: Three modes increase testing and debugging surface
  • Graph maintenance: Temporal edges must be pruned to prevent unbounded growth
  • Approximation: GNN clustering for multi-person is approximate; may merge/split incorrectly

Interaction with Other ADRs

  • ADR-004 (HNSW): GNN operates on HNSW graph structure; depends on HNSW being available
  • ADR-005 (SONA): GNN weights can be adapted via SONA LoRA for environment-specific tuning
  • ADR-003 (RVF): GNN weights stored in model container alongside inference weights
  • ADR-010 (Witness): GNN weight updates recorded in witness chain

References


File: docs/adr/ADR-007-post-quantum-cryptography-secure-sensing.md

ADR-007: Post-Quantum Cryptography for Secure Sensing

Status

Proposed

Date

2026-02-28

Context

Threat Model

WiFi-DensePose processes data that can reveal:

  • Human presence/absence in private spaces (surveillance risk)
  • Health indicators via breathing/heartbeat detection (medical privacy)
  • Movement patterns (behavioral profiling)
  • Building occupancy (physical security intelligence)

In disaster scenarios (wifi-densepose-mat), the stakes are even higher:

  • Triage classifications affect rescue priority (life-or-death decisions)
  • Survivor locations are operationally sensitive
  • Detection audit trails may be used in legal proceedings (liability)
  • False negatives (missed survivors) could be forensically investigated

Current security: The system uses standard JWT (HS256) for API authentication and has no cryptographic protection on data at rest, model integrity, or detection audit trails.

Quantum Threat Timeline

NIST estimates cryptographically relevant quantum computers could emerge by 2030-2035. Data captured today with classical encryption may be decrypted retroactively ("harvest now, decrypt later"). For a system that may be deployed for decades in infrastructure, post-quantum readiness is prudent.

RuVector's Crypto Stack

RuVector provides a layered cryptographic system:

Algorithm Purpose Standard Quantum Resistant
ML-DSA-65 Digital signatures FIPS 204 Yes (lattice-based)
Ed25519 Digital signatures RFC 8032 No (classical fallback)
SLH-DSA-128s Digital signatures FIPS 205 Yes (hash-based)
SHAKE-256 Hashing FIPS 202 Yes
AES-256-GCM Symmetric encryption FIPS 197 Yes (Grover's halves, still 128-bit)

Decision

We will integrate RuVector's cryptographic layer to provide defense-in-depth for WiFi-DensePose data, using a hybrid classical+PQ approach where both Ed25519 and ML-DSA-65 signatures are applied (belt-and-suspenders until PQ algorithms mature).

Cryptographic Scope

text
/* Detailed source-code truncated for AI context efficiency. */

Hybrid Signature Scheme

rust
/// Hybrid signature combining classical Ed25519 with PQ ML-DSA-65
pub struct HybridSignature {
    /// Classical Ed25519 signature (64 bytes)
    ed25519_sig: [u8; 64],

    /// Post-quantum ML-DSA-65 signature (3309 bytes)
    ml_dsa_sig: Vec,

    /// Signer's public key fingerprint (SHAKE-256, 32 bytes)
    signer_fingerprint: [u8; 32],

    /// Timestamp of signing
    timestamp: u64,
}

impl HybridSignature {
    /// Verify requires BOTH signatures to be valid
    pub fn verify(&self, message: &[u8], ed25519_pk: &Ed25519PublicKey,
                  ml_dsa_pk: &MlDsaPublicKey) -> Result {
        let ed25519_valid = ed25519_pk.verify(message, &self.ed25519_sig)?;
        let ml_dsa_valid = ml_dsa_pk.verify(message, &self.ml_dsa_sig)?;

        // Both must pass (defense in depth)
        Ok(ed25519_valid && ml_dsa_valid)
    }
}

Model Integrity Verification

rust
/// Verify model weights have not been tampered with
pub fn verify_model_integrity(model_container: &ModelContainer) -> Result<(), SecurityError> {
    // 1. Extract embedded signature from container
    let signature = model_container.crypto_segment().signature()?;

    // 2. Compute SHAKE-256 hash of weight data
    let weight_hash = shake256(model_container.weights_segment().data());

    // 3. Verify hybrid signature
    let publisher_keys = load_publisher_keys()?;
    if !signature.verify(&weight_hash, &publisher_keys.ed25519, &publisher_keys.ml_dsa)? {
        return Err(SecurityError::ModelTampered {
            expected_signer: publisher_keys.fingerprint(),
            container_path: model_container.path().to_owned(),
        });
    }

    Ok(())
}

CSI Data Encryption

For privacy-sensitive deployments, CSI vectors can be encrypted at rest:

rust
/// Encrypt CSI vectors for storage in RVF container
pub struct CsiEncryptor {
    /// AES-256-GCM key (derived from device key + container salt)
    key: Aes256GcmKey,
}

impl CsiEncryptor {
    /// Encrypt a CSI feature vector
    /// Note: HNSW search operates on encrypted vectors using
    /// distance-preserving encryption (approximate, configurable trade-off)
    pub fn encrypt_vector(&self, vector: &[f32]) -> EncryptedVector {
        let nonce = generate_nonce();
        let plaintext = bytemuck::cast_slice::<f32, u8>(vector);
        let ciphertext = aes_256_gcm_encrypt(&self.key, &nonce, plaintext);
        EncryptedVector { ciphertext, nonce }
    }
}

Performance Impact

Operation Without Crypto With Crypto Overhead
Model load 50 ms 52 ms +2 ms (signature verify)
Vector insert 0.1 ms 0.15 ms +0.05 ms (encrypt)
HNSW search 0.3 ms 0.35 ms +0.05 ms (decrypt top-K)
Container open 10 ms 12 ms +2 ms (integrity check)
Detection event logging 0.01 ms 0.5 ms +0.49 ms (hash chain)

Feature Flags

toml
[features]
default = []
crypto-classical = ["ed25519-dalek"]  # Ed25519 only
crypto-pq = ["pqcrypto-dilithium", "pqcrypto-sphincsplus"]  # ML-DSA + SLH-DSA
crypto-hybrid = ["crypto-classical", "crypto-pq"]  # Both (recommended)
crypto-encrypt = ["aes-gcm"]  # Data-at-rest encryption
crypto-full = ["crypto-hybrid", "crypto-encrypt"]

Consequences

Positive

  • Future-proof: Lattice-based signatures resist quantum attacks
  • Tamper detection: Model poisoning and data manipulation are detectable
  • Privacy compliance: Encrypted CSI data meets GDPR/HIPAA requirements
  • Forensic integrity: Signed audit trails are admissible as evidence
  • Low overhead: <1ms per operation for most crypto operations

Negative

  • Signature size: ML-DSA-65 signatures are 3.3 KB vs 64 bytes for Ed25519
  • Key management complexity: Device key provisioning, rotation, revocation
  • HNSW on encrypted data: Distance-preserving encryption is approximate; search recall may degrade
  • Dependency weight: PQ crypto libraries add ~2 MB to binary
  • Standards maturity: FIPS 204/205 are finalized but implementations are evolving

References


File: docs/adr/ADR-008-distributed-consensus-multi-ap.md

ADR-008: Distributed Consensus for Multi-AP Coordination

Status

Proposed

Date

2026-02-28

Context

Multi-AP Sensing Architecture

WiFi-DensePose achieves higher accuracy and coverage with multiple access points (APs) observing the same space from different angles. The disaster detection module (wifi-densepose-mat, ADR-001) explicitly requires distributed deployment:

  • Portable: Single TX/RX units deployed around a collapse site
  • Distributed: Multiple APs covering a large disaster zone
  • Drone-mounted: UAVs scanning from above with coordinated flight paths

Each AP independently captures CSI data, extracts features, and runs local inference. But the distributed system needs coordination:

  1. Consistent survivor registry: All nodes must agree on the set of detected survivors, their locations, and triage classifications. Conflicting records cause rescue teams to waste time.

  2. Coordinated scanning: Avoid redundant scans of the same zone. Dynamically reassign APs as zones are cleared.

  3. Model synchronization: When SONA adapts a model on one node (ADR-005), other nodes should benefit from the adaptation without re-learning.

  4. Clock synchronization: CSI timestamps must be aligned across nodes for multi-view pose fusion (the GNN multi-person disentanglement in ADR-006 requires temporal alignment).

  5. Partition tolerance: In disaster scenarios, network connectivity is unreliable. The system must function during partitions and reconcile when connectivity restores.

Current State

No distributed coordination exists. Each node operates independently. The Rust workspace has no consensus crate.

RuVector's Distributed Capabilities

RuVector provides:

  • Raft consensus: Leader election and replicated log for strong consistency
  • Vector clocks: Logical timestamps for causal ordering without synchronized clocks
  • Multi-master replication: Concurrent writes with conflict resolution
  • Delta consensus: Tracks behavioral changes across nodes for anomaly detection
  • Auto-sharding: Distributes data based on access patterns

Decision

We will integrate RuVector's Raft consensus implementation as the coordination backbone for multi-AP WiFi-DensePose deployments, with vector clocks for causal ordering and CRDT-based conflict resolution for partition-tolerant operation.

Consensus Architecture

text
/* Detailed source-code truncated for AI context efficiency. */

Replicated State Machine

The Raft log replicates these operations across all nodes:

rust
/// Operations replicated via Raft consensus
#[derive(Serialize, Deserialize, Clone)]
pub enum ConsensusOp {
    /// New survivor detected
    SurvivorDetected {
        survivor_id: Uuid,
        location: GeoCoord,
        triage: TriageLevel,
        detecting_ap: ApId,
        confidence: f64,
        timestamp: VectorClock,
    },

    /// Survivor status updated (e.g., triage reclassification)
    SurvivorUpdated {
        survivor_id: Uuid,
        new_triage: TriageLevel,
        updating_ap: ApId,
        evidence: DetectionEvidence,
    },

    /// Zone assignment changed
    ZoneAssignment {
        zone_id: ZoneId,
        assigned_aps: Vec<ApId>,
        priority: ScanPriority,
    },

    /// Model adaptation delta shared
    ModelDelta {
        source_ap: ApId,
        lora_delta: Vec,  // Serialized LoRA matrices
        environment_hash: [u8; 32],
        performance_metrics: AdaptationMetrics,
    },

    /// AP joined or left the cluster
    MembershipChange {
        ap_id: ApId,
        action: MembershipAction,  // Join | Leave | Suspect
    },
}

Vector Clocks for Causal Ordering

Since APs may have unsynchronized physical clocks, vector clocks provide causal ordering:

rust
/// Vector clock for causal ordering across APs
#[derive(Clone, Serialize, Deserialize)]
pub struct VectorClock {
    /// Map from AP ID to logical timestamp
    clocks: HashMap<ApId, u64>,
}

impl VectorClock {
    /// Increment this AP's clock
    pub fn tick(&mut self, ap_id: &ApId) {
        *self.clocks.entry(ap_id.clone()).or_insert(0) += 1;
    }

    /// Merge with another clock (take max of each component)
    pub fn merge(&mut self, other: &VectorClock) {
        for (ap_id, &ts) in &other.clocks {
            let entry = self.clocks.entry(ap_id.clone()).or_insert(0);
            *entry = (*entry).max(ts);
        }
    }

    /// Check if self happened-before other
    pub fn happened_before(&self, other: &VectorClock) -> bool {
        self.clocks.iter().all(|(k, &v)| {
            other.clocks.get(k).map_or(false, |&ov| v <= ov)
        }) && self.clocks != other.clocks
    }
}

CRDT-Based Conflict Resolution

During network partitions, concurrent updates may conflict. We use CRDTs (Conflict-free Replicated Data Types) for automatic resolution:

rust
/// Survivor registry using Last-Writer-Wins Register CRDT
pub struct SurvivorRegistry {
    /// LWW-Element-Set: each survivor has a timestamp-tagged state
    survivors: HashMap>,
}

/// Triage uses Max-wins semantics:
/// If partition A says P1 (Red/Immediate) and partition B says P2 (Yellow/Delayed),
/// after merge the survivor is classified P1 (more urgent wins)
/// Rationale: false negative (missing critical) is worse than false positive
impl CrdtMerge for TriageLevel {
    fn merge(a: Self, b: Self) -> Self {
        // Lower numeric priority = more urgent
        if a.urgency() >= b.urgency() { a } else { b }
    }
}

CRDT merge strategies by data type:

Data Type CRDT Type Merge Strategy Rationale
Survivor set OR-Set Union (never lose a detection) Missing survivors = fatal
Triage level Max-Register Most urgent wins Err toward caution
Location LWW-Register Latest timestamp wins Survivors may move
Zone assignment LWW-Map Leader's assignment wins Need authoritative coord
Model deltas G-Set Accumulate all deltas All adaptations valuable

Node Discovery and Health

rust
/// AP cluster management
pub struct ApCluster {
    /// This node's identity
    local_ap: ApId,

    /// Raft consensus engine
    raft: RaftEngine<ConsensusOp>,

    /// Failure detector (phi-accrual)
    failure_detector: PhiAccrualDetector,

    /// Cluster membership
    members: HashSet<ApId>,
}

impl ApCluster {
    /// Heartbeat interval for failure detection
    const HEARTBEAT_MS: u64 = 500;

    /// Phi threshold for suspecting node failure
    const PHI_THRESHOLD: f64 = 8.0;

    /// Minimum cluster size for Raft (need majority)
    const MIN_CLUSTER_SIZE: usize = 3;
}

Performance Characteristics

Operation Latency Notes
Raft heartbeat 500 ms interval Configurable
Log replication 1-5 ms (LAN) Depends on payload size
Leader election 1-3 seconds After leader failure detected
CRDT merge (partition heal) 10-100 ms Proportional to divergence
Vector clock comparison <0.01 ms O(n) where n = cluster size
Model delta replication 50-200 ms ~70 KB LoRA delta

Deployment Configurations

Scenario Nodes Consensus Partition Strategy
Single room 1-2 None (local only) N/A
Building floor 3-5 Raft (3-node quorum) CRDT merge on heal
Disaster site 5-20 Raft (5-node quorum) + zones Zone-level sub-clusters
Urban search 20-100 Hierarchical Raft Regional leaders

Consequences

Positive

  • Consistent state: All APs agree on survivor registry via Raft
  • Partition tolerant: CRDT merge allows operation during disconnection
  • Causal ordering: Vector clocks provide logical time without NTP
  • Automatic failover: Raft leader election handles AP failures
  • Model sharing: SONA adaptations propagate across cluster

Negative

  • Minimum 3 nodes: Raft requires odd-numbered quorum for leader election
  • Network overhead: Heartbeats and log replication consume bandwidth (~1-10 KB/s per node)
  • Complexity: Distributed systems are inherently harder to debug
  • Latency for writes: Raft requires majority acknowledgment before commit (1-5ms LAN)
  • Split-brain risk: If cluster splits evenly (2+2), neither partition has quorum

Disaster-Specific Considerations

Challenge Mitigation
Intermittent connectivity Aggressive CRDT merge on reconnect; local operation during partition
Power failures Raft log persisted to local SSD; recovery on restart
Node destruction Raft tolerates minority failure; data replicated across survivors
Drone mobility Drone APs treated as ephemeral members; data synced on landing
Bandwidth constraints Delta-only replication; compress LoRA deltas

References


File: docs/adr/ADR-009-rvf-wasm-runtime-edge-deployment.md

ADR-009: RVF WASM Runtime for Edge Deployment

Status

Proposed

Date

2026-02-28

Context

Current WASM State

The wifi-densepose-wasm crate provides basic WebAssembly bindings that expose Rust types to JavaScript. It enables browser-based visualization and lightweight inference but has significant limitations:

  1. No self-contained operation: WASM module depends on external model files loaded via fetch(). If the server is unreachable, the module is useless.

  2. No persistent state: Browser WASM has no built-in persistent storage for fingerprint databases, model weights, or session data.

  3. No offline capability: Without network access, the WASM module cannot load models or send results.

  4. Binary size: Current WASM bundle is not optimized. Full inference + signal processing compiles to ~5-15 MB.

Edge Deployment Requirements

Scenario Platform Constraints
Browser dashboard Chrome/Firefox <10 MB download, no plugins
IoT sensor node ESP32/Raspberry Pi 256 KB - 4 GB RAM, battery powered
Mobile app iOS/Android WebView Limited background execution
Drone payload Embedded Linux + WASM Weight/power limited, intermittent connectivity
Field tablet Android tablet Offline operation in disaster zones

RuVector's Edge Runtime

RuVector provides a 5.5 KB WASM runtime that boots in 125ms, with:

  • Self-contained operation (models + data embedded in RVF container)
  • Persistent storage via RVF container (written to IndexedDB in browser, filesystem on native)
  • Offline-first architecture
  • SIMD acceleration when available (WASM SIMD proposal)

Decision

We will replace the current wifi-densepose-wasm approach with an RVF-based edge runtime that packages models, fingerprint databases, and the inference engine into a single deployable RVF container.

Edge Runtime Architecture

text
/* Detailed source-code truncated for AI context efficiency. */

Tiered Runtime Profiles

Different deployment targets get different container configurations:

rust
/// Edge runtime profiles
pub enum EdgeProfile {
    /// Full-featured browser deployment
    /// ~10 MB container, full inference + HNSW + SONA
    Browser {
        model_quantization: Quantization::Int8,
        max_fingerprints: 100_000,
        enable_sona: true,
        storage_backend: StorageBackend::IndexedDB,
    },

    /// Minimal IoT deployment
    /// ~1 MB container, lightweight inference only
    IoT {
        model_quantization: Quantization::Int4,
        max_fingerprints: 1_000,
        enable_sona: false,
        storage_backend: StorageBackend::Flash,
    },

    /// Mobile app deployment
    /// ~5 MB container, inference + HNSW, limited SONA
    Mobile {
        model_quantization: Quantization::Int8,
        max_fingerprints: 50_000,
        enable_sona: true,
        storage_backend: StorageBackend::AppSandbox,
    },

    /// Disaster field deployment (maximum capability)
    /// ~50 MB container, full stack including multi-AP consensus
    Field {
        model_quantization: Quantization::Float16,
        max_fingerprints: 1_000_000,
        enable_sona: true,
        storage_backend: StorageBackend::FileSystem,
    },
}

Container Size Budget

Segment Browser IoT Mobile Field
WASM runtime 5.5 KB 5.5 KB 5.5 KB 5.5 KB
Model (ONNX) 3 MB (int8) 0.5 MB (int4) 3 MB (int8) 12 MB (fp16)
HNSW index 4 MB 100 KB 2 MB 40 MB
Fingerprint vectors 2 MB 50 KB 1 MB 10 MB
Config + crypto 50 KB 10 KB 50 KB 100 KB
Total ~10 MB ~0.7 MB ~6 MB ~62 MB

Offline-First Data Flow

text
/* Detailed source-code truncated for AI context efficiency. */

Browser-Specific Integration

rust
/// Browser WASM entry point
#[wasm_bindgen]
pub struct WifiDensePoseEdge {
    container: RvfContainer,
    inference_engine: InferenceEngine,
    hnsw_index: HnswIndex,
    sona: Option<SonaAdapter>,
}

#[wasm_bindgen]
impl WifiDensePoseEdge {
    /// Initialize from an RVF container loaded via fetch or IndexedDB
    #[wasm_bindgen(constructor)]
    pub async fn new(container_bytes: &[u8]) -> Result<WifiDensePoseEdge, JsValue> {
        let container = RvfContainer::from_bytes(container_bytes)?;
        let engine = InferenceEngine::from_container(&container)?;
        let index = HnswIndex::from_container(&container)?;
        let sona = SonaAdapter::from_container(&container).ok();

        Ok(Self { container, inference_engine: engine, hnsw_index: index, sona })
    }

    /// Process a single CSI frame (called from JavaScript)
    #[wasm_bindgen]
    pub fn process_frame(&mut self, csi_json: &str) -> Result<String, JsValue> {
        let csi_data: CsiData = serde_json::from_str(csi_json)
            .map_err(|e| JsValue::from_str(&e.to_string()))?;

        let features = self.extract_features(&csi_data)?;
        let detection = self.detect(&features)?;
        let pose = if detection.human_detected {
            Some(self.estimate_pose(&features)?)
        } else {
            None
        };

        serde_json::to_string(&PoseResult { detection, pose })
            .map_err(|e| JsValue::from_str(&e.to_string()))
    }

    /// Save current state to IndexedDB
    #[wasm_bindgen]
    pub async fn persist(&self) -> Result<(), JsValue> {
        let bytes = self.container.serialize()?;
        // Write to IndexedDB via web-sys
        save_to_indexeddb("wifi-densepose-state", &bytes).await
    }
}

Model Quantization Strategy

Quantization Size Reduction Accuracy Loss Suitable For
Float32 (baseline) 1x 0% Server/desktop
Float16 2x <0.5% Field tablets, GPUs
Int8 (PTQ) 4x <2% Browser, mobile
Int4 (GPTQ) 8x <5% IoT, ultra-constrained
Binary (1-bit) 32x ~15% MCU/ultra-edge (experimental)

Consequences

Positive

  • Single-file deployment: Copy one .rvf.edge file to deploy anywhere
  • Offline operation: Full functionality without network connectivity
  • 125ms boot: Near-instant readiness for emergency scenarios
  • Platform universal: Same container format for browser, IoT, mobile, server
  • Battery efficient: No network polling in offline mode

Negative

  • Container size: Even compressed, field containers are 50+ MB
  • WASM performance: 2-5x slower than native Rust for compute-heavy operations
  • Browser limitations: IndexedDB has storage quotas; WASM SIMD support varies
  • Update latency: Offline devices miss updates until reconnection
  • Quantization accuracy: Int4/Int8 models lose some detection sensitivity

References