Local Database
The local database (lib/local-db.ts) is a SQLite cache powered by expo-sqlite. It mirrors a subset of the Convex cloud data for offline access and instant UI rendering. The database file is named commit.db and uses WAL journaling mode for concurrent read performance.
Schema Version 12 (Instance-Dependent Architecture)
The current schema defines two core tables with zero foreign key constraints:Why No Foreign Keys?
The removal of FK constraints was a direct response to a production database corruption bug. The prior schema required togglingPRAGMA foreign_keys on and off around every write:
By removing FKs entirely, all PRAGMA toggles were eliminated, and write paths became race-free.
Nuke and Pave Migration Strategy
There are no incremental migrations. If the on-devicePRAGMA user_version does not match the current DATABASE_VERSION constant, the entire database is destroyed and rebuilt:
VACUUM command physically reconstructs the entire database file from scratch. This eliminates ghost WAL boundaries that caused Android’s native CursorWindow to misread corrupted lengths (triggering 124MB OOM allocations on the JVM).
Three Recovery Tiers
1
Surgical Purge
Clears all data rows without dropping tables. Preserves file descriptors so the Kotlin Accessibility Service keeps its database handle alive. Used by Manual Resync.
2
Nuke and Pave
Drops all tables, deploys the unified schema, and runs
VACUUM. Used on schema version mismatch or terminal corruption. Requires a full re-sync from Convex (Amnesia Mode).3
OS-Level Clear
If both tiers above fail, the user must clear the app data through Android Settings. This destroys the SQLite file entirely and forces a fresh install state.