Skip to main content

git bisect that treats flakiness as a signal, not noise

Project description

FlareBisect ๐Ÿ”ฅ

PyPI CI License: MIT

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. the good baseline 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

  1. Measure the flake rate at good and bad as baselines.
  2. Binary-search the commit range between them.
  3. At each candidate, run the test N times in an isolated worktree and compute failed / N.
  4. The culprit is the first commit whose flake rate jumps by >= threshold over the good baseline.
  5. Verdict: clean break (rate goes ~0% โ†’ ~100%) vs. flakiness regression (rate goes ~0% โ†’ somewhere in between).
  6. 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flarebisect-0.3.1.tar.gz (15.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

flarebisect-0.3.1-py3-none-any.whl (19.5 kB view details)

Uploaded Python 3

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

Hashes for flarebisect-0.3.1.tar.gz
Algorithm Hash digest
SHA256 a7b7c358189764b2328d88c16691ec0778925aa0c6931e4529854ab713045c3f
MD5 8685ff66f9267628d2e1062e1c55216b
BLAKE2b-256 398eba3006919f2b6b71f5d929e4ae32c64dc97ed896dd718c0028804dc81f12

See more details on using hashes here.

Provenance

The following attestation bundles were made for flarebisect-0.3.1.tar.gz:

Publisher: publish.yml on kaorii-ako/FlareBisect

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for flarebisect-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3f85ead23c2476c9ca84d4c42ba856be33d747c8beb4acb7bdd1e02998c2a81e
MD5 f5c36d448d25262c881aa5b8204121de
BLAKE2b-256 ca4e2ea9805e4c69f4c01aa8b16b39866a170a20c82dd5fe30e6ecea08c94927

See more details on using hashes here.

Provenance

The following attestation bundles were made for flarebisect-0.3.1-py3-none-any.whl:

Publisher: publish.yml on kaorii-ako/FlareBisect

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page