> ## Documentation Index
> Fetch the complete documentation index at: https://panopticon-cli.com/llms.txt
> Use this file to discover all available pages before exploring further.

# State Model

> Where Overdeck keeps state, what is durable, and why the local database is a disposable cache.

# 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:

| Source of truth           | What it holds                                                                    | Where it lives                                   |
| ------------------------- | -------------------------------------------------------------------------------- | ------------------------------------------------ |
| **GitHub Issues**         | What work exists and its lifecycle (todo / in progress / done)                   | github.com                                       |
| **Git repo & workspaces** | The plan, the code, the feature branch, the PR, the per-issue record, task state | Your repo + `origin`                             |
| **Agent transcripts**     | The conversation history to resume an agent mid-task                             | On disk, per harness (kept while work is active) |
| **tmux**                  | Which agents are alive *right now*                                               | Local tmux server                                |

## The local database is a cache

Overdeck uses a local SQLite database (`~/.overdeck/panopticon.db`) for two jobs:

1. **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.
2. **A materialized view of the pipeline** — so the board renders instantly instead of re-scanning every workspace on each page load.

Both are **performance conveniences.** The database stores nothing that cannot be recomputed from the sources of truth above.

<Note>
  **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.
</Note>

## The pipeline is derived, not stored

An issue's pipeline phase is a **function of GitHub + its workspace**, not a value the database owns:

| Workspace / GitHub state           | Phase      |
| ---------------------------------- | ---------- |
| Feature branch + open tasks, no PR | **Work**   |
| PR open, not approved              | **Review** |
| PR approved                        | **Merge**  |
| Issue closed on GitHub             | **Done**   |

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

| State                                                           | Durable home                        | In the cache?             |
| --------------------------------------------------------------- | ----------------------------------- | ------------------------- |
| Issue status / lifecycle                                        | GitHub                              | ✅ cached                  |
| Plan (xBRIEF spec)                                              | git — `.pan/specs/`                 | ✅ cached                  |
| Code & branch                                                   | git / `origin`                      | —                         |
| Task completion (tasks)                                         | git (dolt-backed)                   | ✅ cached                  |
| Per-issue record — decisions, progress, harness/model, verdicts | git — the feature branch            | ✅ cached                  |
| Conversation transcripts                                        | on disk, per harness (while active) | indexed                   |
| Cost                                                            | derived from transcripts            | ✅ cached                  |
| Live activity (who's thinking)                                  | ephemeral                           | cache only                |
| Retry counters, merge-queue position                            | ephemeral bookkeeping               | cache only — safe to lose |

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 in `npm run lint` and 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.
