Expand description
SQLite-backed ReplayStore using [rusqlite-isle].
The crate::store::run::sqlite::SqliteRunStore pattern is the same:
the Connection is confined to a dedicated OS thread by AsyncIsle
and every call is a typed closure dispatched over a bounded channel.
ctx_snapshot_json and step_output_json are stored verbatim as
TEXT; the caller (the dispatcher) is what canonicalizes shape via
super::hash_input_value.
§Schema
CREATE TABLE IF NOT EXISTS replay_log (
seq INTEGER PRIMARY KEY AUTOINCREMENT,
run_id TEXT NOT NULL,
step_ref TEXT NOT NULL,
input_hash TEXT NOT NULL,
occurrence INTEGER NOT NULL,
ctx_snapshot_json TEXT NOT NULL,
step_output_json TEXT NOT NULL,
created_at INTEGER NOT NULL,
UNIQUE (run_id, step_ref, input_hash, occurrence)
);
CREATE INDEX IF NOT EXISTS ix_replay_run ON replay_log(run_id, seq);§Schema versioning
The current schema is tracked with SQLite’s PRAGMA user_version as the
single source of truth (1 = the two-column split above). [init_schema]
reads the value on every open and dispatches:
user_version = 0(fresh DB, or a legacy file created by mse ≤ v0.10.0 / pre-Core-primitive that used avalue_jsonsingle column): if a legacyreplay_logtable is present it isDROPed before the current schema is created, thenuser_versionis stamped to1. Legacy rows carry noctx_snapshot_json, so they cannot be replayed against the current wire anyway — dropping them is safe.user_version = 1: the current schema;CREATE ... IF NOT EXISTSis still run defensively.user_version > 1: reject with an error — an older mse binary must never touch a store written by a newer one.
Future migrations follow the same pattern: add a 1 => migrate_v1_to_v2
arm and stamp user_version = 2.
Structs§
- Sqlite
Replay Store - SQLite-backed persistent
ReplayStore.