> ## Documentation Index
> Fetch the complete documentation index at: https://docs.intention.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# State model

> What constitutes chain state, how it is keyed and versioned, and which of the three state representations is authoritative.

Three different things get called "state" in a trading engine, and confusing them is how systems end up with answers that depend on who you ask. This page separates them and says which one is authoritative.

## Three representations

<div className="dg" data-dg="state-model">
  <div className="dg-c" style={{aspectRatio:"720 / 288"}}>
    <svg className="dg-w" viewBox="0 0 720 288" aria-hidden="true">
      <path className="dg-wire dg--blue" d="M 215.00 90.00 L 243.60 90.00" />

      <path className="dg-head dg--blue" d="M 250.00 90.00 L 243.60 94.40 L 243.60 85.60 Z" />

      <path className="dg-wire dg--green" d="M 470.00 90.00 L 498.60 90.00" />

      <path className="dg-head dg--green" d="M 505.00 90.00 L 498.60 94.40 L 498.60 85.60 Z" />

      <path className="dg-wire dg--green dg-dash" d="M 615.00 145.00 L 615.00 176.00 L 105.00 176.00 L 105.00 151.40" />

      <path className="dg-head dg--green" d="M 105.00 145.00 L 109.40 151.40 L 100.60 151.40 Z" />
    </svg>

    <div className="dg-b dg--blue" style={{left:"0.0000%",top:"13.8889%",width:"29.1667%",height:"34.7222%"}}><span className="dg-t">Engine state</span><span className="dg-s">markets · accounts · positions · books · clearinghouse</span><span className="dg-n">lives across blocks · a reconstruction</span></div>
    <div className="dg-b dg--yellow dg-dashed" style={{left:"35.4167%",top:"13.8889%",width:"29.1667%",height:"34.7222%"}}><span className="dg-t">Block working set</span><span className="dg-s">marks · touched accounts · fills · staged output</span><span className="dg-n">lives for one block · a journal</span></div>
    <div className="dg-b dg--green" style={{left:"70.8333%",top:"13.8889%",width:"29.1667%",height:"34.7222%"}}><span className="dg-t">Chain state</span><span className="dg-s">versioned key-value, Merkle-authenticated</span><span className="dg-n">the authority</span></div>
    <div className="dg-b dg--orange dg-left" style={{left:"0.0000%",top:"72.9167%",width:"100.0000%",height:"23.6111%"}}><span className="dg-t">The failure this prevents</span><span className="dg-s">An engine whose in-memory view has drifted from what was committed keeps serving answers, and every one of them is wrong in a way that only shows up at settlement.</span></div>
    <div className="dg-lbl" style={{left:"50.0000%",top:"61.1111%",width:"45.8333%",whiteSpace:"normal"}}>engine state must be derivable from the committed record, never the other way round</div>
  </div>
</div>

**Engine state** is what the [kernel](/protocol/architecture/kernel) holds between blocks: market metadata, accounts, positions, order books, instrument state, clearinghouse state. It is the working representation — laid out for the access patterns matching and clearing actually have, not for storage.

**The block working set** exists only while a block executes: the marks fixed at the start, which accounts and orders were touched, the fills produced, the outputs being assembled. It is a journal of what happened during this block.

**Chain state** is the committed result: versioned key-value entries, authenticated by a Merkle structure, durable and replayable. It is what a node syncs, what a proof is against, and what an [indexer](/protocol/architecture/indexer) reads.

**Chain state is the authority.** The block working set is a journal used to build deterministic output — not a source of truth. Engine state is a reconstruction of chain state optimized for execution; it must be derivable from the committed record, never the other way round.

Getting this backwards is a specific, recognizable failure: an engine whose in-memory view has drifted from what was committed will keep serving answers, and every one of them will be wrong in a way that only shows up at settlement.

## Keys

Chain state is addressed by key. Trading state is grouped into named, explicitly versioned namespaces — for example the fee configuration, the perpetual index, the leverage tier table, the administrative role list.

The version suffix is not decoration. When the shape of a configuration changes, it moves to a new version of its key, and the previous key is retained so that state written under the old schema can still be read during migration. A reader that hard-codes one version and never re-checks will silently read stale configuration after a migration; a reader that resolves the current key will not.

<Note>
  This is why configuration should be read from the chain rather than pinned in client code. The [fee tier service](/protocol/architecture/programs) reads the live fee configuration on every cycle for exactly this reason — a tier table baked into a client is a table that will eventually disagree with the one the network is applying.
</Note>

## Versions

Every committed block advances a version. State values are stored against the version at which they were written, which means the store is not just "the current state" but "the state at any version."

That property is what makes several things possible at once:

* **Proofs** can be produced against a specific version rather than only against the present.
* **Replay** can start from any version, not just genesis.
* **Reads** can be historical — an indexer reconstructing a position's history is asking for old versions, not scanning a log.
* **Pruning** becomes a policy decision about how far back to keep, rather than a structural limitation.

## What ends up committed

Kernel execution produces two things per block. Each transaction carries its own writes and events, bound to it. Effects that belong to no single user transaction — funding flows, insurance movements, block-level counters — go to a distinguished system channel.

Between the two, nothing is lost. There is no execution effect inside the kernel that is absent from both a transaction's output and the system channel. That completeness is what allows the committed record to be treated as the whole story rather than a summary of it, and it is the reason an event can be traced back to the transaction that caused it even when matching ran as a batch.

## Where to go next

<CardGroup cols={2}>
  <Card title="Storage and proofs" href="/protocol/architecture/state/storage">
    How committed state is physically stored, authenticated, and pruned.
  </Card>

  <Card title="State sync" href="/protocol/architecture/state/sync">
    How a node that has never seen the chain catches up to it.
  </Card>

  <Card title="IntentionKernel" href="/protocol/architecture/kernel">
    Where engine state and the block working set live.
  </Card>

  <Card title="Indexer" href="/protocol/architecture/indexer">
    Turning committed state into something queryable.
  </Card>
</CardGroup>
