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-1.0.0.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-1.0.0-py3-none-any.whl (19.5 kB view details)

Uploaded Python 3

File details

Details for the file flarebisect-1.0.0.tar.gz.

File metadata

  • Download URL: flarebisect-1.0.0.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-1.0.0.tar.gz
Algorithm Hash digest
SHA256 fd2f7f37f2ab14306305c8fdc6591bc25e5fae62d5966529474aed6a1b7299db
MD5 a060a70141051b54933fb207dd1b291a
BLAKE2b-256 8c5de13bade45d4da257a36eb216637d7a509ce4db49ec37f5a66962b4873eaf

See more details on using hashes here.

Provenance

The following attestation bundles were made for flarebisect-1.0.0.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-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: flarebisect-1.0.0-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-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b8fbb0ebb273f704e5f14a095d4fbcac50898e0d4aecda383d7881fc2a02ba21
MD5 276478269912445dc74e8e2b284798d8
BLAKE2b-256 1a2d3706081ffc4c4a4f123442faca98bccab5d37839c8c77ee26bf91f511414

See more details on using hashes here.

Provenance

The following attestation bundles were made for flarebisect-1.0.0-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