storage-kit
This crate is preparing its initial 0.0.1 release. Backwards compatibility is
not guaranteed until 1.0.0; pin exact versions and review release notes before
upgrading.
storage-kit provides two focused Rust APIs:
Databasefor portable data, retrieval, and indexes with always-available LanceDB and opt-in SurrealDB.StateStore -> StateTransactionfor revisioned control-plane state with always-available embedded Lance and opt-in Redb/PostgreSQL/SQLite.
The crate-provided handles use closed built-in dispatch. Callers implement
DatabaseBackend, StateStoreBackend, and StateTransactionBackend directly
on their own concrete types or enums. A caller-owned StateStore enum returns
its caller-owned transaction enum through StateStoreBackend::Transaction;
storage-kit performs no erasure or normalization.
Construction
Built-ins use direct configuration:
use ;
async
use ;
async
There are no builders, durable factories, public conformance owners, storage tool adapters, or public realtime API.
The default embedded Lance StateStore is selected explicitly:
use ;
use ;
use ;
async
Use LanceStateStoreConfig::memory() for an independent process-local store;
clones of its connected handle share that store. Directory mode targets macOS
and Linux. A Lance Database may use the same directory for knowledge collections;
the private state collection is reserved, including ASCII case variants.
The default 30-second timeout bounds admission and observation, not accepted
commit authority or final filesystem joining. Read preconditions inside the
transaction; reconcile a durable application receipt after ambiguous errors.
The evidence ledger records the embedded backend's macOS/APFS and Linux/ext4 validation, consumer and packaged-build checks, and measured capacity. Those results apply to the recorded source, locked dependency graph, and execution environments. The focused verifier runs ordinary real-engine, public-API, and owned-process checks. The privileged fault campaign remains excluded. JSON values retain the existing public representation; the private codec does not impose a nesting limit. Each ordinary read opens a fresh native view and validates its identity before reusing the worker's decoded image. Cold connections and externally changed identities still require a complete scan and decode. Maintenance also scans and validates every native row, but exact previously validated payload bytes can reuse their decoded values. Each private JSON owner retains its encoded bytes in addition to the parsed value; unchanged clones share both. Transactions at one image can share it; transactions retaining different versions retain separate complete images. Multipart writes buffer their payloads. These costs have no implicit transaction expiry, payload-size or record-count cap.
Private maintenance reclaims obsolete native history and unpublished files only while every supplied snapshot lease is absent. It retains the current version and every tombstone, preserving exact logical revisions. Long-lived transactions can defer reclamation indefinitely, and tombstones still grow with the set of deleted keys. Connection-triggered orphan cleanup also scans retained manifest metadata before deleting unpublished files. These memory, storage and contention costs belong in the measured capacity envelope and any deployment sizing. Hosted/external Lance storage and Windows qualification are outside the supported embedded scope.
Recovery and cold backups
An exact TransactionConflict means that transaction published nothing. An
observation timeout or other finalization error can leave a committed result.
For a retryable application operation, put its durable receipt and data changes
in the same transaction. After an uncertain result, read that receipt before
authoring the operation again; a missing receipt while the original commit is
still running is not a rollback acknowledgment.
use ;
use ;
async
Callers own the retry policy and stable operation identifier. A newly authored transaction reads both the receipt and current checkpoint before deriving its next step, then publishes the checkpoint and receipt together. Ordinary polling alone does not fence a retry against concurrent publication. The Kit never automatically replays an authored transaction after uncertainty.
For a cold backup, stop new work in every process using the directory, settle accepted Agent/App work, and release every transaction, StateStore, and same-directory Database handle. Final handle release joins its accepted native work. Copy the entire directory only after all writers and owners have settled. This preserves tombstones, revisions, manifests, retained versions, and knowledge collections. A live recursive copy is not a supported coherent backup, and a StateStore transaction does not include Database effects.
Restore into a new empty directory, open it using the ordinary constructors, and verify application receipts and records before resuming work. Keep the original backup until validation succeeds. Do not repair a corrupt private table by deleting manifests, tombstones, or the sentinel, and do not overwrite an active directory. Cold-copy/restore coverage and its current execution receipt belong in the evidence ledger.
The current native family is LanceDB 0.40.0 with Lance 13.0.0. The supplied
configuration remains local-only. LanceDB's remote feature is enabled solely
to compile its 0.40.0 job decoder; this does not expose a remote deployment or
enable its cloud object-store features.
For a Kit upgrade, first retain a cold copy and validate the candidate against that copy. Stop all older processes before starting the candidate: older prototype clients do not participate in the new private snapshot leases and cannot safely share maintenance with it. The private table still requires schema version 1, Lance file format 2.0, and disabled stable row IDs. Native maintenance or a format upgrade outside the supplied adapter is unsupported. The private reclamation rules depend on the pinned native layout and filenames; a dependency upgrade must requalify those rules before use. Both maintenance paths validate retained references and sweep recognized unreferenced files without assuming that filesystem and manifest clocks agree. Cut over only after application reopen and receipt checks pass, and resume a rollback copy only while all writers are stopped. The portable list/put API cannot migrate exact hidden tombstone revisions from another backend; existing Redb files are never automatically converted or reinterpreted as Lance directories.
For SurrealDB 3.3 embedded memory, RocksDB, and SurrealKV, deep native queries
in unoptimized builds may need an 8 MiB stack on the thread polling the query
future. The upstream debug-test configuration
sets that size, and the crate's embedded regression workloads need it. When
using a current-thread runtime or polling the query directly through
Runtime::block_on, configure the enclosing OS thread with
std::thread::Builder::stack_size(8 * 1024 * 1024). Tokio's
thread_stack_size
configures runtime-created worker threads; it does not resize the calling
thread. Remote HTTP/WebSocket clients do not execute the embedded engine
locally.
Public Modules
database::config— Lance, Surreal, and shared construction datadatabase::catalog— collections and schema alterationdatabase::data— records and portable mutation requestsdatabase::query— retained cross-backend search operationsdatabase::index— portable index lifecyclestate::config— Redb, PostgreSQL, SQLite/Turso, and Lance constructionstate::record— keys, namespaces, records, revisions, and paginationstate::transaction— transaction-domain supporting values
Primary handles, backend traits, and errors remain at the crate root.
Portability
The Database surface contains only behavior with honest semantics in at least two backend families. Unsupported operations return explicit errors before mutation. Live handles and backend traits expose no reusable implementation identity or provenance discriminator. Backend clients, native requests, raw plans, trace/debug payloads, SQL, table layouts, and actor state stay private.
State transactions are owned, lifetime-free, and consumed by commit or rollback. Redb uses a bounded FIFO native-writer owner; PostgreSQL and SQLite/Turso use dedicated per-transaction connection actors. Transaction drop never detaches cleanup or commits implicitly.
StateStore is for Kit control-plane state. Database is for application data
and managed retrieval. Model-visible tools are caller-authored in tools-kit;
storage-kit has no tool runtime dependency.
Features
LanceDB for Database and embedded Lance for StateStore are always compiled,
including with default-features = false. The default feature list is empty.
Construction remains explicit through the existing configuration types; no runtime fallback
or automatic migration opens an existing Redb store as Lance.
| Optional feature | Implementation |
|---|---|
redb |
Redb StateStore |
postgres |
PostgreSQL StateStore |
sqlite |
SQLite/Turso StateStore |
surrealdb |
SurrealDB Database |
Existing users of these implementations must add the corresponding feature to
their dependency. Redb, PostgreSQL and Surreal configuration DTOs stay available
without their implementation feature; valid disabled construction returns the
existing InvalidConfig error before native I/O. SQLite retains its
existing feature-conditional configuration availability. Public traits and
caller-defined static implementations are unchanged.
Dependencies use public registry releases without workspace source patches.
Review the temporary advisory exceptions in
the dependency security policy.
Use the explicit supported feature lanes instead of Storage --all-features.
Run bash storage-kit/scripts/verify_strict_live.sh for default Lance coverage.
Use --backend NAME, --changed-since BASE, or --all-backends for additional
coverage; see testing. Alternative services and their
credentials are required only when selected.
More
Direct public-trait tests
Run bash scripts/check_mock_contracts.sh --crate storage-kit from the workspace
root for the credential-free mock lane. The workspace primary CI entrypoint is
bash scripts/check_ci.sh. See mock testing for
targets, evidence, runtime qualification, and the separate release/live gates.