Skip to content

fix(persistence): preserve run-only metadata on peer reloads - #2303

Merged
KyleAMathews merged 14 commits into
mainfrom
codex/misfits-repair-metadata
Nov 2, 2026
Merged

KyleAMathews merged 14 commits into
mainfrom
codex/misfits-repair-metadata

Conversation

@KyleAMathews

@KyleAMathews KyleAMathews commented Oct 29, 2026 •

Copy link
Copy Markdown
Collaborator

🎯 Changes

This PR fixes metadata loss after a named peer notice reloads an on-demand persisted Collection. It also strengthens the session oracle and its native receiving fixtures.

An inner transaction can delete a row, then write metadata M while the row is missing. An enclosing update can later recreate that row without a metadata write. Decision 16 requires the sync run to retain M, while decisions 9 and 18 keep M nondurable. Previously, an unrelated peer notice reloaded the row and replaced M with absent stored metadata.

The wrapper now distinguishes local metadata from a named peer replacement. Known reloads retain local metadata. Same-key peer writes replace it, unknown-write reloads follow decision 15, and source deletes or truncates clear it. The storage format and public API stay compatible.

The failing CI campaign also exposed a reference-model error. The model incorrectly revived nondurable metadata when a keeping update recreated its row. The model now separates durable row existence from source metadata retained in the run. This correction follows the accepted decisions and leaves the comparisons intact.

Instrument improvements

The oracle checks source reads and durable metadata at completed action cuts. The controlled adapter records durable snapshots between queued commits, so later fix cannot hide an earlier wrong write. Recovery facts become available only after their storage read and successful application.

The native fixture serializes unrelated SQL calls, supports savepoints and active transaction reentry, and revokes reentry when the transaction ends. Its reusable conformance suite exposed and fixed a detached callback that retained an ended transaction's privileges.

Permanent controls challenge intermediate durable corruption, wrong reload reads, stale reads after cleanup, missing recovery application and empty replays. A shared recovery grammar constructs all 18 response/read/application × seed/peer/cleanup × bare/non-bare schedules. Both receiving drivers use the same independent session model and comparison.

Related work

The earlier materialization diagnosis under #2281 stays withdrawn. This new retention defect has its own failing history and fix. It does not establish a common cause with #2281's broader row-loss reports, #2317/P8 or #2298. The native witness contributes bounded evidence toward #2272. This PR closes none of those issues.

🔬 Oracle Coverage

Primary owner: packages/db/tests/sync-metadata-session-oracle.ts. The companion recovery grammar is packages/db/tests/sync-metadata-recovery-oracle.ts.

The fix record binds the final sources, both CI findings and the ORC-001–016 audit. The instrument audit preserves the earlier fixture work. The original evaluation preserves the previous review dispositions.

  • Law: Decisions 9/18 distinguish keeping metadata from writing it. Decision 16 retains missing-row metadata in the run. Decisions 11/15 govern named replacements and unknown-write observations. Authority: the accepted session decisions. No product law changes.
  • Reach: The new grammar constructs twelve cases across partial/full/on-demand lanes on both controlled storage and native SQLite. All 36 states per host reach eight times in each fixed/random campaign. Cases include keeping/explicit writes, core holds, a prior source truncate, named replacements, unknown writes and clears. Existing 108-state receiving, 18-state recovery and 40-run campaigns retain their budgets and guards.
  • RED: Before the production edit, all four receiving campaigns fail at the intended source-metadata comparison. Four on-demand keeping states fail, while the other 32 states pass in the reached batches. The original CI seed/path separately reproduces the model's false durable expectation.
  • GREEN: 1,443 relevant tests pass across the scoped commands, with 49 existing expected failures and one todo in the broad persisted owner. Both guarded seed/path replays pass with one nonzero selected execution each. Source-mapped types, formatting, scoped ESLint, changed-file oracle lint and run-budget checks pass. Scoped ESLint reports zero errors and zero warnings across the seven changed TypeScript files.
  • Mutant: Three isolated retention policies fail the shared source-read assertions on both hosts: original policy, retaining after named replacement, and retaining after unknown writes. The restored isolated baseline passes. Native seed 2220037/path 0 reproduces the original-policy mismatch and passes with the fix. Earlier seven fixture/checker mutations remain documented as historical calibration evidence.
  • Limits: One sync run, serialized authored actions, one-process native SQLite, two Browser coordinators and Node BroadcastChannel/Web Locks. Recovery schedules contain one recovery each. Arbitrary overlap, claim expiry/generation rotation, leadership/transport loss, restart, Chromium OPFS and Electron IPC remain outside the evidence. Read-hold/abandonment lacks the peer/store-held lanes' direct durable trace. The coverage map retains the owner and needed witness.

Run the new receiving campaigns from packages/db-sqlite-persistence-core:

pnpm exec vitest run tests/sync-metadata-missing-row.test.ts \
  --maxWorkers=1 --coverage.enabled=false --typecheck.enabled=false

Replay the native sibling directly:

TANSTACK_DB_ORACLE_PROPERTY=sync-metadata-session.sqlite-missing-row-metadata \
TANSTACK_DB_ORACLE_SEED=2220037 TANSTACK_DB_ORACLE_PATH=0 \
node --import tsx ../db/tests/oracle-replay.ts \
  tests/sync-metadata-missing-row.test.ts \
  --maxWorkers=1 --coverage.enabled=false --typecheck.enabled=false

The fix record includes the original CI replay and the broader verification commands. The retained instrument suites cover controlled/native sessions, recovery, calibrations, recorder guards, native SQL conformance and deterministic write work.

✅ Checklist

  • I have tested this code locally with pnpm test.
  • Focused campaigns, guarded replays, calibrations, isolated mutations, types, formatting and lint pass.

The full workspace command was not run locally. The earlier 253/279-test totals and 12/8-warning totals refer to earlier revisions and scopes. The current fix results appear above.

Formal reviews cover 9eef6525d and adf6a07f9. The mutable CodeRabbit summary last covers ef5c66ed2, and automatic review remains paused. Those reviews do not cover semantic instrument commit 60ace06b or this production fix. The maintainer authorized merge with that known review limit. Final publication-head CI remains a separate merge requirement.

🚀 Release Impact

  • This change affects published code and includes a patch changeset for @tanstack/db-sqlite-persistence-core.
  • This change is docs/CI/dev-only (no release).

No protocol, stored-format, package-manifest or lockfile change accompanies this fix. Local verification uses this branch. Current-head CI must supply integration evidence against the PR base.

Test added 3 commits October 29, 2026 14:20
Snapshot accepted row metadata for durable inserts that omit explicit metadata
writes. Keep explicit metadata writes authoritative and avoid attributing the
preserved metadata to the source. Share completed-reach classification between
the controlled and native SQLite receiving drivers.

Law: Sync metadata session decisions4,5,6,8,9,14,15,18 in
docs/contributing/oracle-reviews/2026-10-22-sync-metadata-session.md, the implicit
row-metadata rules, and glossary hydration-seed contract. An inner equal
re-insert preserves accepted metadata through persistence and peer reload.
Reach: Each controlled/native host campaign completes40 histories in each of
three lanes. Fixed seed527962096 reaches2 completed bare-key1 implicit keeps
and2 completed non-bare keeps per lane, with21 named/19 fullreload notices.
RED: M01 controlled extended owner fails unchanged parent production at
seed2281001/path7:0; M06/M07 native SQLite receiving replays/property fail the
same metadata law, generated path7:0:0.
GREEN: M08/M09 paired40-run campaigns and receiving replays pass. H02 repeats
both hosts with the shared helper; H01b proves final-helper equivalence over
2304 histories/102912 comparisons. Final types/lint/format pass.
Mutant: Original durable-metadata map and always-delete rival both fail the
shared metadata comparison in controlled/native generated histories. An
all-explicit-inner grammar ablation fails the completed implicit-keep reaches.
Limits: One process/native SQLite with two production coordinators. No OPFS,
Electron IPC, transport-loss/leadership-turnover or broader2272 claim. Random
scarce reach is measured; fixed guards enforce both scarce branches. Host runs
precede only an explicit terminal undefined return, linked by exact equivalence.
@changeset-bot

changeset-bot Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 6d79947

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 12 packages
Name Type
@tanstack/db-sqlite-persistence-core Patch
@tanstack/browser-db-sqlite-persistence Patch
@tanstack/capacitor-db-sqlite-persistence Patch
@tanstack/cloudflare-durable-objects-db-sqlite-persistence Patch
@tanstack/electron-db-sqlite-persistence Patch
@tanstack/expo-db-sqlite-persistence Patch
@tanstack/node-db-sqlite-persistence Patch
@tanstack/react-native-db-sqlite-persistence Patch
@tanstack/tauri-db-sqlite-persistence Patch
@tanstack/capacitor-db-sqlite-persistence-e2e-app Patch
@tanstack/expo-db-sqlite-persistence-e2e-app Patch
@tanstack/tauri-db-sqlite-persistence-e2e-app Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai

coderabbitai Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • Resume reviews
  • Trigger review

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: a68b22e2-1ecd-45a0-a3eb-a7daf5e1e346
Commits

Reviewing files that changed from the base of the PR and between adf6a07 and ef5c66e.

Files selected for processing: 1
  • docs/contributing/oracle-reviews/2026-11-02-p6-metadata-closeout.md
Files skipped from review as they are similar to previous changes: 1
  • docs/contributing/oracle-reviews/2026-11-02-p6-metadata-closeout.md

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 2 remain after this review.

Walkthrough

This change revises the sync-metadata session oracle and adds generated histories for metadata durability, seed re-insertion, reload, and queued repairs. It adds persisted-adapter and SQLite/coordinator test coverage, and updates documentation with verification results and coverage limits.

Changes: Sync Metadata Oracle and Receiving Coverage

Layer / File(s) Summary
Define metadata rules and session histories
packages/db/tests/sync-metadata-session-oracle.ts, packages/db/tests/sync-metadata-session.test.ts
The oracle distinguishes metadata retained locally from metadata written durably. It records unknown-storage observations and recovery inputs, compares durable metadata, and adds generated histories for seed reload, durability, and queued repairs. A runner test verifies that recovery input is consumed before an authored action.
Exercise persisted peer lanes
packages/db-sqlite-persistence-core/tests/sync-metadata-session-persisted.test.ts, packages/db-sqlite-persistence-core/tests/sync-metadata-session-campaign.ts, packages/db-sqlite-persistence-core/tests/sync-metadata-write-work.test.ts, packages/db/tests/oracle-config.ts, packages/db/tests/oracle-replay-manifest.ts
Persisted-adapter campaigns cover seed re-insertion, reload, metadata durability, and queued repairs across peer lanes. The registry and replay manifest include the new properties. Write-work tests check generated-history reachability and metadata mutations after repeated refreshes.
Run SQLite-backed coordinator histories
packages/db-sqlite-persistence-core/tests/sync-metadata-sqlite-driver.ts, packages/db-sqlite-persistence-core/tests/sync-metadata-sqlite-driver.test.ts, packages/db-sqlite-persistence-core/tests/sync-metadata-session-sqlite.test.ts
A SQLite driver serializes root operations and scopes nested transactions. Session tests run histories through two coordinators and compare notices, recovery inputs, and durable metadata with the oracle.
Record evidence and coverage boundaries
docs/contributing/oracle-coverage.md, docs/contributing/oracle-reviews/*
The coverage guide and review records document metadata rules, campaign results, bounded receiving schedules, and excluded scenarios. They state that the earlier production diagnosis was withdrawn.

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Other

Possibly related issues

Merge Risk: Minimal · up to ef5c6

No merge-blocking issue is established for this wording update; normal checks can proceed.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Title check Warning The title claims a production fix, but the supplied summaries and objectives describe test, oracle, and documentation changes with no production-source change. It does not accurately summarize the mai… Retitle the pull request to describe the actual test, oracle, and documentation changes, or include the production implementation that the current title claims.
Passed Passed checks: 4 passed
Check name Status Explanation
Docstring Coverage Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description check Passed The description includes all required template sections and provides detailed change context, oracle coverage, verification results, known limits, checklist status, and release impact.
Full details: Docstring Coverage

Explanation

Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 9 functions across 10 files. (1 skipped: 1 unsupported.)

Full details: Title check

Explanation

The title claims a production fix, but the supplied summaries and objectives describe test, oracle, and documentation changes with no production-source change. It does not accurately summarize the main changeset.

Resolution

Retitle the pull request to describe the actual test, oracle, and documentation changes, or include the production implementation that the current title claims.

Finishing Touches
Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Incremental update benchmark

Comparing 3af8447cb (this PR) against 9be51e037 (base). Write times are per-write medians over 100 iterations (20 warmup writes). Cold hydrate is one timed first load of each query.

Overall median write time vs base: 1.02× · cold hydrate time: 1.07× (geometric mean of per-case ratios; lower is faster).

Writes: No significant changes (threshold: ±20% and >0.05ms).

Cold hydrate: 3 regression(s), 1 improvement(s) (threshold: ±50% and >5ms).

Per-case flags are noisy on shared runners. Read the geometric means first.

Writes

Query Δ median write time (geomean) Best case Worst case Flags
list: newest 50 open +2.4% -5.8% +13.0% —
list + author -0.1% -22.9% +9.8% —
list + comment count +2.8% -4.4% +18.0% —
list + 3 recent comments +2.9% -1.1% +11.0% —
issue detail + comments +1.6% -10.7% +6.5% —

Cold hydrate

Query Δ cold hydrate time (geomean) Best case Worst case Flags
list: newest 50 open +12.3% -27.9% +476.1% 1 🔴
list + author +2.7% -25.0% +147.4% 1 🔴
list + comment count +6.1% -52.4% +117.9% 1 🔴 1 🟢
list + 3 recent comments +1.3% -30.4% +49.2% —
issue detail + comments +9.4% -23.6% +31.1% —

Each row aggregates the 14.4 scale/index/write-mode configurations of that query; per-configuration tables below.

100 rows/collection | source indexes: none | synced writes — geomean 1.03×, cold 1.00×
Query Base median PR median Δ median Base p95 PR p95 Δ p95 Base cold PR cold Δ cold
list: newest 50 open 0.255ms 0.253ms -1.0% 0.397ms 0.515ms +29.9% 15.141ms 15.788ms +4.3%
list: newest 50 open 0.522ms 0.590ms +13.0% 0.991ms 1.113ms +12.3% 4.338ms 3.772ms -13.0%
list + author 0.247ms 0.252ms +2.1% 0.439ms 0.391ms -10.9% 16.733ms 14.150ms -15.4%
list + comment count 0.410ms 0.403ms -1.6% 0.637ms 0.655ms +2.8% 14.386ms 16.572ms +15.2%
list + 3 recent comments 0.264ms 0.265ms +0.6% 0.350ms 0.422ms +20.3% 14.278ms 14.218ms -0.4%
issue detail + comments 0.183ms 0.189ms +2.8% 0.347ms 0.349ms +0.6% 2.067ms 2.295ms +11.0%
100 rows/collection | source indexes: none | optimistic writes — geomean 1.01×, cold 1.08×
Query Base median PR median Δ median Base p95 PR p95 Δ p95 Base cold PR cold Δ cold
list: newest 50 open 0.199ms 0.187ms -5.8% 0.316ms 0.320ms +1.1% 2.906ms 3.363ms +15.7%
list: newest 50 open 0.123ms 0.123ms +0.1% 0.186ms 0.179ms -3.4% 3.007ms 2.656ms -11.7%
list + author 0.192ms 0.203ms +5.8% 0.317ms 0.345ms +8.8% 8.552ms 7.903ms -7.6%
list + comment count 0.248ms 0.257ms +3.7% 0.426ms 0.390ms -8.6% 5.314ms 6.446ms +21.3%
list + 3 recent comments 0.219ms 0.220ms +0.5% 0.371ms 0.373ms +0.7% 11.854ms 15.323ms +29.3%
issue detail + comments 0.202ms 0.211ms +4.4% 0.280ms 0.270ms -3.5% 1.486ms 1.596ms +7.4%
100 rows/collection | source indexes: manual | synced writes — geomean 1.00×, cold 1.00×
Query Base median PR median Δ median Base p95 PR p95 Δ p95 Base cold PR cold Δ cold
list: newest 50 open 0.189ms 0.197ms +3.9% 0.292ms 0.274ms -6.1% 5.407ms 5.023ms -7.1%
list: newest 50 open 0.412ms 0.403ms -2.2% 0.699ms 0.654ms -6.3% 1.961ms 2.048ms +4.4%
list + author 0.163ms 0.158ms -2.9% 0.304ms 0.258ms -15.1% 6.793ms 5.095ms -25.0%
list + comment count 0.293ms 0.290ms -1.0% 0.466ms 0.496ms +6.5% 7.160ms 6.634ms -7.4%
list + 3 recent comments 0.188ms 0.194ms +3.4% 0.307ms 0.335ms +9.1% 6.236ms 7.092ms +13.7%
issue detail + comments 0.141ms 0.142ms +1.1% 0.280ms 0.273ms -2.7% 0.645ms 0.846ms +31.1%
100 rows/collection | source indexes: manual | optimistic writes — geomean 1.02×, cold 1.25×, 1 change(s)
Query Base median PR median Δ median Base p95 PR p95 Δ p95 Base cold PR cold Δ cold
list: newest 50 open 0.135ms 0.133ms -1.5% 0.199ms 0.185ms -7.3% 2.603ms 2.417ms -7.1%
list: newest 50 open 0.116ms 0.115ms -1.0% 0.215ms 0.182ms -15.2% 2.468ms 2.349ms -4.8%
list + author 0.183ms 0.172ms -5.7% 0.306ms 0.292ms -4.5% 5.164ms 5.285ms +2.3%
list + comment count 0.228ms 0.252ms +10.7% 0.384ms 0.398ms +3.7% 4.830ms 10.524ms +117.9% 🔴
list + 3 recent comments 0.146ms 0.155ms +6.3% 0.201ms 0.233ms +15.9% 5.882ms 8.775ms +49.2%
issue detail + comments 0.129ms 0.137ms +6.5% 0.178ms 0.215ms +20.8% 0.548ms 0.697ms +27.2%
1,000 rows/collection | source indexes: none | synced writes — geomean 1.01×, cold 0.86×
Query Base median PR median Δ median Base p95 PR p95 Δ p95 Base cold PR cold Δ cold
list: newest 50 open 0.106ms 0.116ms +9.6% 0.216ms 0.217ms +0.6% 7.958ms 12.348ms +55.2%
list: newest 50 open 1.485ms 1.625ms +9.4% 2.181ms 2.254ms +3.3% 12.559ms 9.049ms -27.9%
list + author 0.135ms 0.145ms +7.6% 0.265ms 0.179ms -32.6% 49.192ms 46.802ms -4.9%
list + comment count 0.253ms 0.242ms -4.4% 0.459ms 0.433ms -5.8% 27.569ms 14.083ms -48.9%
list + 3 recent comments 0.166ms 0.164ms -1.1% 0.238ms 0.264ms +11.3% 18.492ms 12.864ms -30.4%
issue detail + comments 0.139ms 0.124ms -10.7% 0.248ms 0.220ms -11.5% 1.610ms 1.676ms +4.1%
1,000 rows/collection | source indexes: none | optimistic writes — geomean 1.01×, cold 1.02×
Query Base median PR median Δ median Base p95 PR p95 Δ p95 Base cold PR cold Δ cold
list: newest 50 open 0.129ms 0.126ms -2.3% 0.251ms 0.240ms -4.2% 6.492ms 6.277ms -3.3%
list: newest 50 open 0.092ms 0.092ms -0.1% 0.136ms 0.128ms -6.1% 8.214ms 7.677ms -6.5%
list + author 0.155ms 0.158ms +1.8% 0.203ms 0.274ms +35.1% 43.012ms 50.462ms +17.3%
list + comment count 0.200ms 0.198ms -1.0% 0.244ms 0.238ms -2.5% 10.649ms 14.701ms +38.0%
list + 3 recent comments 0.129ms 0.136ms +5.9% 0.161ms 0.220ms +37.2% 15.789ms 12.532ms -20.6%
issue detail + comments 0.122ms 0.124ms +1.3% 0.152ms 0.160ms +5.2% 1.468ms 1.429ms -2.7%
1,000 rows/collection | source indexes: manual | synced writes — geomean 1.01×, cold 1.21×
Query Base median PR median Δ median Base p95 PR p95 Δ p95 Base cold PR cold Δ cold
list: newest 50 open 0.106ms 0.103ms -2.6% 0.139ms 0.129ms -6.9% 1.685ms 1.805ms +7.1%
list: newest 50 open 0.365ms 0.385ms +5.5% 0.662ms 0.655ms -0.9% 1.372ms 2.611ms +90.3%
list + author 0.137ms 0.145ms +5.7% 0.242ms 0.195ms -19.5% 4.076ms 4.363ms +7.1%
list + comment count 0.243ms 0.241ms -1.0% 0.407ms 0.360ms -11.6% 3.810ms 4.361ms +14.5%
list + 3 recent comments 0.163ms 0.164ms +0.5% 0.196ms 0.199ms +1.4% 7.667ms 7.746ms +1.0%
issue detail + comments 0.123ms 0.121ms -1.7% 0.169ms 0.180ms +6.9% 0.546ms 0.671ms +22.8%
1,000 rows/collection | source indexes: manual | optimistic writes — geomean 1.04×, cold 1.70×, 2 change(s)
Query Base median PR median Δ median Base p95 PR p95 Δ p95 Base cold PR cold Δ cold
list: newest 50 open 0.124ms 0.124ms +0.2% 0.214ms 0.188ms -12.1% 1.380ms 7.948ms +476.1% 🔴
list: newest 50 open 0.100ms 0.101ms +1.3% 0.138ms 0.138ms +0.2% 1.407ms 1.515ms +7.6%
list + author 0.154ms 0.152ms -1.0% 0.183ms 0.225ms +23.1% 4.225ms 10.454ms +147.4% 🔴
list + comment count 0.200ms 0.237ms +18.0% 0.235ms 0.376ms +60.2% 3.888ms 4.036ms +3.8%
list + 3 recent comments 0.140ms 0.144ms +3.0% 0.186ms 0.185ms -0.3% 6.358ms 7.366ms +15.9%
issue detail + comments 0.126ms 0.130ms +2.9% 0.184ms 0.225ms +22.1% 0.527ms 0.679ms +28.8%
10,000 rows/collection | source indexes: none | synced writes — geomean 0.98×, cold 1.04×
Query Base median PR median Δ median Base p95 PR p95 Δ p95 Base cold PR cold Δ cold
list: newest 50 open 0.100ms 0.100ms +0.4% 0.133ms 0.168ms +25.7% 80.021ms 80.891ms +1.1%
list: newest 50 open 11.461ms 11.980ms +4.5% 13.811ms 13.727ms -0.6% 73.967ms 81.101ms +9.6%
list + author 0.214ms 0.165ms -22.9% 0.272ms 0.264ms -2.9% 349.991ms 381.804ms +9.1%
list + comment count 0.248ms 0.242ms -2.5% 0.342ms 0.399ms +16.8% 93.385ms 86.032ms -7.9%
list + 3 recent comments 0.174ms 0.194ms +11.0% 0.308ms 0.311ms +0.8% 91.563ms 87.825ms -4.1%
issue detail + comments 0.113ms 0.117ms +3.4% 0.145ms 0.150ms +3.3% 6.682ms 7.999ms +19.7%
10,000 rows/collection | source indexes: none | optimistic writes — geomean 1.04×, cold 1.11×
Query Base median PR median Δ median Base p95 PR p95 Δ p95 Base cold PR cold Δ cold
list: newest 50 open 0.122ms 0.127ms +4.6% 0.225ms 0.231ms +2.8% 63.986ms 82.091ms +28.3%
list: newest 50 open 0.085ms 0.094ms +10.1% 0.136ms 0.164ms +20.1% 66.553ms 85.378ms +28.3%
list + author 0.157ms 0.158ms +0.5% 0.206ms 0.249ms +20.9% 343.885ms 347.893ms +1.2%
list + comment count 0.260ms 0.264ms +1.6% 0.645ms 0.333ms -48.4% 85.082ms 99.853ms +17.4%
list + 3 recent comments 0.136ms 0.141ms +3.8% 0.178ms 0.192ms +7.6% 90.949ms 97.303ms +7.0%
issue detail + comments 0.128ms 0.134ms +5.3% 0.167ms 0.212ms +27.3% 6.763ms 5.904ms -12.7%
10,000 rows/collection | source indexes: manual | synced writes — geomean 1.03×, cold 1.00×
Query Base median PR median Δ median Base p95 PR p95 Δ p95 Base cold PR cold Δ cold
list: newest 50 open 0.096ms 0.100ms +3.7% 0.134ms 0.131ms -2.4% 2.472ms 2.321ms -6.1%
list: newest 50 open 1.010ms 1.039ms +2.9% 1.177ms 1.581ms +34.3% 2.342ms 2.318ms -1.0%
list + author 0.131ms 0.135ms +2.9% 0.161ms 0.168ms +4.1% 5.624ms 5.106ms -9.2%
list + comment count 0.243ms 0.257ms +5.6% 0.292ms 0.313ms +7.4% 5.213ms 8.698ms +66.9%
list + 3 recent comments 0.183ms 0.183ms +0.1% 0.232ms 0.224ms -3.7% 8.672ms 7.864ms -9.3%
issue detail + comments 0.131ms 0.132ms +0.5% 0.168ms 0.163ms -3.0% 1.010ms 0.772ms -23.6%
10,000 rows/collection | source indexes: manual | optimistic writes — geomean 1.05×, cold 0.84×, 1 change(s)
Query Base median PR median Δ median Base p95 PR p95 Δ p95 Base cold PR cold Δ cold
list: newest 50 open 0.131ms 0.131ms +0.3% 0.239ms 0.186ms -22.3% 2.284ms 2.236ms -2.1%
list: newest 50 open 0.103ms 0.109ms +6.5% 0.173ms 0.139ms -19.4% 2.299ms 2.222ms -3.4%
list + author 0.151ms 0.166ms +9.8% 0.193ms 0.297ms +53.6% 7.014ms 5.414ms -22.8%
list + comment count 0.278ms 0.298ms +7.1% 0.449ms 0.520ms +15.9% 10.994ms 5.229ms -52.4% 🟢
list + 3 recent comments 0.151ms 0.153ms +1.7% 0.202ms 0.186ms -7.7% 7.290ms 6.448ms -11.6%
issue detail + comments 0.136ms 0.142ms +4.5% 0.166ms 0.177ms +6.5% 0.721ms 0.830ms +15.1%

Runner: node v24.8.0, linux 7.0.0-1017-azure, AMD EPYC 7763 64-Core Processor. Timings on shared CI runners are noisy; treat small deltas as indicative only.

@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Size Change: 0 B

Total Size: 239 kB

ℹ️ View Unchanged
Filename Size
packages/db/dist/esm/client.js 5.51 kB
packages/db/dist/esm/collection-options-brand.js 219 B
packages/db/dist/esm/collection-options.js 258 B
packages/db/dist/esm/collection/change-events.js 1.76 kB
packages/db/dist/esm/collection/changes.js 3.06 kB
packages/db/dist/esm/collection/cleanup-queue.js 828 B
packages/db/dist/esm/collection/config-errors.js 547 B
packages/db/dist/esm/collection/events.js 504 B
packages/db/dist/esm/collection/health-tree.js 698 B
packages/db/dist/esm/collection/index.js 6.23 kB
packages/db/dist/esm/collection/indexes.js 2.3 kB
packages/db/dist/esm/collection/lifecycle.js 5.59 kB
packages/db/dist/esm/collection/mutations.js 2.94 kB
packages/db/dist/esm/collection/state.js 7.69 kB
packages/db/dist/esm/collection/subscription.js 9.86 kB
packages/db/dist/esm/collection/sync.js 6.51 kB
packages/db/dist/esm/collection/validate-config.js 1.17 kB
packages/db/dist/esm/collection/validate-indexing.js 366 B
packages/db/dist/esm/deferred.js 207 B
packages/db/dist/esm/error-message.js 642 B
packages/db/dist/esm/errors.js 7.15 kB
packages/db/dist/esm/event-emitter.js 1.06 kB
packages/db/dist/esm/index.js 4.75 kB
packages/db/dist/esm/indexed-db-wrapper.js 1.91 kB
packages/db/dist/esm/indexed-db.js 3.8 kB
packages/db/dist/esm/indexes/auto-index.js 924 B
packages/db/dist/esm/indexes/base-index.js 1.92 kB
packages/db/dist/esm/indexes/basic-index.js 1.93 kB
packages/db/dist/esm/indexes/btree-index.js 1.62 kB
packages/db/dist/esm/indexes/index-registry.js 916 B
packages/db/dist/esm/indexes/reverse-index.js 1.01 kB
packages/db/dist/esm/live-query-adapter.js 845 B
packages/db/dist/esm/live-query-observer-client.js 2.21 kB
packages/db/dist/esm/live-query-observer.js 3.3 kB
packages/db/dist/esm/live-query-options.js 2.65 kB
packages/db/dist/esm/live-query-primitives.js 406 B
packages/db/dist/esm/live-query-window-binding.js 1.56 kB
packages/db/dist/esm/live-query-window-controller.js 4.02 kB
packages/db/dist/esm/local-only.js 1 kB
packages/db/dist/esm/local-storage.js 4.58 kB
packages/db/dist/esm/optimistic-action.js 359 B
packages/db/dist/esm/paced-mutations.js 1.11 kB
packages/db/dist/esm/proxy.js 3.51 kB
packages/db/dist/esm/query/builder/clone-query.js 854 B
packages/db/dist/esm/query/builder/functions.js 1.61 kB
packages/db/dist/esm/query/builder/group-keys.js 157 B
packages/db/dist/esm/query/builder/include-functions.js 229 B
packages/db/dist/esm/query/builder/index.js 7.67 kB
packages/db/dist/esm/query/builder/query-ir.js 312 B
packages/db/dist/esm/query/builder/ref-proxy-identity.js 292 B
packages/db/dist/esm/query/builder/ref-proxy.js 1.67 kB
packages/db/dist/esm/query/builder/wrapper-identity.js 221 B
packages/db/dist/esm/query/compiler/evaluators.js 2.51 kB
packages/db/dist/esm/query/compiler/expressions.js 603 B
packages/db/dist/esm/query/compiler/find-aggregate.js 328 B
packages/db/dist/esm/query/compiler/group-by.js 4.38 kB
packages/db/dist/esm/query/compiler/grouping.js 161 B
packages/db/dist/esm/query/compiler/index.js 10.3 kB
packages/db/dist/esm/query/compiler/joins.js 3.29 kB
packages/db/dist/esm/query/compiler/lazy-targets.js 1.11 kB
packages/db/dist/esm/query/compiler/order-by.js 2.87 kB
packages/db/dist/esm/query/compiler/parent-routes.js 325 B
packages/db/dist/esm/query/compiler/query-equivalence.js 568 B
packages/db/dist/esm/query/compiler/route-metadata.js 1.45 kB
packages/db/dist/esm/query/compiler/select.js 1.66 kB
packages/db/dist/esm/query/effect.js 5.81 kB
packages/db/dist/esm/query/equality-conjunct.js 486 B
packages/db/dist/esm/query/equality-value-identity.js 736 B
packages/db/dist/esm/query/expression-helpers.js 1.61 kB
packages/db/dist/esm/query/ir-stable-identity.js 4.29 kB
packages/db/dist/esm/query/ir.js 2.26 kB
packages/db/dist/esm/query/join-conditions.js 257 B
packages/db/dist/esm/query/live-query-collection.js 391 B
packages/db/dist/esm/query/live/bucket-facade-adapter.js 3.17 kB
packages/db/dist/esm/query/live/collection-config-builder.js 8.57 kB
packages/db/dist/esm/query/live/collection-registry.js 264 B
packages/db/dist/esm/query/live/collection-subscriber.js 2.69 kB
packages/db/dist/esm/query/live/graph-scheduler.js 305 B
packages/db/dist/esm/query/live/includes-runtime.js 212 B
packages/db/dist/esm/query/live/internal.js 145 B
packages/db/dist/esm/query/live/materialized-pipeline.js 1.94 kB
packages/db/dist/esm/query/live/ordered-source-loader.js 6.53 kB
packages/db/dist/esm/query/live/public-key-reduction.js 970 B
packages/db/dist/esm/query/live/subset-demand-controller.js 2.44 kB
packages/db/dist/esm/query/live/utils.js 1.35 kB
packages/db/dist/esm/query/optimizer.js 2.95 kB
packages/db/dist/esm/query/pooled-live-query.js 5.14 kB
packages/db/dist/esm/query/pooled-source.js 219 B
packages/db/dist/esm/query/query-once.js 359 B
packages/db/dist/esm/query/runtime-reference-identity.js 630 B
packages/db/dist/esm/query/subset-dedupe.js 493 B
packages/db/dist/esm/query/validate-limit.js 247 B
packages/db/dist/esm/scheduler.js 1.23 kB
packages/db/dist/esm/SortedMap.js 1.77 kB
packages/db/dist/esm/strategies/commit-completion.js 154 B
packages/db/dist/esm/strategies/debounceStrategy.js 658 B
packages/db/dist/esm/strategies/queueStrategy.js 523 B
packages/db/dist/esm/strategies/serial-pacer.js 486 B
packages/db/dist/esm/strategies/throttleStrategy.js 738 B
packages/db/dist/esm/sync-persistence.js 669 B
packages/db/dist/esm/sync-receipt.js 211 B
packages/db/dist/esm/transaction-commit-work.js 351 B
packages/db/dist/esm/transactions.js 4.66 kB
packages/db/dist/esm/utils.js 1.7 kB
packages/db/dist/esm/utils/array-utils.js 270 B
packages/db/dist/esm/utils/browser-polyfills.js 304 B
packages/db/dist/esm/utils/btree.js 3.02 kB
packages/db/dist/esm/utils/callbacks.js 219 B
packages/db/dist/esm/utils/comparison.js 1.95 kB
packages/db/dist/esm/utils/cursor.js 753 B
packages/db/dist/esm/utils/error.js 262 B
packages/db/dist/esm/utils/get-or-create.js 155 B
packages/db/dist/esm/utils/index-optimization.js 2.58 kB
packages/db/dist/esm/utils/source-record.js 140 B
packages/db/dist/esm/utils/type-guards.js 230 B
packages/db/dist/esm/utils/uuid.js 530 B
packages/db/dist/esm/virtual-props.js 400 B
packages/react-db/dist/esm/DbProvider.js 317 B
packages/react-db/dist/esm/development.js 190 B
packages/react-db/dist/esm/HydrationBoundary.js 263 B
packages/react-db/dist/esm/index.js 330 B
packages/react-db/dist/esm/source-id-bindings.js 339 B
packages/react-db/dist/esm/useLiveInfiniteQuery.js 1.45 kB
packages/react-db/dist/esm/useLiveQuery.js 3.08 kB
packages/react-db/dist/esm/useLiveQueryEffect.js 504 B
packages/react-db/dist/esm/useLiveSuspenseQuery.js 1.27 kB
packages/react-db/dist/esm/usePacedMutations.js 429 B

compressed-size-action::db-and-react-package-size

@pkg-pr-new

pkg-pr-new Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
More templates

@tanstack/angular-db

npm i https://pkg.pr.new/@tanstack/angular-db@2303

@tanstack/browser-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/browser-db-sqlite-persistence@2303

@tanstack/capacitor-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/capacitor-db-sqlite-persistence@2303

@tanstack/cloudflare-durable-objects-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/cloudflare-durable-objects-db-sqlite-persistence@2303

@tanstack/convex-db-collection

npm i https://pkg.pr.new/@tanstack/convex-db-collection@2303

@tanstack/db

npm i https://pkg.pr.new/@tanstack/db@2303

@tanstack/db-ivm

npm i https://pkg.pr.new/@tanstack/db-ivm@2303

@tanstack/db-sqlite-persistence-core

npm i https://pkg.pr.new/@tanstack/db-sqlite-persistence-core@2303

@tanstack/electric-db-collection

npm i https://pkg.pr.new/@tanstack/electric-db-collection@2303

@tanstack/electron-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/electron-db-sqlite-persistence@2303

@tanstack/expo-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/expo-db-sqlite-persistence@2303

@tanstack/node-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/node-db-sqlite-persistence@2303

@tanstack/offline-transactions

npm i https://pkg.pr.new/@tanstack/offline-transactions@2303

@tanstack/powersync-db-collection

npm i https://pkg.pr.new/@tanstack/powersync-db-collection@2303

@tanstack/preact-db

npm i https://pkg.pr.new/@tanstack/preact-db@2303

@tanstack/query-db-collection

npm i https://pkg.pr.new/@tanstack/query-db-collection@2303

@tanstack/react-db

npm i https://pkg.pr.new/@tanstack/react-db@2303

@tanstack/react-native-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/react-native-db-sqlite-persistence@2303

@tanstack/react-router-with-db

npm i https://pkg.pr.new/@tanstack/react-router-with-db@2303

@tanstack/rxdb-db-collection

npm i https://pkg.pr.new/@tanstack/rxdb-db-collection@2303

@tanstack/solid-db

npm i https://pkg.pr.new/@tanstack/solid-db@2303

@tanstack/svelte-db

npm i https://pkg.pr.new/@tanstack/svelte-db@2303

@tanstack/tauri-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/tauri-db-sqlite-persistence@2303

@tanstack/trailbase-db-collection

npm i https://pkg.pr.new/@tanstack/trailbase-db-collection@2303

@tanstack/vue-db

npm i https://pkg.pr.new/@tanstack/vue-db@2303

commit: 6d79947

Test added 4 commits November 2, 2026 11:25
Law: Decisions 9 and 18 keep tab-local seed metadata separate from durable
writes. Decision 15 permits unknown-author storage observations to adopt
differing durable metadata; named current-run writes follow decision 11.

Reach: Both hosts reach all 36 constructive case/lane states eight times
per fixed and random campaign. Native recovery is reached 96 times each.
Existing 40-run campaigns and fixed completed-branch guards are preserved.

RED: No production defect is claimed on a3c4d06. The original PR diagnosis
is withdrawn. Both hosts reject the old serializer materialization at the
settled durable metadata comparison, seed 2220031, path 0:0:0.

GREEN: 74 controlled and 12 native/helper/work tests pass after extraction;
92 core tests passed before the mechanics-only extraction. Direct replay,
scoped types, formatting and lint pass (12 general ESLint warnings).

Mutant: All five controls reject the intended assertion: materialization
on each host, omitted model recovery input, dropped explicit writes and
unscoped root SQL. Temporary edits are restored byte-for-byte.

Limits: One-process native SQLite with two Browser coordinators and a
bounded correlated notice/recovery schedule. No arbitrary recovery timing,
transport/leadership loss, Chromium OPFS, Electron IPC or restart proof.
Broader #2281/#2272 and the separate #2317/P8 witness remain open.

See docs/contributing/oracle-reviews/2026-11-02-p6-metadata-closeout.md.
Preserve the published PR ancestry. The replacement tree retains main production unchanged and removes the withdrawn materialization and release note. The reviewed test/model/fixture candidate supersedes the older proposal.
@KyleAMathews KyleAMathews changed the title fix(persistence): preserve metadata on implicit equal re-inserts test(persistence): separate local metadata keeps from durable writes Nov 2, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional comments: 1
docs/contributing/oracle-reviews/2026-10-30-kept-metadata-durability.md-32-32: 1

32-32: Minor · Maintainability & Code Quality · Quick win

Unverified finding
Verification ran but could not confirm this finding. It is shown for review, not as a verified issue.

Use precise wording for the pullSince(0) result.

real successful uses real as an adverb and makes the evidence sentence informal. Replace it with A successful \pullSince(0)` response returned row version 2 without transaction replay details.` (raw.githubusercontent.com)

Source: Linters/SAST tools


Review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 3ed59fa4-c60c-44d6-b630-04d05cc92c4b
Commits

Reviewing files that changed from the base of the PR and between ea769ec and 9eef652.

Files selected for processing: 12
  • docs/contributing/oracle-coverage.md
  • docs/contributing/oracle-reviews/2026-10-30-kept-metadata-durability.md
  • docs/contributing/oracle-reviews/2026-11-02-p6-metadata-closeout.md
  • packages/db-sqlite-persistence-core/tests/sync-metadata-session-campaign.ts
  • packages/db-sqlite-persistence-core/tests/sync-metadata-session-persisted.test.ts
  • packages/db-sqlite-persistence-core/tests/sync-metadata-session-sqlite.test.ts
  • packages/db-sqlite-persistence-core/tests/sync-metadata-sqlite-driver.test.ts
  • packages/db-sqlite-persistence-core/tests/sync-metadata-sqlite-driver.ts
  • packages/db-sqlite-persistence-core/tests/sync-metadata-write-work.test.ts
  • packages/db/tests/oracle-config.ts
  • packages/db/tests/oracle-replay-manifest.ts
  • packages/db/tests/sync-metadata-session-oracle.ts

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 6 remain after this review.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional comments: 1
docs/contributing/oracle-reviews/2026-11-02-p6-metadata-closeout.md-335-335: 1

335-335: Minor · Maintainability & Code Quality · Quick win

Unverified finding
Verification ran but could not confirm this finding. It is shown for review, not as a verified issue.

Clarify the transaction modifier.

The phrase two open authored transactions is ambiguous. Rewrite it as while two authored transactions remained open or use two open-authored transactions if that is the intended term.

Source: Linters/SAST tools


Review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: a6979e72-dc82-4552-81c8-435843a70315
Commits

Reviewing files that changed from the base of the PR and between d0c4d0d and adf6a07.

Files selected for processing: 12
  • docs/contributing/oracle-coverage.md
  • docs/contributing/oracle-reviews/2026-11-02-p6-metadata-closeout.md
  • packages/db-sqlite-persistence-core/tests/sync-metadata-session-campaign.ts
  • packages/db-sqlite-persistence-core/tests/sync-metadata-session-persisted.test.ts
  • packages/db-sqlite-persistence-core/tests/sync-metadata-session-sqlite.test.ts
  • packages/db-sqlite-persistence-core/tests/sync-metadata-sqlite-driver.test.ts
  • packages/db-sqlite-persistence-core/tests/sync-metadata-sqlite-driver.ts
  • packages/db-sqlite-persistence-core/tests/sync-metadata-write-work.test.ts
  • packages/db/tests/oracle-config.ts
  • packages/db/tests/oracle-replay-manifest.ts
  • packages/db/tests/sync-metadata-session-oracle.ts
  • packages/db/tests/sync-metadata-session.test.ts
Files skipped from review as they are similar to previous changes: 1
  • docs/contributing/oracle-coverage.md

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 3 remain after this review.

Test added 5 commits November 2, 2026 12:35
Law: preserve D9/D15/D18 and synchronous cleanup invalidation; fixture SQL isolation remains a premise.
Reach: all 18 recovery cells reach eight times per fixed/random campaign; existing 108-state and four-regime guards remain.
RED: the new detached-context SQL witness fails both transaction entry points before fixture correction.
GREEN: 279 local tests pass; scoped types, formatting, lint and unchanged-budget checks pass.
Mutant: seven isolated wrong decisions fail their intended assertions; captured recovery seed/path replays RED and restored GREEN.
Limits: bounded one-process native SQLite schedules; OPFS, Electron, restart, expiry, generation rotation and arbitrary overlap remain outside evidence. See the versioned instrument report.
@KyleAMathews KyleAMathews changed the title test(persistence): separate local metadata keeps from durable writes fix(persistence): preserve run-only metadata on peer reloads Nov 2, 2026
@KyleAMathews
KyleAMathews merged commit b190945 into main Nov 2, 2026
26 checks passed
@KyleAMathews
KyleAMathews deleted the codex/misfits-repair-metadata branch November 2, 2026 21:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant