Event Bus
The sixth of ArcFlow's eight layers. Owns pub/sub — topics, consumer groups, durable offsets, ack/nack semantics, dead-letter handling — all backed by the same WAL that makes the graph itself durable.
One-sentence disambiguation: Event Bus watches what publishers say; Live Surface watches the graph. If the question is "what did the producer say?", you want the Event Bus. If the question is "what changed in my view of the graph?", you want the Live Surface.
The Event Bus is what lets agents coordinate without a separate message broker. Two processes on the same machine that share a workspace can publish + subscribe to topics; the bus carries the messages, persists them, replays them on restart, and tracks per-consumer offsets — without spinning up a JVM, a sidecar, or a network listener.
Event Bus vs Live Surface — when to use which#
The two layers both produce streams of typed records, which is why they're often conflated. They differ in what the contract is about — a topic name on one side, a Cypher pattern's result set on the other:
| Property | Event Bus | Live Surface |
|---|---|---|
| What you subscribe to | A topic name (or wildcard pattern) | A Cypher pattern's result set |
| Who decides what's emitted | The publisher, by choosing what to send | The engine, by observing graph mutations against the pattern |
| Payload shape | Whatever the publisher published — opaque to the bus | Typed deltas (added / removed rows) — schema matches the RETURN clause |
| When events fire | When a publisher calls publish(topic, payload) | When a graph mutation changes the pattern's result set |
| Canonical question | "What did the producer say?" | "What changed in my view of the graph?" |
| Typical uses | Sensor telemetry; cross-process intent relay; ingest progress notifications; system events like _system.partitions.added | Live dashboards; agent loops watching for new high-confidence facts; replication of derived state |
| Wrong tool when… | You want to react to graph changes without writing a publisher | The producer wants to send a message that isn't a Cypher result |
The same agent often uses both: a standing query observes the graph and emits deltas (Live Surface); a workflow program turns those deltas into outbound notifications on a topic (Event Bus); downstream consumers subscribe to the topic. Same agent, two layers, separate contracts.
What the bus provides#
| Capability | What it does |
|---|---|
| Topics | Named streams of typed messages. |
| Publish | Producers append to a topic; the bus commits the message to the WAL. |
| Consumer groups | Multiple subscribers can join a group; each message is delivered to one member of the group. |
| Offsets + ack/nack | Per-consumer offsets persist across restarts; explicit ack advances the offset, nack redelivers. |
| Dead letter | Failed-redelivery messages move to a DLQ topic the operator can inspect. |
| Pattern subscription | pattern.topics_matching lets a consumer subscribe to a glob of topics. |
Why pub/sub is embedded#
Most pub/sub systems are external — a separate process, a network protocol, a cluster of brokers. The Event Bus rejects that shape for the same reason ArcFlow rejects the "graph database as a server" shape:
- In-process pub/sub is sub-millisecond. No serialisation hop, no network round-trip, no broker.
- One durability story. The same WAL that records graph mutations records bus messages. One fsync, one replay path, one crash-recovery sequence.
- One identity story. A message carrying a graph node ID does not need translation between systems.
For multi-process coordination on the same machine, the bus surfaces over a Unix Domain Socket — see Daemon (UDS).
Why this is its own layer#
The Event Bus and the Live Surface look similar from the outside — both produce streams of typed records. They are different in what they carry:
- The Live Surface carries deltas from a standing query. The Cypher pattern is the contract; the delta is the change to the result set.
- The Event Bus carries messages on a topic. The topic name is the contract; the message is whatever the producer published.
A subscriber to a live view watches the graph. A subscriber to a topic watches whatever the producer chose to publish. Both have their place.
Why this matters for agents#
The bus is how agents talk to each other in the same workspace. Examples:
- A capture process publishes telemetry to
telemetry.{source}; a perception process subscribes pattern-matched. - A behavior program emits intents to
intents.{agent_id}; a controller subscribes to a single agent's intents. - A long-running ingest publishes progress to
ingest.progress; an observer in a separate process consumes.
Compared to building this on top of a generic message broker, the bus is one binary, one config file, one persistence story.
See also#
- Event Bus — the canonical surface reference + worked examples.
- Event Sourcing — using the bus as the source-of-truth log.
- Daemon (UDS) — the cross-process delivery shape.
- Intent Relay — high-level coordination patterns layered on top of the bus.