git bisect that treats flakiness as a signal, not noise
Project description
FlareBisect ๐ฅ
FlareBisect finds the commit that made your tests flaky, not just the one that broke them: it bisects on flake-rate drift instead of pass/fail, then flares the culprit with an AI-written root cause.
git bisect gives you confidently wrong answers when the test you're
bisecting on is flaky โ it treats every run as a clean pass/fail signal, so
a test that was already unstable before you started bisecting can point
straight at an innocent commit.
flarebisect bisects on flake rate, not pass/fail. It runs each
candidate commit's test N times in parallel, computes a failure rate, and
finds the commit where that rate jumps โ then asks an LLM to explain, in
plain English, whether the commit broke the test cleanly or made it flakier.
12 commits in range ยท 20 runs per commit ยท parallel worktrees
commit flake rate result status
a1b2c3 5/5 good
4f9e21 5/5 stable
7d3aa0 โโโโโโโ 4/5 wobbling
9c1f88 โโโโโโโโโโโโโโโโโโโโโโโโโโโโ 1/5 flare
HEAD โโโโโโโโโโโโโโโโโโโโโโโโโโโโ 1/5 bad
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ โฆ culprit found ยท commit 9c1f88 โโโโโ โ
โ โโโโโโโโโ โ
โ flake rate jumped 20% โ 80% at this commit โโโโโโโโโ โ
โ "add request counter for rate limiting" โโโโโโโโโ โ
โ โโโโโโโโโ โ
โ ๐ก likely cause โ shared counter incremented without a lock.โโโโโโโโโ
โ concurrent test workers race on the same variable. โโโโโโโโโ โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
โฑ 8.4s โก 5 checked โ 4 parallel workers
Install
pip install flarebisect
For local development:
pip install -e ".[dev]"
pytest -q
Works on Linux, macOS, and Windows โ the only external dependency is git
on your PATH. Every candidate commit runs in its own git worktree under a
temp directory; your actual working tree and index are never touched.
AI provider setup
The root-cause explanation step works with Claude, OpenAI, Gemini, or a local model โ anything speaking an OpenAI-compatible chat API (Ollama, LM Studio, llama.cpp server, vLLM, and similar all qualify).
# cloud
flarebisect config set-key anthropic sk-ant-...
flarebisect config set-key openai sk-...
flarebisect config set-key google AI...
# local, no key needed - just have Ollama running
flarebisect config use ollama
flarebisect config set-model ollama llama3.1
# or let flarebisect pick a model sized to your GPU and pull it for you
flarebisect models detect # shows detected GPU/VRAM + recommended model
flarebisect models pull # downloads it and sets it active (run with no args)
# any other OpenAI-compatible endpoint
flarebisect config use custom
flarebisect config set-base-url custom http://localhost:8080/v1
flarebisect config set-key custom sk-local
Run flarebisect config with no arguments for a guided setup wizard โ for
Ollama it detects your GPU/VRAM, prefills a right-sized model, and offers to
pull it on the spot.
flarebisect config show lists the active provider and stored settings
(keys are masked). Config lives in a JSON file under the OS config dir
(~/.config/flarebisect/config.json on Linux/macOS, %APPDATA% on Windows),
written with owner-only permissions.
Per-run overrides skip the config file entirely:
flarebisect run ... --provider openai --model gpt-4o-mini --api-key sk-...
flarebisect run ... --provider ollama --base-url http://localhost:11434/v1
Env vars (ANTHROPIC_API_KEY, OPENAI_API_KEY, GOOGLE_API_KEY) work too,
as a fallback under whatever's in the config file.
Usage
flarebisect run \
--repo /path/to/repo \
--good <known-good-sha> \
--bad <known-bad-sha> \
--test "pytest -k my_flaky_test" \
--runs 20 \
--threshold 0.3
--runsโ test executions per commit (default 20), run in parallel (capped at your core count so it doesn't oversubscribe). Lower counts are faster but noisier โ a low sample can misattribute the culprit near the threshold boundary.--thresholdโ flake-rate jump (0-1) vs. thegoodbaseline required to call a commit the culprit (default 0.3).--no-explainโ skip the LLM root-cause call entirely (fully offline).
Demo
See demo/ for a self-contained, seeded-flaky-bug repo you can
bisect against with no network access required for the bisection itself.
How it works
- Measure the flake rate at
goodandbadas baselines. - Binary-search the commit range between them.
- At each candidate, run the test
Ntimes in an isolated worktree and computefailed / N. - The culprit is the first commit whose flake rate jumps by
>= thresholdover thegoodbaseline. - Verdict: clean break (rate goes ~0% โ ~100%) vs. flakiness regression (rate goes ~0% โ somewhere in between).
- The configured LLM gets the culprit's diff + the flake-rate evidence and returns a short root-cause read (race condition, shared mutable state, timing assumption, etc.).
Binary search assumes the flake rate is roughly monotonic across the range,
same as ordinary git bisect assumes pass/fail is. At low --runs counts
a noisy sample can occasionally violate that near the threshold boundary โ
bump --runs if a result looks off.
Releasing
Version is single-sourced from src/flarebisect/__init__.py. Bump it, commit,
tag (vX.Y.Z), and cut a GitHub Release โ .github/workflows/publish.yml
builds and publishes to PyPI via trusted publishing (OIDC, no stored token).
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file flarebisect-0.3.1.tar.gz.
File metadata
- Download URL: flarebisect-0.3.1.tar.gz
- Upload date:
- Size: 15.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a7b7c358189764b2328d88c16691ec0778925aa0c6931e4529854ab713045c3f
|
|
| MD5 |
8685ff66f9267628d2e1062e1c55216b
|
|
| BLAKE2b-256 |
398eba3006919f2b6b71f5d929e4ae32c64dc97ed896dd718c0028804dc81f12
|
Provenance
The following attestation bundles were made for flarebisect-0.3.1.tar.gz:
Publisher:
publish.yml on kaorii-ako/FlareBisect
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
flarebisect-0.3.1.tar.gz -
Subject digest:
a7b7c358189764b2328d88c16691ec0778925aa0c6931e4529854ab713045c3f - Sigstore transparency entry: 2256129826
- Sigstore integration time:
-
Permalink:
kaorii-ako/FlareBisect@1c6339fa9d5cd47ee89f63342543ca650a386d0a -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/kaorii-ako
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@1c6339fa9d5cd47ee89f63342543ca650a386d0a -
Trigger Event:
release
-
Statement type:
File details
Details for the file flarebisect-0.3.1-py3-none-any.whl.
File metadata
- Download URL: flarebisect-0.3.1-py3-none-any.whl
- Upload date:
- Size: 19.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3f85ead23c2476c9ca84d4c42ba856be33d747c8beb4acb7bdd1e02998c2a81e
|
|
| MD5 |
f5c36d448d25262c881aa5b8204121de
|
|
| BLAKE2b-256 |
ca4e2ea9805e4c69f4c01aa8b16b39866a170a20c82dd5fe30e6ecea08c94927
|
Provenance
The following attestation bundles were made for flarebisect-0.3.1-py3-none-any.whl:
Publisher:
publish.yml on kaorii-ako/FlareBisect
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
flarebisect-0.3.1-py3-none-any.whl -
Subject digest:
3f85ead23c2476c9ca84d4c42ba856be33d747c8beb4acb7bdd1e02998c2a81e - Sigstore transparency entry: 2256129842
- Sigstore integration time:
-
Permalink:
kaorii-ako/FlareBisect@1c6339fa9d5cd47ee89f63342543ca650a386d0a -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/kaorii-ako
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@1c6339fa9d5cd47ee89f63342543ca650a386d0a -
Trigger Event:
release
-
Statement type: