> ## Documentation Index
> Fetch the complete documentation index at: https://fuguai.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Store

> The SQLite file that holds every answer, every judgment's table and the history of runs.

One SQLite file holds every answer, each judgment's latest table, the run history and logged traffic. WAL mode: batch runs and `judge()` callers can use it at the same time.

## Where it lives

In order:

1. `HUNCH_STORE`, if set.
2. The nearest `.hunch/store.sqlite` in the spec's folder or any folder above it.
3. Otherwise a new `.hunch/store.sqlite` at the root of the git repository, or in the spec's folder outside a repository.

A new store is announced on stderr:

```
new answer store: /path/to/.hunch/store.sqlite (no store in this folder or above; HUNCH_STORE=... to share one)
```

Seeing it for a project you have run before means every answer will be asked again; set `HUNCH_STORE` to the existing store.

Keep `.hunch/` out of git: about 80 MB per 100,000 rows, and it holds your rows' text.

## The answer cache

`answers` is content-addressed: each answer is keyed by a hash of exactly what was asked.

| Column         | Meaning                                                                                                                                                                                             |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `key`          | SHA-256 of the request: the model, the state (the row's `state` columns after `redact` and `clip`), and the question as sent. For an LLM engine it also includes the adapter version `logprobs-v1`. |
| `model`        | The engine that answered.                                                                                                                                                                           |
| `answer`       | The engine's answer as JSON.                                                                                                                                                                        |
| `input_tokens` | Input tokens billed for it (shared equally when one request answered several questions).                                                                                                            |
| `created_at`   | When it was stored.                                                                                                                                                                                 |

* Same row, question and model anywhere (batch, `judge()`, server): cache hit.
* New key: a change to `instructions`, `criteria`, option order, model, or any state column's text.
* Not in the key: `act`, `gold`, `escalate`, `tests`, `where`, the spec's name and `source`.

Answer shapes:

```json theme={null}
{"type": "choice", "choice": "billing", "confidence": 1.0,
 "probabilities": {"none_of_these": 0.0, "sales": 0.0, "billing": 1.0, "technical": 0.0}}
{"type": "noul", "noul": 0.1}
{"type": "score", "score": 0.35, "confidence": 0.65,
 "legend": {"0": "Calm", "1": "Mildly annoyed", "2": "Frustrated", "3": "Very angry"},
 "probabilities": {"0": 0.65, "1": 0.35, "2": 0.0, "3": 0.0}}
```

`noul` is p(yes).

## Judgment tables

`hunch run` writes one table per judgment, named after it, replaced in one transaction; a failed run leaves the previous table. Columns: the [answer columns](/reference/spec#columns-a-judgment-adds), plus:

| Column           | Meaning                          |
| ---------------- | -------------------------------- |
| `<question>_key` | The answer's `key` in `answers`. |
| `_hunch_run_id`  | The run that wrote the row.      |

Under `--model`, the table name gets the engine as a suffix (`intent__deepseek_deepseek_flash`), leaving the spec's own table untouched.

## Runs and lineage

| Table                | One row per           | Columns                                                                                                               |
| -------------------- | --------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `_hunch_runs`        | judgment per run      | `run_id`, `judgment`, `spec_hash`, `git_sha`, `model`, `rows`, `asked`, `cost`, `status`, `started_at`, `finished_at` |
| `_hunch_row_answers` | row, question and run | `judgment`, `row_id`, `qid`, `key`, `shash`, `run_id`                                                                 |

* `spec_hash` covers what the judgment asks, not `on_change` or `source`; `on_change: freeze` compares it with the last complete run's.
* `status` is `complete`, or `failed: <error>`.
* `shash`: hash of the row's state. `new_rows_only` reuses an answer only when row id and `shash` both match.
* `/v1/drift` and the runs page read label mixes from `_hunch_row_answers`.

## Traffic

`judge(..., log=True)` and `judge(..., shadow=...)` keep each row in `traffic` (`judgment`, `rhash`, `row`, `n`, `first_at`, `last_at`), redacted by the live spec's rules; a repeat increments `n`. `--traffic` exports it to `.hunch/traffic/<judgment>.csv` and runs on that.

## Querying it

Plain SQLite. Which engine answered each row of the triage example, and when:

```sh theme={null}
sqlite3 -header -column prototype/.hunch/store.sqlite \
  "select t.id, t.dept, t.dept_p, t.dept_by, a.created_at
   from triage t join answers a on a.key = t.dept_key order by t.id"
```

```
id      dept       dept_p          dept_by              created_at
--  -------------  ------  -----------------------  -------------------
1   billing           1.0  jev-1.13.0               2026-09-24 17:16:27
2   technical       0.998  deepseek:deepseek-flash  2026-09-24 17:16:27
3   none_of_these     1.0  jev-1.13.0               2026-09-24 17:16:27
4   sales             1.0  jev-1.13.0               2026-09-24 17:16:27
5   technical         1.0  jev-1.13.0               2026-09-24 17:16:27
6   billing           1.0  jev-1.13.0               2026-09-24 17:16:27
```

From Python, [`hunch.results`](/reference/python#results) returns a judgment's table as a list of dicts.
