Single-host SQLite persistence for the MCP Tasks extension.
This adapter accepts an application-owned Ecto.Repo; it never starts a
repository, creates a database file, or runs migrations. Task snapshots and
serializable work descriptors are stored atomically as versioned JSON. Each
applied event is committed to a separate ledger in the same transaction as
the aggregate update.
SQLite has no row locks and permits only one writer. Every store mutation
therefore uses an IMMEDIATE transaction, acquiring the database write
reservation before it reads availability, lease, revision, or clock state.
Competing writers wait according to the application Repo's :busy_timeout.
Exhausted contention is normalized to {:error, :database_busy}.
The supported deployment boundary is a file-backed WAL database on one
host. Recovery remains at least once, so applications must deduplicate
external effects with Snodo.Extensions.Tasks.Work.idempotency_key.
create/4 refuses a task with {:error, {:capacity_exceeded, limit}} when
the table already holds :max_tasks tasks (default 10,000) or the caller's
scope already has :max_active_tasks_per_scope working or input-required
tasks (default 100). Either may be :infinity. The counts are taken inside
the creating IMMEDIATE transaction. The per-scope count decodes the scope
of every active task, because scopes are compared as decoded values. An
expired task counts until it is reaped.
reap/1 deletes at most :reap_batch_size expired tasks per call (default
500). A runner calling it every :reap_interval_ms therefore removes at most
that many tasks per interval.
Summary
Functions
Audits one bounded page of aggregate and ledger rows.
Checks the migration and required file-backed WAL Repo settings.
Returns the validated applied-event history visible to request access.
Builds immutable adapter configuration around an application-owned Repo.
Builds adapter configuration or raises ArgumentError.
Types
@type audit_report() :: %{ checked: non_neg_integer(), errors: [map()], next_cursor: String.t() | nil }
Functions
@spec audit(Snodo.Extensions.Tasks.Store.SQLite.Config.t(), keyword()) :: {:ok, audit_report()} | {:error, term()}
Audits one bounded page of aggregate and ledger rows.
@spec check_schema(Snodo.Extensions.Tasks.Store.SQLite.Config.t()) :: :ok | {:error, term()}
Checks the migration and required file-backed WAL Repo settings.
@spec history(Snodo.Extensions.Tasks.Store.SQLite.Config.t(), String.t(), term()) :: {:ok, [map()]} | :not_found | {:error, term()}
Returns the validated applied-event history visible to request access.
@spec new(keyword()) :: {:ok, Snodo.Extensions.Tasks.Store.SQLite.Config.t()} | {:error, term()}
Builds immutable adapter configuration around an application-owned Repo.
@spec new!(keyword()) :: Snodo.Extensions.Tasks.Store.SQLite.Config.t()
Builds adapter configuration or raises ArgumentError.