A pipeline binary takes ORCA_DATABASE_URL=sqlite:<path> (or
sqlite://<path>, so sqlite:///var/orca/runs.db is an absolute path):
run, resume and status then keep pipelines, runs, steps, attempts,
reads and commits in that file, through sqlite-mojo, with nothing to
operate. A run killed anywhere is resumed from the file as from Postgres,
by the same RunStore code path. The scheduler, the UI and orca's other
commands stay on Postgres (orca.state.State refuses a SQLite URL).
The tables are Postgres's, under the same names without the orca. schema,
holding what a pipeline binary writes: steps' inputs and outputs are hex
text, times are Unix seconds (julianday based, to the millisecond).
Concurrency. The file is in WAL mode, so readers (status, sqlite3)
don't block the writer and the writer doesn't block them. There is one
writer at a time: each change is one BEGIN IMMEDIATE transaction, which
takes the file's write lock up front, and a writer that finds it taken
waits up to a second (busy_timeout), then fails; the owned run's writes
are retried, reopening the file, for ORCA_DB_RETRY_SECONDS, as PgStore
reconnects. That serialises several runs' processes on one machine, which
is fine for steps that take seconds and rows that take microseconds; it
isn't meant for hundreds of runs at once. Claims are a single guarded
UPDATE, so two resumes racing for a run can't both win, and every attempt
checks ownership in its own transaction, as on Postgres. The file must be
on a local disk: SQLite's locks don't hold over NFS and most network file
systems, so two machines must not share one.
synchronous = FULL: a commit is on disk before it returns, so a power
loss, not only a killed process, keeps every recorded attempt.