appcore-sync-sqlite
Release candidate appcore-sync-sqlite 1.0.0-rc.2. Select this RC explicitly; it does not replace earlier stable releases or certify a deployment. Internal AppCore dependencies, where present, are pinned to each dependency’s independent RC.
English guide | Guia em português | Guide français
Optional post-1.0 SQLite persistence for AppCore synchronization state.
The crate implements the existing replication-log, outbox and checkpoint contracts. It also provides portable snapshots, bounded opaque tombstones, integrity inspection and verified online backup/restore. It never exposes a SQLite connection or accepts application SQL, tables, migrations or workflows.
Every database uses transactional internal schema V4, WAL, synchronous=FULL,
a bounded connection pool, busy timeout, SQLite runtime limits and startup
integrity validation. Unknown, unversioned and future schemas fail with
NO MORE SUPPORTED PLEASE UPDATE.
Schema V2 adds bounded attempt counters and readiness timestamps to the outbox.
peek and next_ready select count/byte metadata before reading BLOBs; stats
contain no payload and a partial receipt deletes only an exact ordered prefix
in one transaction. Enqueue measures the exact canonical JSON length first,
then writes directly to a zeroblob; duplicate comparison, page reads and
startup integrity validation also stream BLOB content. No encoded
record-sized Vec<u8> coexists with the owned message. The stream buffers use
the encoded record size up to fixed 64 KiB read and 1 MiB write ceilings, so a
small record never reserves either maximum. A known schema V1 database migrates
atomically with zeroed
retry metadata. Preserve a pre-migration backup for rollback.
Portable snapshot creation moves the payloads read from SQLite into the V1
snapshot. Restore validates the caller-owned snapshot by reference, checks its
aggregate payload against max_database_bytes before mutation and inserts
directly from those borrowed records in one transaction. No complete in-memory
replication log or second payload collection coexists with the snapshot.
The capability descriptor declares transactions, locking, snapshot,
online_backup and multi_process. It deliberately does not declare
streaming or multi_host.
This development crate is not selected by stable V1 manifests or by the SDK.
Direct consumers opt in explicitly. See
release/sqlite-sync-provider-v1.md.
Each pool connection and backup/restore auxiliary connection explicitly sets
and checks cache_size=-2048 and mmap_size=0. The cache setting is a suggested
2 MiB target, not a hard heap cap. Eight default pool connections imply about
16 MiB of cache targets before auxiliary connections, queries, temporary data,
WAL, payloads and allocator overhead. No process-global SQLite heap policy is
changed. Temporary storage and WAL growth still require deployment budgets.
See SQLite cache semantics.
Connections also request and verify temp_store=FILE before use, without
changing the process-global temporary directory. This is not a guarantee that
all temporary work goes to disk: SQLITE_TEMP_STORE=3 overrides the request
(the bundled Android build uses it). SQLite may also retain temporary pages
in cache. Deployments must inspect their build and budget private temporary
storage, memory and cleanup; memory-only builds need a separate memory budget.
See SQLite temporary storage.
WAL autocheckpoint at 1,000 pages is a trigger, not a disk-space cap. A held reader can prevent complete checkpointing while writers keep extending the WAL. An internal regression holds one read transaction across eight 1 MiB appends, observes more than 1,000 frames, then verifies truncation and intact records after releasing the reader and reopening. The test uses private SQL; it does not add a public checkpoint API. Bound readers/backups and monitor WAL and filesystem capacity in deployment; never delete a live WAL to reclaim space.
Replication-log pages now validate the aggregate length(payload) values
before converting any page BLOB into a Rust Vec. Count, metadata and payload
reads share one deferred transaction, so concurrent replacement cannot change
the admitted page between passes. An oversized selected page still fails as
a whole, preserving the existing contract. This adds a metadata pass and does
not bound SQLite's internal cache or provide streaming output.
Stable documentation
Stable ID: ACR-026. See the supplemental architecture and integration guide. This permanent ID remains valid if the wiki page moves.
Composed commits and recoverable objects (schema V3)
These APIs are independently versioned. Verify the exact registry package before consumer adoption.
SqliteSyncStore::transaction exposes a bounded SqliteSyncWork for log append, outbox enqueue, checkpoint and stage_object_write, in one immediate SQLite transaction with at most 1,024 operations. Propagate every error; callback failure/unwind rolls back. Do not reenter the store or perform network/filesystem work inside the callback. Full outbox is an error in this composition. Checkpoints require an authenticated observed head. conflict_store persists bounded evidence and idempotent resolution using existing Sync contracts (at most 4,096 conflicts). Known owned schemas V1/V2 migrate to V3; ownership is checked before migration. Unknown/foreign schemas fail at the version wall. Preserve a verified pre-V3 backup for rollback; older binaries must not open V3. Do not open an application database as this provider or infer compatibility between different rusqlite versions.
ObjectWriteIntentV1 journals encrypted/opaque envelopes up to 1 MiB, installation and opaque object key alongside outbox work. There are at most 4,096 intents; pages admit at most 1,024 records/16 MiB before payload reads. Replay committed intents in FIFO order with pending_object_writes, map keys through a safe application-owned path policy, atomically publish/sync/reverify each envelope, then call acknowledge_object_write with observed digest. Serialize object writes in the deployment and never reuse completed intent IDs. Ack records caller evidence, not independent filesystem verification. No universal filesystem/SQLite atomicity is promised. Online backup includes conflicts/intents; bind a combined filesystem/SQLite backup manifest to installation identity outside this provider.
Windows backup flush opens files and parent directories with write access and synchronizes metadata. Unsupported parent sync returns an error, never a successful durable-publication claim.
Release candidate — 2026-10-14
0.1.0-alpha.8: source changes.
Canonical opaque objects — V4 candidate 1.0.0-rc.2
opaque_objects_v1() adds bounded canonical encrypted/opaque envelopes to the
same database as log, outbox, checkpoints and materialization intents.
SqliteSyncWork::put_object_v1 applies an explicit absent/exact-revision
precondition. A durable mutation identity returns its original revision on exact
replay and rejects different bytes; replay never overwrites a later value.
Errors must propagate from the callback so all operations roll back together.
Keys are opaque safe identifiers (128 bytes); envelope limit is 1 MiB and opaque routing metadata is limited to 4 KiB. Debug omits identities and bytes. Metadata is not encrypted by this provider: deployments must keep secrets and business plaintext out of it. SHA-256 validates integrity, not authenticity; callers authenticate envelopes and own key management. No filesystem paths are resolved.
head and get are read-only. scan admits at most 1,000 records/16 MiB of
envelope+metadata per page before loading BLOBs. Capture the head before scanning,
then catch up changes; scans are not frozen historical snapshots. Changes use a
pinned revision range, deduplicate keys, validate generation and return values
current in the page transaction. Values can have revisions above the requested
range; cursor progress describes invalidations, not historical object values.
A too-small page fails rather than returning an empty non-advancing page.
Schema V4 migrates known owned V1–V3 databases additively. Older binaries reject V4; preserve a verified pre-migration backup for rollback. Online backup includes objects, generation and replay records. Portable replication snapshots still cover the existing log contract and are not full object-store backups.
Limits are 100,000 current keys (including tombstones), 1,000,000 retained changes and the configured database-byte bound. Capacity fails closed. This candidate does not yet expose change-log compaction or a bulk prior-state import contract; those remain required before promising unlimited lifecycle or application migration readiness. Registry availability must be verified independently for the selected version.
Security adoption: refresh and audit the consumer lockfile; ctutils must resolve to >=0.4.4 for RUSTSEC-2026-0385. This candidate package was validated with 0.4.4. Updating a library alone does not update an existing application lockfile.