Skip to content
Looms
Documentation
On this page

Execution model

This notation describes the execution model. It is not a proof of implementation correctness. Replay assumes deterministic reducers, compatible definitions, and available event history or a compatible snapshot.

1. The Canonical Run Log#

A Run RR is a tuple consisting of a globally unique run identity rr and an ordered, append-only sequence of immutable events LL:

R=(r,L),L=⟨e1,e2,…,en⟩R = (r, L), \quad L = \langle e_1, e_2, \dots, e_n \rangle

Every agent, DAG workflow, child thread, external signal, and observable effect outcome participates in this single, canonical event stream.

2. Thread Universe & Parent Relation#

The units of computation participating in Run RR form a thread universe XRX_R with a partial parent relation:

XR={x∣x is a Thread belonging to Run R}X_R = \{ x \mid x \text{ is a Thread belonging to Run } R \}
parent:XR⇀XR\text{parent} : X_R \rightharpoonup X_R

The root thread x0x_0 has parent(x0)=⊥\text{parent}(x_0) = \bot. Every child thread references its parent, inducing a strict tree hierarchy over threads within the run.

3. State Transition Function#

Each thread kind kk (e.g. agent, workflow, or a custom module kind) defines a pure, deterministic state transition function:

δk:Sk×E→Sk×F∗\delta_k : S_k \times E \to S_k \times F^*
(st+1x,Φtx)=δk(stx,et)(s_{t+1}^x, \Phi_t^x) = \delta_k(s_t^x, e_t)

Given current state stx∈Sks_t^x \in S_k and incoming event et∈Ee_t \in E, the reducer deterministically computes next state st+1xs_{t+1}^x and an ordered sequence of requested effects Φtx∈F∗\Phi_t^x \in F^*.

4. Projections as Folds#

Compute state and read models by folding over the event log:

P(L0…n)=fold(reduce,S0,⟨e1,…,en⟩)P(L_{0 \dots n}) = \text{fold}(\text{reduce}, S_0, \langle e_1, \dots, e_n \rangle)

With persisted snapshot checkpoints at event sequence m≤nm \le n, state reconstruction is accelerated:

Sn=fold(reduce,Sm,⟨em+1,…,en⟩)S_n = \text{fold}(\text{reduce}, S_m, \langle e_{m+1}, \dots, e_n \rangle)

5. Causal Ordering vs. Structural Hierarchy#

Log order records when events were appended. Causation IDs record which event caused each one:

ei≺cej  ⟺  causationId(ej)=id(ei)e_i \prec_c e_j \iff \text{causationId}(e_j) = \text{id}(e_i)

Events from concurrent threads can interleave in the log while retaining their causal links.

6. Replay & Durability Invariant#

Let πx(L)\pi_x(L) denote the projection filtering events relevant to thread xx. The state at logical step tt is reproducible under those assumptions:

stx=fold(δkstate,s0x,πx(L≤t))s_t^x = \text{fold}(\delta_k^{\text{state}}, s_0^x, \pi_x(L_{\le t}))

During historical replay, the effect stream Φ\Phi is ignored by the runtime kernel. Recovery also resumes unfinished work, which may retry external calls. Safe retries require idempotency or reconciliation at the external boundary.

See Concepts for the mental model, vocabulary, and event/effect boundary.