Runtime Model

The runtime model defines how Asset Core processes state changes and serves queries with deterministic, auditable guarantees.

Problem this concept solves

Distributed systems face a fundamental tension between consistency, availability, and partition tolerance. Traditional approaches often sacrifice one to achieve the others, leading to:

  • Race conditions when multiple writers update the same state
  • Lost updates when concurrent changes overwrite each other
  • Non-deterministic behavior that makes debugging and auditing difficult
  • Expensive consensus protocols that add latency and complexity

Asset Core solves these problems by embracing a single-writer architecture with event sourcing, trading horizontal write scalability for absolute determinism and simplicity.

Core ideas

Single-Writer World

Each world has exactly one writer. This eliminates:

  • Coordination overhead between writers
  • Race conditions on state mutations
  • The need for distributed locks or consensus

The write daemon serializes all commits through a single pipeline. While this limits write throughput to what one node can handle, it guarantees that every commit sees a consistent view of the world.

Commit Log as Source of Truth

All state changes are recorded as events in an append-only commit log:

  • Events are sealed into batches before acknowledgement
  • Batches are durably persisted before clients receive success responses
  • The log is the authoritative record of everything that happened

This design enables deterministic replay: given the same sequence of events, any reader will reconstruct the same state.

Projections

Projections are read-optimized views of state derived from the commit log:

  • The read daemon tails the commit log for new batches
  • Events are applied via replay to update in-memory state
  • Snapshots are published atomically for query serving

Projections are eventually consistent with the commit log. The gap between committed events and published projections is the freshness lag.

Three-Layer Architecture

The runtime separates concerns across three layers:

LayerResponsibilityBehavior
L1 (Storage)Raw data mutationsNo validation, no events
L2 (Operations)Business logicValidates preconditions, emits events
L3 (Transactions)CoordinationRecords undo, handles replay

This separation ensures that:

  • Storage operations are fast and predictable
  • Business rules are enforced consistently
  • Transactions can be rolled back atomically

How it fits into the system

The runtime model shapes every aspect of Asset Core:

Write Path:

  1. Client sends commit request
  2. Write daemon validates and executes operations (L2/L3)
  3. Events are sealed and persisted to commit log
  4. Client receives success with sequence number

Read Path:

  1. Read daemon tails commit log
  2. Events are replayed via L1 setters (idempotent)
  3. Projections are published via atomic swap
  4. Queries read from current projection

Recovery:

  1. Load checkpoint (last known good state)
  2. Replay events from checkpoint position
  3. Resume normal operation

Key invariants and guarantees

Determinism

Given the same event sequence, replay produces identical state. This requires:

  • Operations emit post-state in events (not deltas)
  • Replay uses L1 setters (no arithmetic, no validation)
  • No external dependencies during replay

Idempotency

Applying the same event twice has no additional effect:

  • Events carry the final state to set
  • Replay simply overwrites with that state
  • Safe to retry after failures

Atomicity

All operations in a commit succeed or fail together:

  • L3 records undo steps during execution
  • Failures trigger rollback of all changes
  • No partial commits are visible

Crash Safety

The system recovers correctly from crashes:

  • Commit log survives restarts
  • Checkpoints record progress
  • Replay reconstructs any missing state

See also