For "this used to work" bugs, the fastest path to root cause is not reading code — it is git bisect, which finds the breaking commit in log₂(N) steps with zero theorizing. AI enters after localization, where it excels: explaining the fault mechanism of a specific diff, and helping you script the bisect test itself.
Tier: Core · Workflow area: Debugging
Deterministic tool for locating, LLM for understanding — each doing the job the other is bad at.
git log (hundreds of commits, or the symptom is far from the cause).Skip it when the bug is not a regression, when history is unbisectable (giant squash merges), or when git log -S "export_format" finds the culprit in one command — try that first.
v2.14.0 good, HEAD bad).Script the verdict. Turn "is it broken here?" into an exit code. Ask AI for the harness:
Write a bash script for `git bisect run`. Broken = `pytest
tests/exports/test_csv.py::test_unicode_headers -x` fails.
Requirements: exit 0 if test passes, 1 if fails, 125 if the commit
can't be built (pip install -e . fails) so bisect skips it.
Reinstall deps only if pyproject.toml changed vs a cached hash.
Sanity-check the script on both endpoints before trusting it: must exit 0 on the good ref, 1 on the bad ref. A wrong verdict script bisects you to an innocent commit with total confidence.
Run the bisect.
git bisect start HEAD v2.14.0
git bisect run ./bisect-check.sh
# ... "abc1234 is the first bad commit"
git bisect reset
For a flaky symptom, make the script run the test several times and fail if any run fails — bisect assumes a deterministic verdict.
Hand the culprit diff to AI — with the symptom. The diff alone invites generic review; the pairing is what you want explained:
git bisect identified this commit as the first bad one. Symptom: CSV
export garbles non-ASCII column headers (ü -> ü) - a mojibake.
Commit message: "perf: stream exports instead of buffering".
[git show abc1234 output]
Explain the fault MECHANISM: exactly how this change produces this
symptom. Trace the data path. If the diff alone can't explain it,
say what else you need to see rather than speculating.
Confirm the mechanism, don't adopt it. A good answer names something checkable — "the old path wrote through codecs.open(..., 'utf-8'); the new streaming path writes raw bytes from str.encode() defaulting to the locale under the C locale of the worker". Verify: read the two code paths it names; reproduce with the one-line probe it implies (LC_ALL=C python -c ...). If the story doesn't survive contact with the code, feed the missing files and iterate.
Fix at the mechanism level. With mechanism in hand, decide: revert, forward-fix, or both. Ask AI for the minimal forward-fix and what else the same mechanism could have broken ("what other write paths in this commit rely on locale-default encoding?") — bisect finds one symptom; the mechanism often has siblings.
Keep the artifacts. Culprit hash, mechanism explanation (verified), and the verdict script go in the ticket. The script is reusable for the next regression in this area.
git bisect run with a solid verdict script is fully unattended — kick it off, make tea, come back to the culprit. The engineering is all in step 1.
abc1234, symptom present; check out abc1234~1, symptom absent.git log — that is theorizing, exactly what bisect exists to replace. Localize mechanically, explain with AI.Bisect itself is local git — no restriction applies. The AI steps need only the culprit diff and the symptom, one of the smallest disclosure footprints of any AI-debugging workflow: a single sanitized git show (strip proprietary identifiers if needed) rather than whole modules. That usually fits even strict engagements' rules for sanctioned enterprise tools; failing that, local models explain single-diff mechanisms decently when the diff is under a few hundred lines. Keep commit messages with customer names out of pasted output.