docs(decisions): ADR 0003 — MQTT spine
This commit is contained in:
@@ -0,0 +1,51 @@
|
|||||||
|
# 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.
|
||||||
Reference in New Issue
Block a user