AI-powered Git bisect for engineers who want the culprit commit and a concise explanation without sending their whole repository to a hosted product.
Culprit is a local-first Rust CLI that guides a bisect run, executes your test command at each candidate commit, restores your original checkout, and can optionally summarize the suspect commit with your own OpenAI-compatible API key.
git bisect is powerful, but the workflow is easy to fumble when a failure is urgent. Culprit wraps the sharp parts with a safer terminal assistant:
- guided or fully scripted bisect runs
- clean-worktree checks before checkout changes
- deterministic Git bisect semantics
- concise transcript of tested commits and outcomes
- optional AI summary of the suspect commit, diff stat, bounded diff excerpt, and failing-output tail
- no hosted backend and no project-owned inference bill
cargo install --path .From a published checkout, you can also run directly:
cargo run -- doctorRun the guided flow:
culprit runOr run it non-interactively:
culprit run \
--good v1.2.0 \
--bad HEAD \
--cmd "cargo test failing_case"Exit-code handling matches Git bisect conventions:
0means the commit is good125means skip this commit- any other exit code means the commit is bad
Explain a known suspect commit:
culprit explain 4f3c2a1 --aiCheck local setup:
culprit doctorAI is optional and bring-your-own-key. Culprit does not store API keys and does not send repository content unless you explicitly opt in with --ai or the guided confirmation prompt. Use --ai --yes for scripted runs that should skip the confirmation prompt.
Environment variables:
export CULPRIT_API_KEY="..."
export CULPRIT_BASE_URL="https://api.openai.com/v1"
export CULPRIT_MODEL="gpt-4.1-mini"
export CULPRIT_MAX_DIFF_BYTES="24000"
export CULPRIT_MAX_OUTPUT_TOKENS="800"
export CULPRIT_TIMEOUT_SECONDS="60"You can also set non-secret defaults in .culprit.toml:
[ai]
base_url = "https://api.openai.com/v1"
model = "gpt-4.1-mini"
max_diff_bytes = 24000
max_output_tokens = 800
timeout_seconds = 60When --repo points at another checkout, Culprit reads .culprit.toml from that repository root.
Culprit is designed for real repositories:
- refuses to bisect a dirty worktree unless
--allow-dirtyis passed - uses Git itself for checkout and bisect state
- calls
git bisect resetafter successful and failed runs - captures only a short test-output tail for summaries
- trims diff context before AI calls
- bounds AI response length and request timeout
The test command should not modify tracked files. If your test suite creates build output, configure it to write ignored files or temporary directories.
MIT