# Bisect

> Find the exact commit that introduced a bug or regression using automated git bisect. Use when something used to work and doesn't anymore, and the user wants the guilty commit — especially from a plain-English symptom like "scrolling got janky sometime last month."

- Skill: `tokyubevoxelverse/bisect` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add tokyubevoxelverse/bisect`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tokyubevoxelverse/bisect/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: tokyubevoxelverse (https://skillmd.com/u/tokyubevoxelverse)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tokyubevoxelverse/bisect

---


# Bisect

Something used to work. Your job is to hand back the exact commit that broke it, with an explanation of *why* it broke. `git bisect` does the search; your job is building a reliable oracle and driving the machine.

## Phase 1 — Build the oracle

Translate the symptom into an executable check script that exits `0` when the behavior is good and non-zero when it's bad. This script is everything — a wrong oracle bisects to a wrong commit with total confidence.

- Prefer the narrowest observable signal: a failing test, a grep on output, an HTTP probe, an exit code — not "run the app and look."
- **Validate the oracle before trusting it:** it must fail at the suspected-bad ref (usually HEAD) and pass at some older ref. If the user can't name a good ref, probe backwards — last release tag, then earlier tags/dates — until the check passes. No verified good/bad pair, no bisect.
- If the symptom is flaky, make the oracle run the check N times and fail on any failure (or majority, if the flake is inverse). State the confidence tradeoff.

## Phase 2 — Drive the machine

- Work in a **separate worktree** (`git worktree add`) so the user's working directory is untouched.
- `git bisect start <bad> <good>`, then `git bisect run <oracle>`.
- Handle history friction:
  - Commit doesn't build for unrelated reasons → `git bisect skip`.
  - Build/setup steps changed across history → make the oracle detect and adapt (e.g. try both old and new install commands), or bisect in stages across the boundary.
  - Dependencies must match each era — reinstall per checkout if lockfiles change.
- If `bisect run` can't work (manual-only check), fall back to stepping manually and asking the user to observe only when unavoidable — automate everything else.

## Phase 3 — The verdict

Never stop at the commit hash. Deliver:

1. **The guilty commit** — hash, author, date, message.
2. **The mechanism** — read the diff and explain *how* this change produces the observed symptom. If the connection isn't obvious, trace it until it is; a bisect result you can't explain is a suspect, not a conviction.
3. **The options** — clean revert (test whether it reverts cleanly and whether the symptom disappears), or a forward fix sketch, with a recommendation.

## Cleanup

Always `git bisect reset` and remove the worktree, even after failure. Leave no machinery behind.

## Edge cases

- **Merge-heavy history:** if the guilty commit is a merge, bisect the merged branch's commits (`git bisect` handles this, but explain the result carefully).
- **The oracle passes everywhere / fails everywhere:** the good/bad pair was wrong or the symptom is environmental (data, config, dependency drift — not the repo's history). Say so; that's a real answer.
- **Very expensive checks:** estimate steps first (`log --oneline good..bad | wc -l` → log₂) and tell the user the cost before starting.

