client_ops and Metadata in sync_metaDate: 2026-04-10 Status: Accepted
Client sync state is currently persisted via a DataScript-backed store in the
dedicated client-ops-* sqlite database (kvs + DataScript entities).
This design has become a bottleneck for local sync hot paths:
local-tx, checksum, graph uuid) and operation payloads are mixed
in DataScript entity shape, which complicates low-level sqlite debugging and
parity with server-side sync storage.Server sync storage already uses explicit sqlite tables (tx_log,
sync_meta) over the same sqlite runtime. Client storage should follow the
same direction.
client-ops-* sqlite database file.
Do not merge this storage into the main graph sqlite DB in this change.sync_meta for key/value metadata rowsclient_ops for operation rowssync_meta schema:
key TEXT PRIMARY KEYvalue TEXTsync_meta keys for this ADR:
local-txchecksumgraph-uuidclient_ops stores both local tx ops and asset ops (single table,
discriminated by row kind).client_ops minimum columns:
id INTEGER PRIMARY KEY AUTOINCREMENTkind TEXT NOT NULL ('tx' or 'asset')created_at INTEGER NOT NULLtx_id TEXT (uuid string)pending INTEGER NOT NULL DEFAULT 0failed INTEGER NOT NULL DEFAULT 0outliner_op TEXTundo_redo TEXT (undo/redo/none)forward_outliner_ops TEXT (Transit string)inverse_outliner_ops TEXT (Transit string)inferred_outliner_ops INTEGERnormalized_tx_data TEXT (Transit string)reversed_tx_data TEXT (Transit string)asset_uuid TEXTasset_op TEXT (update-asset/remove-asset)asset_t INTEGERasset_value TEXT (Transit or JSON string payload)UNIQUE(tx_id) where kind='tx' and tx_id IS NOT NULL(kind, pending, created_at, id)(kind, asset_uuid)asset ops must be stored in client_ops (not separate DataScript
entities).d/datoms/d/entity over client-op storage.sync_meta).client_ops/sync_meta use sqlite transactions.(created_at, id) order.tx_id and must continue to read forward/
inverse semantic ops from persisted local tx rows.pending and failed flags are explicit row state and must not be inferred
from absence.Chosen policy: no migration from old DataScript client-op entities.
On first open with this schema:
sync_meta + client_ops tables and indexes.Rationale:
Focused verification after implementation:
bb dev:test -v frontend.worker.db-sync-test/handle-local-tx-persists-pending-local-tx-test
bb dev:test -v frontend.worker.db-sync-test/flush-pending-clears-pending-local-tx-count-test
bb dev:test -v frontend.worker.undo-redo-test/undo-history-records-semantic-action-metadata-test
bb dev:test -v frontend.worker.db-sync-test/asset-ops-queue-coalesces-update-and-remove-test
Additional checks:
(created_at, id) order.tx_id.local-tx, checksum, and graph-uuid read/write through sync_meta.