Runtime Model
Turn execution is a process running. The configuration is the full state of that process at any point: environment, managed context, memory, mailbox, tool registry, pending effect, frames, and remaining bytecode.
Configuration (Process State)
| Component | Type | Lifetime |
|---|---|---|
| env | Map: identifier → value | Lexical: push/pop on blocks |
| context | Tripartite structured context (P0: system/primacy, P1: working/recency, P2: episodic/middle) | Per process. Token-bounded |
| memory | Isolated O(1) key-value store (HashMap) | Per process. Persisted across runs |
| mailbox | Message queue (send/receive) | Per process |
| tool_registry | Map: tool name → handler | Set at startup |
| turn_state | Turn ID + pending suspension | Updated on turn entry / suspension |
| pending_effect | Effect name + serialized argument | Set on suspension, cleared on resume |
| program | Remaining AST/bytecode | Current instruction pointer |
Config = (env, context, memory, mailbox, tool_registry, turn_state, pending_effect, program)
Serializable state = (env, context, memory, mailbox, turn_state, pending_effect)
Tool registry and program are provided separately on resume.Invariants
context.append(expr) writes into a bounded working tier. When that tier is full, the oldest working item moves to episodic memory; the oldest episodic item is eventually dropped when its bound is exceeded.
P0 (system prompt) is never evicted. When P1 (working/recency) overflows, oldest items are evicted to P2. P2 (episodic/middle) oldest items are dropped first.
All components are finite, valid structures at all times. No component is undefined or malformed.
The serialized VM state retains frames, stack, managed runtime state, mailbox, scheduler, gas, and any pending effect request required to continue execution.
Transition: One Step
Config → Config' or Config → Suspension(effect, arg, continuation). One step takes the configuration to a new configuration or to a suspension point.
Key transition rules:
let id = expr: evaluateexprand extendenvwith the bindingcontext.append(expr): evaluate the expression and append it to context (with token budget check)remember(k, v): update memory with the given key and valuecall(tool, arg): Suspension: the runtime executes the tool and resumes with its resultinfer Type { prompt }: Suspension: generative inference with a provider-facing schemadecide(state, questions): Suspension: bounded questions sent to a decision providersuspend: Suspension: writes a durable checkpoint to diskuse "path.wasm": Suspension: loads a Wasm module into its sandbox and returns closuresreturn expr: the turn completes with the given value
Deterministic Semantics
IMPORTANT
Turn's core language is deterministic: given a configuration and input sequence, execution is reproducible. Non-determinism is quarantined at effect boundaries (call, infer). Same inputs produce the same state transitions.
This enables deterministic tests when effect results are supplied explicitly. The current runtime persists pending effect requests and re-executes them after restart; it does not yet persist a complete effect-result journal for automatic offline replay.
The Universal Loop
1. Load: Initialize VM with Program + State (or fresh)
2. Run: Execute until Complete or Suspended
3. Handle: If Suspended(tool, arg, continuation):
a. Persist continuation + pending effect request
b. Execute the tool (async, human-in-the-loop, etc.)
c. Resume: clear pending effect, inject result, goto 2
4. Complete: Return final valueTHE ENGINEERING SOLUTION
This loop ensures the agent is never blocked on a thread. Instead, it is suspended in state, preserving all execution context until the next input arrives. This is the key to scalable, long-running agentic software.
WARNING
Pending effects replay with at-least-once delivery after restart. Non-idempotent tools need idempotency keys.