Docs
Get started

Configuration

Keys, models, and the per-repo settings in culprit.toml, and which source wins when they disagree.

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:

Terminal
culprit init --keys

Which source wins#

Each setting is taken from the first of these that sets it:

  1. Your shell environment, for example export OPENROUTER_API_KEY=…, or a CI secret.
  2. The repo's .env file, to override for one repo.
  3. What culprit init saved.

culprit init prints where each setting came from:

Output
  OPENROUTER_API_KEY: from culprit init
  NEATLOGS_API_KEY: from repo .env

When 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.

TOML
# 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.

Culprit 0.1.0 · Apache-2.0 · Team PiedPiper