Events — Concept
An event is an immutable record of something that happened. Events are never updated or deleted. All entity state and read models are derived from the event stream.
Facts, not commands
| Wrong (command) | Correct (fact) |
|---|---|
FOLLOW_ARTIST | ARTIST_FOLLOWED |
CREATE_ORDER | ORDER_CREATED |
SEND_EMAIL | EMAIL_SENT |
Intents are commands. Events are past-tense facts about what already occurred.
Global event registry
Event type names are global within an application. SHOW_ANNOUNCED cannot be declared for both artist and venue state — use domain-scoped names like ARTIST_SHOW_ANNOUNCED.
The compiler validates that every event_type in emit lists exists in events: before deploy.
Envelope vs payload
Every event carries automatic envelope fields:
| Field | Source |
|---|---|
event.type | Event type name |
event.ts | Millisecond timestamp |
event.entity_id | Entity ID from routing |
Payload fields are declared in events: and available as event.<field> in rules and projections. Never declare type, ts, or entity_id in payload.
Related docs
| Topic | Where to read |
|---|---|
| Events (this section) | Declaring, naming, dispatching, versioning in your app |
| Replay | Rebuilding state from the ledger |
| Debugging | Tracing ledger commits and intent outcomes |
Next steps
- Defining Events — DSL reference
- Dispatching Events —
op: emit - Examples — concert catalog