Omnis

ADR-0005 — Configuration lives in files, data lives in PGlite

  • Status: Accepted · Date: 2026-09-06 · Resolves: D2

Context

The transcript puts appearance profiles in a brand_appearance_profiles table and the same settings in settings.json, with no stated precedence. It also names the store: a "Serialized PGlite Mailbox" — embedded Postgres, not a server, which settles the local-first tension but not the overlap.

Decision

Configuration — themes, icon themes, profiles, keymaps, layouts, feature flags, settings — lives in versioned files and resolves through defaults → profile → user → workspace → runtime. It is diffable, shareable, reviewable, and survives losing the database.

User data — workspaces, tabs, chat threads, audit entries, CAS metadata, VCS state, context fragments, escrow tickets — lives in PGlite.

The transcript's brandAppearanceProfiles table is not adopted. The test: would a user want this in version control, or be alarmed to find it there? Config is the first, data the second.

Alternatives rejected

  • Everything in the database. Profiles stop being shareable artifacts, configuration becomes unreviewable, and a corrupt store takes the user's setup with it.
  • Everything in files. Chat history, audit streams, and CAS metadata as flat files means no queries, no transactions, and a synchronisation problem per file.
  • A server Postgres. Contradicts local-first; makes a background service a hard dependency for a desktop application.
  • SQLite instead of PGlite. Defensible and lighter. Rejected to keep one dialect across the eventual sync and mailbox work. Worth revisiting if PGlite's footprint proves unacceptable — that would supersede this ADR.

Consequences

Two persistence mechanisms and two backup stories, with a boundary that will be argued at the edges (a pinned context fragment is data, because the user did not author it as a setting). Config writes must be atomic and attributable in the same way database mutations are. The sync boundary (E19) must handle both, and they have different conflict semantics: config merges textually, data through the CRDT.

Omnis