Commit Graph

18 Commits

Author SHA1 Message Date
rUv 523be943b0
feat: QEMU ESP32-S3 testing platform + swarm configurator (ADR-061/062) (#260)
9-layer QEMU testing platform (ADR-061) and YAML-driven swarm
configurator (ADR-062) for ESP32-S3 firmware testing without hardware.

12 commits, 56 files, +9,500 lines. Tested on Windows with
Espressif QEMU 9.0.0 — firmware boots, mock CSI generates frames,
14/16 validation checks pass. 39 bugs found and fixed across
2 deep code reviews.

Closes #259

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-14 13:39:51 -04:00
rUv d793c1f49f
feat(firmware): --channel and --filter-mac provisioning (ADR-060)
- provision.py: add --channel (CSI channel override) and --filter-mac
  (AA:BB:CC:DD:EE:FF format) arguments with validation
- nvs_config: add csi_channel, filter_mac[6], filter_mac_set fields;
  read from NVS on boot
- csi_collector: auto-detect AP channel when no NVS override is set;
  filter CSI frames by source MAC when filter_mac is configured
- ADR-060 documents the design and rationale

Fixes #247, fixes #229
2026-03-13 08:27:08 -04:00
rUv 7c1351fd5d
feat(demo): wire all 6 RuVector WASM attention mechanisms into pose fusion
* feat: dual-modal WASM browser pose estimation demo (ADR-058)

Live webcam video + WiFi CSI fusion for real-time pose estimation.
Two parallel CNN pipelines (ruvector-cnn-wasm) with attention-weighted
fusion and dynamic confidence gating. Three modes: Dual, Video-only,
CSI-only. Includes pre-built WASM package (~52KB) for browser deployment.

- ADR-058: Dual-modal architecture design
- ui/pose-fusion.html: Main demo page with dark theme UI
- 7 JS modules: video-capture, csi-simulator, cnn-embedder, fusion-engine,
  pose-decoder, canvas-renderer, main orchestrator
- Pre-built ruvector-cnn-wasm WASM package for browser
- CSI heatmap, embedding space visualization, latency metrics
- WebSocket support for live ESP32 CSI data
- Navigation link added to main dashboard

Co-Authored-By: claude-flow <ruv@ruv.net>

* fix: motion-responsive skeleton + through-wall CSI tracking

- Pose decoder now uses per-cell motion grid to track actual arm/head
  positions — raising arms moves the skeleton's arms, head follows
  lateral movement
- Motion grid (10x8 cells) tracks intensity per body zone: head,
  left/right arm upper/mid, legs
- Through-wall mode: when person exits frame, CSI maintains presence
  with slow decay (~10s) and skeleton drifts in exit direction
- CSI simulator persists sensing after video loss, ghost pose renders
  with decreasing confidence
- Reduced temporal smoothing (0.45) for faster response to movement

Co-Authored-By: claude-flow <ruv@ruv.net>

* fix: video fills available space + correct WASM path resolution

- Remove fixed aspect-ratio and max-height from video panel so it
  fills the available viewport space without scrolling
- Grid uses 1fr row for content area, overflow:hidden on main grid
- Fix WASM path: resolve relative to JS module file using import.meta.url
  instead of hardcoded ./pkg/ which resolved incorrectly on gh-pages
- Responsive: mobile still gets aspect-ratio constraint

Co-Authored-By: claude-flow <ruv@ruv.net>

* feat: live ESP32 CSI pipeline + auto-connect WebSocket

- Add auto-connect to local sensing server WebSocket (ws://localhost:8765)
- Demo shows "Live ESP32" when connected to real CSI data
- Add build_firmware.ps1 for native Windows ESP-IDF builds (no Docker)
- Add read_serial.ps1 for ESP32 serial monitor

Pipeline: ESP32 → UDP:5005 → sensing-server → WS:8765 → browser demo

Co-Authored-By: claude-flow <ruv@ruv.net>

* docs: add ADR-059 live ESP32 CSI pipeline + update README with demo links

- ADR-059: Documents end-to-end ESP32 → sensing server → browser pipeline
- README: Add dual-modal pose fusion demo link, update ADR count to 49
- References issue #245

Co-Authored-By: claude-flow <ruv@ruv.net>

* feat: RSSI visualization, RuVector attention WASM, cache-bust fixes

- Add animated RSSI Signal Strength panel with sparkline history
- Fix RuVector WasmMultiHeadAttention retptr calling convention
- Wire up RuVector Multi-Head + Flash Attention in CNN embedder
- Add ambient temporal drift to CSI simulator for visible heatmap animation
- Fix embedding space projection (sparse projection replaces cancelling sum)
- Add auto-scaling to embedding space renderer
- Add cache busters (?v=4) to all ES module imports to prevent stale caches
- Add diagnostic logging for module version verification
- Add RSSI tracking with quality labels and color-coded dBm display
- Includes ruvector-attention-wasm v2.0.5 browser ESM wrapper

Co-Authored-By: claude-flow <ruv@ruv.net>

* feat: 26-keypoint dexterous pose + full RuVector attention pipeline

Pose Decoder (17 → 26 keypoints):
- Add finger approximations: thumb, index, pinky per hand (6 new)
- Add toe tips: left/right foot index (2 new)
- Add neck keypoint (1 new)
- Hand openness driven by arm motion intensity
- Finger positions computed from wrist-elbow axis angles

CNN Embedder (full RuVector WASM pipeline):
- Stage 1: Multi-Head Attention (global spatial reasoning)
- Stage 2: Hyperbolic Attention (hierarchical body-part tree)
- Stage 3: MoE Attention (3 experts: upper/lower/extremities, top-2)
- Blended 40/30/30 weighting → final embedding projection

Canvas Renderer:
- Magenta finger joints with distinct glow
- Cyan toe tips
- White neck keypoint
- Thinner limb lines for hand/foot connections
- Joint count shown in overlay label

CSI Simulator:
- Skip synthetic person state when live ESP32 connected
- Only simulate CSI data in demo mode (was already correct)

Embedding Space:
- Fixed projection: sparse 8-dim projection replaces cancelling sum
- Auto-scaling normalizes point spread to fill canvas

Cache busters bumped to v=5 on all imports.

Co-Authored-By: claude-flow <ruv@ruv.net>

* fix: centroid-based pose tracking for responsive limb movement

Rewrites pose decoder from intensity-based to position-based tracking:
- Arms now track toward motion centroid in each body zone
- Elbow/wrist positions computed along shoulder→centroid vector
- Legs track toward lower-body zone centroids
- Smoothing reduced from 0.45 to 0.25 for responsiveness
- Zone centroids blend 30% old / 70% new each frame

6 body zones with overlapping coverage:
- Head (top 20%, center cols)
- Left/Right Arm (rows 10-60%, outer cols)
- Torso (rows 15-55%, center cols)
- Left/Right Leg (rows 50-100%, half cols each)

Hand openness now driven by arm spread distance + raise amount.
Cache busters v=6.

Co-Authored-By: claude-flow <ruv@ruv.net>

* fix: remove duplicate lAnkleX/rAnkleX declarations in pose-decoder

Stale code block from old intensity-based tracking was left behind,
re-declaring variables already defined by centroid-based tracking.

Co-Authored-By: claude-flow <ruv@ruv.net>

* feat(demo): wire all 6 RuVector WASM attention mechanisms into pose fusion

- Add WasmLinearAttention and WasmLocalGlobalAttention to browser ESM wrapper
- Add 6 WASM utility functions (batch_normalize, pairwise_distances, etc.)
- Extend CnnEmbedder to 6-stage pipeline: Flash → MHA → Hyperbolic → Linear → MoE → L+G
- Use log-energy softmax blending across all 6 stages
- Wire WASM cosine_similarity and normalize into FusionEngine
- Add RuVector pipeline stats panel to UI (energy, refinement, pose impact)
- Compute embedding-to-joint mapping stats without modifying joint positions
- Center camera prompt with flexbox layout
- Add cache busters v=12

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-12 20:59:57 -04:00
ruv 952f27a1ce fix(firmware): enable CSI in sdkconfig and add build guard (ADR-057)
The committed sdkconfig had CONFIG_ESP_WIFI_CSI_ENABLED disabled, causing
all builds to crash at runtime with "CSI not enabled in menuconfig".
Root cause: sdkconfig.defaults.template existed but ESP-IDF only reads
sdkconfig.defaults (no .template suffix).

Fixes:
- Add sdkconfig.defaults with CONFIG_ESP_WIFI_CSI_ENABLED=y
- Add #error compile guard in csi_collector.c to prevent recurrence
- Fix NVS encryption default (requires eFuse, breaks clean builds)

Verified: Docker build + flash to ESP32-S3 + CSI callbacks confirmed.

Closes #241
Relates to #223, #238, #234, #210, #190

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-12 13:49:20 -04:00
Reuven fc92436f52 chore: add build artifacts and session state
- NVS config binaries for ESP32 WiFi provisioning
- macOS Tauri schema
- package-lock.json update
- Claude Flow session state

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-10 10:36:16 -04:00
Reuven a28a875594 fix(firmware): provision.py nvs import + partition config template
Fixes #215: provision.py now correctly imports from esp_idf_nvs_partition_gen
package (the pip-installable version) before falling back to legacy import.

Fixes #216: Added sdkconfig.defaults.template with custom partition table
configuration for 8MB flash boards. Copy to sdkconfig.defaults before build:
  cp sdkconfig.defaults.template sdkconfig.defaults

Changes:
- firmware/esp32-csi-node/provision.py: Try esp_idf_nvs_partition_gen first
- scripts/provision.py: Same import fix
- firmware/esp32-csi-node/sdkconfig.defaults.template: 8MB flash config with
  2MB OTA partitions, compiler size optimization, and CSI enabled

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-10 08:40:47 -04:00
ruv 47223a98be fix: security hardening — replace fake HMAC, add path traversal protection, OTA auth (ADR-050)
Sprint 1 security fixes from quality engineering analysis (issue #170):

- Replace XOR-fold fake HMAC with real HMAC-SHA256 (hmac + sha2 crates) in secure_tdm.rs
- Add path traversal sanitization on DELETE /api/v1/models/:id and /api/v1/recording/:id
- Default bind address changed from 0.0.0.0 to 127.0.0.1 (configurable via --bind-addr / SENSING_BIND_ADDR)
- Add PSK authentication to ESP32 OTA firmware upload endpoint (ota_update.c)
- Flip WASM signature verification to default-on (CONFIG_WASM_SKIP_SIGNATURE opt-out vs opt-in)
- Add 6 new security tests: HMAC key/message sensitivity, determinism, wrong-key rejection, bit-flip detection, enforcing mode
- Add clap env feature for environment variable configuration

All 106 hardware crate tests pass. Sensing server compiles clean.

Closes #170

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-06 13:11:04 -05:00
ruv c45690ed4e fix: use montserrat_14 for display_ui big label (montserrat_20 not in Kconfig)
Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-05 11:45:59 -05:00
ruv 8b57a6f64c docs: update README with ADR-045–048, Observatory, adaptive classifier, AMOLED display
- Update ADR count from 44 to 48
- Add adaptive classifier (ADR-048) to Intelligence features
- Add Observatory visualization (ADR-047) and AMOLED display (ADR-045) to Deployment features
- Update screenshot to v2-screen.png
- Add ADR-045 (AMOLED), ADR-046 (Android TV), ADR-047 (Observatory), DDD deployment model
- Add AMOLED display firmware (display_hal, display_task, display_ui, LVGL config)
- Add Observatory UI (13 Three.js modules, CSS, HTML entry point)
- Add trained adaptive model JSON
- Update .gitignore for managed_components, recordings, .swarm

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-05 10:20:48 -05:00
rUv ce171696b2
fix: rate-limit CSI sends and add ENOMEM backoff to prevent crash (#132)
The CSI callback fires for every WiFi frame in promiscuous mode
(100-500+ fps). Each call invoked sendto() synchronously, exhausting
lwIP packet buffers (errno 12 = ENOMEM). The rapid-fire failures
cascaded into a LoadProhibited guru meditation crash.

Two fixes:

1. csi_collector.c: Rate-limit UDP sends to 50 Hz (20ms interval).
   CSI frames arriving between sends are dropped — the sensing
   pipeline only needs 20-50 Hz.

2. stream_sender.c: When sendto fails with ENOMEM, suppress further
   sends for 100ms to let lwIP reclaim buffers. Logs the backoff
   event and resumes automatically.

Closes #127
2026-03-03 16:00:40 -05:00
rUv b6f7b8a74a
fix: add TDM and edge intelligence flags to provision.py (#131)
The user guide and release notes document TDM and edge intelligence
provisioning flags but provision.py only accepted --ssid, --password,
--target-ip, --target-port, and --node-id.

Add all NVS keys the firmware actually reads:
- --tdm-slot / --tdm-total: TDM mesh slot assignment
- --edge-tier: edge processing tier (0=off, 1=stats, 2=vitals)
- --pres-thresh, --fall-thresh: detection thresholds
- --vital-win, --vital-int: vitals timing parameters
- --subk-count: top-K subcarrier selection

Also validates that --tdm-slot and --tdm-total are specified together
and that slot < total.

Closes #130
2026-03-03 15:53:43 -05:00
ruv e94c7056f2 feat: add ADR-042 CHCI protocol, 24 new edge modules, README restructure
- ADR-042: Coherent Human Channel Imaging (non-CSI sensing protocol)
  with DDD domain model (6 bounded contexts)
- 24 new WASM edge modules: medical (5), retail (5), security (5),
  building (5), industrial (5), exotic (8)
- README: plain-language rewrites, moved detail sections below TOC,
  added edge module links to use case tables, firmware release docs
- User guide: firmware release table, edge intelligence documentation
- .gitignore: added rules for wasm, esp32 temp files, NVS binaries
- WASM edge crate: cargo config, integration tests, module registry

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-03 11:35:57 -05:00
ruv 4b1005524e feat: complete vendor repos, add edge intelligence and WASM modules
- Add 154 missing vendor files (gitignore was filtering them)
  - vendor/midstream: 564 files (was 561)
  - vendor/sublinear-time-solver: 1190 files (was 1039)
- Add ESP32 edge processing (ADR-039): presence, vitals, fall detection
- Add WASM programmable sensing (ADR-040/041) with wasm3 runtime
- Add firmware CI workflow (.github/workflows/firmware-ci.yml)
- Add wifi-densepose-wasm-edge crate for edge WASM modules
- Update sensing server, provision.py, UI components

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-02 23:53:25 -05:00
ruv e0fe10b3dc feat: add provision.py to repo, fix user guide paths
- Move provision.py from release-only asset into firmware/esp32-csi-node/
- Fix user guide references from scripts/provision.py to correct path
- Update release link to v0.2.0-esp32

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-02 19:07:32 -05:00
rUv 915943cef4
feat: ESP32 CSI MAC address filtering with NVS/Kconfig support (#101)
* feat: add MAC address filter for ESP32 CSI collection

In multi-AP environments, CSI frames from different access points get
mixed together, corrupting the sensing signal. Add transmitter MAC
filtering so only frames from a specified AP are processed.

Implementation:
- csi_collector: filter in wifi_csi_callback by comparing info->mac
  against configured MAC; log transmitter MAC in periodic debug output
- csi_collector_set_filter_mac(): runtime API to enable/disable filter
- Kconfig: CSI_FILTER_MAC option (format "AA:BB:CC:DD:EE:FF")
- NVS: "filter_mac" 6-byte blob overrides Kconfig at runtime
- nvs_config: parse Kconfig MAC string at boot, load NVS override
- main: apply filter from config after csi_collector_init()

When no filter is configured (default), behavior is unchanged —
all transmitter MACs are accepted for backward compatibility.

Fixes #98

Co-Authored-By: claude-flow <ruv@ruv.net>

* chore: add CLAUDE.local.md to .gitignore

Local machine configuration (ESP-IDF paths, COM port, build
instructions) should not be committed to the repository.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-02 17:08:27 -05:00
ruv 303871275b feat: ADR-029/031 TDM sensing protocol, channel hopping, and NVS config
Implement the hardware and firmware portions of RuvSense (ADR-029) and
RuView (ADR-031) for multistatic WiFi sensing:

Rust (wifi-densepose-hardware):
- TdmSchedule: uniform slot assignments with configurable cycle period,
  guard intervals, and processing window (default 4-node 20 Hz)
- TdmCoordinator: manages sensing cycles, tracks per-slot completion,
  cumulative clock drift compensation (±10 ppm over 50 ms = 0.5 us)
- SyncBeacon: 16-byte wire format for cycle synchronization with
  drift correction offsets
- TdmSlotCompleted event for aggregator notification
- 18 unit tests + 4 doctests, all passing

Firmware (C, ESP32):
- Channel-hop table in csi_collector.c (s_hop_channels, configurable
  via csi_collector_set_hop_table)
- Timer-driven channel hopping via esp_timer at dwell intervals
- NDP frame injection stub via esp_wifi_80211_tx()
- Backward-compatible: hop_count=1 disables hopping entirely
- NVS config extension: hop_count, chan_list, dwell_ms, tdm_slot,
  tdm_node_count with bounds validation and Kconfig fallback defaults

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-01 21:33:48 -05:00
ruv 7872987ee6 fix(docker): Update Dockerfile paths from src/ to v1/src/
The source code was moved to v1/src/ but the Dockerfile still
referenced src/ directly, causing build failures. Updated all
COPY paths, uvicorn module paths, test paths, and bandit scan
paths. Also added missing v1/__init__.py for Python module
resolution.

Fixes #33

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-02-28 13:38:21 -05:00
rUv 92a5182dc3 feat(adr-018): ESP32-S3 firmware, Rust aggregator, and live CSI pipeline
Complete end-to-end WiFi CSI capture pipeline verified on real hardware:

- ESP32-S3 firmware: WiFi STA + promiscuous mode CSI collection,
  ADR-018 binary serialization, UDP streaming at ~20 Hz
- Rust aggregator CLI binary (clap): receives UDP frames, parses with
  Esp32CsiParser, prints per-frame summary (node, seq, rssi, amp)
- UDP aggregator module with per-node sequence tracking and drop detection
- CsiFrame bridge to detection pipeline (amplitude/phase/SNR conversion)
- Python ESP32 binary parser with UDP reader
- Presence detection confirmed: motion score 10/10 from live CSI variance

Hardware verified: ESP32-S3-DevKitC-1 (CP2102, MAC 3C:0F:02:EC:C2:28),
Docker ESP-IDF v5.2 build, esptool 5.1.0 flash, 20 Rust + 6 Python tests pass.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-02-28 13:22:04 -05:00