mirror of
https://github.com/ruvnet/RuView.git
synced 2026-06-02 00:58:56 +02:00
ab8d7a8583
Iter 49. Ships the crate's first README — genuinely missing artifact.
crates.io renders this file; the rendered page is what downstream
operators see when they `cargo doc --open` or browse the registry.
Added:
- v2/crates/wifi-densepose-bfld/README.md (~135 lines):
* Three structural invariants (I1/I2/I3) table with enforcement
mechanism per invariant
* Quickstart snippet: in-process consumer (BfldPipeline::process)
* Quickstart snippet: production worker (BfldPipelineHandle +
bootstrap helpers)
* Feature flag matrix (std / serde-json / mqtt / soul-signature)
* Two runnable example invocations
* Testing matrix (no_default / default / mqtt)
* Companion artifacts pointer (ADRs, research bundle, HA
blueprints, CI workflow)
* ADR cross-reference table (ADR-118 through ADR-123)
* BFLD_MQTT_BROKER env-var doc for live mosquitto opt-in
- v2/crates/wifi-densepose-bfld/Cargo.toml:
readme = "README.md"
(so crates.io picks it up on publish)
- v2/crates/wifi-densepose-bfld/tests/crate_readme.rs (8 tests):
readme_documents_three_structural_invariants
readme_documents_feature_flag_matrix
readme_documents_both_runnable_examples
readme_documents_three_test_invocations
readme_references_companion_adrs_118_through_123
readme_quickstart_uses_canonical_public_api
(8 symbol-presence checks: BfldPipeline::new, BfldConfig::new,
SignatureHasher::new, SensingInputs, IdentityEmbedding::from_raw,
pipeline.process, publish_availability_online, publish_discovery,
BfldPipelineHandle::spawn, PipelineInput)
readme_points_at_research_bundle_and_blueprints
readme_documents_env_gated_mosquitto_integration
ADR-124 status (iter step 0 sibling check):
- docs/adr/ADR-124-rvagent-mcp-ruvector-npm-integration.md unchanged
at 431 lines. SENSE-BRIDGE scope remains orthogonal.
ACs progressed:
- ADR-118 §2.1 documentation surface — crates.io / cargo doc landing
page now exists. Operators encountering wifi-densepose-bfld for the
first time get the three structural invariants, quickstart snippets
for both deployment patterns, feature matrix, and ADR map without
having to read source.
Test config:
- cargo test --no-default-features → 101 passed (crate_readme cfg-out)
- cargo test → 327 passed (319 + 8)
Out of scope (next iter target):
- PR-readiness pivot. CHANGELOG, witness bundle, AC closeout table.
External-resource-gated work (KIT BFId, Pi5/Nexmon) still skipped.
Co-Authored-By: claude-flow <ruv@ruv.net>
117 lines
5.5 KiB
Markdown
117 lines
5.5 KiB
Markdown
# wifi-densepose-bfld
|
|
|
|
**BFLD — Beamforming Feedback Layer for Detection.** Privacy-gated WiFi sensing primitives derived from 802.11ac/ax Beamforming Feedback Information (BFI). See [ADR-118](../../../docs/adr/ADR-118-bfld-beamforming-feedback-layer-for-detection.md) for the umbrella architecture decision and [`docs/research/BFLD/`](../../../docs/research/BFLD/) for the full design dossier.
|
|
|
|
## Three structural invariants
|
|
|
|
The crate enforces three privacy invariants **structurally** (via the type system + memory hygiene), not by policy text:
|
|
|
|
| ID | Invariant | Enforced by |
|
|
|----|-----------|-------------|
|
|
| **I1** | Raw BFI never exits the node | [`Sink`] marker-trait hierarchy + [`PrivacyClass::Raw.allows_network() == false`] |
|
|
| **I2** | Identity embedding is in-RAM-only | [`IdentityEmbedding`] has no `Serialize` / `Clone` / `Copy` + `Drop` zeroizes storage |
|
|
| **I3** | Cross-site identity correlation is cryptographically impossible | [`SignatureHasher`] per-site BLAKE3-keyed hash with daily epoch rotation |
|
|
|
|
## Quickstart
|
|
|
|
Minimal in-process consumer (see `examples/bfld_minimal.rs`):
|
|
|
|
```rust
|
|
use wifi_densepose_bfld::{
|
|
BfldConfig, BfldPipeline, IdentityEmbedding, SensingInputs,
|
|
SignatureHasher, EMBEDDING_DIM, SITE_SALT_LEN,
|
|
};
|
|
|
|
let mut pipeline = BfldPipeline::new(
|
|
BfldConfig::new("seed-01")
|
|
.with_signature_hasher(SignatureHasher::new([0xAB; SITE_SALT_LEN])),
|
|
);
|
|
|
|
let event = pipeline
|
|
.process(
|
|
SensingInputs { /* timestamp, presence, motion, ... */
|
|
timestamp_ns: 1_700_000_000_000_000_000, presence: true,
|
|
motion: 0.42, person_count: 1, sensing_confidence: 0.91,
|
|
sep: 0.2, stab: 0.2, consist: 0.2, risk_conf: 0.2,
|
|
rf_signature_hash: None,
|
|
},
|
|
Some(IdentityEmbedding::from_raw([0.05; EMBEDDING_DIM])),
|
|
)
|
|
.expect("low-risk emit");
|
|
|
|
println!("{}", event.to_json().unwrap());
|
|
```
|
|
|
|
Production worker-thread + HA-DISCO publishing (see `examples/bfld_handle.rs`):
|
|
|
|
```rust
|
|
use wifi_densepose_bfld::{
|
|
publish_availability_online, publish_discovery, BfldConfig, BfldPipeline,
|
|
BfldPipelineHandle, PipelineInput, PrivacyClass, SignatureHasher,
|
|
};
|
|
|
|
// Bootstrap: retained "online" + 6 retained HA-DISCO config payloads.
|
|
publish_availability_online(&mut publisher, "seed-01")?;
|
|
publish_discovery(&mut publisher, "seed-01", PrivacyClass::Anonymous)?;
|
|
|
|
// Spawn worker. Per-frame: handle.send(PipelineInput { inputs, embedding }).
|
|
let handle = BfldPipelineHandle::spawn(
|
|
BfldPipeline::new(BfldConfig::new("seed-01")
|
|
.with_signature_hasher(SignatureHasher::new(salt))),
|
|
publisher,
|
|
);
|
|
handle.send(PipelineInput { inputs, embedding })?;
|
|
```
|
|
|
|
## Feature flags
|
|
|
|
| Feature | Default | Pulls in | Enables |
|
|
|---------|---------|----------|---------|
|
|
| `std` | ✅ | (no extra deps) | `BfldFrame`, `BfldPayload`, `BfldPipeline`, `BfldPipelineHandle`, `BfldEvent`, `BfldEmitter`, `PrivacyGate`, MQTT topic router, HA discovery |
|
|
| `serde-json` | ✅ | `serde` + `serde_json` | `BfldEvent::to_json()`, custom `rf_signature_hash: "blake3:<hex>"` serializer, `privacy_class` string encoding |
|
|
| `mqtt` | — | `rumqttc 0.24` (`use-rustls`) | `RumqttPublisher`, `connect_with_lwt`, live broker integration |
|
|
| `soul-signature`| — | — | `--features` gate signaling Soul Signature deployment (ADR-118 §1.4, ADR-120 §2.7, ADR-121 §2.6) |
|
|
|
|
Stripping to `--no-default-features` keeps the no_std-compatible core (`BfldFrameHeader`, `PrivacyClass`, `Sink` traits, `CoherenceGate`, `SignatureHasher`, `IdentityEmbedding`, `EmbeddingRing`, risk-score function + `GateAction`).
|
|
|
|
## Examples
|
|
|
|
```sh
|
|
cargo run -p wifi-densepose-bfld --example bfld_minimal # in-process consumer
|
|
cargo run -p wifi-densepose-bfld --example bfld_handle # worker-thread + HA-DISCO
|
|
```
|
|
|
|
## Companion artifacts
|
|
|
|
| Path | Purpose |
|
|
|------|---------|
|
|
| `docs/adr/ADR-118` through `ADR-123` | Architecture decisions |
|
|
| `docs/research/BFLD/` | 13,544-word design bundle (11 files) |
|
|
| `v2/crates/cog-ha-matter/blueprints/bfld/` | Three HA operator blueprints (presence-lighting, motion-HVAC, identity-risk-anomaly) |
|
|
| `.github/workflows/bfld-mqtt-integration.yml` | CI matrix incl. live mosquitto Docker service |
|
|
|
|
## ADR cross-reference
|
|
|
|
| ADR | Scope |
|
|
|-----|-------|
|
|
| [118](../../../docs/adr/ADR-118-bfld-beamforming-feedback-layer-for-detection.md) | Umbrella + invariants I1/I2/I3 |
|
|
| [119](../../../docs/adr/ADR-119-bfld-frame-format-and-wire-protocol.md) | Wire format (86-byte header + payload sections + CRC-32/ISO-HDLC) |
|
|
| [120](../../../docs/adr/ADR-120-bfld-privacy-class-and-hash-rotation.md) | 4 privacy classes + per-site keyed hash with daily rotation |
|
|
| [121](../../../docs/adr/ADR-121-bfld-identity-risk-scoring.md) | Multiplicative risk score + coherence-gate hysteresis + Soul Signature exemption |
|
|
| [122](../../../docs/adr/ADR-122-bfld-ruview-ha-matter-exposure.md) | HA-DISCO + Matter cluster boundary + MQTT topic routing |
|
|
| [123](../../../docs/adr/ADR-123-bfld-capture-path-nexmon-and-esp32.md) | Pi 5 / Nexmon capture adapter + ESP32 self-only mode |
|
|
|
|
## Testing
|
|
|
|
```sh
|
|
cargo test -p wifi-densepose-bfld --no-default-features # no_std-compatible core
|
|
cargo test -p wifi-densepose-bfld # default std + serde-json
|
|
cargo test -p wifi-densepose-bfld --features mqtt # incl. rumqttc smoke
|
|
```
|
|
|
|
A `BFLD_MQTT_BROKER=tcp://localhost:1883` env var unlocks the live-broker `mosquitto_integration` test suite (see `tests/mosquitto_integration.rs`).
|
|
|
|
## License
|
|
|
|
MIT — same as the wifi-densepose workspace.
|