Use mesh-aligned capture timestamps, remediate Rust advisories, harden the audit gate, and correct deployment claims. Includes the live MQTT subscriber lifetime fix verified against Mosquitto.
New leaf crate v2/crates/ruview-offaxis implementing ADR-324's projection
core from the published math only (Kooima 2008 generalized perspective
projection; Casiez 2012 one-euro filter) — no code from the unlicensed
prior-art repo. Dependency-free native core; wasm-bindgen surface gated to
wasm32 (cdylib+rlib, ~54 KB wasm after bindgen).
- projection: Screen (3 corners, any orientation) + off_axis() -> typed
errors, never NaN matrices; column-major f64 (three.js Matrix4 layout).
Tests pin the defining invariants: screen corners -> NDC corners for a
grid of eye positions and tilted screens; screen-plane points are
eye-invariant; centered eye reduces to the symmetric frustum; near/far
map to NDC -1/+1.
- filter: one-euro with injected timestamps (no clock in crate);
monotonicity/convergence/NaN-rejection tests.
- rf: field-peak extraction mirroring field_localize.rs constants
(X_SCALE 0.6, Z_SCALE 0.5, PEAK_THRESHOLD 0.35) and the Tier B
coarse-parallax stage (deadband, gain, hard clamp) so over-claiming is
impossible at the API level. No accuracy numbers asserted.
- wasm: OffAxisCamera + RfParallax bindgen classes; per-frame updates hold
last good state instead of throwing.
- benches (criterion): full Tier B frame ~598 ns; argmax scan optimized
-18%/-33% (20x20/100x100). MEASURED table + reproducer in README.
- examples/three.js/demos/07-off-axis-window.html: demo with SYNTHETIC
mouse simulator and labeled RF Tier B mode ('coarse body parallax - not
head tracking'), physical calibration panel, /ws/sensing input, and a
build-instructions overlay when the local pkg/ output is missing
(generated artifacts stay uncommitted; .gitignore entry added).
- Validated 23 unit tests + doctest, clippy clean, wasm32 release build,
Node smoke test of the bindgen output, and a headless-Chromium run of
the demo (engine load, eye response, mode labels, ws failure path).
- ADR-324: header + section 2.5 amendment recording the Rust/WASM core.
Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01BU3NcEgTpAVvu5QGtw4czT
Deep-research ADR answering whether icurtis1/off-axis-sneaker can be used
with RuView. Adopts the head-coupled perspective technique (Kooima
generalized off-axis projection) via a clean-room implementation — the
upstream repo is unlicensed, so no code or assets are reused. Defines a
tiered integration: webcam-fine tracking with RF presence gating and
multi-person arbitration (Tier A), an explicitly labeled RF-only coarse
body-parallax mode (Tier B), and evidence-gated future metric RF head
positioning (Tier C). No server changes; existing /ws/sensing and
/api/v1/stream/pose streams only. Indexed in the ADR README.
Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01BU3NcEgTpAVvu5QGtw4czT
Fix breathing confidence, Windows desktop launch and clean UI builds, contributor-harness line-ending integrity, runtime secret hygiene, and remove the six ADR-299 CSI/person-data files from the current tree.
Reviews and fixes RuView's 10 most recent substantive issues, plus closes
the wiring gap flagged in the perception-substrate review (docs/adr,
gist, release notes from the PR #1579 review).
## Fixed
- #1526: UI falsely claimed "LIVE — ESP32 Hardware Connected" whenever the
unauthenticated /api/v1/status probe 401'd. Now sends the bearer token
on the probe (the fallback direction was already fixed by ADR-295).
- #1554: top-level `classification` (GET /api/v1/sensing/latest) was the
last UDP packet's single node, not the fused room aggregate, so it
flapped at packet rate with 2+ disagreeing nodes. Now derived from
`RoomInference` (ADR-297's `fuse_room`) at both call sites.
- #1541: per-node MQTT `presence`/`presence_score` read a `classification`
JSON key that does not exist on `NodeInfo` (the real field is
`node_inference`), silently falling back to the room aggregate for
every node — reproducing the exact "lockstep publish" the field report
measured. Also fixed the *existing* regression test for this bug,
which used the same wrong key in its own fixture and so never caught it.
- #1557: pose-fusion's `wsPortMap` only knew port 3000, so a remapped host
port fell through to `localhost:8765` (nothing there for a remote
viewer). WS port is now derived from `location.port` instead of a
2-entry lookup table (the "never render simulated as live" half was
already fixed by ADR-295's `onVerifiedFrame` gate).
- #1525: the no-model pose path already clamps keypoint confidence to a
0.1 floor, but the renderer's own threshold is also 0.1 compared with
`<=`/`>` — a keypoint at exactly the floor was still invisible. Floor
raised to 0.15 to clear the client's gate.
- #1556: `--mqtt-ca-file`/`--mqtt-client-cert`/`--mqtt-client-key` were
parsed and stored but never applied — TLS always used the system trust
store, so a self-signed broker always failed UnknownIssuer. Now builds
`rumqttc::TlsConfiguration::Simple` from the real PEM files (no new TLS
dependency needed). A file that can't be read logs why and falls back
to system trust instead of failing opaquely later.
- #1555: the MQTT availability heartbeat asserted "online" for every known
node on a fixed 30s timer regardless of whether that node's data was
still arriving. Now tracks each node's last-seen broadcast snapshot and
only reports "online" within a 10s freshness window, otherwise
"offline" — a frozen sensor can no longer look available. (The other
half — restarting a publisher that goes permanently silent — needs a
reproduction the reporter themselves weren't certain of; left for a
follow-up rather than guessing at the trigger.)
- #1540: already fixed on main (node-keyed RateLimiter, ADR-297).
- #1521/#1522: not fixable in this repo (published HF model artifact);
replied with the ADR-298 gate status and the exact byte-level fix for
the safetensors header, and corrected the README row that claimed the
file loads with the reference loader.
- #1542, #1527: replied — #1542 is a real, larger firmware+server feature
left open for follow-up; #1527's suggested fixes were already applied,
the one residual sample is an inherent first-frame paint gap.
## Certificate spine wiring (closes the gap flagged in the PR #1579 review)
`ruview-certify` and `ruview-policy` now depend on `ruview-ood` and provide
real `From<ruview_ood::DomainState>` adapters plus a composed entry point,
`ruview_policy::authorize_from_certificate`, matching the adapter contract
`ruview-policy`'s own doc comment already described but that no code
actually implemented. A new cross-crate integration test
(`acceptance_test_b_real_integration`) mints a real signed
`CapabilityCertificate` and proves a real post-drift `ruview_ood::Unknown`
denies a `SafetyCritical` action through the composed pipeline — not two
disconnected unit tests hand-setting the same enum value.
Also:
- Wires `evaluate_linear_head` (ADR-298 model-release gate) into a new CI
job so the checker itself can't silently regress; documents that gating
an actual model publish is still a manual step (no HF automation here).
- Wires `SourceState::export_watermark()` into `start_recording`: a
recording captured while the source is synthetic is now stamped in its
metadata (not the filename or per-line JSON, to avoid breaking
`delete_recording`'s path reconstruction or the training dataset
loader's schema).
- Updates docs/user-guide.md's "Developer Preview" section to describe
what's now genuinely wired vs. still not (no live continuous
calibration/OOD loop in the running server yet).
## Validation
- cargo test --workspace --no-default-features: 4391 passed, 0 failed
- cargo build --release -p wifi-densepose-sensing-server --features mqtt:
clean
- Server smoke-tested end-to-end against the simulator (real startup,
UDP/WS/HTTP listeners, /api/v1/sensing/latest stable across calls)
- Real ESP32-S3 hardware was NOT reachable this session (no COM port
present, zero UDP frames received after 40s bound to 0.0.0.0:5005) —
the multi-node fixes are validated by the new unit/integration tests
and full-workspace regression, not by live hardware.
Co-Authored-By: claude-flow <ruv@ruv.net>
Documents the 9 new spine crates (calibrate -> certify -> govern) as a
composable library, explicit about current status: each crate is tested in
isolation but not yet wired together or into the live sensing-server
request path (DomainState is 3 separate enum types across
ruview-ood/certify/policy with no automatic bridge). Contrasts against the
two ADR-292-296 remediation items that ARE genuinely enforced today: UDP
source allowlisting (checked on every packet) and the CSI data-policy CI
guard.
The higher-ceiling primitives on the fused world state. Six crates, all
deterministic SYNTHETIC/L0 model scaffolds (a twin predicts, it never measures);
70 tests + 6 doctests, verified green independently.
ruview-twin (ADR-312): per-deployment RF twin — radio geometry, a documented
synthetic log-distance + wall-attenuation propagation model, per-link expected
distributions, and the load-bearing delta(observed,expected) that localizes a
physical change (moved node / new reflector) to specific links. 8 tests.
ruview-infogain (ADR-311): Value(sensor) = expected uncertainty reduction /
weighted cost; pure bounded-greedy selection under a multi-dimension budget;
unknown-value candidates handled explicitly (defer/probe, never silent zero). 15.
ruview-active (ADR-306): closed-loop control vocabulary (channel/bandwidth/
cadence/antenna as validated ranges); step() proposes the next measurement to
reduce uncertainty, widening exploration when the last response is UNKNOWN;
emits a plan, never RF. 13.
ruview-placement (ADR-305): floorplan + inventory -> ranked placement via the
twin's propagation model; blind-spot flags; predicted-vs-observed adjustment. 11.
ruview-memory (ADR-309): learns per-zone normal physics; anomalies are
significant deltas vs baseline emitted as evidence records; UNKNOWN before a
baseline exists (no false positives). 14.
ruview-counterfactual (ADR-310): scores hypotheses under the twin — empty-room
vs occupied, one person vs two; UNKNOWN when indistinguishable. 8.
Flips ADR-305/306/309/310/311/312 to implemented. Completes all three phases of
the ADR-297 perception-substrate program. No hardware/MEASURED claims.
Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_015TcKegTS7QqhWPC2L2SzaS
The layer that turns the certificate spine into a modality-agnostic perception
substrate. Four crates, all deterministic and green independently (43 tests).
ruview-hal (ADR-317): one abstraction mapping any modality (CSI/802.11bf/BLE/
UWB/mmWave/acoustic/camera/lidar/IMU/custom) to a canonical ontology Observation.
SensorHal trait + two SYNTHETIC/L0 reference adapters; malformed input yields a
degraded UNKNOWN observation, never a panic; synthetic can never alias measured.
8 tests.
ruview-groundtruth (ADR-300): reference sensors as a formal VALIDATION plane
(never an estimator input, enforced by the type boundary); modality-agnostic
ReferenceSeries, deterministic cross-correlation alignment, AgreementReport with
mandatory SessionScope, emitting per-context ruview-evidence records; Measured
requires reference + coverage + reproducer. 15 tests.
ruview-track (ADR-304): privacy-preserving persistent tracks (opaque person ids,
coarse non-reversible features, no civil-identity binding); ambiguous detections
stay tentative rather than misassigned; cross-zone hand-off. 8 tests.
ruview-fusion (ADR-308): multiple HalObservations -> one probabilistic WorldState,
uncertainty-aware (confidence-weighted, not naive averaging); irreconcilable
conflict or insufficient coverage yields UNKNOWN, not a confident average.
9+ tests incl. irreconcilable_conflict_yields_unknown.
Flips ADR-300/304/308/317 to implemented; registers the four crates as workspace
members. SYNTHETIC/L0 throughout; no hardware/MEASURED claims.
Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_015TcKegTS7QqhWPC2L2SzaS
Completes the phase-1 certificate spine; both acceptance tests now pass as code.
ruview-ood (ADR-299): domain-distance vs the certified fingerprint and a pure
DomainState KNOWN/DEGRADED/UNKNOWN classifier implementing the ADR-297
VALID->DEGRADED->UNKNOWN staleness guard; InferenceGate suppresses the class
(UNKNOWN as a first-class value) when domain is not KNOWN; RecalibrationRequest
signalled on DEGRADED/UNKNOWN. 25 tests.
ruview-witness (ADR-316): ordered, append-only, BLAKE3 hash-linked stage chain
(observation->DSP->inference->corroboration->spatial->policy) rooted in an
attest VerifiedMeasurement; verify() catches mutation/reorder/dropped/broken
links; effective level is the minimum across stages. 19 tests.
ruview-certify (ADR-315): signed CapabilityCertificate minted from a single-
context evidence slice (never pooled), evidence level capped at the slice floor,
valid_until bounded by calibration validity; is_valid(now, domain) returns false
when expired OR domain != KNOWN (certificate conditional on the live domain
signature). 17 tests incl. non_known_domain_invalidates.
ruview-scorecard (ADR-314): multi-domain scorecard with per-domain CIs,
worst_domain(), and a promotion gate that fails when only pooled average
improved while a worst-domain slice regressed. 17 tests.
ruview-policy (ADR-318): fail-closed action gate; Convenience/Security/
SafetyCritical assurance classes; authorize() denies with a named failed
condition; UNKNOWN denies high-assurance actions. Includes
acceptance_test_b_post_drift_unknown_denies_safety_critical. 10 tests.
All five verified green independently (88 tests). Registers the five crates as
workspace members. SYNTHETIC/L0 reference crypto; no hardware claims.
Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_015TcKegTS7QqhWPC2L2SzaS
Four foundational perception-substrate crates (dependency roots of the
certificate spine), each pure/leaf and deterministically tested:
ruview-ontology (ADR-303): canonical Site>Building>Floor>Space>Zone +
Sensor/Person/Object/Observation/Track/Event, typed serde-transparent ids,
WorldGraph registry with dangling-parent/duplicate rejection and containment
resolution, EvidenceLevel L0-L5, and a docs-only migration table for the
per-surface shapes. 8 tests + doctest.
ruview-attest (ADR-302): DeviceId + SignedMeasurement envelope binding
{device, monotonic sequence, timestamp, payload hash, calibration ref};
AttestationVerifier enforces unknown-device, signature, tamper, strict
per-device sequence (replay), and freshness; Signer/Verifier traits with a
blake3-keyed SYNTHETIC-grade reference MAC (Ed25519 is a drop-in). 14 tests.
ruview-evidence (ADR-301): append-only per-(room,device,subject,model) ledger;
immutable records with provenance-gated constructors (synthetic forces L0,
measured needs a reproducer); summarize() never pools across contexts; a slice
reports the floor evidence level, never above its weakest record. 8 tests.
wifi-densepose-calibration (ADR-298): CalibrationCertificate — signed, versioned
room fingerprint minted from existing calibration/bank state, compare/drift, and
invalidate-on-drift/expiry. 78 tests green.
Registers the three new crates as workspace members. All four verified green
independently. SYNTHETIC/L0 reference crypto; no hardware claims.
Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_015TcKegTS7QqhWPC2L2SzaS
ADR-292 (sensing-server): SourceState enum + pure transition (provenance.rs);
auth-error/unknown can never resolve to LiveVerified; synthetic exports
watermarked. Pose-fusion simulator starts SYNTHETIC and only shows LIVE on a
real decoded frame (#1557); sensing client no longer labels an unauthorized
status endpoint as live (#1526).
ADR-294 (sensing-server): NodeInference distinct from RoomInference (inference.rs);
deterministic freshness-weighted fuse_room; RateLimiter re-keyed to
(NodeId,EntityKind) so nodes do not starve each other (#1541); stale nodes go
unavailable not frozen-online (#1555).
ADR-293 (sensing-server): --udp-bind (default 127.0.0.1) + --udp-allow allowlist
+ fail-closed refusal of routable bind without allowlist unless --udp-insecure-lan
(udp_bind.rs); crate SECURITY.md documents the threat model and the deferred
per-device-auth step two.
ADR-295 (train): model_gates.rs — constant-output, unreachable-boundary (the
issue-1521 degenerate presence head), class-balance, baseline, and
metric-name-provenance gates.
ADR-296 (ci): scripts/csi-data-policy-check.sh (+ allowlist) and a workflow that
fails on tracked CSI-format/oversized-JSONL files; 6/6 self-tests pass.
Per-crate suites reported green by the swarm; CSI policy self-test 6/6 and JS
syntax verified here. Full workspace re-verification deferred until the
concurrent phase-1 spine build frees the target dir (disk pressure).
Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_015TcKegTS7QqhWPC2L2SzaS
Elevates decision policy (action authorization) into phase 1 (ADR-318): a
fail-closed gate that authorizes a governed action only when the capability
certificate class, freshness, uncertainty ceiling, evidence floor, and live
domain state (KNOWN, not DEGRADED/UNKNOWN) all satisfy the action class —
convenience vs security vs safety-critical. UNKNOWN denies high-assurance
actions; every decision is the terminal witness-chain stage.
Amends ADR-297 with: the epistemic-reliability pipeline as the product thesis;
four non-negotiable rules (UNKNOWN first-class; certificates bind
cryptographically; one canonical downstream semantics; benchmarks expose
worst-domain + CIs); the certificate-staleness guard (certificates conditional
on a continuously evaluated domain signature; VALID->DEGRADED->UNKNOWN
auto-degrade triggers recalibration); the three-primitive commercial framing
(Runtime / Certify / Trust-Fleet); and acceptance test B (drift invalidation
before a false inference reaches an actuator).
Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_015TcKegTS7QqhWPC2L2SzaS
Frames the calibration/evidence/trust/deployment layer as a 20-primitive
phased program with a dependency DAG and phase assignments. Phase 1 is the
certificate spine (spatial ontology, authenticated identity, witness chain,
calibration cert, OOD gating, evidence engine, capability certificate,
multi-domain benchmark scorecard) — the acceptance test decomposed and
buildable without new hardware. Phase 2/3 are integration and research-forward
primitives. Child ADRs 298-317 follow.
Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_015TcKegTS7QqhWPC2L2SzaS