# @garuda/ingest — MQTT ingestion (SPOF-resilient)

The device edge publishes MQTT; the engine consumes via **EMQX shared subscriptions**
(`$share/garuda-engine/<topic>`). This is the corrected v0.1 integration path (INTEGRATION-PLAN):
simulation only at the device edge, production path everywhere downstream, and **no single point of
failure at ingestion** (ADR-0013 D13.1).

## Why shared subscriptions
A fixed-clientId subscription (today's `queue-manager`) can't run N replicas — the broker kicks the
duplicate. **Shared subscriptions load-balance one topic across a group**, so the engine scales N-up with
no lock. A *different* group gets its own full copy — which is also how the engine shadows the workers.

## Proof (`src/proof.mjs`, against the running EMQX)
6 device events, **2 engine consumers in one shared group** → EMQX load-balanced **3 + 3**, **0 lost**.
Run: `node src/proof.mjs` (needs EMQX at `mqtt://localhost:1883`).

```
published 6 · consumer-a got 3 · consumer-b got 3 · total 6
shared-subscription load-balanced across 2 replicas: YES ✓
no message lost: YES ✓
```

## Next (INTEGRATION-PLAN §6)
CLI device sim (Tunnel) publishes the session/read/encode/verify protocol; the engine consumer runs the
Blueprint over it → lifted event log → projections → workflow-derived runtime UI.
