The transactional execution core
Every mutation follows one rule: committed PostgreSQL rows are the input and output of the workflow transition. A replica does not continue from a mutable process object retained from an earlier request. This is the ACID rail that carries every workload identically — legacy BPMN, native APL, decision tables, agent steps and the Insight loop’s terminal facts.
Atomic command lifecycle
Section titled “Atomic command lifecycle”sequenceDiagram
actor Client
participant API as Controller
participant Command as Core command
participant DB as PostgreSQL
participant Outbox as Outbox dispatcher
Client->>API: mutation + identity + optional idempotency key
API->>Command: typed command
Command->>DB: begin transaction
Command->>DB: load and lock authoritative rows
DB-->>Command: committed state
Command->>Command: authorize and validate
Command->>Command: advance canonical state
Command->>DB: persist state, work, facts, history and outbox
Command->>DB: commit
Command-->>Client: deterministic result
Outbox->>DB: lease committed events
Outbox-->>Client: retryable lifecycle delivery
- Load. Fetch the definition version and mutable aggregate records needed by the command.
- Lock. Use row locks for single-winner transitions and optimistic versions for stale-write detection.
- Authorize and validate. Check the authenticated permission, task assignment, current status, lease ownership and command inputs.
- Advance. Execute the canonical process model — APL and BPMN compile to the same graph — and create successor tokens or durable work.
- Persist. Store variables, tasks, subscriptions, jobs, history, terminal Insight facts, idempotency result and outbox events in the same transaction.
- Commit. Only a successful commit makes the transition visible.
Deterministic law, probabilistic advice
Section titled “Deterministic law, probabilistic advice”The execution core separates what runs inside the transaction from what must not:
| Concern | Where it runs |
|---|---|
Decision tables (FIRST/UNIQUE/COLLECT, otherwise fallback) |
Inside the transaction — reproducible, audited as DECISION_TABLE_APPLIED |
| Scripts and embedded delegates | Inside the transaction, for deterministic local logic |
Agent nodes and engine-tasks |
Durable external tasks; a worker reports back through a command |
| Insight terminal facts | One idempotent row per terminal node visit, written in the command transaction |
| Model and tool calls | Never inside a workflow transaction |
A probabilistic output is never trusted as an engine decision: agent results
merge through the normal external-task completion command, and Insight
proposals are discarded unless AplParser validates them and a human
approves them.
Failure semantics
Section titled “Failure semantics”- Failure before commit rolls back workflow state, new work, facts, history and outbox records together.
- Failure after commit leaves durable progress. An idempotency record lets a duplicate API mutation replay its logical response.
- Scripts and embedded delegates run inside the transaction, but an irreversible external side effect cannot be rolled back by PostgreSQL.
- External tasks are the preferred boundary for remote effects; workers must make at-least-once effects idempotent.
Cache policy
Section titled “Cache policy”The sole execution cache stores immutable parsed definitions keyed by deployment ID. A new process start queries PostgreSQL for the latest version; an existing instance reloads its pinned version. Evicting the cache changes latency, not semantics.
Mutable instances, tokens, joins, tasks, subscriptions, timers, jobs, variables and facts never live in runtime-wide maps. Command-local maps are allowed only while materializing and advancing one locked aggregate.
Executable boundary
Section titled “Executable boundary”Controller-reachable mutations enter services marked with
@AtomicRuntimeCommand. AtomicRuntimeCommandContractTest inventories that
boundary, while PostgreSQL rollback and two-context tests prove the behavior
under failures and concurrent commands.