wifi-densepose/v2/crates/wifi-densepose-sensing-server/src
ruv 59c503d01e feat(adr-115): P3 — state encoder + rate limiter + rumqttc publisher (45 tests)
Implements ADR-115 §3.5 (QoS/retain matrix), §3.6 (LWT/availability
heartbeat), §3.7 (per-entity rate limits) as three new submodules:

- `mqtt::state` — `RateLimiter` (per-entity HashMap of last-emitted
  Duration; allow() returns false within the configured 1/Hz gap),
  `StateEncoder` rendering binary/numeric/event payloads from a
  `VitalsSnapshot` projection, `StateMessage` carrying topic + payload
  + QoS + retain bits keyed off `DiscoveryComponent` so the wire-level
  matrix from §3.5 is enforced in one place. Compiles without rumqttc
  so it's testable under --no-default-features.

- `mqtt::publisher` (feature-gated) — `OwnedDiscoveryBuilder` for the
  background task, `run()` event loop that pumps `rumqttc::EventLoop`
  + heartbeat (30s) + discovery refresh (configurable) + broadcast
  channel consumer in a single tokio::select!. Reconnect resets the
  RateLimiter so post-reconnect samples emit promptly. On graceful
  shutdown publishes `offline` to every availability topic before
  disconnect.

- `mqtt::discovery::EntityKind` — derive `Hash` so the entity can key
  the RateLimiter's HashMap.

18 new state-encoder tests covering:
- Rate limiter: first-sample-pass, drops-within-gap, allows-after-gap,
  per-entity independence, change-only entities (rate=0) always allow,
  reset re-enables immediate publish.
- Boolean encoder: ON/OFF payload, QoS 1 + retain (per §3.5), rejects
  non-binary entities, topic matches discovery state topic.
- Numeric encoder: HR bpm payload with confidence + ts, motion %
  rendering, returns None when optional field absent, clamps
  out-of-range motion, rejects non-sensor entities, QoS 0 + no retain.
- Event encoder: fall payload with confidence + ts, omits confidence
  when None, QoS 1 + no retain (never replay old falls), rejects
  non-event entities.
- iso_ts: RFC 3339 UTC with millisecond fraction.

Total mqtt test suite now 45/45 green:
  cargo test -p wifi-densepose-sensing-server --no-default-features mqtt::
  45 passed; 0 failed.

Compile-checked under --features mqtt + rumqttc 0.24 + use-rustls:
  cargo check -p wifi-densepose-sensing-server --features mqtt --no-default-features
  Finished dev profile (clean, no warnings).

Refs #776.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-05-23 13:57:16 -04:00
..
mqtt feat(adr-115): P3 — state encoder + rate limiter + rumqttc publisher (45 tests) 2026-05-23 13:57:16 -04:00
adaptive_classifier.rs fix(security): audit — fix RUSTSEC vulns, clippy warnings, dead code (#769) 2026-05-23 05:36:13 -04:00
bearer_auth.rs fix(security): audit — fix RUSTSEC vulns, clippy warnings, dead code (#769) 2026-05-23 05:36:13 -04:00
cli.rs feat(adr-115): P1 — Cargo features + CLI flags for MQTT/Matter/Semantic 2026-05-23 13:43:02 -04:00
csi.rs fix(security): audit — fix RUSTSEC vulns, clippy warnings, dead code (#769) 2026-05-23 05:36:13 -04:00
dataset.rs fix(security): audit — fix RUSTSEC vulns, clippy warnings, dead code (#769) 2026-05-23 05:36:13 -04:00
edge_registry.rs fix(security): audit — fix RUSTSEC vulns, clippy warnings, dead code (#769) 2026-05-23 05:36:13 -04:00
embedding.rs fix(security): audit — fix RUSTSEC vulns, clippy warnings, dead code (#769) 2026-05-23 05:36:13 -04:00
field_bridge.rs fix(security): audit — fix RUSTSEC vulns, clippy warnings, dead code (#769) 2026-05-23 05:36:13 -04:00
graph_transformer.rs fix(security): audit — fix RUSTSEC vulns, clippy warnings, dead code (#769) 2026-05-23 05:36:13 -04:00
host_validation.rs fix(security): audit — fix RUSTSEC vulns, clippy warnings, dead code (#769) 2026-05-23 05:36:13 -04:00
introspection.rs fix(security): audit — fix RUSTSEC vulns, clippy warnings, dead code (#769) 2026-05-23 05:36:13 -04:00
lib.rs feat(adr-115): P2 — HA discovery emitter + privacy filter + config (27 tests) 2026-05-23 13:50:33 -04:00
main.rs fix(security): audit — fix RUSTSEC vulns, clippy warnings, dead code (#769) 2026-05-23 05:36:13 -04:00
model_manager.rs fix(security): path-traversal guard on 5 sensing-server endpoints (closes #615) (#616) 2026-05-17 19:59:20 -04:00
multistatic_bridge.rs fix(security): audit — fix RUSTSEC vulns, clippy warnings, dead code (#769) 2026-05-23 05:36:13 -04:00
path_safety.rs fix(security): path-traversal guard on 5 sensing-server endpoints (closes #615) (#616) 2026-05-17 19:59:20 -04:00
pose.rs fix(security): audit — fix RUSTSEC vulns, clippy warnings, dead code (#769) 2026-05-23 05:36:13 -04:00
recording.rs fix(security): path-traversal guard on 5 sensing-server endpoints (closes #615) (#616) 2026-05-17 19:59:20 -04:00
rvf_container.rs fix(security): audit — fix RUSTSEC vulns, clippy warnings, dead code (#769) 2026-05-23 05:36:13 -04:00
rvf_pipeline.rs fix(security): audit — fix RUSTSEC vulns, clippy warnings, dead code (#769) 2026-05-23 05:36:13 -04:00
sona.rs fix(security): audit — fix RUSTSEC vulns, clippy warnings, dead code (#769) 2026-05-23 05:36:13 -04:00
sparse_inference.rs fix(security): audit — fix RUSTSEC vulns, clippy warnings, dead code (#769) 2026-05-23 05:36:13 -04:00
tracker_bridge.rs fix(security): audit — fix RUSTSEC vulns, clippy warnings, dead code (#769) 2026-05-23 05:36:13 -04:00
trainer.rs fix(security): audit — fix RUSTSEC vulns, clippy warnings, dead code (#769) 2026-05-23 05:36:13 -04:00
training_api.rs fix(security): path-traversal guard on 5 sensing-server endpoints (closes #615) (#616) 2026-05-17 19:59:20 -04:00
types.rs fix(security): audit — fix RUSTSEC vulns, clippy warnings, dead code (#769) 2026-05-23 05:36:13 -04:00
vital_signs.rs fix(security): audit — fix RUSTSEC vulns, clippy warnings, dead code (#769) 2026-05-23 05:36:13 -04:00