persistence-driftlisted
Install: claude install-skill zakariaf/CatchLaw
# Persistence — Drift / SQLite
The on-device store is the single source of truth: with no server, everything must rebuild from this DB alone after
process death, reboot, or restore. Push invariants into the schema, confine Drift to one layer, make every mutation
one durable transaction, and store canonical values only. Applies to any `lib/data/` Drift table, DAO, repository,
connection setup, or backup.
Read the reference for the task at hand:
- `references/schema-and-daos.md` — audit-column mixin, STRICT/CHECK/FK invariants, canonical column types, the index + `EXPLAIN QUERY PLAN` gate, DAO↔repository split, files-on-disk-with-relative-paths for blobs.
- `references/backup-and-wal.md` — the checkpoint→vacuum→verify-by-reopen primitive, WAL rules, the backup-before-anything lesson, optional SQLCipher (key-first, assert-cipher, header-check).
- `references/persistence-without-drift.md` — the same discipline for a small app on plain JSON files (injected base dir, debounce + lifecycle flush, atomic writes, lenient decode).
Run `scripts/check-drift-confinement.sh` and `scripts/check-persistence-bans.sh` before a PR. Migrations and their tests: see `run-migration`.
## Non-negotiable rules
1. **Drift lives only in `lib/data/`; everything else sees value types.** `package:drift` and `package:sqlite3` are imported nowhere else — a banned-import lint/grep enforces it. DAOs map rows to immutable value objects; no `Table`, `Companion`, `TableInfo`, or generated row class crosses th