## Security audit (`mqtt::security`)
New module enforcing the ADR-115 §3.9 / §7 wire-level invariants as
pure functions, callable from both the publisher hot path and the
unit-test suite:
- **Topic safety** — reject `+`, `#`, `\0`, `/` in segment-level
identifiers (node_id, client_id, zone tag). Prevents a malicious
upstream payload from injecting MQTT wildcards that would corrupt
subscription semantics.
- **Path safety** — reject NUL / newline in TLS cert / CA paths.
- **Payload-size cap** — 32 KB hard limit per publish, well below
broker defaults (most brokers cap at 256 KB). Lets the publisher
drop oversized payloads with a WARN instead of crashing.
- **Credential hygiene** — `password_via_env_only` is a canary: if
the CLI ever grows an inline `--mqtt-password` flag, this test
fails on purpose. Today we only accept `--mqtt-password-env <VAR>`.
- **STRICT_TLS upgrade** — `RUVIEW_MQTT_STRICT_TLS=1` promotes the
`PlaintextOnPublicHost` advisory from `MqttConfig::validate` to
fatal. This is the planned v0.8.0 default per ADR §9.5.
- **Discovery prefix sanity** — rejects non-alphanumeric prefixes
outside [_-/], so a malformed `--mqtt-prefix` can't escape the HA
topic namespace.
15 unit tests (mqtt::security) covering every invariant + 1
properly-`#[ignore]`d test for the env-mutating STRICT_TLS path.
## Criterion benchmarks (`benches/mqtt_throughput.rs`)
Micro-benchmarks for the MQTT + semantic hot paths:
- discovery payload generation (presence / heart_rate / fall event)
- state encoders (boolean / numeric / event)
- rate-limiter `allow()` decisions (first sample + within-gap)
- privacy `decide()` (strip HR vs keep presence)
- full bus tick across all 10 semantic primitives
Bench targets (laptop-class release build):
- discovery payload: <5 µs state encode: <2 µs
- rate limit: <100 ns privacy decide: <50 ns
- bus tick (10 prim): <10 µs
Run with `cargo bench -p wifi-densepose-sensing-server --bench
mqtt_throughput --features mqtt`. Numbers will be captured into the
witness bundle in P10.
`criterion` 0.5 added as dev-dep. `[[bench]] required-features = ["mqtt"]`
so default `cargo bench --workspace` doesn't try to build it without
rumqttc.
Lib test count: **372 passed** (357 → 372, +15 security tests).
Refs #776.
Co-Authored-By: claude-flow <ruv@ruv.net>