mirror of
https://github.com/ruvnet/RuView
synced 2026-08-04 19:31:42 +00:00
23fe8012e0
Iter 23. Production Publish trait impl using rumqttc 0.24 (same crate
version + use-rustls feature pinning as wifi-densepose-sensing-server,
so both publishers can share broker connection posture).
Added:
- rumqttc = "0.24" optional dep (default-features = false, use-rustls)
- New `mqtt` cargo feature: ["std", "dep:rumqttc"]
- src/rumqttc_publisher.rs (gated on `feature = "mqtt"`):
* RumqttPublisher wrapping rumqttc::Client + QoS + retain flag
* RumqttPublisher::new(client, qos) const constructor
* with_retain(bool) builder for availability-style topics
* RumqttPublisher::connect(opts, capacity) -> (Self, Connection)
Returns the unpumped Connection — caller spawns a thread that
iterates connection.iter() to drive the MQTT protocol. Default
QoS is AtLeastOnce (HA-DISCO recommendation for state topics).
* impl Publish with Error = rumqttc::ClientError
- pub use RumqttPublisher from lib.rs
tests/rumqttc_publisher_smoke.rs (7 named tests, all green, gated on mqtt):
rumqttc_publisher_constructs_without_broker
(uses 127.0.0.1:1 — reserved port refuses immediately; no hang)
with_retain_builder_yields_a_publisher
publish_queues_message_without_blocking_on_broker_state
*** Critical property: rumqttc's sync Client::publish queues into
an unbounded channel; publish_event returns Ok without round-
tripping to the (offline) broker. The queued packet only sends
if a thread iterates Connection::iter(). ***
restricted_event_publishes_four_messages_through_rumqttc
(class 3 + no zone: presence/motion/count/confidence — 4 topics)
publisher_trait_object_is_constructible
(Box<dyn Publish<Error = rumqttc::ClientError>> works)
direct_publish_call_through_trait_object
default_qos_is_at_least_once_via_connect
ACs progressed:
- ADR-122 §2.2 broker integration — production publisher now wired,
matching the sensing-server's TLS / version posture. The two
crates can share a single broker connection if an operator wants
both publishers in the same process.
- ADR-122 AC4 still enforced — publish_event's class-gated routing
is upstream of rumqttc, so no broker-level config can leak Raw frames.
Test config:
- cargo test --no-default-features → 72 passed (mqtt feature off)
- cargo test → 169 passed (mqtt feature off)
- cargo test --features mqtt --test rumqttc_publisher_smoke → 7 passed
- With --features mqtt: 169 + 7 = 176 total
Out of scope (next iter target):
- mosquitto integration test (env-gated MQTT_BROKER=tcp://localhost:1883):
* spawn a thread iterating Connection::iter()
* publish a BfldEvent
* subscribe in the test, await SubAck per the workspace memory note
`feedback_mqtt_integration_test_patterns`
* assert the topics received match render_events output
- BfldPipelineHandle: Arc<Mutex<BfldPipeline>> with a thread that pumps
inbound (inputs, embedding) → process → publish_event(&rumqttc_pub, &event)
for a single-call "set up MQTT publisher and walk away" API.
Co-Authored-By: claude-flow <ruv@ruv.net>
53 lines
1.8 KiB
TOML
53 lines
1.8 KiB
TOML
[package]
|
|
name = "wifi-densepose-bfld"
|
|
description = "BFLD — Beamforming Feedback Layer for Detection. Privacy-gated WiFi BFI sensing primitives. See ADR-118."
|
|
version.workspace = true
|
|
edition.workspace = true
|
|
authors.workspace = true
|
|
license.workspace = true
|
|
repository.workspace = true
|
|
documentation.workspace = true
|
|
keywords.workspace = true
|
|
categories.workspace = true
|
|
|
|
[features]
|
|
default = ["std", "serde-json"]
|
|
std = []
|
|
# JSON serialization for BfldEvent (ADR-121 §2.1, ADR-122 §2.1). Pulls in
|
|
# serde + serde_json; tied to `std` because serde_json is std-only.
|
|
serde-json = ["std", "dep:serde", "dep:serde_json"]
|
|
# rumqttc-backed Publish trait impl. Pairs with the `mqtt` feature in
|
|
# wifi-densepose-sensing-server so the same broker connection can serve
|
|
# both publishers in the same process if desired.
|
|
mqtt = ["std", "dep:rumqttc"]
|
|
# Soul Signature integration (ADR-118 §1.4, ADR-120 §2.7, ADR-121 §2.6) —
|
|
# enables privacy_class = 1 (derived) mode and the SoulMatchOracle gate
|
|
# exemption. Disabled by default per the structural class-2 default.
|
|
soul-signature = []
|
|
|
|
[dependencies]
|
|
thiserror.workspace = true
|
|
static_assertions = "1.1"
|
|
crc = "3"
|
|
blake3 = { version = "1.5", default-features = false }
|
|
serde = { workspace = true, features = ["derive"], optional = true }
|
|
serde_json = { workspace = true, optional = true }
|
|
# MQTT publisher backend (optional). Matches the `rumqttc` choice already in
|
|
# `wifi-densepose-sensing-server` so both crates share TLS / version posture.
|
|
rumqttc = { version = "0.24", default-features = false, features = ["use-rustls"], optional = true }
|
|
|
|
[dev-dependencies]
|
|
proptest.workspace = true
|
|
|
|
[lints.rust]
|
|
unsafe_code = "forbid"
|
|
missing_docs = "warn"
|
|
|
|
[lints.clippy]
|
|
all = "warn"
|
|
pedantic = "warn"
|
|
nursery = "warn"
|
|
module_name_repetitions = "allow"
|
|
missing_const_for_fn = "allow"
|
|
missing_panics_doc = "allow"
|