All projects

Solo, Hack the North 2026

Whodunit

Git bisect with a brain. A Gemini agent turns a plain-English bug report into a reproduction test and finds the culprit commit, even when the test is flaky.

  • TypeScript
  • Gemini
  • Elasticsearch
  • Node.js
  • React
Whodunit mid-investigation: suspect commits pinned to a board with probabilities, a timeline of the posterior, and live Elasticsearch queries.

Problem

git bisect treats every commit as equally suspicious and trusts the test every time. That makes it a slow midpoint search, and a single flaky run can blame an innocent commit.

The commit that looks guilty is often a red herring, too. I wanted a bisect that reads the diffs, CI logs and issue threads first, weighs the suspects, and still works when the test lies.

What I built

You type what broke. A Gemini tool-calling agent searches the history, writes a reproduction test and runs a Bayesian bisect to find the culprit. It then writes a cited verdict and can commit a fix if the reproduction and npm test both pass.

The interface streams the investigation live over SSE, and a simulated case replays real history in the browser if the Wi-Fi or APIs fail mid-demo.

How

  1. Bug reportOne plain-English sentence
  2. Gemini agentTool loop: investigate, reproduce, fix
  3. BM25Keyword search
    Gemini embeddings768-d kNN search
  4. Reciprocal Rank FusionElasticsearch: commits, hunks, CI logs, issues
  5. Bayesian bisectProbes the weighted median of the posterior
  6. Git worktree oracleRuns the repro; the result updates the posterior
  7. Cited verdictOptional verified fix

Search evidence sets a prior over every commit, so probes are spent where the suspicion is. Each step tests the weighted median of the posterior, rather than the midpoint.

The test is modelled as noisy: every result updates the posterior using a flake rate ε instead of ruling commits out for good. Every probe runs in its own git worktree, and the same engine runs in Node and in the browser simulation.

The Whodunit complaint desk, where you describe the bug in one sentence.
You start by describing what broke, in one sentence.
A newspaper-styled verdict naming commit 4c58cb3 as the culprit.
The verdict cites the evidence behind commit 4c58cb3.

Results

  • On a 108-commit demo repository, it names 4c58cb3: Math.floor became Math.trunc, so negative money rounds the wrong way by one cent. The credit-note feature is the red herring.
  • Search evidence alone cut uncertainty from 6.74 bits to 4.17 bits before any test ran.
  • With the flaky oracle turned on, classic bisect derails while the Bayesian search still closes on the culprit.

What I learned

  • A demo has to survive the venue, so quota fallback and an offline simulation mattered as much as the model did.
  • Treating a test as evidence rather than truth makes the search both faster and more honest about what it knows.
Next projectWharf