Skip to content

Releases: ruvnet/RuView

v0.8.3-esp32 — multistatic + csi_fps + control-packet fixes

Choose a tag to compare

@ruvnet ruvnet released this 27 Jun 17:22
c0d3d7c

ESP32-S3 CSI node firmware v0.8.3-esp32 — bug-fix release.

Fixed

  • #1170 — multistatic fusion DimensionMismatch flood. The live sensing-server bridge fed raw, un-canonicalized per-node CSI (HT20≈64 / HT40≈128/192 bins) into MultistaticFuser, so fusion errored every cycle on a mixed mesh and silently fell back to per-node sum/dedup. Node frames are now resampled onto the canonical 56-tone grid (resample-only, no z-score) before fusion.
  • #1180csi_fps_ema inflated 40–840×. Sub-millisecond UDP burst arrivals (36 µs → ~27 kHz) polluted the per-node frame-rate EMA. A 5 ms plausibility floor now rejects burst deltas, and the arrival anchor is kept across bursts so the next genuine gap measures true cadence.
  • #1183 — ENOMEM backoff starved control packets. Under a weak uplink the global CSI backoff also suppressed the ≤48 B/≤1 Hz feature_state/HEALTH/sync packets. A new priority send path bypasses the backoff gate (without touching the streak) for those control packets; the misleading "HEALTH sent" log now reports the real send result.

Tooling

  • Added scripts/firmware-release-guard.sh (#1194): regenerates the expected partition table from the variant's CSV and byte-compares it to the built partition-table.bin (+ flash-size cross-check), failing closed so a release can't ship a partition table that doesn't match its flash-size variant.

Verification (MEASURED)

  • wifi-densepose-signal: 501 passed, 0 failed
  • wifi-densepose-sensing-server: 677 passed, 0 failed
  • Firmware: both variants build clean (ESP-IDF v5.4); release guard PASS for 8MB (partitions_display.csv) and 4MB (partitions_4mb.csv).
  • Hardware smoke test PASS — flashed the 8MB build to an ESP32-S3 (QFN56 rev v0.2, the #1116 board); booted clean, streamed real WiFi CSI (mixed len=128/len=384, RSSI −42…−59), emitted HEALTH/feature_state via the #1183 priority path, mesh time-sync fail=0, and no #1116 edge_dsp watchdog crash over the capture. Note: #1183 starvation needs a weak (~−78 dBm) uplink to trigger; strong-RSSI bench run shows no regression but does not reproduce that specific condition.

Binaries

File Variant SHA-256
esp32-csi-node-s3-8mb.bin 8MB/common ed825c52468e8ecf1cfd14417914d9e2b6acd2b1489bd60168d2559ee3ba6c88
esp32-csi-node-s3-4mb.bin 4MB 94c547a033448b437a65659bbcd8c81616d5e5d83990a9f7829625a5581bad66
bootloader.bin 8MB/common 74f90ff55a097539d788bef133c6fd2b13ee85f53b1e07f23d65de2d2f63941d
ota_data_initial.bin 8MB/common 7d2c7ac4888bfd75cd5f56e8d61f69595121183afc81556c876732fd3782c62f
partition-table.bin 8MB/common 67222c257c0477501fd4002275638dc4262b34eb68235b8289fb1337054d322b
partition-table-4mb.bin 4MB 4c2cc4ffd52641e23b779bd57b3908014083ac3c1aab395756478c89e70d81f0

ESP32-S3 v0.8.2-esp32 — phantom LD2410 + ENOMEM fix (#1135)

Choose a tag to compare

@ruvnet ruvnet released this 22 Jun 16:51
7831f29

ESP32-S3 CSI node firmware — fixes the #1135 phantom-LD2410 + sendto ENOMEM loop reported against v0.8.1-esp32.

Fixes (#1135)

  • Phantom LD2410 on a floating UART (root cause). Probe-detection matched only the 4-byte head 0xF4F3F2F1, so line noise at 256000 baud on an unconnected UART1 could phantom-detect a sensor and spawn a UART task. Now requires a full validated report frame (head + sane intra-frame length + matching tail 0xF8F7F6F5) — the same validate-before-trust gate used for MR60BHA2 in v0.8.1. Extracted to mmwave_detect.h and covered by a host unit test (test_mmwave_detect.c).
  • sendto ENOMEM stuck loop. The fixed 100 ms backoff was too short to drain sustained lwIP/WiFi buffer pressure. Now exponential (100→200→…→2000 ms per consecutive ENOMEM, reset on first successful send). Removing the phantom LD2410 task also removes the extra load that tipped tier-2 nodes into the stuck state.

Validation

  • All CI green (firmware s3-8mb/4mb + c6, all QEMU configs, fuzzing, security scans).
  • Host unit test: the #1135 case (head magic without valid tail) is REJECTED.
  • Hardware (ESP32-S3 QFN56 rev v0.2): streams clean at tier-0 and tier-2, correctly reports no mmWave (no phantom), no regression.
  • Caveat: the reporter's environment-specific floating-pin noise could not be reproduced on the bench, so the deterministic proof for the phantom case is the unit test. If you hit #1135, please confirm this build clears it.

Flashing (ESP32-S3)

esptool --chip esp32s3 -p <PORT> -b 460800 write_flash \
  0x0 bootloader.bin  0x8000 partition-table.bin \
  0xf000 ota_data_initial.bin  0x20000 esp32-csi-node-s3-8mb.bin

4MB boards: esp32-csi-node-s3-4mb.bin @ 0x20000, partition-table-4mb.bin @ 0x8000.

SHA-256

d1dd4143…ee24f7d  esp32-csi-node-s3-8mb.bin
958fdd68…a686fcc  esp32-csi-node-s3-4mb.bin
4c402ce4…714da509  bootloader.bin
67222c25…054d322b  partition-table.bin
4c2cc4ff…e70d81f0  partition-table-4mb.bin
7d2c7ac4…3782c62f  ota_data_initial.bin

App version 0.7.0 · ESP-IDF v5.4 · built from main @ 7831f29.

ESP32-S3 v0.8.1-esp32 — display + mmwave false-detect fixes (#1000, #1107)

Choose a tag to compare

@ruvnet ruvnet released this 17 Jun 16:03
65e29ef

ESP32-S3 CSI node firmware — two field-reported sensing bugs fixed and validated on real hardware (ESP32-S3 QFN56 rev v0.2, 8MB flash / 2MB PSRAM).

Fixes

  • #1000 — no CSI on a bare/display-less DevKit. The SH8601 QSPI AMOLED is write-only, so panel init "succeeds" even with no panel attached; that false-positive left display_is_active() true and starved CSI at MGMT-only frames. Now the readable FT3168 touch controller gates it: no touch readback → run headless → CSI upgrades to MGMT+DATA. (PR #1121)
  • #1107 — false MR60BHA2 detection → ENOMEM. UART probe now requires a validated MR60 header (8-byte SOF + checksum + type 0x0A__/0x0F09) instead of counting bare 0x01 bytes, so an empty UART no longer false-detects a sensor. (PR #1119)

Hardware validation (boot log, rev v0.2 silicon)

disp_hal: SH8601 panel init OK (368x448)            # write-only panel "succeeds" on bare board
disp_hal: FT3168 not found (ret=ESP_FAIL)           # touch readback fails — no real panel
disp_task: ... running headless so CSI captures (#1000)
csi_collector: CSI filter upgraded to MGMT+DATA (no display, RuView#893)
mmwave: No mmWave sensor detected (CSI-only mode)   # no false detect on empty UART

CSI streamed cleanly (frames len 128→384/256), 600 callbacks / 22s, zero crash or watchdog.

Flashing

ESP32-S3, esptool offsets:

esptool --chip esp32s3 -p <PORT> -b 460800 write_flash \
  0x0 bootloader.bin  0x8000 partition-table.bin \
  0xf000 ota_data_initial.bin  0x20000 esp32-csi-node-s3-8mb.bin

4MB (no-display) boards: use esp32-csi-node-s3-4mb.bin @ 0x20000 and partition-table-4mb.bin @ 0x8000.

SHA-256

0a66190d…36822  esp32-csi-node-s3-8mb.bin
b818e358…f6e7c2  esp32-csi-node-s3-4mb.bin
dda279df…d8a216  bootloader.bin
67222c25…4d322b  partition-table.bin
4c2cc4ff…0d81f0  partition-table-4mb.bin
7d2c7ac4…82c62f  ota_data_initial.bin

App version 0.7.0 · ESP-IDF v5.4 · built from main @ 65e29ef. Binaries are the exact bytes flashed during hardware validation.

Release v1770

Choose a tag to compare

@github-actions github-actions released this 14 Jun 17:01
f250149

Automated release from CI pipeline

Changes:
feat(ADR-262 P1): wifi-densepose-rufield bridge — RuView sensing → signed RuField FieldEvents (fail-closed privacy map) (#1070)

  • feat(rufield): ADR-262 P1 — wifi-densepose-rufield anti-corruption bridge

New v2 workspace member that converts RuView WiFi-CSI sensing output into
signed RuField FieldEvents. Path-deps the vendor/rufield submodule crates
(rufield-core/-provenance/-privacy/-fusion); single coupling point between
RuView and the standalone RuField MFS spec (ADR-262 §5.4).

  • SensingSnapshot: owned primitives mirroring SensingUpdate + TrustedOutput
    (no dependency on wifi-densepose-sensing-server).
  • snapshot_to_field_event(): builds a WifiCsi FieldTensor + Observation,
    derives a real position from the signal-field peak (never fabricated),
    real sha256 provenance + ed25519 signature (synthetic=false).
  • map_privacy() (§3.3 crux): maps by information content, NEVER byte value —
    Derived (byte 1) → P4/P5, never P1; fail-closed demotion floor to P2.

P1 gates (tests/p1_gates.rs): round-trip serde, is_fusable verified receipt,
RuFieldFusion::ingest accept + infer runs, privacy-safety (Derived never P1),
full §3.3 table, fail-closed demotion, determinism, no-fabricated-position.
15 tests pass (5 unit + 9 integration + 1 doc), 0 failed.

Honesty: P1 plumbing (tested conversion + safe privacy mapping), NOT wired
into the live server (P3) and NOT an accuracy claim.

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

  • docs(adr-262): mark P1 implemented + CI submodules:recursive + CHANGELOG/CLAUDE
  • ADR-262 Status → "Proposed — P1 implemented"; add §0.1 Implementation
    status (the bridge crate + the five P1 gates that pass; defers the
    provenance-carrier reuse, P3 live wiring, and P4 multi-modality).
  • ci.yml: add submodules: recursive to the rust-tests checkout so the new
    crate's vendor/rufield path-deps resolve in CI (they fail otherwise even
    though the workspace build passes locally with the submodule present).
  • CHANGELOG [Unreleased]: P1 bridge entry (kept alongside the upstream
    ADR-262 research entry).
  • CLAUDE.md: crate table row for wifi-densepose-rufield.

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

Docker Image:
ghcr.io/ruvnet/RuView:f250149e94148d3f9b6a01a004c074178413cc2c

Release v1767

Choose a tag to compare

@github-actions github-actions released this 14 Jun 16:16
faca053

Automated release from CI pipeline

Changes:
docs(adr-262): RuField↔RuView integration design (Proposed) (#1069)

Researched integration ADR: thin wifi-densepose-rufield bridge crate
(rvcsi pattern), live SensingServerAdapter emitting signed FieldEvents,
vertical fusion composition (ruvsense within-WiFi → rufield cross-modal),
and ONE canonical privacy/provenance model (RuView effective_class →
RuField P0-P5 at egress; reuse cog-ha-matter SHA-256+Ed25519 receipt).
Key finding: RuView has 2 privacy enums + 3 witness mechanisms; the
Derived(byte=1)<Anonymous(byte=2)-but-carries-identity trap means the
bridge must map by information content, not byte value. Plumbing
architecture, not accuracy (real-CSI is unlabeled replay today).

Co-authored-by: ruv ruvnet@gmail.com

Docker Image:
ghcr.io/ruvnet/RuView:faca0530defc1599ae0be96308046740d466f509

Release v1765

Choose a tag to compare

@github-actions github-actions released this 14 Jun 15:59
6f6c867

Automated release from CI pipeline

Changes:
feat(rufield): CsiReplayAdapter — first real WiFi-CSI adapter (submodule bump) (#1068)

Bumps vendor/rufield to include CsiReplayAdapter: RuField now ingests real
captured WiFi CSI (.csi.jsonl) → FieldTensor → CSI-variance motion/presence
proxy → signed FieldEvents → fusion. Measured on 199 real frames: 182 fused
inferences (115 breathing, 67 person_present) from real signal. Replay-from-file,
unlabeled (proxy not validated accuracy) — live streaming + labeled accuracy
remain roadmap; mmWave/thermal stay synthetic.

Co-authored-by: ruv ruvnet@gmail.com

Docker Image:
ghcr.io/ruvnet/RuView:6f6c8676296481bd5928a5a3e26735ed28299f86

Release v1762

Choose a tag to compare

@github-actions github-actions released this 14 Jun 15:23
95a5ecc

Automated release from CI pipeline

Changes:
feat(rufield): rufield-viewer dashboard — completes ADR-260 §27.9 (#1067)

Bumps the vendor/rufield submodule to include the new rufield-viewer crate
(Axum + vanilla JS read-only dashboard streaming the deterministic
SyntheticSim→fusion camera-free room-intelligence demo: live room state,
P0–P5 privacy-badged event log, fusion graph, signed-receipt viewer, behind
a permanent SYNTHETIC banner). All ADR-260 §27 criteria 1–10 now PASS.
Read-only demo viewer, not device management (real-adapter milestone later).
rufield repo now 7 crates / 72 tests.

Co-authored-by: ruv ruvnet@gmail.com

Docker Image:
ghcr.io/ruvnet/RuView:95a5ecc746f018e3222f72c470b5d84cfdb40ac3

Release v1759

Choose a tag to compare

@github-actions github-actions released this 14 Jun 14:44
1f05456

Automated release from CI pipeline

Changes:
feat(ADR-261 M2): multi-bit + large-N ANN scaling study — measured, no crossover (refutes M1 prediction) (#1066)

  • feat(ADR-261): multi-bit (b∈{1,2,4}) quantized HNSW traversal + scaling harness

Generalize the SymphonyQG-style quantized-traversal HNSW from 1-bit Hamming to a
b-bit-per-dimension code (b ∈ {1,2,4}), mirroring ADR-156 §10's multi-bit RaBitQ
scheme (rotate via FHT Pass-2, uniform mid-rise scalar quantizer over [-3,3],
ranked by per-dim L1). b=1 is byte-for-byte the original construction (codes in
{0,1} ⇒ L1 == Hamming), pinned by one_bit_build_bits_matches_legacy_build.
Bytes/node scales linearly: 128-d → 16/32/64 B for b=1/2/4.

  • hnsw_quantized.rs: QuantizedHnswIndex::build_bits(...,bits,...), bits()/
    bytes_per_node() accessors, code-L1 greedy+beam traversal. build(...) kept as
    the b=1 backward-compatible entry point. +4 tests (multi-bit recall regression,
    bits clamp, bytes/node, legacy parity).
  • ann_measure.rs: build_indices_bits / build_quant_bits / run_scaling_study +
    best_float_op / best_quant_op; scaling_report (#[ignore], --release) and a
    CI-safe scaling_study_small_is_consistent.
  • ann_bench.rs: 2-bit and 4-bit quant criterion benches over the shared graph.

ruvector lib 151 → 156 passed, 0 failed, 1 ignored (scaling_report).

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

  • docs(adr-261): record M2 multi-bit scaling study — measured, no crossover (refutes M1 prediction)

Multi-bit (b∈{1,2,4}) quantized HNSW traversal + N∈{10k,100k,250k} scaling study,
measured on this box. No crossover at any (N,b): at 10k more bits help (ratio
0.19→0.48×, b≥2 reaches 0.90 recall) but quant stays slower than float HNSW at
equal recall; at 100k/250k quant recall collapses (b=4: 1.0→0.788→0.624, never
≥0.90) while float holds ≥0.92. The predicted large-N crossover moved the wrong
way. Published negative with the mechanism explained. ADR-261 §11.

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


Co-authored-by: ruv ruvnet@gmail.com

Docker Image:
ghcr.io/ruvnet/RuView:1f05456588ccccc03ef487b76959e2685425f02a

Release v1753

Choose a tag to compare

@github-actions github-actions released this 14 Jun 06:46
f756a8a

Automated release from CI pipeline

Changes:
feat(ADR-261): ruvector HNSW graph-ANN (25x measured vs linear) + honest SymphonyQG-direction refutation (#1063)

  • feat(ruvector): real float HNSW + SymphonyQG-style quantized-traversal index (ADR-261)

Adds the graph-ANN index the ruvector retrieval path was missing (ADR-156
§5 #1 noted there was no HNSW baseline to measure SymphonyQG against).

  • hnsw.rs: correct float HNSW (Malkov & Yashunin) — multi-layer NSW graph,
    ef_construction/ef_search, Algorithm-4 neighbour selection, seeded-
    deterministic level assignment (SplitMix64, reused from rotation.rs),
    L2 + cosine, brute-force ground truth, full degenerate-case guards.
    recall@10 correctness gate >=0.95 vs brute force (L2 + cosine).
  • hnsw_quantized.rs: SymphonyQG-style variant — same graph, traversal scored
    by cheap 1-bit Hamming over the RaBitQ Pass-2 rotated sign code, final
    exact-float rerank.
  • ann_measure.rs: shared deterministic planted-cluster fixture + recall/QPS
    measurement (ann_bench_report is the ADR source of truth).

Fixes an index-out-of-bounds bug the recall gate caught: insert wired
bidirectional edges before pushing the node's own link row. +20 tests,
ruvector lib 131->151, 0 failed.

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

  • bench(ruvector): criterion ann_bench for HNSW vs quantized vs linear (ADR-261)

Times the same shared ann_measure fixture/indices through criterion so the
bench and the report test can never measure different graphs.

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

  • docs(adr-261): graph-ANN index ADR with MEASURED HNSW vs quantized verdict

ADR-261 (Accepted): float HNSW ~25x QPS over linear scan at recall >=0.99
(the baseline ADR-156 said was missing). Honest negative: the 1-bit
quantized traversal is too coarse to beat float HNSW at equal recall at
N=10k (best recall 0.738, no >=0.90 equal-recall point) — the SymphonyQG
3.5-17x is NOT reproduced by our 1-bit construction; expected crossover at
large N + a multi-bit code. Caveat: our HNSW + our quant, not SymphonyQG's
system — direction tested, not a 1:1 reproduction.

ADR-156 §5 #1 + §8 backlog: CLAIMED -> MEASURED-direction-tested.
CHANGELOG [Unreleased] entry.

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

Docker Image:
ghcr.io/ruvnet/RuView:f756a8af493a960a5217e39776685668bcdf19ad

Release v1749

Choose a tag to compare

@github-actions github-actions released this 14 Jun 05:25
261ce80

Automated release from CI pipeline

Changes:
feat(adr-260): RuField MFS spec + vendor/rufield submodule (#1061)

ADR-260 (Accepted — v0.1 reference stack): RuField, the open specification
for camera-free multimodal field sensing — one FieldEvent/FieldTensor/
FusionGraph/PrivacyClass/ProvenanceReceipt model above WiFi CSI/CIR/BFLD,
UWB, BLE Channel Sounding, mmWave radar, ultrasound, subsonic, infrared,
and quantum sensors.

Published standalone as github.com/ruvnet/rufield and vendored here as the
vendor/rufield submodule (the vendor/rvcsi pattern — not a v2/ workspace
member). v0.1 reference stack: 6 crates, 60 tests/0 failed, clippy-clean.
All benchmark metrics SYNTHETIC (simulator ground truth, no hardware).

Co-authored-by: ruv ruvnet@gmail.com

Docker Image:
ghcr.io/ruvnet/RuView:261ce80a72c6ffd285f1e7c59b43b113110fd996