sagas — State Machine Workflows
How this compiles. Each step with on: is macro-expanded at compile time into an ordinary event-triggered core rule (op: merge into state_path, plus current_step). There is no separate Temporal-style saga engine. Optional from: becomes a when.expr guard on entity.<state_path>.current_step. See Defining Sagas for the full guide.
Sagas are entity-attached state machines that track multi-step workflows. State is stored under a _tmp/ path on the entity.
sagas:
order_lifecycle:
state: order
state_path: _tmp/order_saga
steps:
- name: idle
set: { status: idle }
- name: placed
on: ORDER_PLACED
from: [idle]
set: { status: placed }
- name: confirmed
on: ORDER_CONFIRMED
from: [placed]
set: { status: confirmed }
end: true
- name: cancelled
on: ORDER_CANCELLED
from: [idle, placed]
set: { status: cancelled }
end: trueSaga fields
| Field | Required | Description |
|---|---|---|
state | yes | Entity type that owns this saga |
state_path | yes | _tmp/ path to store saga state |
steps | yes | List of step definitions |
steps[].name | yes | Step id; stamped as current_step on enter |
steps[].on | no | Event that triggers this step (omit for idle / default) |
steps[].from | no | Prior current_step values required before this transition |
steps[].when | no | Extra expression guard (AND-ed with from) |
steps[].set | no | Fields merged into the saga object (alongside current_step) |
steps[].end | no | Terminal marker (authoring / docs intent; not a hard runtime lock) |
Composition with from:
- Without
from:— choreography style: any matchingon:event merges the step’ssetvalues. - With
from:— the expander requiresentity.<state_path>.current_stepto be one of the listed prior step names before the transition fires.
Every transition always writes current_step: <step.name> into the saga object so guards have a stable field.
Runtime compensation (separate)
DSL sagas: do not run Temporal-style compensations. For multi-entity 2PC abort paths, actions may declare reliability.compensating_intent — see Defining Sagas → Runtime reliability. That is a different subsystem from the sagas: macro.