State Model
Overdeck keeps almost no irreplaceable state of its own. The durable record of your work lives in systems that already exist for their own reasons — GitHub and git — and the local database is a derived cache: a fast view over those sources that holds nothing which can’t be rebuilt from them. If you remember one thing from this page: the database is a cache, not a source of truth.The sources of truth
Everything Overdeck needs — to show you a board, run the pipeline, or recover after a crash — is a function of four things that live outside its database:The local database is a cache
Overdeck uses a local SQLite database (~/.overdeck/panopticon.db) for two jobs:
- A uniform read/write API for the dashboard, the deacon, and the CLI — so every component talks to state the same way instead of each parsing files.
- A materialized view of the pipeline — so the board renders instantly instead of re-scanning every workspace on each page load.
The design principle: the database holds no state that isn’t derivable from GitHub + your workspaces. It is a cache in front of those sources, not a system of record — which is what keeps recovery and cross-machine work straightforward. The durable record of your work lives in git, not in a local file you have to back up.
The pipeline is derived, not stored
An issue’s pipeline phase is a function of GitHub + its workspace, not a value the database owns:
Overdeck computes this view by walking the workspaces and reading GitHub, then caches the result. The cache is for speed; the derivation is the truth.
What lives where
The only things that vanish on a database loss are ephemeral counters — retry counts, queue positions. They gate loop-prevention, not your work; on a rebuild they reset, and the worst case is an agent gets a fresh set of attempts.
Search indexes are the exception
Overdeck also keeps search indexes in SQLite — full-text and semantic search over conversations and docs. Unlike pipeline state, a search index is legitimately a database’s job and persists as one. These indexes are rebuildable from the transcripts on disk, but they are a search feature, not part of the “pipeline is a cache” model.The rules that keep this true
- All state mutations go through the database API — never ad-hoc writes to scattered files. The database is the single write surface; the per-issue git record is its durable mirror. This is enforced mechanically by
scripts/lint-state-writes.sh, which runs innpm run lintand CI. - Legacy continue/feedback/session writers are being routed to the record writer. A small set of pre-PAN-1919 writers (continue files, feedback files, session JSONL) remain while they are migrated; the guard allowlists them explicitly and fails on any new ad-hoc state write.
- The database is reconstructable. A rebuild path walks every workspace + GitHub and repopulates the cache from scratch.
- The few facts a workspace can’t derive — an agent’s chosen harness/model, pipeline verdicts, retry counters — live in the per-issue record committed to the feature branch, so they travel across machines and survive a database loss.
Why it matters
- Recovery is trivial. Lost database, corrupted file, fresh machine —
git clone, start Overdeck, and the board rebuilds. No backups to restore, no event logs to replay. - Work is portable. Because the durable record travels in git, another machine — or another engineer — can pull a branch and continue exactly where the last agent left off.
- The system is simple to reason about. Every piece of state has a clear home: if it isn’t derivable from GitHub + the workspaces, it lives in the per-issue git record — never only in the local cache.