Files
wdmUI/decisions/0003-mqtt-como-espina-dorsal.md

52 lines
2.5 KiB
Markdown

# ADR-0003 · MQTT as the spine of the system
**Status**: accepted
**Date**: 2026-05
## Context
The platform has many independent processes that need to communicate: cameras → Frigate → enrichers → forensic engine → console → hub. Options considered:
- **REST APIs everywhere**: tight coupling, polling overhead, hard to add subscribers.
- **gRPC streams**: better but still point-to-point, no topic-based filtering.
- **Kafka**: too heavy for edge devices, requires Zookeeper or KRaft, persistent disk-heavy.
- **NATS**: lightweight but newer, less ecosystem maturity.
- **MQTT**: mature, lightweight, broker available everywhere (Mosquitto), topic-based, retain messages, QoS levels, well-known TLS bridge mechanics.
## Decision
MQTT is the **spine** of the system. Mosquitto runs on the router as the local broker. Bridges to the hub are configured selectively, with topic remapping. Components communicate via MQTT topics with a documented contract (see `docs/01-architecture/mqtt-contract.md`).
Key topics:
```
hai/<cam_id>/events/<type> # detection events
hai/<cam_id>/state/<key> # retained state (online, fps)
hai/<cam_id>/snapshots/<n> # frame snapshots — NEVER bridged
hai/<cam_id>/telemetry/<key> # raw telemetry — NEVER bridged
hai/_registry/announce # service discovery
hai/_registry/heartbeat/<id> # liveness
hai/healthd/health # selftest reports
hai/_bridge/status # bridge health (retained)
_cmd/<command> # commands incoming from hub
```
**Sovereignty principle**: snapshots and raw telemetry **never** bridge. Aggregated health does. Events do (with site prefix). The `bridge.conf` policy is in GitOps and visible in the UI.
## Consequences
**Good**:
- Adding a new subscriber is free (no config changes upstream).
- Selective bridging gives operational sovereignty as a programmable property.
- `mosquitto_sub` is a superb debugging tool always available.
- Retained messages handle late-joining subscribers correctly.
**Bad / trade-offs**:
- MQTT 5 has features we want (response topics, message expiry) but Mosquitto's MQTT5 support is partial — we stay on MQTT 3.1.1 for compatibility.
- No native request-response semantics — we use `req-id` correlation in payloads where needed.
- Encryption at rest of the broker DB is not transparent — addressed via LUKS at the OS layer.
## Alternatives considered
See above. **Kafka** was the strongest alternative; rejected primarily for edge-device cost and operational complexity.