Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
07f8d91
fix: preserve persisted resume baseline integrity
KyleAMathews Sep 17, 2026
758532d
chore: add persisted resume integrity changeset
KyleAMathews Sep 17, 2026
8024319
Merge github/main into rfc-1659-ws1-red-oracle
KyleAMathews Sep 17, 2026
41c2645
test(sqlite): allow CLI oracle for CI load
KyleAMathews Sep 17, 2026
9d74e9b
fix(sqlite): preserve runtime-owned resume resets
KyleAMathews Sep 17, 2026
de7412f
ci: trigger PR checks
KyleAMathews Sep 18, 2026
f6c293e
docs(test): explain persisted resume oracles
KyleAMathews Sep 21, 2026
c44e908
Merge github/main into rfc-1659-ws1-red-oracle
KyleAMathews Sep 21, 2026
f80fa5c
fix: require complete sync persistence capability
KyleAMathews Sep 21, 2026
9c85990
fix: enforce complete persistence forwarding
KyleAMathews Sep 21, 2026
a330d43
fix(electric-db-collection): require certified resume evidence
KyleAMathews Sep 21, 2026
8533802
test(electric): cover on-demand resume evidence loss
KyleAMathews Sep 21, 2026
230190a
Merge remote-tracking branch 'origin/main' into rfc-1659-ws1-red-oracle
KyleAMathews Sep 21, 2026
b5c5d79
Merge github/main into rfc-1659-ws1-red-oracle
KyleAMathews Sep 21, 2026
2cafeb8
Merge concurrent PR head reconciliation
KyleAMathews Sep 21, 2026
6613b2c
fix(sqlite): reduce resume evidence overhead
KyleAMathews Sep 22, 2026
17bfedb
Merge github/main into rfc-1659-ws1-red-oracle
KyleAMathews Sep 22, 2026
abc74ad
test(sqlite-persistence): update adapter type oracle
KyleAMathews Sep 22, 2026
382b38b
fix(sqlite): preserve on-demand rows and trim evidence work
KyleAMathews Sep 22, 2026
063158c
docs(db): mark sync persistence protocol internal
KyleAMathews Sep 22, 2026
4d80452
docs(oracles): track reusable boundary laws
KyleAMathews Sep 22, 2026
924c689
docs(oracles): record reusable law owners
KyleAMathews Sep 22, 2026
46e7442
test(persistence): prove membership scan observer
KyleAMathews Sep 22, 2026
a8c2097
test(persistence): execute reusable boundary laws
KyleAMathews Sep 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .changeset/preserve-resume-baseline-integrity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
'@tanstack/db-sqlite-persistence-core': minor
'@tanstack/db': minor
'@tanstack/electron-db-sqlite-persistence': minor
'@tanstack/electric-db-collection': patch
'@tanstack/query-db-collection': patch
---

Preserve persisted resume integrity with atomic SQLite baseline evidence and stale-writer rejection, expose persistence sync metadata as one versioned capability, and refresh uncertified Electric baselines before publishing resumed data.

This changes the public persistence contracts: custom `PersistenceAdapter` implementations must now implement `loadResumeSnapshot`, and `SyncMetadataApi.persistence` is required with `null` explicitly representing no persistence. Custom sync wrappers must forward `metadata.persistence` unchanged so consumers receive either that sentinel or the complete versioned capability. The Electron bridge now transports the atomic resume snapshot through IPC protocol v2; Electron main and renderer integrations must upgrade together because mixed v1/v2 peers fail closed.
61 changes: 59 additions & 2 deletions docs/contributing/oracle-coverage.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,9 @@ comment and the current API/architecture contract before extending its model.
| Ordered acquisition | [pagination](https://github.com/TanStack/db/blob/main/packages/db/tests/query/pagination-oracle.property.test.ts), [ordered work](https://github.com/TanStack/db/blob/main/packages/db/tests/query/ordered-work-oracle.property.test.ts), [ordered lifecycle](https://github.com/TanStack/db/blob/main/packages/db/tests/query/ordered-lifecycle-oracle.property.test.ts) | Complete finite provider results, inherited collation with exact own-key request options, real lexical/numeric disagreement, pending windows, ties/nulls, ownership and documented repair timing. Request completion is not proof of unrequested source extent. |
| Join equality and cold acquisition | `packages/db/tests/query/cold-join-reconciliation-oracle.test.ts` | Independent recomputation for cold acquisition plus direct join/predicate equivalence across established equality domains. Binary/string and nullish classes, replacement histories, raw on-demand values, and both scan/auto-index paths are explicit; compound join syntax is not claimed. |
| Opaque backend pagination | [window oracle](https://github.com/TanStack/db/blob/main/packages/query-db-collection/tests/cursor-pagination.oracle.test.ts), [cache histories](https://github.com/TanStack/db/blob/main/packages/query-db-collection/tests/cursor-pagination.cache-oracle.test.ts), [cache publication](https://github.com/TanStack/db/blob/main/packages/query-db-collection/tests/cursor-pagination.publication-oracle.test.ts), [browser acquisition boundaries](https://github.com/TanStack/db/blob/main/packages/query-db-collection/tests/cursor-pagination.boundary-oracle.test.ts), [QueryCollection integration](https://github.com/TanStack/db/blob/main/packages/query-db-collection/tests/cursor-pagination.integration.test.ts) | Full filter/sort/slice reference, opaque token transport, actual Query cache expiry/invalidation/GC, forced refresh during growth, protocol failure publication/recovery, bounded slice work, nested cancellation/replacement, reader abort, browser retry defaults, manual-write cache isolation, and production window publications. Stable backend sequences; not snapshot guarantees for changing endpoints. Peek-ahead remains enabled. |
| Electric and TrailBase | [Electric histories](https://github.com/TanStack/db/blob/main/packages/electric-db-collection/tests/electric-oracle.property.test.ts), [PostgreSQL semantics](https://github.com/TanStack/db/blob/main/packages/electric-db-collection/e2e/sql-predicate-semantics.e2e.test.ts), [TrailBase contract](https://github.com/TanStack/db/blob/main/packages/trailbase-db-collection/tests/ORACLE.md) | Installed SDK delivery/framing, independent predicates, exact subscription arguments and late errors. SDK fixtures and a real service test earn different credit. |
| Electric and TrailBase | [Electric histories](https://github.com/TanStack/db/blob/main/packages/electric-db-collection/tests/electric-oracle.property.test.ts), [recovery histories](https://github.com/TanStack/db/blob/main/packages/electric-db-collection/tests/electric-recovery-oracle.test.ts), [held resume snapshots](https://github.com/TanStack/db/blob/main/packages/electric-db-collection/tests/electric-resume-snapshot-races.test.ts), [PostgreSQL semantics](https://github.com/TanStack/db/blob/main/packages/electric-db-collection/e2e/sql-predicate-semantics.e2e.test.ts), [TrailBase contract](https://github.com/TanStack/db/blob/main/packages/trailbase-db-collection/tests/ORACLE.md) | Installed SDK delivery/framing, independent predicates, exact subscription arguments, restart/reset lineage, held certification races, and late errors. The recovery fixtures use a mocked ShapeStream; they do not establish live Electric-service framing or native persistence-host behavior. |
| PowerSync | [tests](https://github.com/TanStack/db/tree/main/packages/powersync-db-collection/tests), `tests/correctness-oracle.test.ts` | Applied receipt positions crossed with held peers, native SQLite/SDK and cleanup evidence. Run the focused owner with the package's `test:oracles` command. A timeout mutant proves a progress failure, not every value assertion. |
| SQLite persistence and native hosts | [persisted histories](https://github.com/TanStack/db/blob/main/packages/db-sqlite-persistence-core/tests/persisted.test.ts), [driver contracts](https://github.com/TanStack/db/blob/main/packages/db-sqlite-persistence-core/tests/contracts/sqlite-driver-contract.ts), [browser OPFS lifecycle](https://github.com/TanStack/db/blob/main/packages/browser-db-sqlite-persistence/tests/opfs-page-lifecycle-oracle.test.ts), [worker diagnostics](https://github.com/TanStack/db/blob/main/packages/browser-db-sqlite-persistence/tests/opfs-worker-diagnostics-oracle.test.ts), [113-law manifest](https://github.com/TanStack/db/blob/main/packages/db-collection-e2e/src/fixtures/persisted-conformance-manifest.ts) | Cache/remote rejection/peer/reopen histories, exact driver results, controlled page/worker ownership, and diagnostic-cause retention. Fake workers and synthetic page events do not prove native handle release or real bfcache admission. The manifest excludes progressive and move suites; registration and shim runs are not device execution. |
| SQLite persistence and native hosts | [persisted histories](https://github.com/TanStack/db/blob/main/packages/db-sqlite-persistence-core/tests/persisted.test.ts), [reset/resume histories](https://github.com/TanStack/db/blob/main/packages/db-sqlite-persistence-core/tests/sqlite-core-adapter.test.ts), [dual-adapter resume snapshots](https://github.com/TanStack/db/blob/main/packages/db-sqlite-persistence-core/tests/sqlite-resume-snapshot.test.ts), [driver contracts](https://github.com/TanStack/db/blob/main/packages/db-sqlite-persistence-core/tests/contracts/sqlite-driver-contract.ts), [browser OPFS lifecycle](https://github.com/TanStack/db/blob/main/packages/browser-db-sqlite-persistence/tests/opfs-page-lifecycle-oracle.test.ts), [worker diagnostics](https://github.com/TanStack/db/blob/main/packages/browser-db-sqlite-persistence/tests/opfs-worker-diagnostics-oracle.test.ts), [113-law manifest](https://github.com/TanStack/db/blob/main/packages/db-collection-e2e/src/fixtures/persisted-conformance-manifest.ts) | Cache/remote rejection/peer/reopen histories, atomic reset/resume lineage, key-set evidence, dual-adapter races, exact driver results, controlled page/worker ownership, and diagnostic-cause retention. The reset/resume owners use sqlite3 CLI and in-memory node:sqlite seams; they do not prove multi-process WAL, mobile/Tauri, or other native-device execution. Fake workers and synthetic page events do not prove native handle release or real bfcache admission. The manifest excludes progressive and move suites; registration and shim runs are not device execution. |
| Offline execution | [scheduler](https://github.com/TanStack/db/blob/main/packages/offline-transactions/tests/KeyScheduler.property.test.ts), [leadership](https://github.com/TanStack/db/blob/main/packages/offline-transactions/tests/leadership-replay.property.test.ts), [settlement](https://github.com/TanStack/db/blob/main/packages/offline-transactions/tests/transaction-settlement.property.test.ts), [serialization](https://github.com/TanStack/db/blob/main/packages/offline-transactions/tests/transaction-serializer.property.test.ts) | Declarative FIFO eligibility, per-transaction outcomes, durable state and typed wire trees. Issued work may finish after ownership loss, but new work must not start. Exactly-once network execution is not promised. |
| Frameworks | [React conformance](https://github.com/TanStack/db/blob/main/packages/react-db/tests/conformance.test.tsx), [React pagination](https://github.com/TanStack/db/blob/main/packages/react-db/tests/infinite-query-conformance.test.tsx), [shared suites](https://github.com/TanStack/db/tree/main/packages/db-collection-e2e/src/suites) | Exact exposed rows/pages and each framework's own lifecycle cuts. A React witness does not prove Vue/Solid/Angular/Svelte scheduling. Preserve their receiving registrations. |
| Structural values and ordered primitives | [hash values](https://github.com/TanStack/db/blob/main/packages/db-ivm/tests/hash.property.test.ts), [hash graphs](https://github.com/TanStack/db/blob/main/packages/db-ivm/tests/hash-graph.property.test.ts), [mixed hash graphs](https://github.com/TanStack/db/blob/main/packages/db-ivm/tests/hash-mixed-graph.property.test.ts), [hash retry](https://github.com/TanStack/db/blob/main/packages/db-ivm/tests/hash-failure-retry.property.test.ts), [comparison](https://github.com/TanStack/db/blob/main/packages/db/tests/comparison.property.test.ts), [deep equality](https://github.com/TanStack/db/blob/main/packages/db/tests/utils.property.test.ts), [cursor](https://github.com/TanStack/db/blob/main/packages/db/tests/cursor.property.test.ts), [indexes](https://github.com/TanStack/db/blob/main/packages/db/tests/index-update.property.test.ts), [query identity](https://github.com/TanStack/db/blob/main/packages/db/tests/query/identity-output-shape-oracle.test.ts) | Independent flat values, graph topology, algebraic laws, Map/group/sort recomputation, expression denotation, and compiled output bags. Hash collision freedom is not promised. Unsupported composite cursors reject. |
Expand Down Expand Up @@ -188,6 +188,63 @@ project, worker progress RPC starvation produced passing assertions with a
nonzero process exit. Such a run is not green. Raising a test timeout alone
does not let the worker process its progress messages.

## Reusable-law backlog

RFC #1659 reviews found several green oracles whose stated laws remained valid
but whose fixtures, grammars, or observations did not cover a neighboring
boundary. Track the generalized repairs here instead of accumulating isolated
regressions. Completion requires an executable owner, a production-path witness,
a hostile wrong-answer control, and an explicit statement of remaining limits.

- [x] **Real-provider conformance fixtures.** Frozen 15.2.7 React Native and
Node receipts cover the supported peer version; 18.2.1 React Native, Node,
and browser receipts cover the known forward shapes. Exact-row checks and a
row-dropping hostile control prove the shim accepts those envelopes without
mutating them. Owner:
`packages/react-native-db-sqlite-persistence/tests/fixtures/op-sqlite-provider-results.ts`
and `packages/react-native-db-sqlite-persistence/tests/op-sqlite-driver.test.ts`.
Native device/host execution remains a separate runtime receipt.
- [x] **Minimal ambiguity and name invariance.** Generate one-field and
otherwise minimally distinguishable results. Renaming a selected column to a
structural-looking alias must not turn a data row into a write envelope.
Owner: `packages/react-native-db-sqlite-persistence/tests/op-sqlite-driver.test.ts`.
- [x] **Carrier coexistence and representation symmetry.** Cross `rows`,
`rawRows`, `columnNames`, and supported result containers, including legal
coexistence. Equivalent array and object forms must agree on rows or on the
documented rejection. Owner:
`packages/react-native-db-sqlite-persistence/tests/op-sqlite-driver.test.ts`
and the shared SQLite driver contract.
- [x] **Transitions at every relevant await.** Hold each coordination boundary,
then change leadership, remote-subset ownership, abort state, cleanup, or
restart generation before release. Owners: browser/electron coordinator,
persisted-history, and collection cleanup/restart oracles.
- [x] **Local-versus-transport refinement.** Compare local-leader and transported
remote-subset behavior for immutable values. Separately prove that local
`signal` and `subscription` references survive delivery and reach matching
unload cleanup. Owners: browser/electron coordinator and persisted-history
suites.
- [x] **Partial-construction cleanup.** Fail database, driver, worker, and
subscription construction after each acquired resource. Preserve the primary
failure while proving all acquired resources are released exactly once.
Owners: OP-SQLite driver-contract construction and OPFS page/worker lifecycle
suites.
- [x] **On-demand persistence after evidence changes.** Cross baseline versus
on-demand hydration with consistent, unknown, and incompatible key-set
evidence. A baseline certification failure must not silently erase valid
on-demand rows. `loadSubset` checks baseline visibility and on-demand rows;
the sync-absent `forceReloadSubset` route crosses the same startup evidence
states but records baseline visibility as unobserved because that API does
not expose baseline hydration. Owner:
`packages/db-sqlite-persistence-core/tests/persisted.test.ts`.
- [x] **Deterministic value-and-work laws.** Pair row correctness with stable
statement, scan, trigger, or queue-cardinality observations where the
subsystem promises bounded work. Owners: SQLite resume snapshots, Electric
acquisition work, and shared-driver scheduling suites.
- [x] **Explicit omission records.** Add a short `Known omissions` section to
each primary executable owner touched above and keep this map synchronized as
laws land. An omission record narrows evidence; it does not waive a product
obligation.

## Deferred contracts and evidence

The maintainer assigned offline policy work to
Expand Down
35 changes: 35 additions & 0 deletions docs/contributing/oracle-tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -624,4 +624,39 @@ For a new oracle or a claimed repair, ask:
6. Can capture, cleanup or shrinking turn this into a different failure?
7. Which larger promises remain outside this test, and where are they tracked?

### Reusable boundary-law checklist

Adapter and lifecycle oracles should consider these laws when the contract has
the corresponding boundary. They are prompts, not universal requirements. State
why an inapplicable law does not belong to the owner instead of adding a vacuous
case.

- **Real-provider conformance:** freeze representative values from each
supported provider version. Prove the fixture accepts those values before it
stands in for that provider.
- **Minimal ambiguity:** include the smallest valid input for every classifier
branch. Rich values that carry several redundant signals do not cover a
one-field collision.
- **Name invariance:** changing a user-controlled name or SQL alias must not
change envelope classification unless the public contract assigns that name
structural meaning.
- **Representation symmetry:** equivalent array/object forms and coexisting
carriers must produce the same public result or the same documented error.
- **Await-boundary transitions:** hold each relevant `await`, change ownership,
leadership, generation, abort, cleanup, or restart state, then release it.
Compare the result with the contract for that transition.
- **Local/transport refinement:** immutable transported data must have the same
meaning on local and remote paths. Live local references must remain local,
and cleanup must receive the exact lifecycle object delivered locally.
- **Partial-construction cleanup:** fail each construction step after it acquires
a resource. Preserve the primary error and prove every acquired resource is
released exactly once.
- **Value-and-work refinement:** when bounded work is promised, check the exact
result and a deterministic work/cardinality measure. Correct rows alone do
not establish the work law.

Every owner should also state its known omissions beside the contract. The
coverage map tracks open reusable laws; an unchecked item is not evidence that
the neighboring laws are absent.

The payoff is not a bigger test framework. It is a smaller distance between “this test is green” and a precise account of what that green result protects.
2 changes: 1 addition & 1 deletion docs/guides/collection-options-creator.md
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ sync: {
For complete, production-ready examples, see the collection packages in the TanStack DB repository:

- **[@tanstack/query-db-collection](https://github.com/TanStack/db/tree/main/packages/query-db-collection)** - Pattern A: User-provided handlers with full refetch strategy
- **[@tanstack/trailbase-db-collection](https://github.com/TanStack/db/tree/main/packages/trailbase-db-collection)** - Pattern B: Built-in handlers with ID-based tracking
- **[@tanstack/trailbase-db-collection](https://github.com/TanStack/db/tree/main/packages/trailbase-db-collection)** - Pattern B: Built-in handlers with ID-based tracking
- **[@tanstack/electric-db-collection](https://github.com/TanStack/db/tree/main/packages/electric-db-collection)** - Pattern A: Transaction ID tracking with complex sync protocols
- **[@tanstack/rxdb-db-collection](https://github.com/TanStack/db/tree/main/packages/rxdb-db-collection)** - Pattern B: Built-in handlers that bridge [RxDB](https://rxdb.info) change streams into TanStack DB's sync lifecycle

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,16 @@ function createStubAdapter(): PersistenceAdapter & {
return {
appliedTxs,
loadSubset: () => Promise.resolve([]),
loadResumeSnapshot: () =>
Promise.resolve({
rows: [],
keySet: { status: `consistent` },
collectionMetadata: [],
latestTerm: 0,
latestSeq: 0,
latestRowVersion: 0,
resetEpoch: 0,
}),
applyCommittedTx: (collectionId, tx) => {
appliedTxs.push({ collectionId, txId: tx.txId })
return Promise.resolve()
Expand Down
Loading
Loading