Culprit has two kinds of settings: your keys and models, which belong to you and work across all
your repos, and repo settings, which describe one agent and live in culprit.toml.
Keys#
culprit init asks for your keys the first time and saves them in
~/.config/culprit/credentials.env (or under $XDG_CONFIG_HOME), readable only by you. Every repo
you set up afterwards uses them without asking.
| Setting | Needed | What it's for |
|---|---|---|
ANTHROPIC_API_KEY |
one of the two | Claude models. Used when set, before OpenRouter. |
OPENROUTER_API_KEY |
one of the two | Any model on OpenRouter. |
NEATLOGS_API_KEY |
no | Tracing every run and decision in neatlogs. See Tracing. |
To change saved keys:
culprit init --keysWhich source wins#
Each setting is taken from the first of these that sets it:
- Your shell environment, for example
export OPENROUTER_API_KEY=…, or a CI secret. - The repo's
.envfile, to override for one repo. - What
culprit initsaved.
culprit init prints where each setting came from:
OPENROUTER_API_KEY: from culprit init
NEATLOGS_API_KEY: from repo .envWhen a repo's .env supplies a setting, every command says so on its first line, for example
culprit: using NEATLOGS_API_KEY from /path/to/repo/.env. In a repo you didn't write, that tells you
its .env is choosing whose account your calls go to.
What Culprit reads from a repo's .env
Only its own five settings: the two model keys, NEATLOGS_API_KEY, VICTIM_MODEL and
CULPRIT_MODEL. Everything else in that file, such as proxy settings, is ignored by Culprit
itself, because it could redirect your keys. Your agent's own runs still get the whole file.
Models#
Culprit uses two models, both from the provider your key selects:
| Setting | Role | Default with Anthropic | Default with OpenRouter |
|---|---|---|---|
VICTIM_MODEL |
Runs your agent at every commit. | claude-sonnet-5-5 |
z-ai/glm-5.3 |
CULPRIT_MODEL |
Culprit's own calls: ranking hunks, writing fixes, audit mutants. | claude-sonnet-5-5 |
z-ai/glm-5.3 |
Set either one in your shell, a repo's .env, or the saved setup. The model must belong to the
provider in use: OpenRouter IDs look like vendor/model, Anthropic IDs have no slash. If you set
VICTIM_MODEL=google/gemini-3.8-flash while an Anthropic key is present, Culprit stops and says so.
The victim model is chosen once when a run starts and recorded with it, so every commit in the run, and any resume, is judged by the same model.
Pick the victim model you ship
Whether a change is a regression can depend on the model. In our tests, removing a safety check hurt a small model and changed nothing on a stronger one, and both verdicts were right. Bisect with the model your agent runs in production.
culprit.toml#
culprit init writes this at your repo's root. Commit it so your team and CI share the settings.
# Culprit settings for this repo (https://culprit-site.vercel.app). Keys go in .env, never here.
eval_module = "myagent.eval" # python -m <eval_module> --task <id> --seed <n>
suite = "evals" # one file per task; the copy at suite_ref judges every commit
suite_ref = "main"| Key | Default | Meaning |
|---|---|---|
eval_module |
detected by init |
The module Culprit runs for each task. See Prepare your agent. |
suite |
evals |
The suite directory in your repo, or a directory on disk (an absolute path, or one containing /). |
suite_ref |
your branch when you ran init |
The ref whose copy of the suite judges every commit. |
Commands look for culprit.toml in the current directory and its parents, up to the git root, so
you can run Culprit from anywhere inside the repo. A command-line flag (--eval-module, --suite,
--suite-ref, --repo) always wins over the file.
Where Culprit keeps things#
| What | Where | Commit it? | Change with |
|---|---|---|---|
| Saved keys | ~/.config/culprit/credentials.env |
Never: it holds your keys. | XDG_CONFIG_HOME |
| Repo settings | culprit.toml |
Yes, so your team and CI share it. | culprit init |
| Ledger: every run, step and result | .culprit/ledger.sqlite |
No | --db, or CULPRIT_STATE_DIR for the whole folder |
| Worktrees, one per tested commit | .culprit/worktrees/ |
No | CULPRIT_STATE_DIR |
| Pinned suite snapshots | .culprit/suites/ |
No | CULPRIT_STATE_DIR |
| Reports | .culprit/reports/ |
No | culprit report --out |
PR comment from culprit ci |
culprit-comment.md |
No | culprit ci --comment-file |
.culprit/ is created in the directory you run Culprit from, normally your repo's root, and
culprit init adds it to .gitignore. Culprit never edits your checkout: it only creates worktrees
inside .culprit/.
Other environment variables#
Besides the five settings above, Culprit reads these from your shell only:
| Variable | Same as | Purpose |
|---|---|---|
CULPRIT_EVAL_MODULE |
--eval-module |
The module that runs one task. |
CULPRIT_VICTIM_REPO |
--repo |
The agent's repo. |
CULPRIT_STATE_DIR |
Where .culprit/ goes. Default: the current directory. |
|
XDG_CONFIG_HOME |
Where saved keys go. Default: ~/.config. |
|
NEATLOGS_CLI |
Path to the neatlogs CLI, for verify-trace. |
The variables Culprit sets for your agent's runs are listed in Prepare your agent.