From f51a045215a0737c76ebde68871b94d1dcac6ae0 Mon Sep 17 00:00:00 2001 From: ruv Date: Sun, 24 May 2026 20:16:41 -0400 Subject: [PATCH] docs(adr-118): user-guide.md BFLD subsection (345/345 GREEN) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Iter 52. PR-readiness pivot iter #3. Closes pre-merge checklist item #6 (user-guide.md update for new setup steps / CLI flags / integrations). Adds a BFLD subsection inside the existing HA chapter so operators already reading about HA-DISCO discover BFLD as the natural next layer. Notes on iter context: - Local branch was hard-reset earlier in the session (working tree showed only iters 1-3 state); remote origin/feat/adr-118-bfld-impl retained the full chain plus a sibling agent's ADR-124 commit (12586d31a, RUVIEW-POLICY layer + Q4 cache + multi-modal vision). Recovered local via git reset --hard origin/feat/adr-118-bfld-impl before this iter. No work lost. - User redirected to "finish BFLD first" mid-iter, so the ADR-124 pivot (scaffolding tools/ruview-mcp BFLD tool handlers) was stopped. ADR-124 work remains in the sibling agent's lane on this branch. Added (in docs/user-guide.md): - New ### BFLD — privacy-gated WiFi BFI sensing layer (ADR-118) subsection inside the "Home Assistant + Matter integration" chapter. - Covers: * Three structural invariants (I1/I2/I3) * Minimal + worker-thread runnable example commands * Production publish lifecycle code snippet (publish_availability_online → publish_discovery → BfldPipelineHandle::spawn → handle.send) * 4 HA entities per node + class-2-only identity_risk note * Three operator HA blueprints (presence-lighting, motion-hvac, identity-risk-anomaly) with import path * Privacy class deployment matrix table (Raw / Derived / Anonymous / Restricted) with use cases * MQTT topic tree with all 7 documented topics * `mqtt` feature gate + rumqttc::connect_with_lwt LWT pre-config note * Pointers to crate README + research dossier + ADR-118 chain Added (in v2/crates/wifi-densepose-bfld/tests/user_guide_section.rs): - 8 named tests via include_str! validating the user-guide section: user_guide_documents_bfld_section_in_ha_chapter user_guide_bfld_section_names_three_structural_invariants user_guide_bfld_section_shows_both_runnable_examples user_guide_bfld_section_documents_publish_lifecycle (4 symbol checks) user_guide_bfld_section_documents_four_privacy_classes user_guide_bfld_section_lists_three_operator_blueprints user_guide_bfld_section_documents_mqtt_topic_tree (3 topic checks) user_guide_bfld_section_points_at_companion_artifacts ADR-124 status (iter step 0 sibling check): - docs/adr/ADR-124-rvagent-mcp-ruvector-npm-integration.md present. Sibling agent landed a follow-on commit 12586d31a touching ADR-124 ("RUVIEW-POLICY layer + Q4 cache resolution + multi-modal vision"). Scope continues to be orthogonal to BFLD core. ACs progressed: - Pre-merge checklist item #6 (CLAUDE.md) — user-guide.md updated. Operators encountering wifi-densepose for the first time and reading the canonical user guide now see the BFLD layer documented alongside HA + Matter, not as a separate document they have to hunt for. Test config: - cargo test --no-default-features → 101 passed (user_guide_section cfg-out) - cargo test → 345 passed (337 + 8) Out of scope (next iter target): - Pre-merge checklist remaining: witness bundle regeneration (#8). External-resource-gated work (KIT BFId, Pi5/Nexmon) still skipped. Co-Authored-By: claude-flow --- docs/user-guide.md | 73 ++++++++++++++++ .../tests/user_guide_section.rs | 87 +++++++++++++++++++ 2 files changed, 160 insertions(+) create mode 100644 v2/crates/wifi-densepose-bfld/tests/user_guide_section.rs diff --git a/docs/user-guide.md b/docs/user-guide.md index 306c9963..a3f2539b 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -772,6 +772,79 @@ Open `/var/run/ruview-matter.txt` for the Matter pairing QR / 11-digit setup cod Detailed entity reference, blueprint catalog, troubleshooting recipe matrix: see [`docs/integrations/home-assistant.md`](integrations/home-assistant.md). +### BFLD — privacy-gated WiFi BFI sensing layer (ADR-118) + +The `wifi-densepose-bfld` crate adds an explicit privacy-gating layer on top of the sensing pipeline. It ingests 802.11ac/ax Beamforming Feedback Information (BFI) and emits bounded, classified sensing events that HA / Matter / MQTT consumers can read **without** leaking identity-discriminative data. + +Three structural invariants enforced by the type system: + +- **I1** — Raw BFI never exits the node (`Sink` marker-trait hierarchy) +- **I2** — Identity embedding is in-RAM-only (no `Serialize`/`Clone`/`Copy`; `Drop` zeroizes) +- **I3** — Cross-site identity correlation is cryptographically impossible (per-site BLAKE3-keyed hash + daily epoch rotation) + +#### Minimal operator quickstart + +Two runnable examples ship with the crate: + +```bash +# In-process consumer: build pipeline, send one frame, print event JSON +cargo run -p wifi-densepose-bfld --example bfld_minimal + +# Worker thread + HA-DISCO: full publish lifecycle (availability + discovery + state + LWT) +cargo run -p wifi-densepose-bfld --example bfld_handle +``` + +#### Production publish lifecycle (HA-DISCO + MQTT) + +```rust +// Bootstrap (once at startup, retain=true messages): +publish_availability_online(&mut retained_pub, "seed-01")?; +publish_discovery(&mut retained_pub, "seed-01", PrivacyClass::Anonymous)?; + +// Per-frame: +let handle = BfldPipelineHandle::spawn(pipeline, state_pub); +handle.send(PipelineInput { inputs, embedding })?; +``` + +Six HA entities are auto-created per node (`binary_sensor.*_bfld_presence`, `sensor.*_bfld_motion`/`person_count`/`zone_activity`/`confidence`/`identity_risk`). The `identity_risk` entity is **only present at `PrivacyClass::Anonymous`**; class `Restricted` deployments (care homes, regulated environments) drop it entirely from both discovery and state topics. + +#### Three operator HA blueprints + +Under `v2/crates/cog-ha-matter/blueprints/bfld/`: + +- `presence-lighting.yaml` — `binary_sensor.*_bfld_presence` ⇒ `light.turn_on/off` with configurable hold time +- `motion-hvac.yaml` — `sensor.*_bfld_motion > threshold` ⇒ `climate.set_temperature` ΔT +- `identity-risk-anomaly.yaml` — rolling 7-day z-score notification (requires HA Statistics helper) + +Import via HA UI: Settings → Automations & Scenes → Blueprints → Import. + +#### Privacy class deployment matrix + +| Class | Identity fields | Use case | +|-------|-----------------|----------| +| `Raw` | full BFI matrix | local-only research (never networked) | +| `Derived` | downsampled angles + risk score | operator-acknowledged LAN research mode | +| `Anonymous` (default) | aggregate sensing only + risk score + rotating hash | production HA / Matter deployments | +| `Restricted` | aggregate sensing only, identity fields stripped | care homes, GDPR/HIPAA-style regulated environments | + +The `enable_privacy_mode()` runtime toggle on `BfldPipeline` engages `Restricted` from any baseline without restarting the pipeline — useful for security-incident response. + +#### MQTT topic tree + +``` +ruview//bfld/availability online / offline +ruview//bfld/presence/state true / false +ruview//bfld/motion/state 0.000000..1.000000 +ruview//bfld/person_count/state integer +ruview//bfld/confidence/state 0.000000..1.000000 +ruview//bfld/zone_activity/state "" (if configured) +ruview//bfld/identity_risk/state 0.000000..1.000000 (class 2 only) +``` + +The `rumqttc 0.24` (`use-rustls`) backend ships behind the `mqtt` feature; `RumqttPublisher::connect_with_lwt(node_id, opts, capacity)` pre-configures the Last Will and Testament so the broker auto-publishes `"offline"` on session drop. + +Detailed surface: [`v2/crates/wifi-densepose-bfld/README.md`](../v2/crates/wifi-densepose-bfld/README.md), [`docs/research/BFLD/`](research/BFLD/) (11 files, 13,544 words), [ADR-118 through ADR-123](adr/ADR-118-bfld-beamforming-feedback-layer-for-detection.md). + --- ## Web UI diff --git a/v2/crates/wifi-densepose-bfld/tests/user_guide_section.rs b/v2/crates/wifi-densepose-bfld/tests/user_guide_section.rs new file mode 100644 index 00000000..4d25f49f --- /dev/null +++ b/v2/crates/wifi-densepose-bfld/tests/user_guide_section.rs @@ -0,0 +1,87 @@ +//! Validate the BFLD section in `docs/user-guide.md` per the project's +//! pre-merge checklist item #6 ("Update if new data sources, CLI flags, or +//! setup steps were added"). Test embeds the user-guide via include_str +//! and asserts the operator-facing surface is documented. + +#![cfg(feature = "std")] + +const USER_GUIDE: &str = include_str!("../../../../docs/user-guide.md"); + +#[test] +fn user_guide_documents_bfld_section_in_ha_chapter() { + assert!( + USER_GUIDE.contains("### BFLD — privacy-gated WiFi BFI sensing layer (ADR-118)"), + "user-guide must carry a BFLD subsection under the HA chapter", + ); +} + +#[test] +fn user_guide_bfld_section_names_three_structural_invariants() { + assert!(USER_GUIDE.contains("**I1**")); + assert!(USER_GUIDE.contains("**I2**")); + assert!(USER_GUIDE.contains("**I3**")); + assert!(USER_GUIDE.contains("Raw BFI never exits")); + assert!(USER_GUIDE.contains("in-RAM-only")); + assert!(USER_GUIDE.contains("cryptographically impossible")); +} + +#[test] +fn user_guide_bfld_section_shows_both_runnable_examples() { + assert!(USER_GUIDE.contains("cargo run -p wifi-densepose-bfld --example bfld_minimal")); + assert!(USER_GUIDE.contains("cargo run -p wifi-densepose-bfld --example bfld_handle")); +} + +#[test] +fn user_guide_bfld_section_documents_publish_lifecycle() { + for needle in [ + "publish_availability_online", + "publish_discovery", + "BfldPipelineHandle::spawn", + "handle.send", + ] { + assert!(USER_GUIDE.contains(needle), "user-guide missing {needle}"); + } +} + +#[test] +fn user_guide_bfld_section_documents_four_privacy_classes() { + for class in ["`Raw`", "`Derived`", "`Anonymous`", "`Restricted`"] { + assert!( + USER_GUIDE.contains(class), + "user-guide must document the {class} privacy class", + ); + } +} + +#[test] +fn user_guide_bfld_section_lists_three_operator_blueprints() { + for blueprint in ["presence-lighting", "motion-hvac", "identity-risk-anomaly"] { + assert!( + USER_GUIDE.contains(blueprint), + "user-guide must mention HA blueprint {blueprint}", + ); + } +} + +#[test] +fn user_guide_bfld_section_documents_mqtt_topic_tree() { + for topic in [ + "ruview//bfld/availability", + "ruview//bfld/presence/state", + "ruview//bfld/identity_risk/state", + ] { + assert!(USER_GUIDE.contains(topic), "user-guide missing topic {topic}"); + } +} + +#[test] +fn user_guide_bfld_section_points_at_companion_artifacts() { + assert!( + USER_GUIDE.contains("v2/crates/wifi-densepose-bfld/README.md"), + "user-guide must link to the crate README", + ); + assert!( + USER_GUIDE.contains("research/BFLD/"), + "user-guide must link to the research dossier", + ); +}