yggvault ratatoskr-space connected via regular web
Color theme
also available via yggdrasil mesh http://[203:b338:2a84:a18f:986:47ae:1a4:d8d3]/pkg/ruview/v1647
vault / ruview / v1647

ruview @ v1647

integrity

size
61.2 MiB
downloaded
last checked
source https://github.com/ruvnet/RuView · available · github

release notes

Automated release from CI pipeline

Changes: feat: per-room calibration system (ADR-151) + cognitum-v0 appliance integration spec (#989)

Room-first calibration -> bank of small specialised ruVector models (breathing, heartbeat, restlessness, posture, presence, anomaly) distilled from the frozen Hugging-Face-published RF Foundation Encoder (ADR-150).

Four-stage local-first pipeline: baseline (ADR-135 environmental fingerprint) -> guided enrollment (NEW EnrollmentProtocol, clean anchors not hours) -> feature extraction (reuse signal_features + ruvsense) -> specialist bank training (rapid_adapt LoRA heads, RVF storage, HNSW prototypes).

Invariants: specialisation over scale; local heads over a shared public base; honest STALE degradation on baseline drift. Indexes ADR-149/150/151.

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

Adds wifi-densepose calibrate-serve — an Axum HTTP API that wraps the ADR-135 CalibrationRecorder so a UI (or any client) can drive an empty-room baseline capture remotely. Stage 1 ("teach the room") of the ADR-151 room calibration & training pipeline.

A single background task owns the UDP socket (ESP32 0xC511_0001 frames) and the optional active recorder; HTTP handlers talk to it over an mpsc command channel and read a shared status snapshot, keeping the &mut recorder lock-free. CORS permissive so a browser UI can call it.

Endpoints (/api/v1/calibration/*): GET /health liveness + UDP ingest stats (frames_seen, streaming) POST /start { tier?, duration_s?, room_id?, min_frames? } GET /status live progress (state, frames, progress, z, eta) — poll for UI POST /stop finalize the current session early GET /result finalized baseline summary (amp/phase-dispersion averages) GET /baselines list persisted baseline .bin files

Reuses the existing calibrate.rs ESP32 wire parser (made pub(crate)); honest abort when <10 frames arrive in the window (e.g. ESP32 not streaming).

Verified end-to-end over loopback: start -> 300 replayed HT20 frames -> state=complete, 52-subcarrier baseline, phase_dispersion_avg=0.00096 (concentrated/valid), persisted to disk; all 6 endpoints exercised. CLI: 19 tests pass; crate builds clean.

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

Windows Defender blocks inbound LAN UDP to a freshly-built binary without an admin allow-rule; python.exe is already allowed. This relay binds the public CSI port and forwards each datagram verbatim to a loopback port where calibrate-serve --udp-bind 127.0.0.1 --udp-port 5006 listens (loopback is firewall-exempt). No admin required.

Validated: ESP32-format 0xC5110001 frames -> :5005 -> relay -> :5006 -> calibrate-serve -> state=complete, 52-subcarrier baseline, phase_dispersion_avg=0.00098 (clean). Completes the no-admin live-test path.

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

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

New crate wifi-densepose-calibration implementing the per-room pipeline beyond Stage-1 baseline:

Statistical heads make the pipeline runnable/validatable today; the ADR-150 HF RF Foundation Encoder backbone is the documented upgrade path. 29 unit tests pass.

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

Integrates the wifi-densepose-calibration crate into the CLI as four subcommands driving the full Stage 2–5 pipeline against a live ESP32 raw-CSI stream (edge_tier=0):

Per-frame scalar is the mean CSI amplitude (carries presence/motion + breathing modulation). Validated end-to-end on the live ESP32 (COM8, edge_tier=0): the real parser → feature extraction → runtime detected breathing (~16–31 BPM) on hardware. Full multi-anchor enrollment accuracy requires the operator to perform the poses; phase-based breathing extraction is a noted refinement.

48 tests pass (29 calibration + 19 CLI).

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

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

The max-variance-subcarrier carrier locked onto motion artifacts (not breathing) and also had an out-of-bounds bug on variable CSI subcarrier counts. Reverted to the mean-amplitude carrier, which is validated live to detect breathing. Phase-based extraction on a stable subcarrier remains the proper higher-SNR refinement (ADR-151 §4).

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

MultiNodeMixture fuses several co-located nodes (each with its own room-calibrated SpecialistBank) into one RoomState:

Same-room multistatic only; cross-room is federation (ADR-105), not fusion. 6 unit tests (presence OR, best-confidence breathing, single-node veto, staleness). 35 calibration tests pass.

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

room-watch --node-bank N:path (repeatable) groups live CSI frames by node_id and fuses per-node banks via MultiNodeMixture. Validated live on COM8 (node 9, edge_tier=0): frames grouped + fused end-to-end. True 2-node fusion is covered by unit tests; a second raw-CSI node is the hardware blocker. 54 tests pass.

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

Detailed cross-repo integration spec for cognitum-one/v0-appliance: data contracts (CSI wire format, ADR-135 baseline binary, enrollment/bank/RoomState JSON schemas), calibrate-serve HTTP API, public crate API, Pi5+Hailo tiering, and a 5-step appliance integration plan. Grounded in the verified cognitum-v0 inventory (aarch64, cargo 1.96, HAILO10H, ruview-vitals-worker:50054).

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

Resolves the review on #989:

35 calibration + 15 CLI tests (no-default) / 20 CLI (default) pass.

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

Plain-language overviews + feature lists, comparison tables (symbolic graph vs predictive occupancy; graph vs grid vs event-log), usage, and technical details. Adds readme = "README.md" to both manifests so they render on crates.io on the next release.

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

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

Aligns ADR-151 §7 + the appliance integration doc with the PR #989 scope clarification: nothing has run a clean baseline → enroll → train → infer on live CSI; the live breathing read used the stateless head, not a trained bank. Adds --source-format adr018v6 to the backlog.

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

Adds a live RoomState readout over HTTP — the appliance UI's main need. The ingest task maintains a rolling per-frame scalar window (flushed on the 200 ms tick, no per-frame lock); the handler loads a bank (resolved as a sanitized name under output_dir — same path-traversal defense as room_id), runs the MixtureOfSpecialists over the window, returns RoomState JSON.

Validated live (ESP32-S3 via relay): breathing 14-19 BPM over HTTP; a bank=../../etc/passwd query is neutralized to 'etcpasswd' (no traversal).

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

Validated live (ESP32-S3): POST train (4 anchors → 6 specialists, persisted) → GET /room/state returns RoomState with the trained presence/restlessness; the synthetic-vs-real scale mismatch correctly triggers the anomaly veto. 36 calibration tests pass.

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

Closes the last HTTP gap — the appliance can now drive the ENTIRE calibration pipeline over HTTP without the CLI: baseline (start/stop) -> enroll/anchor x8 -> room/train -> room/state

Validated live (ESP32-S3): capture baseline -> enroll stand_still (271 frames, 6s) -> gate correctly rejects "no person detected (presence_z 0.90 < 1.50)" relative to a same-occupancy baseline (a clean empty-room baseline is the documented on-target prerequisite). Builds clean; CLI tests pass.

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

Factor the router into build_router() (shared by execute + tests) and add tower-oneshot integration tests (no network/ingest needed):

CI regression coverage for the endpoints added this session. 18 CLI tests pass.

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

Making wifi-densepose-mat optional in the CLI (for the aarch64/ort decouple) exposed a latent feature bug: mat's api module compiles unconditionally and uses serde, but serde was an optional dep enabled only via the api/serde features. Previously the CLI's unconditional mat dependency enabled those features transitively, so --workspace --no-default-features still got serde; once mat became optional+gated, the workspace build lost it → error[E0432]: unresolved import serde across mat's api/* (CI red).

mat already pulls serde_json + axum unconditionally, so making serde non-optional has no real cost and restores the workspace build. Does NOT affect the aarch64 CLI build (mat isn't built there at all): verified cargo tree -p wifi-densepose-cli --no-default-features still shows 0 ort/openssl deps, and cargo test --workspace --no-default-features compiles clean.

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

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

Records the 2026-06-10 deep-research run (22 sources, 110 claims, 25 adversarially verified: 24 confirmed / 1 refuted) and the decisions it implies:

Every number is evidence-graded CLAIMED vs MEASURED in the source register. Re-check horizon 2026-12.

Co-Authored-By: RuFlo ruv@ruv.net

Closes the software half of PR #989's headline validation gap: the complete calibration loop had never run end-to-end anywhere, even in-process. tests/full_loop.rs (412 lines, deterministic xorshift32 room simulator, HT20/52-subcarrier/20Hz, same fingerprint family as the ADR-135 roundtrip test) now drives the CLI's exact stage order through the public API:

  1. baseline — 600 static frames, zero motion flags post-warmup, calibration_uuid() exactly as the CLI derives it
  2. enroll — all 8 AnchorLabel::SEQUENCE anchors through AnchorQualityGate::default(), session is_complete()
  3. extract — AnchorFeature::from_series recovers injected 0.25Hz and 0.125Hz breathing within ±0.04Hz
  4. train — SpecialistBank::train fits all 6 specialists; JSON round-trip and the runtime consumes the RELOADED bank
  5. infer — positive: never-enrolled 0.30Hz subject reads present, 18±2 BPM; negative: empty window reads absent; degradation: foreign baseline_id flags STALE

Seed-robust (5 seeds), passes with and without default features: 36 unit + 1 integration green.

Validation docs updated (ADR-151 §7 + integration doc §7 matrix): what remains is strictly the on-target hardware session (real CSI, physically empty room, operator performing the guided anchors). Three behavioral findings from building the test are recorded for pre-session triage: z-band squeeze between baseline motion flagging (z>2.0) and the still- anchor gate (presence_z≥1.5) — likeliest on-hardware enroll failure; variance-only PresenceSpecialist missing motionless-person mean shift; ungated breathing_hz/heart_hz in noise-window embeddings.

Co-Authored-By: RuFlo ruv@ruv.net

The full-loop integration test surfaced three findings; fixing the third exposed a fourth. All four are fixed and regression-guarded:

  1. z-band squeeze (enrollment.rs) — anchor motion is now measured from frame-to-frame deltas of the deviation series (|Δz| > Z_DELTA_MOTION 0.5 ∨ |Δφ| > π/6), not from the absolute motion_flagged, which fires at amplitude_z_median > 2.0 vs the EMPTY baseline and so conflated presence strength with motion. A strongly-reflecting still person (z = 3.0 — every frame flagged by the old heuristic) now enrolls. The old unit tests mocked (z=3.0, motion=false), a combination the real deviation() can never emit — which is exactly how the squeeze hid; tests now derive the flag from z the way the producer does.

  2. variance-only presence (specialist.rs) — PresenceSpecialist gains a mean-shift channel: present when variance > threshold OR |mean − empty_mean| > mean_dist_threshold (trained at half the empty→occupied mean distance, None when the means don't separate). Detects the motionless person whose body raises the scalar mean but not its variance. Old persisted banks deserialize with the channel inert (serde default None) — variance-only behavior preserved, proven by a fixture test against pre-change JSON.

  3. ungated hz embedding (extract.rs) — Features::embedding() zeroes breathing_hz/heart_hz below EMBED_MIN_SCORE (0.25), keeping the random in-band peaks of noise windows out of the posture/anomaly prototype space. Raw fields stay ungated (specialists have their own stricter gates).

  4. heart-band lag-floor leakage (extract.rs, found while fixing 3) — a pure 0.30 Hz breathing signal scored 0.67 in the heart band at 3.33 Hz: out-of-band rhythm leaks as a monotonic slope whose max sits at the band's lag floor, so score gating alone cannot stop it. autocorr_dominant now requires the winning lag to be an interior local maximum; band-edge "peaks" are rejected, true in-band peaks (interior by definition) are preserved.

full_loop.rs strengthened to drive the fixes end-to-end: the StandStill anchor is now a z=3.0 strong reflector (unenrollable pre-fix), and a new motionless-person runtime case proves mean-channel detection at empty- level variance.

Validation: 41 calibration unit + 1 full-loop integration + 23 CLI tests green; cargo test --workspace --no-default-features exit 0.

Co-Authored-By: RuFlo ruv@ruv.net

Docker Image: ghcr.io/ruvnet/RuView:2a307138f2350e61fbee42ff105a2f3e286655ae

download

unix · zip
curl -fL -o v1647.zip https://ratatoskr.space/pkg/ruview/v1647.zip
                    printf '%s  %s\n' 'a847db49cd3389ce0400a34f56ddaadaff7c4fb37eab077d6519ecc0c06c6c99' 'v1647.zip' | sha256sum -c -
windows · zip
$url = "https://ratatoskr.space/pkg/ruview/v1647.zip"
$out = "v1647.zip"
Invoke-WebRequest -Uri $url -OutFile $out
if ((Get-FileHash $out -Algorithm SHA256).Hash.ToLowerInvariant() -ne "a847db49cd3389ce0400a34f56ddaadaff7c4fb37eab077d6519ecc0c06c6c99") { throw "sha256 mismatch" }
unix · tar.gz
curl -fL -o v1647.tar.gz https://ratatoskr.space/pkg/ruview/v1647.tar.gz
                    printf '%s  %s\n' '2ec48aaaa9dd9f487b83a7b86dcd3614fbf03c273073a014bc2377e587cd6cf6' 'v1647.tar.gz' | sha256sum -c -
windows · tar.gz
$url = "https://ratatoskr.space/pkg/ruview/v1647.tar.gz"
$out = "v1647.tar.gz"
Invoke-WebRequest -Uri $url -OutFile $out
if ((Get-FileHash $out -Algorithm SHA256).Hash.ToLowerInvariant() -ne "2ec48aaaa9dd9f487b83a7b86dcd3614fbf03c273073a014bc2377e587cd6cf6") { throw "sha256 mismatch" }
download via yggdrasil mesh
unix · zip
curl -fL -o v1647.zip http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/ruview/v1647.zip
                    printf '%s  %s\n' 'a847db49cd3389ce0400a34f56ddaadaff7c4fb37eab077d6519ecc0c06c6c99' 'v1647.zip' | sha256sum -c -
windows · zip
$url = "http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/ruview/v1647.zip"
$out = "v1647.zip"
Invoke-WebRequest -Uri $url -OutFile $out
if ((Get-FileHash $out -Algorithm SHA256).Hash.ToLowerInvariant() -ne "a847db49cd3389ce0400a34f56ddaadaff7c4fb37eab077d6519ecc0c06c6c99") { throw "sha256 mismatch" }
unix · tar.gz
curl -fL -o v1647.tar.gz http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/ruview/v1647.tar.gz
                    printf '%s  %s\n' '2ec48aaaa9dd9f487b83a7b86dcd3614fbf03c273073a014bc2377e587cd6cf6' 'v1647.tar.gz' | sha256sum -c -
windows · tar.gz
$url = "http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/ruview/v1647.tar.gz"
$out = "v1647.tar.gz"
Invoke-WebRequest -Uri $url -OutFile $out
if ((Get-FileHash $out -Algorithm SHA256).Hash.ToLowerInvariant() -ne "2ec48aaaa9dd9f487b83a7b86dcd3614fbf03c273073a014bc2377e587cd6cf6") { throw "sha256 mismatch" }
artifact format size hashes
v1647.zip zip 61.2 MiB
blake3-24 4adc81ff59146540b4bb7872cde650cc3c5d948a63ec9613
sha256 a847db49cd3389ce0400a34f56ddaadaff7c4fb37eab077d6519ecc0c06c6c99
sha1 1ac349c0c8350c90182f488c2f082e0fc7fef642
v1647.tar.gz tar.gz 59.4 MiB
blake3-24 665a66230815f4223dbfae9e803ab0831afa6869e7a4e56a
sha256 2ec48aaaa9dd9f487b83a7b86dcd3614fbf03c273073a014bc2377e587cd6cf6
sha1 e972bcb9f3a24f31c4fd887a1916cd732e209cc3

install

bazel
http_archive(
    name = "ruview",
    urls = ["https://ratatoskr.space/pkg/ruview/v1647.tar.gz"],
    integrity = "sha256-LsSKqqndn0h7g6e4bc02FPvwPCcwc6AUvCN35YfNbPY=",
    strip_prefix = "ruview-v1647",
)
zig
.url = "https://ratatoskr.space/pkg/ruview/v1647.tar.gz",
install via yggdrasil mesh
bazel
http_archive(
    name = "ruview",
    urls = ["http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/ruview/v1647.tar.gz"],
    integrity = "sha256-LsSKqqndn0h7g6e4bc02FPvwPCcwc6AUvCN35YfNbPY=",
    strip_prefix = "ruview-v1647",
)
zig
.url = "http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/ruview/v1647.tar.gz",
← v0.8.0-esp32v1613 →