Commit graph

138 commits

Author SHA1 Message Date
ruv
ca97527646 feat(introspection): I6 — regime-changed signal + per-frame analyze + honest ADR-099 D8 amendment
Three threads in this commit:

1) Per-frame attractor analysis (default analyze_every_n: 8 → 1).
   The I5 benchmark put per-frame update at 0.012 ms p99 — 83× under D4's
   1 ms budget. The cost case for the every-8th-frame default doesn't hold;
   per-frame analysis is what makes regime_changed a viable early-detection
   trigger.

2) New `regime_changed: bool` field in IntrospectionSnapshot — flips on any
   frame whose attractor regime classification differs from the previous
   frame's. Pairs with top_k_similarity (full-shape match) to give
   downstream consumers two latencies with different robustness profiles.

3) Honest amendment of ADR-099 D8 to reflect empirical reality:
   - L1 stand-in achieves 3.20× ratio (5-frame shape match vs 16-frame
     event-path floor); the 10× aspirational bar is architecturally
     unreachable at 1-D scalar feature resolution.
   - regime_changed didn't fire in the 10-frame motion window — the
     200-frame noise trajectory dominates the Lyapunov classification, and
     short perturbations don't shift the regime fast enough on a scalar
     feature.
   - Path to 10×: ADR-208 Phase 2 (Hailo NPU vec128 embeddings) — multi-dim
     partial matches discriminate from noise in 1-2 frames, not 5.
   - Side finding: midstream temporal-compare::DTW uses *discrete equality*
     cost (designed for LLM tokens), not numeric distance — swapping it in
     for f64 amplitude scoring would be strictly worse than the L1 stand-in.
     A numeric DTW is a separate concern (hand-roll or new crate).
   - Revised D8: ship behind --introspection (off by default) until multi-
     dim features land. Per-frame update budget IS met (0.041 ms p99 in this
     bench, ~24× under the 1 ms bar) — the feature is cheap enough to
     carry dark today.

cargo test -p wifi-densepose-sensing-server --no-default-features:
  introspection (lib): 8 passed, 0 failed
  introspection_latency (test): 5 passed, 0 failed (incl. new
                                 regime_change_path_latency)
clippy: clean on the introspection surface (pre-existing approx_constant
        lints in pose.rs / main.rs unchanged).

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-05-13 23:29:37 -04:00
ruv
900b877c64 docs(adr): ADR-099 — adopt midstream as RuView's real-time introspection + low-latency tap (Proposed)
ADR-098 rejected midstream as a *replacement* for RuView's existing seams.
ADR-099 is the other half: midstream's `temporal-compare` (DTW) and
`temporal-attractor-studio` (Lyapunov + regime classification) crates as a
*parallel* per-frame introspection tap, alongside the existing window-aggregated
event pipeline.

The 8 decisions:

  D1 — Only midstreamer-temporal-compare 0.2 + midstreamer-attractor 0.2;
       scheduler / neural-solver / strange-loop are out of scope of this ADR.
  D2 — Tap point: post-validate, parallel to WindowBuffer::push in csi.rs.
       The existing /ws/sensing path is unchanged.
  D3 — New /ws/introspection topic + /api/v1/introspection/snapshot REST endpoint
       carrying IntrospectionSnapshot { regime, lyapunov_exponent,
       attractor_dim, top_k_similarity }.
  D4 — Per-frame updates only, never window-blocked. Soonest-event latency on
       the "shape recognized" path collapses from ~533 ms (16-frame @ 30 Hz
       window) to ~33 ms (one frame), a ~16× win.
  D5 — temporal-neural-solver (LTL) is out of scope (separate MAT audit ADR).
  D6 — ESP32 firmware unchanged; deployment is host-side only.
  D7 — Signature library is JSON, on-disk, customer-owned; three reference
       signatures ship as developer fixtures.
  D8 — Promotion bar is empirical: ≥10× p99 latency reduction vs. the existing
       /ws/sensing event path, or the feature stays behind a CLI flag.

Indexed in docs/adr/README.md. Phased adoption (P0 spike + benchmark → P1 first
real signature library → P2 dashboard widget → P3 capture workflow → P4 optional
adaptive_classifier hook). Implementation lands as ~150–250 lines + one
integration test in v2/crates/wifi-densepose-sensing-server in follow-up PRs.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-05-13 22:42:05 -04:00
ruv
7a407556ba docs(adr): ADR-097 — adopt rvCSI as RuView's primary CSI runtime (Proposed)
rvCSI was extracted to its own repo (PR #542→#544): 9 crates on crates.io @
0.3.1, `@ruv/rvcsi` on npm, vendored at `vendor/rvcsi`. RuView currently
*vendors but does not consume* it — zero `rvcsi-*` deps in `v2/`, zero
`use rvcsi_…` imports, zero `@ruv/rvcsi` JS imports. ADR-097 decides:

  D1 — Depend on the published crates from crates.io, not the submodule path.
  D2 — Pilot in `wifi-densepose-sensing-server` (smallest, best-bounded
       touchpoint: UDP receiver + handlers + WS fan-out).
  D3 — `wifi-densepose-signal` is *layered on top of* rvCSI, not replaced.
       The SOTA / RuvSense modules go beyond rvCSI's scope and stay in
       RuView; they consume `rvcsi_core::CsiFrame`. Overlapping basic DSP
       primitives delegate to `rvcsi-dsp` or become thin shims.
  D4 — `wifi-densepose-hardware` stops carrying ESP32 wire-format parsing;
       the parser moves to a new `rvcsi-adapter-esp32` crate (ADR-095 §1.2
       / D15 follow-up, owned in the rvCSI repo).
  D5 — `wifi-densepose-ruvector` (training pipeline) and `rvcsi-ruvector`
       (runtime RF memory) stay separate for now; a follow-up unifies them
       once the production RuVector binding lands.
  D6 — `rvcsi_core::CsiFrame` is the boundary type at the runtime edge;
       one explicit `From`/`Into` conversion point at that edge.
  D7 — Track via `rvcsi-* = "0.3"` SemVer ranges + bump the `vendor/rvcsi`
       submodule pin per RuView release for reproducible offline builds.
  D8 — Once every consumer depends on crates.io, decide (separately)
       whether to drop the submodule.

Adoption is phased (P1 pilot → P2 signal shim → P3 ESP32 adapter →
P4 clean-up → P5 submodule review); each phase is one PR with tests.

Indexed in docs/adr/README.md.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-05-13 09:23:25 -04:00
ruv
deb561bf9c fix(rvcsi): scale-relative baseline-drift thresholds + ESP32 end-to-end validation
BaselineDriftDetector compared `mean_amplitude` against its EWMA baseline
with *absolute* thresholds (anomaly 1.0, drift 0.15). Fine for the synthetic
unit tests (amplitudes ~1.0), but raw ESP32 CSI is int8 I/Q with amplitudes
up to ~128, so window-to-window RMS distance is routinely 5-50 >> 1.0 and
AnomalyDetected fired on ~96% of windows (319/331 on a real node-1 capture).

Drift is now `||current - baseline||2 / ||baseline||2` (a fraction, with an
eps floor that falls back to absolute for a degenerate near-zero baseline),
so one tuning is valid across raw-int8 ESP32, int16-scaled Nexmon, and
baseline-subtracted streams. AnomalyDetected drops to 40/331 on the same
data; the existing detector tests still pass (their explicit configs are
valid relative thresholds too); added baseline_drift_is_scale_invariant_
no_anomaly_storm. rvcsi-events 18 -> 19 tests; 162 rvcsi tests, 0 failures,
clippy-clean.

Surfaced by an end-to-end test against real ESP32 CSI on COM7: the device
(ESP32-S3, node 1, ADR-018 firmware, WiFi "ruv.net" ch5 RSSI -39, CSI cb
only because nothing listens at .156). rvcsi has no ESP32 adapter yet, so a
7,000-frame node-1 recording was transcoded to .rvcsi via the new
scripts/esp32_jsonl_to_rvcsi.py (stand-in for `record --source esp32-jsonl`)
and run through `rvcsi inspect`/`replay`/`calibrate`/`events` end-to-end.

ADR-095 D13 and ADR-096 sections 2.1/5 updated; CHANGELOG entry added;
rvcsi-adapter-esp32 (live serial/UDP source) noted as a follow-up.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-05-12 22:19:15 -04:00
Claude
d40411e6d7
feat(rvcsi): Raspberry Pi 5 (BCM43455c0) + Nexmon chip registry
Adds first-class support for the Raspberry Pi 5's WiFi chip (CYW43455 /
BCM43455c0 — the same 802.11ac wireless as the Pi 4 / Pi 3B+ / Pi 400, and the
chip with the most mature nexmon_csi support), plus a registry of the other
Nexmon-supported Broadcom/Cypress chips.

rvcsi-adapter-nexmon — new `chips.rs`:
- `NexmonChip` (Bcm43455c0, Bcm43436b0, Bcm4366c0, Bcm4375b1, Bcm4358, Bcm4339,
  Unknown{chip_ver}) + `RaspberryPiModel` (Pi5/Pi4/Pi400/Pi3BPlus/PiZero2W/
  PiZeroW) — Pi5/Pi4/Pi400/Pi3B+ → Bcm43455c0; PiZero2W → Bcm43436b0.
- `nexmon_adapter_profile(chip)` / `raspberry_pi_profile(model)` build the
  per-device `AdapterProfile` (channels: 2.4 GHz 1-13 + 5 GHz UNII for dual-band;
  bandwidths 20/40/80[/160]; expected subcarrier counts 64/128/256[/512]) that
  `validate_frame` bounds CSI frames against.
- `NexmonChip::from_chip_ver` (0x4345 → Bcm43455c0, 0x4339, 0x4358, 0x4366,
  0x4375 — best-effort; the raw `chip_ver` is always preserved) and `from_slug`
  / `RaspberryPiModel::from_slug` ("pi5", "raspberry pi 4", "bcm43455c0", ...).
- `NexmonCsiHeader::chip()`; `NexmonPcapAdapter` auto-detects the chip from the
  packets' `chip_ver` and uses the matching profile, overridable via
  `.with_chip(NexmonChip)` / `.with_pi_model(RaspberryPiModel)`; `.detected_chip()`.

rvcsi-runtime: `decode_nexmon_pcap_for(.., chip_spec)` (validate against a chip /
Pi model, drop non-conforming) + `nexmon_profile_for(spec)`; `NexmonPcapSummary`
gains `chip_names` + `detected_chip`; `CaptureSummary` gains `chip`.

rvcsi-cli: `record --source nexmon-pcap --chip pi5`; new `nexmon-chips`
subcommand (lists chips + Pi models, human or `--json`); `inspect-nexmon` and
`inspect` now print the resolved chip.

rvcsi-node (napi-rs): `nexmonDecodePcap` gains an optional `chip` arg;
`nexmonChipName(chipVer)`, `nexmonProfile(spec)`, `nexmonChips()`. @ruv/rvcsi
SDK + `.d.ts` updated (AdapterProfile / NexmonChipsListing interfaces, the new
fns, `chip` on CaptureSummary, `chip_names`/`detected_chip` on NexmonPcapSummary).

168 rvcsi tests pass (adapter-nexmon 22→28, cli 9→10), 0 failures, clippy-clean.
The synthetic test captures now stamp chip_ver = 0x4345 (the BCM4345 family chip
ID), so the chip-detection happy path is exercised end to end.
ADR-096, CHANGELOG, README, CLAUDE.md updated.

https://claude.ai/code/session_01CdYAPvRTjcch6YrYf42n1z
2026-05-13 01:32:27 +00:00
Claude
b116a99481
feat(rvcsi): real nexmon_csi UDP/PCAP fidelity — chanspec decode, libpcap reader, NexmonPcapAdapter
Raises the Nexmon path from a normalized record format to parsing what the
patched Broadcom firmware actually emits, end to end.

napi-c shim (ABI 1.0 -> 1.1, additive):
- rvcsi_nx_csi_udp_header / rvcsi_nx_csi_udp_decode — parse the real nexmon_csi
  UDP payload: the 18-byte header (magic 0x1111, rssi int8, fctl, src_mac[6],
  seq_cnt, core/spatial-stream, Broadcom chanspec, chip_ver) + nsub complex CSI
  samples (modern int16 LE I/Q export — what CSIKit/csireader.py read for the
  BCM43455c0 / 4358 / 4366c0; nsub = (len-18)/4). rvcsi_nx_csi_udp_write to
  synthesize payloads for tests. rvcsi_nx_decode_chanspec — d11ac chanspec ->
  channel (chanspec & 0xff) / bandwidth (bits [13:11], cross-checked against the
  FFT size) / band (bits [15:14], cross-checked against the channel number).
  Still allocation-free, bounds-checked, structured errors, never panics.
- ffi.rs wraps it: decode_chanspec / parse_nexmon_udp_header / decode_nexmon_udp
  / encode_nexmon_udp + DecodedChanspec / NexmonCsiHeader; every unsafe block
  documented; the ABI guard now expects 1.1.

rvcsi-adapter-nexmon:
- pcap.rs — a dependency-free classic-libpcap reader (all four byte-order /
  timestamp-resolution magics; Ethernet / raw-IPv4 / Linux-SLL link types;
  tolerates a truncated final record; pcapng is a follow-up) + extract_udp_payload
  + a synthetic_udp_pcap / synthetic_nexmon_pcap test/example generator.
- NexmonPcapAdapter (a CsiSource) — reads the CSI UDP packets out of a
  `tcpdump -i wlan0 dst port 5500 -w csi.pcap` capture, decodes each via the C
  shim, stamps the frame timestamp from the pcap packet time; non-CSI packets
  counted as "skipped" in health.

rvcsi-runtime: decode_nexmon_pcap, summarize_nexmon_pcap (+ NexmonPcapSummary:
link type, CSI frame count, channels, bandwidths, subcarrier counts, chip
versions, RSSI range, time span), CaptureRuntime::open_nexmon_pcap[_bytes].

rvcsi-node (napi-rs): nexmonDecodePcap, inspectNexmonPcap, decodeChanspec,
RvcsiRuntime.openNexmonPcap. @ruv/rvcsi SDK + .d.ts updated (NexmonPcapSummary,
DecodedChanspec). rvcsi-cli: `record --source nexmon-pcap`, `inspect-nexmon`,
`decode-chanspec`.

161 rvcsi tests pass (adapter-nexmon 9->22), 0 failures, clippy-clean.
ADR-096 §2.2/§2.3/§5, CHANGELOG, CLAUDE.md updated.

https://claude.ai/code/session_01CdYAPvRTjcch6YrYf42n1z
2026-05-13 01:15:22 +00:00
Claude
94745242a8
feat(rvcsi): rvcsi-dsp (DSP stages + SignalPipeline) + ADR-096 (FFI/crate layout)
- rvcsi-dsp — reusable signal-processing stages (ADR-095 FR4): mean/variance/
  std_dev/median, remove_dc_offset, unwrap_phase, moving_average, ewma,
  hampel_filter(_count), short_window_variance, subtract_baseline + DspError;
  scalar features motion_energy(_series), presence_score (logistic, ≈0.5 at
  threshold), confidence_score, breathing_band_estimate (heuristic, FFT-free);
  SignalPipeline (hampel → smooth → DC-remove → baseline-subtract → unwrap,
  non-destructive of validation state) + learn_baseline. 28 tests, clippy-clean,
  forbid(unsafe_code), no heavy deps.
- docs/adr/ADR-096-rvcsi-ffi-crate-layout.md — the implementation ADR: 8-crate
  topology, the napi-c shim record format + contract, the napi-rs Node surface,
  build/test invariants, alternatives. Indexed in docs/adr/README.md.
- CHANGELOG: rvCSI entry updated to cover the implementation crates.

https://claude.ai/code/session_01CdYAPvRTjcch6YrYf42n1z
2026-05-13 00:00:40 +00:00
Claude
d98b7e3f65
docs: rvCSI edge RF sensing platform — PRD, ADR-095, DDD domain model
Adds design documentation for rvCSI, a Rust-first / TypeScript-accessible /
hardware-abstracted edge RF sensing runtime that normalizes WiFi CSI from
Nexmon, ESP32, Intel, Atheros, file and replay sources into one validated
CsiFrame schema, runs reusable DSP, emits typed confidence-scored events,
and bridges to RuVector RF memory, an MCP tool server and a TS SDK.

- docs/prd/rvcsi-platform-prd.md — purpose, users, success criteria,
  FR1-FR10, NFRs (safety/perf/reliability/privacy/security/portability),
  system architecture, runtime components, reference layout, data model
- docs/adr/ADR-095-rvcsi-edge-rf-sensing-platform.md — the 15 architectural
  decisions (Rust core, C-at-the-boundary, TS SDK via napi-rs, normalized
  schema, validate-before-FFI, CSI-as-temporal-delta, RuVector as RF memory,
  replayability, detection != decision, local-first, read-first/write-gated
  MCP, mandatory quality scoring, versioned calibration, plugin adapters)
- docs/ddd/rvcsi-domain-model.md — 7 bounded contexts (Capture, Validation,
  Signal, Calibration, Event, Memory, Agent) with aggregates, invariants,
  context map, data model and domain services
- indexed in docs/adr/README.md and docs/ddd/README.md; CHANGELOG entry

Design-only; no code or crates added yet.

https://claude.ai/code/session_01CdYAPvRTjcch6YrYf42n1z
2026-05-12 23:15:10 +00:00
rUv
eaedfded6f
fix(train): wire wifi-densepose-signal into the pipeline; correct MODEL_CARD env-sensor claim (#536)
Addresses three findings from the 2026-05-11 training-pipeline audit:

#1/#2 — `wifi-densepose-signal` was a phantom dependency of `wifi-densepose-train`
(listed in Cargo.toml, never imported), and vitals/CSI signal features were
absent from the pipeline. New module `wifi_densepose_train::signal_features`:
`extract_signal_features(&Array4<f32>, &Array4<f32>) -> Array1<f32>` (and the
convenience method `CsiSample::signal_features()`) runs a windowed observation's
centre frame through `wifi_densepose_signal::features::FeatureExtractor`,
producing a fixed-length (FEATURE_LEN=12) amplitude / phase-coherence / PSD
feature vector — the hook for a future vitals / multi-task supervision head
(breathing- and heart-rate-band power are read off the PSD summary). The vector
is produced on demand and is not yet fed back into the loss; wiring it as a
training target is the documented follow-up. `wifi-densepose-signal` is now an
actually-used dependency. 5 new tests (2 unit in signal_features.rs, 3
integration in tests/test_dataset.rs); existing wifi-densepose-train tests
unchanged and green.

#3 — `docs/huggingface/MODEL_CARD.md` presented PIR/BME280 environmental-sensor
weak-label fine-tuning as a current capability; there is no env-sensor
ingestion in the training pipeline. Marked that path as planned/not-implemented
in the training-steps list and the data-provenance section.

(#5 — README's "92.9% PCK@20" overclaim — fixed separately in PR #535.)

CHANGELOG updated.
2026-05-11 23:40:55 -04:00
ruv
ad41a89960 feat(pointcloud): integrate ESP32 CSI as optional data stream from hosted viewer
The hosted GitHub Pages viewer can now act as a thin client for a
locally-running ruview-pointcloud serve instance — flip a button, the
ESP32's CSI fusion (camera depth + WiFi CSI + mmWave) renders inside
the same Three.js scene that previously only showed the face mesh
demo. No clone, no rebuild, no toolchain on the visitor's side.

Server (stream.rs):
- Add tower_http::cors::CorsLayer with a deliberate allowlist:
  https://ruvnet.github.io, http://localhost:*, http://127.0.0.1:*,
  and 'null' (for file:// origins). Anything else is denied — not a
  wildcard CORS. Modern browsers (Chrome 94+, Firefox 116+, Safari
  16.4+) treat 127.0.0.1 as a "potentially trustworthy" origin so
  HTTPS Pages → HTTP loopback is permitted. The new layer wraps the
  existing /api/cloud, /api/splats, /api/status, /health routes.
- Cargo.toml: pull in workspace tower-http (cors feature already on).

Viewer:
- New "📡 Connect ESP32…" CTA bottom-right. Clicking prompts for a
  ruview-pointcloud serve URL (default http://127.0.0.1:9880),
  persists the last-used value in localStorage, and reloads with
  ?backend=<url> so the existing remote-mode fetch path takes over.
  When already connected the button toggles to "disconnect" and
  reloads back to the demo.
- Reuses the existing transport selector — no new code path to
  maintain. The face mesh / synthetic demo render path is unaffected;
  this is purely an additive UI affordance over the ?backend= query.

Docs:
- ADR-094 §2.3 expanded with the local-ESP32 workflow and the CORS
  posture rationale.
- Workflow README documents ?backend=http://127.0.0.1:9880 as the
  intended local-ESP32 path.

Tests: cargo test -p wifi-densepose-pointcloud → 15/15 passed.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-29 20:33:00 -04:00
ruv
cbedbce9e3 feat(pointcloud): use MediaPipe Face Mesh for the live demo (ADR-094)
The previous synthetic procedural demo did not represent what the local
fusion pipeline produces — a real depth-backprojected point cloud of
the user's face and surroundings. This commit ports the closest browser
equivalent: MediaPipe Face Mesh runs in-browser at ~30 fps and emits
478 3D landmarks per frame. Each visitor now sees the outline of their
own face rendered as a point cloud, with a small floor + back wall for
spatial context.

- Adds MediaPipe Face Mesh + Camera Utils via jsdelivr CDN.
- Adds an "▶ Enable camera" CTA so getUserMedia is gated on a user
  gesture (required by some browsers and good UX regardless).
- New face-mesh frame generator uses the same splat shape as the live
  /api/splats payload, so a single render path drives both modes.
- Mirrors x to match selfie convention; maps lm.z (relative depth) to
  the world-coord range used by the live pipeline.
- Falls back automatically to the procedural floor + walls + figure
  when the camera is denied, dismissed, or unavailable.
- Badge surfaces the new state: '● DEMO Your Face (MediaPipe)'.
- Bumps poll cadence to 4 Hz so face mesh updates feel live.
- ADR-094 updated to reflect the new default behavior.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-29 19:42:51 -04:00
rUv
21b2b3352f
feat(pointcloud): GitHub Pages demo with optional live backend (ADR-094) (#495)
Publishes the live 3D point cloud viewer to gh-pages/pointcloud/ so it
can be linked from the README alongside the Observatory and Dual-Modal
Pose Fusion demos. The viewer auto-selects its transport from URL
parameters:

- default / ?backend=auto — try /api/splats, fall back to synthetic demo
- ?backend=demo — synthetic in-browser only, no network
- ?backend=<url> — fetch from a CORS-permitting host running
  ruview-pointcloud serve
- ?live=1 — strict mode, show offline panel instead of demo fallback

The synthetic frame matches the live API JSON shape (splats, count,
frame, live, pipeline.{skeleton,vitals}) so a single render path drives
both modes. New workflow uses keep_files: true to preserve the existing
observatory/, pose-fusion/, and nvsim/ deployments on gh-pages.

See docs/adr/ADR-094-pointcloud-github-pages-deployment.md for the full
decision record and 6 acceptance gates.
2026-04-29 19:35:41 -04:00
ruv
e11d569a39 docs(readme): split details to docs/readme-details.md and reorganize
- Move Latest Additions, Key Features, and everything from Installation
  through Changelog (1855 lines) into docs/readme-details.md.
- Keep README focused on overview, capability table, How It Works,
  Use Cases, Documentation, License, and Support.
- Add per-row emojis to the top capability table.
- Add 3D point cloud row noting optional camera + WiFi CSI + mmWave
  fusion with link to the live viewer demo.
- Move Documentation table closer to the bottom (just above License).
- Collapse Edge Intelligence (ADR-041) into a <details> block matching
  the sibling Use Case sections.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-29 19:34:24 -04:00
rUv
7f5a692632
feat(nvsim): full simulator stack — Rust crate, dashboard, server, App Store, Ghost Murmur [ADR-089/090/091/092/093]
Squashed merge of feat/nvsim-pipeline-simulator (29 commits).

## Shipped

- ADR-089 nvsim crate (Accepted) — 50/50 tests, ~4.5 M samples/s, pinned witness cc8de9b01b0ff5bd…
- ADR-092 dashboard implementation (Implemented) — 8/12 §11 gates , 4/12 ⚠ (external infra)
- ADR-093 dashboard gap analysis (Implemented) — 21/21 catalogued gaps closed
- Plus ADR-090 (proposed conditional) and ADR-091 (proposed research-only)

## Live deploy
https://ruvnet.github.io/RuView/nvsim/

## Infra

- nvsim-server Dockerfile + GHCR publish workflow (.github/workflows/nvsim-server-docker.yml)
- axe-core + Playwright cross-browser CI (.github/workflows/dashboard-a11y.yml)
- gh-pages auto-deploy workflow already in place (preserves observatory + pose-fusion siblings)

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-27 12:41:01 -04:00
ruv
905b680747 docs(adr): ADR-084 — promote Proposed → Accepted
Some checks failed
Continuous Integration / Tests-1 (push) Has been cancelled
Continuous Integration / Tests-2 (push) Has been cancelled
Security Scanning / Static Application Security Testing (push) Has been cancelled
Security Scanning / Dependency Vulnerability Scan (push) Has been cancelled
Security Scanning / Container Security Scan (push) Has been cancelled
Security Scanning / Infrastructure Security Scan (push) Has been cancelled
Continuous Integration / Code Quality & Security (push) Has been cancelled
Continuous Integration / Rust Workspace Tests (push) Has been cancelled
Continuous Deployment / Pre-deployment Checks (push) Has been cancelled
Continuous Integration / Tests (push) Has been cancelled
Security Scanning / Secret Scanning (push) Has been cancelled
Security Scanning / License Compliance Scan (push) Has been cancelled
Security Scanning / Security Policy Compliance (push) Has been cancelled
Continuous Deployment / Deploy to Staging (push) Has been cancelled
Continuous Deployment / Deploy to Production (push) Has been cancelled
Continuous Deployment / Rollback Deployment (push) Has been cancelled
Continuous Deployment / Post-deployment Monitoring (push) Has been cancelled
Continuous Deployment / Notify Deployment Status (push) Has been cancelled
Continuous Integration / Performance Tests (push) Has been cancelled
Continuous Integration / Docker Build & Test (push) Has been cancelled
Continuous Integration / API Documentation (push) Has been cancelled
Continuous Integration / Notify (push) Has been cancelled
Security Scanning / Security Report (push) Has been cancelled
All five implementation passes plus four security-review hardenings
shipped in PR #435 (squash-merged as d71ef9a). Acceptance numbers
measured on synthetic AETHER-shape data:

- Compare-cost reduction: 8x-30x floor → 43-51x pair-wise (d=512),
  12.4x top-K (d=128 n=1024 k=8), 7.6x full pipeline (d=128 n=4096 k=8).
- Top-K coverage: ≥90% floor → 90%+ at prefilter_factor=8 (78.9%
  at factor=4 documented as fail; codified in
  test_search_prefilter_topk_coverage_meets_adr_084).
- Wire envelope: 28-byte AETHER 128-d (vs 512-byte raw float; 18x
  compression).

The third acceptance criterion (`< 1 pp end-to-end accuracy regression`)
needs a real-CSI soak test against a multi-day AETHER trace; that's
post-merge follow-up rather than a merge-blocker. Synthetic-data
acceptance was sufficient evidence to ship.

PR #434 (ADR-086 firmware-side gate) merged separately as 17509a2.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-26 02:22:26 -04:00
rUv
d71ef9aefa
docs(adr): ADR-086 — edge novelty gate (proposed) (#434)
Pushes the ADR-084 novelty sensor down into the ESP32 sensor MCU's
Layer 4 (On-device Feature Extraction) of ADR-081's 5-layer kernel:
sketch + 32-slot ring bank in IRAM, suppress UDP send when novelty
< CONFIG_RV_EDGE_NOVELTY_THRESHOLD (default 0.05).

Wire format bumps to magic 0xC5110007 with two new fields
(suppressed_since_last: u16, gate_version: u8) packed in by narrowing
the existing 16-bit quality_flags to 8-bit (only 8 bits were ever
defined). Frame size stays at 60 bytes; v6 receivers fall back
gracefully.

Stuck-gate self-heal at CONFIG_RV_EDGE_MAX_CONSEC_SUPPRESS (default
50 frames ≈ 10 s) so a wedged threshold can't silently disappear a
node. Default-off Kconfig so existing deployments are unaffected.

Validation commitments:
- ≤ 200 µs sketch insert+score on Xtensa LX7
- ≥ 30% UDP TX-energy reduction in steady-state quiet rooms
- ≤ 5 pp drop on cluster-Pi novelty top-K coverage vs unsuppressed
- ≥ 50% bandwidth reduction in stable-room scenarios

Six-pass implementation plan, default-off Kconfig, QEMU + COM7
hardware-in-loop validation. Honest gaps flagged: Xtensa LX7 POPCNT
absence is conjecture (Pass 2 bench is the falsifier); interaction
with ADR-082's Tentative→Active gate is the likeliest weak point
(Open Q4).

ADR-087 / ADR-088 reserved as pointer stubs at end:
- ADR-087: Pass-4 mesh-exchange scope (cluster↔cluster vs sensor→Pi)
- ADR-088: Firmware-release coordination policy

Status: Proposed. SOTA review by goal-planner agent.
2026-04-26 02:21:40 -04:00
rUv
d3020fec6b
docs(adr): ADR-085 — RaBitQ pipeline expansion (proposed) (#433)
Some checks failed
Continuous Deployment / Notify Deployment Status (push) Blocked by required conditions
Continuous Integration / Code Quality & Security (push) Waiting to run
Continuous Integration / Rust Workspace Tests (push) Waiting to run
Continuous Integration / Tests (push) Waiting to run
Continuous Integration / Tests-1 (push) Waiting to run
Continuous Integration / Tests-2 (push) Waiting to run
Continuous Integration / Performance Tests (push) Blocked by required conditions
Continuous Integration / Docker Build & Test (push) Blocked by required conditions
Continuous Integration / API Documentation (push) Blocked by required conditions
Continuous Integration / Notify (push) Blocked by required conditions
Security Scanning / License Compliance Scan (push) Waiting to run
Security Scanning / Security Policy Compliance (push) Waiting to run
Security Scanning / Static Application Security Testing (push) Waiting to run
Security Scanning / Dependency Vulnerability Scan (push) Waiting to run
Security Scanning / Container Security Scan (push) Waiting to run
Security Scanning / Infrastructure Security Scan (push) Waiting to run
Security Scanning / Secret Scanning (push) Waiting to run
Security Scanning / Security Report (push) Blocked by required conditions
Firmware QEMU Tests (ADR-061) / Fuzz Testing (ADR-061 Layer 6) (push) Has been cancelled
Firmware QEMU Tests (ADR-061) / NVS Matrix Generation (push) Has been cancelled
Firmware QEMU Tests (ADR-061) / Build Espressif QEMU (push) Has been cancelled
Verify Pipeline Determinism / Verify Pipeline Determinism (push) Has been cancelled
Firmware QEMU Tests (ADR-061) / QEMU Test (edge-tier0) (push) Has been cancelled
Firmware QEMU Tests (ADR-061) / QEMU Test (edge-tier1) (push) Has been cancelled
Firmware QEMU Tests (ADR-061) / QEMU Test (full-adr060) (push) Has been cancelled
Firmware QEMU Tests (ADR-061) / QEMU Test (tdm-3node) (push) Has been cancelled
Firmware QEMU Tests (ADR-061) / QEMU Test (boundary-max) (push) Has been cancelled
Firmware QEMU Tests (ADR-061) / QEMU Test (boundary-min) (push) Has been cancelled
Firmware QEMU Tests (ADR-061) / QEMU Test (default) (push) Has been cancelled
Firmware QEMU Tests (ADR-061) / Swarm Test (ADR-062) (push) Has been cancelled
Extends ADR-084's RaBitQ-as-similarity-sensor pattern from five sites
to twelve, adding seven additional pipeline locations the user
identified during ADR-084 implementation:

- Per-room adaptive classifier short-circuit (Mahalanobis prefilter)
- Recording-search REST endpoint (GET /api/v1/recordings/similar)
- WiFi BSSID fingerprinting (channel-hop scheduler input)
- mmWave (LD2410 / MR60BHA2) signature wake-gate
- Witness bundle drift detection (CI ratchet)
- Agent / swarm memory routing (ADR-066 swarm bridge)
- Log / event-pattern anomaly detection (cluster Pi)

Each site has a 2-3 sentence decision (what gets sketched, what
triggers the comparison, what the refinement does on miss) and a
witness-hash artifact (what the system stores in place of the raw
embedding/event/signal).

Implementation plan ordered cheapest-first / least-risky-first.
Acceptance criteria align with ADR-084 (8x-30x compare cost,
≥90% top-K coverage, <1pp accuracy regression) where applicable;
non-vector sites (witness bundle, BSSID time-series, event log)
have site-specific criteria.

Three open questions explicitly flagged:
1. Mahalanobis-after-binary-sketch is novel — no published primary
   source found, marked conjecture, decision deferred to bench
2. Canonical "non-vector → sketchable" encoding is unsolved
3. MERIDIAN (ADR-027) cross-environment domain interaction needs
   site-by-site analysis before bank rebuild semantics are committed

Status: Proposed. SOTA review by goal-planner agent.
2026-04-26 00:11:32 -04:00
rUv
c19a33ee1c
docs(adr): ADR-084 — RaBitQ similarity sensor for CSI/pose/memory (proposed) (#429)
Adopt RaBitQ-style binary sketches as a first-class cheap similarity
sensor at four points in the RuView pipeline: AETHER re-ID hot-cache
filter, per-room novelty / drift detection, mesh-exchange compression,
and privacy-preserving event logs. Implementation home is
ruvector-core::quantization::BinaryQuantized (already vendored, already
SIMD-accelerated NEON+POPCNT, 32x compression, 1-bit sign quantization
+ hamming distance), re-exported through a thin RuView-flavored API in
wifi-densepose-ruvector::sketch.

Pattern at every site: dense embedding -> RaBitQ sketch -> hamming
pre-filter to top-K -> full-precision refinement only on miss. Decision
boundary unchanged; sketch is a sensor that gates *which* comparisons
run, not *what* they decide.

Acceptance test (per source proposal):
- sketch compare cost reduction: 8x-30x vs full float
- top-K candidate coverage: >= 90% agreement with full-float pass
- end-to-end accuracy regression: < 1 percentage point

Site-by-site rollback if any criterion fails at a given site;
remaining sites continue. Five implementation passes, each
independently testable: ruvector module wrap, AETHER re-ID pre-filter,
cluster-Pi novelty sensor, mesh-exchange compression, privacy log.

Sensor MCU unchanged; sketches happen at the cluster Pi (ADR-083).
Validation requires acceptance numbers on >= 3 of 5 passes.

Open question (out-of-scope until pass-1 benchmark): whether RuView
embeddings need a Johnson-Lindenstrauss / RaBitQ-paper randomized
rotation before sign-quantization, or whether pure 1-bit sign
quantization (today's BinaryQuantized) is sufficient.
2026-04-25 23:08:05 -04:00
rUv
259939b7ec
docs(adr): ADR-083 — per-cluster Pi compute hop (proposed) (#428)
Adopt one Pi per cluster of 3-6 ESP32-S3 sensor nodes as the canonical
fleet-shape, rather than the full three-tier (dual-MCU + per-node Pi)
shape. Sensor nodes are unchanged from ADR-028 / ADR-081; the cluster
Pi gains the responsibilities the ESP32-S3 cannot carry — pose-grade
ML inference, QUIC backhaul to gateway/cloud, and a cluster-level OTA
+ secure-boot anchor.

The cluster-Pi shape is the L3-hybrid path identified in
docs/research/architecture/decision-tree.md §2 — the cheapest viable
upgrade. The full three-tier shape remains the long-term exploration
target, gated behind no_std CSI maturity (decision-tree L4) and
per-node ISR-jitter evidence (L2).

Status: Proposed. Acceptance gated on:
1. Cross-compile to aarch64 / armv7 with workspace tests passing
2. 3-sensor + 1-Pi field test demonstrating end-to-end CSI → fusion →
   cloud at <=100 ms cluster latency
3. Cluster-Pi SoC choice ADR (decision-tree L6) approved

References:
- docs/research/architecture/three-tier-rust-node.md (seed exploration)
- docs/research/architecture/decision-tree.md (L3 hybrid path)
- docs/research/sota/2026-Q2-rf-sensing-and-edge-rust.md (SOTA evidence)
2026-04-25 23:08:02 -04:00
rUv
81cc241b9e
chore(repo): move v1/ → archive/v1/ + add archive/README.md (#430)
The Rust port at v2/ has been the primary codebase since the rename
in #427. The Python implementation at v1/ is no longer the active
target; the only load-bearing path is the deterministic proof bundle
at v1/data/proof/ (per ADR-011 / ADR-028 witness verification).

Move the whole Python tree into archive/v1/ and document the policy
in archive/README.md: no new features, bug fixes only when they affect
a still-load-bearing path (currently just the proof), CI continues to
verify the proof on every push and PR.

Path references updated in 26 files via path-pattern sed (only
matches v1/<known-child> patterns, never bare v1 or API URLs like
/api/v1/). Two double-prefix typos (archive/archive/v1/) caught and
hand-fixed in verify-pipeline.yml and ADR-011.

Validated:
- Python proof verify.py imports cleanly at archive/v1/data/proof/
  (numpy/scipy still required; CI installs requirements-lock.txt
  from archive/v1/ now)
- cargo test --workspace --no-default-features → 1,539 passed,
  0 failed, 8 ignored (unaffected by Python tree relocation)
- ESP32-S3 on COM7 untouched (no firmware paths changed)

After-merge: contributors should re-run any local `python v1/...`
commands as `python archive/v1/...` (CLAUDE.md and CHANGELOG already
updated).
2026-04-25 23:07:52 -04:00
ruv
5bcb25b2b0 docs(adr): update bare wifi-densepose-rs refs to v2/ in ADR-012, ADR-052
Two leftover references missed by the sed pass in #427 (which only
matched the full `rust-port/wifi-densepose-rs` path). These are bare
references to the workspace directory name, which is now v2/.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-25 21:43:21 -04:00
rUv
f49c722764
chore(repo): rename rust-port/wifi-densepose-rs → v2/ (flatten to one level) (#427)
The Rust port lived two directories deep (rust-port/wifi-densepose-rs/)
without any sibling under rust-port/ that warranted the extra level.
Move the whole workspace up to v2/ to match v1/ (Python) at the same
depth and shorten every cd / build command across the repo.

git mv preserves history for all tracked files. 60 files updated for
path references (CI workflows, ADRs, docs, scripts, READMEs, internal
.claude-flow state). Two manual fixes for relative-cd paths in
CLAUDE.md and ADR-043 that became wrong after the depth change
(cd ../.. → cd ..).

Validated:
- cargo check --workspace --no-default-features → clean (after target/
  nuke; the gitignored target/ was carried by the OS rename and had
  hard-coded old paths in build scripts)
- cargo test --workspace --no-default-features → 1,539 passed, 0 failed,
  8 ignored (same totals as pre-rename)
- ESP32-S3 on COM7 → still streaming live CSI (cb #40300, RSSI -64 dBm)

After-merge follow-up: contributors should `rm -rf v2/target` once and
let cargo regenerate from the new path.
2026-04-25 21:28:13 -04:00
ruv
2a58fe478b docs(research): three-tier Rust node design + 2026-Q2 SOTA survey + decision tree
Three exploratory research documents under docs/research/:

- architecture/three-tier-rust-node.md (3,382 words) — exploration of a
  dual-ESP32-S3 + Pi Zero 2W node architecture with BQ24074 power-path,
  ESP-WIFI-MESH + LoRa fallback + QUIC backhaul, and an esp-hal/Embassy
  vs esp-idf-svc Rust toolchain split. Status: Exploratory — not adopted.

- sota/2026-Q2-rf-sensing-and-edge-rust.md (3,757 words) — twelve-section
  state-of-the-art survey covering WiFi CSI through-wall pose, IEEE 802.11bf
  (ratified 2025-09-26), edge ML on ESP32-class hardware, embedded Rust
  ecosystem maturity (esp-hal 1.x, esp-radio rename, embassy-executor
  ISR-safety on esp-idf-svc), LoRa for sensor mesh fallback, QUIC for IoT
  backhaul, solar power-path management beyond BQ24074, mesh routing
  alternatives, and Pi Zero 2W secure-boot reality.

- architecture/decision-tree.md (1,461 words) — Mermaid decision tree
  mapping each load-bearing decision in the three-tier proposal to its
  dependencies, evidence-for-yes/no, and prospective ADR slot.

No production code, firmware, or ADRs touched. Research-only.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-25 20:41:14 -04:00
rUv
7f201bdf6f
fix(tracker): exclude Lost tracks from bridge output (#420, ADR-082) (#426)
`tracker_bridge::tracker_to_person_detections` documented itself as filtering
to `is_alive()` but never actually filtered — it forwarded every non-Terminated
track to the WebSocket stream. With 3 ESP32-S3 nodes × ~10 Hz CSI, transient
detections that fell outside the Mahalanobis gate created a steady stream of
new Tentative tracks that aged through Active and into Lost. Lost tracks are
kept in the tracker for `reid_window` (~3 s) so re-identification can match
them when a similar detection reappears, but they are NOT currently observed
and must not render as live skeletons. Up to ~90 ghost skeletons could
accumulate at any moment, hence the 22-24 phantoms users saw while
`estimated_persons` correctly reported 1.

Add `PoseTracker::confirmed_tracks()` that returns only `Tentative ∪ Active`
and rewire the bridge to use it. `Lost` tracks remain in the tracker for
re-ID; they just no longer ship to the UI. `active_tracks()` is left
unchanged for the AETHER re-ID consumers (ADR-024).

Regression test `test_lost_tracks_excluded_from_bridge_output` drives a
track to Active, lapses for `loss_misses + 1` ticks to push it to Lost,
and asserts `tracker_update` returns an empty Vec while the Lost track
is still present in `all_tracks()` (re-ID still works).

Validated:
- cargo test --workspace --no-default-features → 1,539 passed, 0 failed
- ESP32-S3 on COM7 still streaming live CSI (cb #32800)
2026-04-25 20:03:03 -04:00
rUv
79477c17a9
fix: restore WSL release build for sensing server (#389)
Some checks failed
Firmware CI / Build ESP32-S3 Firmware (4mb) (push) Has been cancelled
Firmware CI / Build ESP32-S3 Firmware (8mb) (push) Has been cancelled
Firmware QEMU Tests (ADR-061) / Build Espressif QEMU (push) Has been cancelled
Firmware QEMU Tests (ADR-061) / Fuzz Testing (ADR-061 Layer 6) (push) Has been cancelled
Firmware QEMU Tests (ADR-061) / NVS Matrix Generation (push) Has been cancelled
Security Scanning / Static Application Security Testing (push) Has been cancelled
Security Scanning / Dependency Vulnerability Scan (push) Has been cancelled
Security Scanning / Container Security Scan (push) Has been cancelled
Security Scanning / Infrastructure Security Scan (push) Has been cancelled
Security Scanning / Secret Scanning (push) Has been cancelled
Security Scanning / License Compliance Scan (push) Has been cancelled
Security Scanning / Security Policy Compliance (push) Has been cancelled
Continuous Deployment / Deploy to Staging (push) Has been cancelled
Continuous Deployment / Deploy to Production (push) Has been cancelled
Continuous Deployment / Rollback Deployment (push) Has been cancelled
Continuous Deployment / Post-deployment Monitoring (push) Has been cancelled
Continuous Deployment / Notify Deployment Status (push) Has been cancelled
Continuous Integration / Performance Tests (push) Has been cancelled
Continuous Integration / Docker Build & Test (push) Has been cancelled
Continuous Integration / API Documentation (push) Has been cancelled
Continuous Integration / Notify (push) Has been cancelled
Firmware QEMU Tests (ADR-061) / QEMU Test (boundary-max) (push) Has been cancelled
Firmware QEMU Tests (ADR-061) / QEMU Test (boundary-min) (push) Has been cancelled
Firmware QEMU Tests (ADR-061) / QEMU Test (default) (push) Has been cancelled
Firmware QEMU Tests (ADR-061) / QEMU Test (edge-tier0) (push) Has been cancelled
Firmware QEMU Tests (ADR-061) / QEMU Test (edge-tier1) (push) Has been cancelled
Firmware QEMU Tests (ADR-061) / QEMU Test (full-adr060) (push) Has been cancelled
Firmware QEMU Tests (ADR-061) / QEMU Test (tdm-3node) (push) Has been cancelled
Firmware QEMU Tests (ADR-061) / Swarm Test (ADR-062) (push) Has been cancelled
Security Scanning / Security Report (push) Has been cancelled
fix: restore successful WSL release build for rust sensing server
2026-04-20 14:29:15 -04:00
rUv
648ff525a2
docs: troubleshooting guide for ESP32 CSI deployments (#377)
docs: troubleshooting guide for ESP32 CSI deployments
2026-04-20 14:29:11 -04:00
rUv
0943a32248
feat: Real-time dense point cloud from camera + WiFi CSI (#405)
* Add wifi-densepose-pointcloud: real-time dense point cloud from camera + WiFi CSI

New crate with 5 modules:
- depth: monocular depth estimation + 3D backprojection (ONNX-ready, synthetic fallback)
- pointcloud: Point3D/ColorPoint types, PLY export, Gaussian splat conversion
- fusion: WiFi occupancy volume → point cloud + multi-modal voxel fusion
- stream: HTTP + Three.js viewer server (Axum, port 9880)
- main: CLI with serve/capture/demo subcommands

Demo output: 271 WiFi points + 19,200 depth points → 4,886 fused → 1,718 Gaussian splats.
Serves interactive 3D viewer at http://localhost:9880 with Three.js orbit controls.

ADR-SYS-0021 documents the architecture for camera + WiFi CSI dense point cloud pipeline.

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

* Optimize pointcloud: larger splat voxels, smaller responses, faster fusion

- Gaussian splat voxel size: 0.10 → 0.15 (42% fewer splats: 1718 → 994)
- Splat response: 399 KB → 225 KB (44% smaller)
- Pipeline: 22.2ms mean (100 runs, σ=0.3ms)
- Cloud API: 1.11ms avg, 905 req/s
- Splats API: 1.39ms avg, 719 req/s
- Binary: 1.0 MB arm64 (Mac Mini), tested

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

* Complete implementation: camera capture, WiFi CSI receiver, training pipeline

Three new modules added to wifi-densepose-pointcloud:

1. camera.rs — Cross-platform camera capture
   - macOS: AVFoundation via Swift, ffmpeg avfoundation
   - Linux: V4L2, ffmpeg v4l2
   - Camera detection, listing, frame capture to RGB
   - Graceful fallback to synthetic data when no camera

2. csi.rs — WiFi CSI receiver for ESP32 nodes
   - UDP listener for CSI JSON frames from ESP32
   - Per-link attenuation tracking with EMA smoothing
   - Simplified RF tomography (backprojection to occupancy grid)
   - Test frame sender for development without hardware
   - Ready for real ESP32 CSI data from ruvzen

3. training.rs — Calibration and training pipeline
   - Depth calibration: grid search over scale/offset/gamma
   - Occupancy training: threshold optimization for presence detection
   - Ground truth reference points for depth RMSE measurement
   - Preference pair export (JSONL) for DPO training on ruOS brain
   - Brain integration: submit observations as memories
   - Persistent calibration files (JSON)

New CLI commands:
   ruview-pointcloud cameras         # list available cameras
   ruview-pointcloud train           # run calibration + training
   ruview-pointcloud csi-test        # send test CSI frames
   ruview-pointcloud serve --csi     # serve with live CSI input

All tested: demo, training (10 samples, 4 reference points, 3 pairs),
CSI receiver (50 test frames), server API.

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

* Fix viewer: replace WebSocket with fetch polling

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

* Wire live camera into server — real-time updating point cloud

- Server captures from /dev/video0 at 2fps via ffmpeg
- Background tokio task refreshes cloud + splats every 500ms
- Viewer polls /api/splats every 500ms, only updates on new frame
- Shows 🟢 LIVE / 🔴 DEMO indicator
- Camera position set for first-person view (looking forward into scene)
- Downsample 4x for performance (19,200 points per frame)
- Graceful fallback to demo data if camera capture fails

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

* Add MiDaS GPU depth, serial CSI reader, full sensor fusion

- MiDaS depth server: PyTorch on CUDA, real monocular depth estimation
- Rust server calls MiDaS via HTTP for neural depth (falls back to luminance)
- Serial CSI reader for ESP32 with motion detection + presence estimation
- CSI disabled by default (RUVIEW_CSI=1 to enable) — serial reader needs baud config
- Edge-enhanced depth for better object boundaries
- All sensors wired: camera, ESP32 CSI, mmWave (CSI gated until serial fixed)

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

* Complete 7-component sensor fusion pipeline (all working)

1. ADR-018 binary parser — decodes ESP32 CSI UDP frames, extracts I/Q subcarriers
2. WiFlow pose — 17 COCO keypoints from CSI (186K param model loaded)
3. Camera depth — MiDaS on CUDA + luminance fallback
4. Sensor fusion — camera depth + CSI occupancy grid + skeleton overlay
5. RF tomography — ISTA-inspired backprojection from per-node RSSI
6. Vital signs — breathing rate from CSI phase analysis
7. Motion-adaptive — skip expensive depth when CSI shows no motion

Live results: 510 CSI frames/session, 17 keypoints, 26% motion, 40 BPM breathing.
Both ESP32 nodes provisioned to send CSI to 192.168.1.123:3333.
Magic number fix: supports both 0xC5110001 (v1) and 0xC5110006 (v6) frames.

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

* Add brain bridge — sparse spatial observation sync every 60s

Stores room scan summaries, motion events, and vital signs
in the ruOS brain as memories. Only syncs every 120 frames
(~60 seconds) to keep the brain sparse and optimized.

Categories: spatial-observation, spatial-motion, spatial-vitals.

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

* Update README + user guide with dense point cloud features

Added pointcloud section to README (quick start, CLI, performance).
Added comprehensive user guide section: setup, sensors, commands,
pipeline components, API endpoints, training, output formats,
deep room scan, ESP32 provisioning.

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

* Add ruview-geo: geospatial satellite integration (11 modules, 8/8 tests)

New crate with free satellite imagery, terrain, OSM, weather, and brain integration.

Modules: types, coord, locate, cache, tiles, terrain, osm, register, fuse, brain, temporal
Tests: 8 passed (haversine, ENU roundtrip, tiles, HGT parse, registration)
Validation: real data — 43.49N 79.71W, 4 Sentinel-2 tiles, 2°C weather, brain stored

Data sources (all free, no API keys):
- EOX Sentinel-2 cloudless (10m satellite tiles)
- SRTM GL1 (30m elevation)
- Overpass API (OSM buildings/roads)
- ip-api.com (geolocation)
- Open Meteo (weather)

ADR-044 documents architecture decisions.
README.md in crate subdirectory.

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

* Update ADR-044: add Common Crawl WET, NASA FIRMS, OpenAQ, Overture Maps sources

Extended geospatial data sources leveraging ruvector's existing web_ingest
and Common Crawl support for hyperlocal context.

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

* Fix OSM/SRTM queries, add change detection + night mode

- OSM: use inclusive building filter with relation query and 25s timeout
- SRTM: switch to NASA public mirror with viewfinderpanoramas fallback
- Add detect_tile_changes() for pixel-diff satellite change detection
- Add is_night() solar-declination model for CSI-only night mode
- 6 new unit tests (night mode + tile change detection)

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

* Enhance viewer: skeleton overlay, weather, buildings, better camera

Add COCO skeleton rendering with yellow keypoint spheres and white bone
lines, info panel sections for weather/buildings/CSI rate/confidence,
overhead camera at (0,2,-4), and denser point size with sizeAttenuation.

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

* Add CSI fingerprint DB + night mode detection

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

* Fix ADR-044 numbering conflict, update geo README

Renumbered provisioning tool ADR from 044 to 050 to avoid conflict
with geospatial satellite integration ADR-044.

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

* Clean up warnings: suppress dead_code for conditional pipeline modules

Removes unused imports/variables via cargo fix and adds #[allow(dead_code)]
for modules used conditionally at runtime (CSI, depth, fusion, serial).
Pointcloud: 28 → 0 warnings. Geo: 2 → 0 warnings. 8/8 tests pass.

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

* Fix PR #405 blockers: async runtime panic, crate rename, path traversal, brain URL config

- brain_bridge.rs: replace `Handle::current().block_on(...)` inside async fn
  with `.await` (was a guaranteed "runtime within runtime" panic). Brain URL
  now read from RUVIEW_BRAIN_URL env var (default http://127.0.0.1:9876),
  logged once via OnceLock.
- wifi-densepose-geo: rename Cargo package from `ruview-geo` to
  `wifi-densepose-geo` to match directory and workspace conventions. Update
  all use sites (tests/examples/README). Same env-var pattern for brain URL
  in brain.rs + temporal.rs.
- training.rs: add sanitize_data_path() rejecting `..` components and
  safe_join() that canonicalises + enforces base-dir containment on every
  write (calibration.json, samples.json, preference_pairs.jsonl,
  occupancy_calibration.json). Defence-in-depth check also in main.rs
  before TrainingSession::new.
- osm.rs: clamp Overpass radius to MAX_RADIUS_M=5000m; return Err beyond
  that. Add parse_overpass_json() that rejects malformed payloads
  (missing top-level `elements` array).

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

* csi_pipeline: rename WiFlow stub to heuristic_pose_from_amplitude, decouple UDP

Blocker 3 (PR #405 review): The "WiFlow inference" path was a stub that
built a model from empty weight vectors and synthesised keypoints from
amplitude energy. Presenting this as "WiFlow inference" was misleading.

- Rename WiFlowModel to PoseModelMetadata (empty tag struct; we only care
  if the on-disk file exists)
- Rename load_wiflow_model() -> detect_pose_model_metadata() and log
  "amplitude-energy heuristic enabled/disabled" (no "WiFlow" claim)
- Rename estimate_pose() -> heuristic_pose_from_amplitude() with
  prominent `STUB:` doc comment saying this is NOT a trained model

Blocker 4 (PR #405 review): The UDP receiver held the shared Arc<Mutex>
across a synchronous process_frame() call, starving HTTP handlers.

- Introduce a std::sync::mpsc channel between the UDP thread (which only
  parses + pushes) and a dedicated processor thread (which locks only
  briefly around a single process_frame). HTTP snapshots via
  get_pipeline_output no longer contend with the socket read loop.

Also:
- Move ADR-018 parser to parser.rs (see next commit); csi_pipeline re-exports
- send_test_frames now uses parser::build_test_frame for synthetic frames
- Log a one-line node stats summary every 500 frames (reads every public
  CsiFrame field on the runtime path)

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

* Extract ADR-018 parser into parser.rs + wire Fingerprint CLI

File-split (strong concern #9 in PR #405 review): csi_pipeline.rs was 602
LOC; extract the pure-function ADR-018 parser + synthetic frame builder
into src/parser.rs. Inline unit tests in parser.rs cover:

- 0xC5110001 (raw CSI, v1) roundtrip
- 0xC5110006 (feature state, v6) roundtrip
- wrong magic is rejected
- truncated header is rejected
- truncated payload is rejected

main.rs: expose `fingerprint NAME [--seconds N]` subcommand wiring
record_fingerprint() (this was the only caller needed to make the public
API non-dead on the runtime path). Also:

- Replace `--host/--port` + external `--csi` with a single `--bind`
  defaulting to loopback (`127.0.0.1:9880`) — addresses strong concern
  #7 about exposing camera/CSI/vitals by default.
- Update synthetic `csi-test` to target UDP 3333 (matching the ADR-018
  listener) and use the shared parser::build_test_frame.
- Defence-in-depth: call training::sanitize_data_path on the expanded
  --data-dir before TrainingSession::new does the same.

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

* stream: extract viewer HTML to viewer.html, default bind to loopback

Strong concern #7 (PR #405): default HTTP bind leaked camera/CSI/vitals
to the LAN. The `serve` fn now takes a single `bind` arg and prints a
loud WARNING when bound outside loopback.

Strong concern #10 (PR #405): embedded HTML+JS was ~220 LOC of the 418
LOC stream.rs. Moved the markup verbatim into viewer.html and inlined
via `include_str!("viewer.html")`. Also:

- Drop the #![allow(dead_code)] crate-level silencing (reviewer point
  #11). Remove the now-unused AppState.csi_pipeline field.
- capture_camera_cloud_with_luminance returns the mean luminance of the
  captured frame; the background loop feeds that to
  CsiPipelineState::set_light_level so the night-mode flag actually
  toggles at runtime (previously it could only be set from tests).

Net effect on file size: stream.rs 418 → 232 LOC.

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

* Dead-code cleanup + tests for fusion/depth/OSM/training/fingerprinting

Reviewer point #11 (PR #405): remove the `#![allow(dead_code)]`
silencing added in 8eb808d and fix the underlying issues.

- Delete csi.rs: duplicate of csi_pipeline.rs with incompatible wire
  format (JSON vs ADR-018 binary). csi_pipeline is the real path.
- Delete serial_csi.rs: never referenced by any module.
- Drop Frame.timestamp_ms (unread), AppState.csi_pipeline (unread),
  brain_bridge::brain_available (caller-less), fusion::fetch_wifi_occupancy
  (caller-less) — these had no runtime users.
- Drop crate-level #![allow(dead_code)] from camera.rs, depth.rs,
  fusion.rs, pointcloud.rs.

Tests (target: 8-12, actual: 15 unit + 9 geo unit + 8 geo integration
= 32 total, all pass):

- parser.rs: 5 tests (v1/v6 magic roundtrip, wrong magic, truncated
  header, truncated payload).
- fusion.rs: 2 tests (non-overlapping merge, voxel dedup).
- depth.rs: 2 tests (2x2 backproject → 4 points at z=1, NaN rejected).
- training.rs: 4 tests (rejects `..`, accepts relative child, refuses
  TrainingSession::new("../etc/passwd"), accepts a clean tmpdir).
- csi_pipeline.rs: 2 tests (set_light_level toggles is_dark,
  record_fingerprint stores and self-identifies).
- osm.rs: 3 tests (parse_overpass_json minimal fixture, rejects
  malformed payload, fetch_buildings rejects > MAX_RADIUS_M).

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

* Update README + user-guide for PR #405 review-fix additions

- serve now uses --bind 127.0.0.1:9880 (loopback default) instead of --port
- Add fingerprint subcommand to CLI tables
- Document RUVIEW_BRAIN_URL env var + --brain flag
- Flag pose path as amplitude-energy heuristic stub (not trained WiFlow)
- Security note on exposing server outside loopback
- Add wifi-densepose-pointcloud + wifi-densepose-geo rows to crate table

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-20 12:48:54 -04:00
rUv
5a7f431b0e
ADR-081: Implement 5-layer adaptive CSI mesh firmware kernel (#404)
* ADR-081: adaptive CSI mesh firmware kernel + scaffolding

Introduces a 5-layer firmware kernel that reframes the existing ESP32
modules as components of a chipset-agnostic architecture and authorizes
adaptive control + a compact feature-state stream as the default upstream.

Layers:
  L1 Radio Abstraction Layer  — rv_radio_ops_t vtable + ESP32 binding
  L2 Adaptive Controller      — fast/medium/slow loops (200ms/1s/30s)
  L3 Mesh Sensing Plane       — anchor/observer/relay/coordinator (spec)
  L4 On-device Feature Extr.  — rv_feature_state_t (magic 0xC5110006)
  L5 Rust handoff             — feature_state default; debug raw gated

Files:
  docs/adr/ADR-081-adaptive-csi-mesh-firmware-kernel.md  (new)
  firmware/esp32-csi-node/main/rv_radio_ops.h            (new)
  firmware/esp32-csi-node/main/rv_radio_ops_esp32.c      (new)
  firmware/esp32-csi-node/main/rv_feature_state.{h,c}    (new)
  firmware/esp32-csi-node/main/adaptive_controller.{h,c} (new)
  firmware/esp32-csi-node/main/main.c                    (wire L1+L2)
  firmware/esp32-csi-node/main/CMakeLists.txt            (add 4 sources)
  firmware/esp32-csi-node/main/Kconfig.projbuild         (controller knobs)
  CHANGELOG.md                                           (Unreleased)

Default policy is conservative: enable_channel_switch and
enable_role_change are off, so behavior matches today's firmware
unless an operator opts in via menuconfig. The pure
adaptive_controller_decide() is exposed for offline unit tests.

Reuses (does not rewrite): csi_collector, edge_processing (ADR-039),
swarm_bridge (ADR-066), secure_tdm (ADR-032), wasm_runtime (ADR-040).

* ADR-081: implement Layers 1/2/4 end-to-end + host tests + QEMU hooks

Turns the ADR-081 scaffolding into a working adaptive CSI mesh kernel:
Layer 1 radio abstraction has an ESP32 binding and a mock binding; Layer 2
adaptive controller runs on FreeRTOS timers; Layer 4 feature-state packet
is emitted at 5 Hz by default, replacing raw ADR-018 CSI as the default
upstream.

New files:
  firmware/esp32-csi-node/main/adaptive_controller_decide.c  (pure policy)
  firmware/esp32-csi-node/main/rv_radio_ops_mock.c           (QEMU binding)
  firmware/esp32-csi-node/tests/host/Makefile                (host tests)
  firmware/esp32-csi-node/tests/host/test_adaptive_controller.c
  firmware/esp32-csi-node/tests/host/test_rv_feature_state.c
  firmware/esp32-csi-node/tests/host/esp_err.h               (shim)
  firmware/esp32-csi-node/tests/host/.gitignore

Modified:
  adaptive_controller.c         — includes pure decide.c; emit_feature_state()
                                  wired into fast loop (200 ms = 5 Hz)
  rv_radio_ops_esp32.c          — get_health() fills pkt_yield + send_fail
  csi_collector.{c,h}           — pkt_yield/send_fail accessors (ADR-081 L1)
  rv_feature_state.h            — packed size corrected to 60 bytes
                                  (was incorrectly 80 in initial commit)
  main.c                        — mock binding registered under mock CSI
  CMakeLists.txt                — rv_radio_ops_mock.c under CSI_MOCK_ENABLED
  scripts/validate_qemu_output.py — 3 new ADR-081 checks (17/18/19)
  docs/adr/ADR-081-*.md         — status → Accepted (partial);
                                  implementation-status matrix; measured
                                  benchmarks (decide 3.2 ns, CRC32 614 ns);
                                  bandwidth 300 B/s @ 5 Hz (99.7% vs raw);
                                  verification section
  CHANGELOG.md                  — artifact-level entries

Tests (host, gcc -O2 -std=c11):
  test_adaptive_controller:  18/18 pass, decide() = 3.2 ns/call
  test_rv_feature_state:     15/15 pass, CRC32(56 B) = 614 ns/pkt, 87 MB/s
                             sizeof(rv_feature_state_t) == 60 asserted
                             IEEE CRC32 known vectors verified

Deferred (tracked in ADR-081 roadmap Phase 3/4):
  Layer 3 mesh-plane message types, role-assignment FSM, Rust-side mirror
  trait in crates/wifi-densepose-hardware/src/radio_ops.rs.

* ADR-081: Layer 3 mesh plane + Rust mirror trait — all 5 layers landed

Fully implements the remaining deferred pieces of the adaptive CSI mesh
firmware kernel. All 5 layers (Radio Abstraction, Adaptive Controller,
Mesh Sensing Plane, On-device Feature Extraction, Rust handoff) are
now implemented and host-tested end-to-end.

Layer 3 — Mesh Sensing Plane (firmware/esp32-csi-node/main/rv_mesh.{h,c}):
  * 4 node roles: Unassigned / Anchor / Observer / FusionRelay / Coordinator
  * 7 message types: TIME_SYNC, ROLE_ASSIGN, CHANNEL_PLAN,
    CALIBRATION_START, FEATURE_DELTA, HEALTH, ANOMALY_ALERT
  * 3 auth classes: None / HMAC-SHA256-session / Ed25519-batch
  * Payload types: rv_node_status_t (28 B), rv_anomaly_alert_t (28 B),
    rv_time_sync_t (16 B), rv_role_assign_t (16 B),
    rv_channel_plan_t (24 B), rv_calibration_start_t (20 B)
  * 16-byte envelope + payload + IEEE CRC32 trailer
  * Pure rv_mesh_encode()/rv_mesh_decode() plus typed convenience encoders
  * rv_mesh_send_health() + rv_mesh_send_anomaly() helpers

Controller wiring (adaptive_controller.c):
  * Slow loop (30 s default) now emits HEALTH
  * apply_decision() emits ANOMALY_ALERT on transitions to ALERT /
    DEGRADED
  * Role + mesh epoch tracked in module state; epoch bumps on role
    change

Layer 5 — Rust mirror (crates/wifi-densepose-hardware/src/radio_ops.rs):
  * RadioOps trait mirrors rv_radio_ops_t vtable
  * MockRadio backend for offline tests
  * MeshHeader / NodeStatus / AnomalyAlert types mirror rv_mesh.h
  * Byte-identical IEEE CRC32 (poly 0xEDB88320) verified against
    firmware test vectors (0xCBF43926 for "123456789")
  * decode_mesh / decode_node_status / decode_anomaly_alert / encode_health
  * 8 unit tests, including mesh_constants_match_firmware which asserts
    MESH_MAGIC/VERSION/HEADER_SIZE/MAX_PAYLOAD match rv_mesh.h
    byte-for-byte
  * Exported from lib.rs
  * signal/ruvector/train/mat crates untouched — satisfies ADR-081
    portability acceptance test

Tests (all passing):
  test_adaptive_controller:   18/18   (C, decide() 3.2 ns/call)
  test_rv_feature_state:      15/15   (C, CRC32 87 MB/s)
  test_rv_mesh:               27/27   (C, roundtrip 1.0 µs)
  radio_ops::tests (Rust):     8/8
  --- total:                 68/68 assertions green ---

Docs:
  * ADR-081 status flipped to Accepted
  * Implementation-status matrix updated; L3 + Rust mirror both
    marked Implemented
  * Benchmarks table extended with rv_mesh encode+decode roundtrip
  * Verification section updated with cargo test invocation
  * CHANGELOG: two new entries for L3 mesh plane + Rust mirror

Remaining follow-ups (Phase 3.5 polish, not blocking):
  * Mesh RX path (UDP listener + dispatch) on the firmware
  * Ed25519 signing for CHANNEL_PLAN / CALIBRATION_START
  * Hardware validation on COM7

* Add test_rv_mesh to host-test .gitignore

Fixes an untracked-file warning from the repo stop-hook: the compiled
binary was built by make but the .gitignore update was missed in
8dfb031. No source changes.

* Fix implicit decl of emit_feature_state in adaptive_controller

fast_loop_cb calls emit_feature_state() at line 224, but the static
definition is at line 256. GCC treats the implicit declaration as
non-static, then the real static definition conflicts, and
-Werror=all promotes both to hard build errors.

Add a forward declaration above the first use. Unblocks ESP32-S3
firmware build and all QEMU matrix jobs.

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-20 10:38:23 -04:00
bilibili12433014
1871ef3c2d docs(user-guide): add Linux desktop build prerequisites for Rust builds
- add Debian/Ubuntu desktop build prerequisites to the Rust source build guide
- document required GTK/WebKit development packages for Linux release builds
- add a matching troubleshooting entry for native desktop build dependencies
- keep installation and troubleshooting guidance aligned and context-consistent
2026-04-16 16:58:12 +08:00
Deploy Bot
b74fdcc733 docs: add troubleshooting guide for common ESP32 CSI issues
Covers 8 known issues encountered during multi-node ESP32-S3 deployments:
1. Node not appearing (limping state after USB flash)
2. Person count stuck at 1 (ADR-044)
3. Heart rate/breathing rate jitter (last-write-wins from multiple nodes)
4. Signal quality placeholder
5. Dashboard freezing (WS disconnect loop)
6. OTA crash at 59% (BLE vs OTA conflict)
7. SSH LAN hang (Tailscale workaround)
8. USB-C port selection

Helps with #268 (no nodes found), #375 (node_id), #366 (build errors).
2026-04-10 07:04:48 -04:00
ruv
ccb27b280c merge: bring feat/adr-080-qe-remediation up to date with main
Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-06 18:36:20 -04:00
ruv
599ea61a17 docs: update README and user guide for v0.7.0 camera-supervised training
- Add v0.7.0 section with 92.9% PCK@20 result and new scripts
- Add camera-supervised training section to user guide with step-by-step
- Update release table (v0.7.0 as latest)
- Update ADR count (62 → 79)
- Update beta notice with camera ground-truth link

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-06 17:52:44 -04:00
ruv
924c32547e fix: ADR-080 P0 security + CI remediation from QE analysis
Address all 5 P0 issues from QE analysis (55/100 score):

- P0-1: Rate limiter bypass — validate X-Forwarded-For against trusted proxy list
- P0-2: Exception detail leak — generic 500 messages, exception_type gated by dev mode
- P0-3: WebSocket JWT in URL (CWE-598) — first-message auth pattern replaces query param
- P0-4: Rust tests not in CI — add rust-tests job gating docker-build and notify
- P0-5: WebSocket path mismatch — use WS_PATH constant instead of hardcoded /ws/sensing

Includes ADR-080 remediation plan and 9 QE reports (4,914 lines).
Firmware validated on ESP32-S3 (COM8): CSI collecting, calibration OK.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-06 16:12:13 -04:00
ruv
d09baa6a09 fix: remove hardcoded Tailscale IPs and usernames from public files
- ADR-079: strip SSH user/IP from optimization description
- mac-mini-train.sh: replace hardcoded IP with env var WINDOWS_HOST

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-06 14:39:21 -04:00
ruv
486392bb68 docs: update ADR-079 with validated hardware, ruvector optimizations, baseline
- Status: Proposed → Accepted
- Add O6-O10 optimizations (subcarrier selection, attention, Stoer-Wagner
  min-cut, multi-SPSA, Mac M4 Pro training via Tailscale)
- Add validated hardware table (Mac camera, MediaPipe, M4 Pro GPU, Tailscale)
- Add baseline benchmark results (PCK@20: 35.3%)
- Update implementation plan with completion status

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-06 14:38:40 -04:00
ruv
e3522ddcda feat: camera ground-truth training pipeline (ADR-079, #362)
Add 4 scripts for camera-supervised WiFlow pose training:

- collect-ground-truth.py: synchronized webcam + CSI capture via
  MediaPipe PoseLandmarker (17 COCO keypoints at 30fps)
- align-ground-truth.js: time-align camera keypoints with CSI windows
  using binary search, confidence-weighted averaging
- train-wiflow-supervised.js: 3-phase supervised training (contrastive
  pretrain → supervised keypoint regression → bone-constrained
  refinement) with curriculum learning and CSI augmentation
- eval-wiflow.js: PCK@10/20/50, MPJPE, per-joint breakdown, baseline
  proxy mode for benchmarking

Baseline benchmark (proxy poses, no camera supervision):
  PCK@10: 11.8% | PCK@20: 35.3% | PCK@50: 94.1% | MPJPE: 0.067

Camera pipeline validated over Tailscale to Mac Mini M4 Pro
(1920x1080, 14/17 keypoints visible, MediaPipe confidence 0.94-1.0).

Target after camera-supervised training: PCK@20 > 50%

Closes #362

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-06 14:07:25 -04:00
ruv
b3fd0e2951 docs: add HuggingFace models, 17 sensing apps, v0.6.0 to README + user guide
README:
- New "Pre-Trained Models" section with HuggingFace download link
- Model table (safetensors, q4, q2, presence head, LoRA adapters)
- Updated benchmarks (0.008ms, 164K emb/s, 51.6% contrastive)
- "17 Sensing Applications" section (health, environment, multi-freq)
- v0.6.0 in release table as Latest

User guide:
- "Pre-Trained Models" section with quick start + huggingface-cli
- What the models do (presence, fingerprinting, anomaly, activity)
- Retraining instructions
- "Health & Wellness Applications" section with all 4 health scripts
- Medical disclaimer

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-03 10:28:29 -04:00
ruv
4fc491dea5 feat: ADR-078 — 5 multi-frequency mesh applications
RF tomography (2D backprojection imaging), passive bistatic radar
(neighbor APs as illuminators), frequency-selective material
classification (metal/water/wood/glass), through-wall motion
detection (per-channel penetration weighting), device fingerprinting
(RF emission signatures per SSID)

All impossible with single-channel WiFi — require 6-channel hopping.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-03 08:52:50 -04:00
ruv
4f6780f884 feat: ADR-077 — 6 novel RF sensing applications
Sleep monitor (hypnogram + efficiency), apnea detector (AHI scoring),
stress monitor (HRV + LF/HF via FFT), gait analyzer (cadence + tremor),
material detector (null pattern classification), room fingerprint
(k-means clustering + anomaly scoring)

All validated on overnight data (113K frames). Pure Node.js, zero deps.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-03 08:50:48 -04:00
ruv
28368b2c70 feat: ADR-076 CNN spectrogram embeddings + graph transformer fusion
CSI-as-image: 64x20 subcarrier×time matrix → 224x224 → CNN → 128-dim
embedding. Same-node similarity 0.95+, cross-node 0.6-0.8.

- csi-spectrogram.js: WASM CNN embedding, ASCII visualization, Seed ingest
- mesh-graph-transformer.js: GATv2 multi-head attention over ESP32 mesh,
  fuses multi-node features, generalizes to 3+ nodes

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-03 00:36:38 -04:00
ruv
4bb8c3303f feat: ADR-075 min-cut person separation — fixes #348
Stoer-Wagner min-cut on subcarrier correlation graph replaces broken
threshold-based person counting (was always 4, now correct).

Validated: 24/24 windows correctly report 1 person on test data
where old firmware reported 4. Pure JS, <5ms per window.

- mincut-person-counter.js: live UDP + JSONL replay, overrides vitals
- csi-graph-visualizer.js: ASCII spectrum + correlation heatmap
- ADR-075: algorithm, comparison, migration path

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-03 00:34:57 -04:00
ruv
b9778c5ad2 feat: ADR-074 spiking neural network for real-time CSI sensing
128→64→8 SNN with STDP online learning — adapts to room in <30s
without labels. Event-driven: 16-160x less compute than FC encoder.

- snn-csi-processor.js: live UDP with ASCII visualization, EWMA
- ADR-073 updated with SNN integration for multi-channel fusion
- Fixed magic number parsing to use ADR-018 format (0xC5110001)

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-03 00:34:31 -04:00
ruv
b4c9e7743f feat: ADR-073 multi-frequency mesh RF scanning
Live RF room scanner with ASCII spectrum visualization:
- rf-scan.js: single-channel scanner with null/dynamic/reflector classification,
  cross-node correlation, phase coherence, Unicode spectrum display
- rf-scan-multifreq.js: wideband view merging 6 channels, null diversity,
  per-channel penetration quality, frequency-dependent scatterer detection
- benchmark-rf-scan.js: null diversity gain, spectrum flatness, resolution estimate

Validated: 228 frames in 5s, 23 fps/node, 19% nulls detected,
0.993 cross-node correlation, line-of-sight confirmed

ADR-073: interleaved channel hopping (Node 1: ch 1/6/11, Node 2: ch 3/5/9)
targets 6x subcarrier diversity, <5% null gap, ~15cm resolution

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-03 00:18:29 -04:00
ruv
8f2de7e9f2 feat: ADR-072 WiFlow SOTA architecture — TCN + axial attention + pose decoder
Pure JS implementation of WiFlow (arXiv:2602.08661) adapted for ESP32:
- TCN temporal encoder (dilated causal conv, k=7, dilation 1/2/4/8)
- Asymmetric spatial encoder (1x3 residual blocks, stride-2)
- Axial self-attention (width + height, 8 heads, 256 channels)
- Pose decoder (adaptive pooling → 17x2 COCO keypoints)
- SmoothL1 + bone constraint loss (14 skeleton connections)
- 1.8M params (1.6 MB at INT8), 198M FLOPs

Integrated with camera-free pipeline (pose proxy labels from
RSSI triangulation + subcarrier asymmetry + vibration)

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-02 23:40:23 -04:00
ruv
74c965f7ec docs: remove HuggingFace publishing section from user guide
Contains GCloud project ID and secret names — not appropriate for
a public repo. Publishing instructions kept in scripts/ only.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-02 23:14:20 -04:00
ruv
73d4cb9fc2 docs: update README + user guide with v0.5.4 capabilities
README:
- Test badge 1300+ → 1463
- Updated capability table (171K emb/s, 100% presence, 0.012ms)
- Added "What's New in v0.5.4" section with full benchmark table
- Training pipeline quick start commands

User guide:
- Camera-Free Pose Training section (10 sensor signals, 5-phase pipeline)
- ruvllm Training Pipeline section (5 phases, quantization options)
- Publishing to HuggingFace section
- Updated table of contents

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-02 23:11:30 -04:00
ruv
ba82fcfc37 feat: camera-free 17-keypoint pose training (10 sensor signals)
Multi-modal pipeline using PIR, BME280, reed switch, vibration,
RSSI triangulation, subcarrier asymmetry — no camera needed.

Phases: multi-modal collection → weak label generation → enhanced
contrastive → 5-keypoint pose proxy → 17-keypoint interpolation
→ self-refinement (3 rounds) → LoRA + TurboQuant + EWC

Validated: 2,360 frames, 100% presence, 0 skeleton violations,
82.8 KB model (8 KB at 4-bit), 114.8s training

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-02 23:05:07 -04:00
ruv
a73a17e264 feat: ADR-071 ruvllm training pipeline — contrastive + LoRA + TurboQuant
5-phase training pipeline using ruvllm (Rust-native, no PyTorch):
1. Contrastive pretraining (triplet + InfoNCE, 5 triplet strategies)
2. Task head training (presence, activity, vitals via SONA)
3. Per-node LoRA refinement (rank-4, room-specific adaptation)
4. TurboQuant quantization (2/4/8-bit, 6-8x compression)
5. EWC consolidation (prevent catastrophic forgetting)

Exports: SafeTensors, HuggingFace config, RVF, per-node LoRA, quantized
Validated: 249 triplets, 37,775 emb/s, 100% presence accuracy on test data
Target: <5 min training on M4 Pro, <10ms inference on Pi Zero

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-02 22:27:24 -04:00
ruv
9a2bc1839a feat: HuggingFace model publishing pipeline + model card
- publish-huggingface.sh: retrieves HF token from GCloud Secrets,
  uploads models to ruvnet/wifi-densepose-pretrained
- publish-huggingface.py: Python alternative with --dry-run support
- docs/huggingface/MODEL_CARD.md: beginner-friendly model card with
  WiFi sensing explanation, quick start code, hardware BOM, and citation

GCloud Secret: HUGGINGFACE_API_KEY in project cognitum-20260110

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-02 22:04:16 -04:00
ruv
77a2e7e4e9 docs: add Cognitum Seed pretraining tutorial (530 lines)
Some checks are pending
Continuous Deployment / Post-deployment Monitoring (push) Blocked by required conditions
Continuous Deployment / Notify Deployment Status (push) Blocked by required conditions
Continuous Integration / Tests (push) Waiting to run
Continuous Integration / Tests-1 (push) Waiting to run
Continuous Integration / Tests-2 (push) Waiting to run
Continuous Integration / Code Quality & Security (push) Waiting to run
Continuous Integration / Performance Tests (push) Blocked by required conditions
Continuous Integration / Docker Build & Test (push) Blocked by required conditions
Continuous Integration / API Documentation (push) Blocked by required conditions
Continuous Integration / Notify (push) Blocked by required conditions
Firmware CI / Build ESP32-S3 Firmware (push) Waiting to run
Firmware QEMU Tests (ADR-061) / Swarm Test (ADR-062) (push) Blocked by required conditions
Firmware QEMU Tests (ADR-061) / Build Espressif QEMU (push) Waiting to run
Firmware QEMU Tests (ADR-061) / QEMU Test (boundary-max) (push) Blocked by required conditions
Firmware QEMU Tests (ADR-061) / QEMU Test (boundary-min) (push) Blocked by required conditions
Firmware QEMU Tests (ADR-061) / QEMU Test (default) (push) Blocked by required conditions
Firmware QEMU Tests (ADR-061) / QEMU Test (edge-tier0) (push) Blocked by required conditions
Firmware QEMU Tests (ADR-061) / QEMU Test (edge-tier1) (push) Blocked by required conditions
Firmware QEMU Tests (ADR-061) / QEMU Test (full-adr060) (push) Blocked by required conditions
Firmware QEMU Tests (ADR-061) / QEMU Test (tdm-3node) (push) Blocked by required conditions
Firmware QEMU Tests (ADR-061) / Fuzz Testing (ADR-061 Layer 6) (push) Waiting to run
Firmware QEMU Tests (ADR-061) / NVS Matrix Generation (push) Waiting to run
Security Scanning / Static Application Security Testing (push) Waiting to run
Security Scanning / Dependency Vulnerability Scan (push) Waiting to run
Security Scanning / Container Security Scan (push) Waiting to run
Security Scanning / Infrastructure Security Scan (push) Waiting to run
Security Scanning / Secret Scanning (push) Waiting to run
Security Scanning / License Compliance Scan (push) Waiting to run
Security Scanning / Security Policy Compliance (push) Waiting to run
Security Scanning / Security Report (push) Blocked by required conditions
Step-by-step guide covering hardware setup, Seed pairing, 2-node ESP32
provisioning, bridge operation, 6-scenario data collection protocol,
feature vector explanation, kNN queries, troubleshooting, and next steps.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-02 20:49:05 -04:00