NATS Event Bridge
stratt advanced 6 min read
ELI5
When a unit changes state, STRATT shouts the news on a NATS channel. Each shout has a unique ticket so listeners that hear it twice can ignore the duplicate.
Technical Deep Dive
Publish-Subscribe Flow
sequenceDiagram participant CLI as @stratt/cli participant SVC as orchestrator-http participant JS as NATS JetStream participant CHO as Choco consumer CLI->>SVC: publish unit (POST) SVC->>SVC: persist + recompute fingerprint SVC->>JS: publish strat.dev.unit.published JS-->>CHO: deliver (durable consumer) CHO->>CHO: dedupe by idempotencyKey alt processing fails CHO-->>JS: NAK JS-->>CHO: redeliver (≥1 semantics) else exhausted JS->>JS: route to DLQ end JS->>JS: forward to choco.strat.* subjectSubject Pattern
strat.{domain}.{event-type} — e.g. strat.dev.unit.published, strat.core.chain.gate.fired. Forwarded to choco.strat.* for cross-platform consumers.
Seven Event Types (IC-03)
| Event | Trigger |
|---|---|
unit.published | Lifecycle reaches published |
unit.deprecated | Transition to deprecated |
unit.tampered | Fingerprint mismatch detected |
unit.fingerprint.verified | Successful re-verify |
unit.import.resolved | Bridge resolver satisfied a cross-scheme URI |
chain.gate.fired | CI gate began |
chain.gate.resolved | CI gate ended (pass or fail) |
Envelope Fields
eventId (UUID), eventType, eventVersion ("1.0"), domain, timestamp (RFC 3339), idempotencyKey, source (service:component:version), payload, meta.
Delivery Guarantees
At-least-once via durable JetStream consumers. 30-second processing timeout, 30-day retention, DLQ on consumer NAK exhaustion. Consumers MUST dedupe on idempotencyKey.
Key Terms
- Durable consumer → a JetStream subscription that survives reconnects and tracks acknowledgements per consumer name.
- idempotencyKey → the dedupe key emitted alongside the event; stable across redeliveries.
- DLQ → dead-letter subject the broker forwards to once a message exhausts its redelivery budget.
Q&A
Q: Are events delivered exactly-once?
A: No — at-least-once. Exactly-once semantics are the consumer’s responsibility, achieved via the idempotencyKey.
Q: Why mirror to choco.strat.* instead of having Choco subscribe directly?
A: It gives the Choco platform an isolated subject hierarchy with its own retention and ACL policy, decoupled from STRATT’s namespace.
Examples
A unit.deprecated for strat://dev/rule/no-secrets@1.0.0 is published on strat.dev.unit.deprecated, forwarded to choco.strat.dev.unit.deprecated, with idempotencyKey derived from (eventType, uri, fingerprint).
neighbors on the map
- Dependency DAG & Blast Radius estimating the impact of changing a shared rule