Concepts

Atomic commits

Keep each supported write and its synchronization metadata together.

Each supported Silo database mutation commits its data change and mutation journal entry in one SQLite transaction. When synchronization is configured, the pending outbox change is committed in that same transaction. If any part of that mutation fails, SQLite rolls it back.

Add several rows as one operation

silo row add accepts one row or a JSON array. Use an array when the rows must succeed or fail together. This example assumes the issues table from Getting started:

printf '%s\n' '[{"title":"Review migration plan"},{"title":"Update release notes"}]' \
  | silo row add issues

Silo validates every row before commit. If either row fails validation or a SQLite constraint, neither row is saved. On success, the rows, one mutation journal entry, and—when synchronization is enabled—one outbox changeset commit together. Two separate CLI commands are two separate operations.

What commits together

Effect Contract
User data The rows, schema, saved query, or report changed by the command.
Mutation journal One entry records the operation and resources that may need refreshing.
Synchronization state When configured, one changeset-backed pending transaction contains the supported data change.

Schema changes use a full-checkpoint transaction instead of a row changeset. Synchronization reapplies or rejects each pending transaction as a unit; it does not merge application semantics or select a last writer. See Synchronization model for the checkpoint and conflict protocol.

Failure and boundaries

If validation, a missing row, a constraint, or a revision check fails, the operation leaves no partial data, journal entry, or pending synchronization transaction. Read the latest state before deciding whether to retry.

The Rust database crate owns writable SQLite access. silo sql and saved-query execution are read-only. Writing directly to the SQLite file bypasses Silo's validation and bookkeeping. Separate CLI commands do not share a larger transaction; use one array input for a set of row additions or upserts that must commit together.

The mutation journal is bounded change metadata for internal readers. It is not an event replay API or audit history.