SQLite‑first locally, Postgres + Electric SQL for the cloud — one resolved backend honored by every path: the run, the CLI reads, the gateway, and the UI.
.smithers/specs/pluggable-db-backends.md
workflow run writes a SQLite store (seeded workflows use the sync, sqlite‑only createSmithers()).SMITHERS_MIGRATION_REQUIRED on a brand‑new install.find-db.js always opens bun:sqlite, so a PGlite run is invisible — ps shows [], exit 0.bun:sqlite regardless.init → run → ps round‑trip, so it shipped.openSmithersStore() in packages/smithers: resolve once, open exactly that backend, return a SmithersDb adapter + teardown.findAndOpenDb() delegates to it — so ps/inspect/output/chat read the resolved backend (PGlite & Postgres included).openSmithersBackend's fresh‑workspace default from PGlite → SQLite.createSmithers() (sqlite) — now coherent with reads.--backend / env / smithers.config.ts.Electric needs real Postgres — but that constraint must not dictate the local default. So the sync transport is mode‑selected, parallel to the pluggable engine backend.
gateway-client / gateway-react talk to a pluggable client transport, not a hard‑wired backend.SmithersDb, so it works off SQLite with no Electric lib loaded.SMITHERS_BACKEND_CONFLICT, never a silent pick..smithers/backend.json = authorization marker; migrated.json = migration receipt. Probes still win.smithers migrate becomes multi‑directional: --from/--to any pair (incl. pglite → sqlite).SQLite default + a backend‑aware read opener makes init → run → ps round‑trip and unblocks onboarding — by itself.
Symmetric detection + multi‑directional migrate (with the agent backstop) keep existing PGlite users safe.
SQLite by default. init → run → ps → inspect just works — no migration, no socket, no config.
One resolved backend honored by run, reads, gateway, eval. PGlite & Postgres are first‑class, not special‑cased.
Same UI: gateway‑WS direct off SQLite locally, Electric + Postgres for cloud multiplayer. A transport swap.
Physical‑truth legacy rule, multi‑directional migrate, agent repair fallback, and an e2e round‑trip matrix so this never regresses.
Next: implement Phase 1 (codex) → review (opus + codex) → land.