Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

State Persistence

Spells can maintain state across runs using the state section and a local SQLite store.

The state Section

Declare named state variables in your spell:

spell StatefulStrategy {
  state: {
    persistent: {
      last_rebalance_at: 0
      total_volume: 0
    }
    ephemeral: {
      current_price: 0
    }
  }

  venues: { dex: @uniswap_v3 }

  on hourly: {
    current_price = price(ETH, USDC)

    if current_price < 2000 {
      dex.swap(USDC, ETH, 1000)
      state.total_volume = state.total_volume + 1000
      state.last_rebalance_at = now()
    }
  }
}
State typeLifetimeDescription
persistentSurvives across runsSaved to SQLite after each execution
ephemeralCurrent run onlyReset to declared defaults each run

Storage

State is stored in a local SQLite database:

.grimoire/grimoire.db

Configurable with --state-dir <dir> on any CLI command.

Inspecting State

Terminal
# List spells with persisted state
grimoire history
 
# List all runs for a spell
grimoire history spells/my-strategy.spell
 
# Inspect the event ledger for a specific run
grimoire log spells/my-strategy.spell <runId>

Bypassing State

Run without reading or writing state:

Terminal
grimoire simulate spells/my-strategy.spell --chain 1 --no-state

Useful for isolated testing or CI environments.

Advisory Replay

State is also used to record and replay advisory decisions. When you simulate a spell with advisory blocks, the model's outputs are saved to the ledger. You can then replay those exact decisions for live execution:

Terminal
# Simulate and record advisory outputs
grimoire simulate spells/my-strategy.spell --chain 1
 
# Replay recorded decisions during live cast
grimoire cast spells/my-strategy.spell \
  --chain 1 \
  --key-env PRIVATE_KEY \
  --rpc-url <rpc> \
  --advisory-replay <runId>

See Advisory Decisions for more.