Skip to main content
Glama

Culprit — автоматический git bisect с изоляцией и точным доказательством

Знакомая боль: что-то сломалось, а виновный коммит потерялся среди сотен изменений. Ручной git bisect работает, но дёргает вашу рабочую копию туда- сюда на каждом шаге и требует вручную гонять тесты. Culprit делает то же самое — полностью изолированно (через git worktree, ваша рабочая копия не трогается вообще) и резюмируемо между вызовами.

Доказано на настоящем репозитории, не гипотетически

15 реальных коммитов, баг внедрён ИМЕННО в commit 9

start_bisect(good=v-good, bad=HEAD, check="<your interpreter> -c '...'")
run_bisect(session_id)

  …  GOOD / BAD …

CULPRIT FOUND after ≤5 test(s): …  "commit 9"

Вместо перебора кандидатов — ⌈log₂ n⌉ проб. HEAD и рабочая копия после прогона не меняются — это проверяет интеграционный тест, а не README.

Related MCP server: culprit

Ключевая инженерная деталь: git worktree, а не checkout

Наивная автоматизация делает git checkout <commit> в рабочей копии — переключает ветку, конфликтует с грязным деревом, оставляет detached HEAD. Culprit для каждого кандидата поднимает изолированный git worktree и сразу сносит его. Ваш checkout в процессе не участвует.

Алгоритм: бинарный поиск с обработкой SKIP

Ядро — чистая BisectAlgorithm.advance() без git и I/O:

  • SKIP на середине → берётся ближайший непротестированный сосед;

  • весь диапазон SKIP → честный ambiguous, без бесконечного цикла;

  • результаты можно копить в любом порядке — границы пересчитываются из полной истории outcomes.

Код возврата 125 = SKIP, как у git bisect run. Таймаут check-команды тоже становится SKIP.

Архитектура (Clean Architecture)

src/culprit/
├── entities/          # CommitRef, BisectAlgorithm, BisectSession
├── use_cases/         # start / step / run-to-completion / status
├── interfaces/        # порты (Git, Runner, SessionRepository, Clock, Id)
├── infrastructure/    # real git worktree, subprocess+timeout, sqlite
└── presentation/      # composition root, MCP tools, response formatting

Почему здесь есть subprocess

В отличие от Loom/Ward/Covenant, subprocess — суть инструмента (как у git bisect run). Trust boundary: check_command задаёт человек (тест/скрипт, который вы уже доверяете). Агент/LLM не должен изобретать shell-пейлоады — только передать вашу команду в start_bisect.

Линейность истории

Кандидаты берутся через git log --first-parent good..bad: бинарный поиск идёт по mainline, а не по произвольному merge-DAG. Для типичного «сломалось на main» этого достаточно; полный обход всех merge-веток не поддерживается.

Установка

git clone <этот репозиторий>
cd culprit
pip install -e ".[dev]"

Проверка качества (lint, типы, тесты, покрытие, стена Мартина):

.\make.ps1

Подключение к Claude Desktop / Claude Code

{
  "mcpServers": {
    "culprit": {
      "command": "culprit-mcp",
      "env": {
        "CULPRIT_DB": "~/.culprit/sessions.db",
        "CULPRIT_CHECK_TIMEOUT_SECONDS": "300"
      }
    }
  }
}

~ в CULPRIT_DB раскрывается через os.path.expanduser (и для env, и для default). Невалидный timeout тихо откатывается к 300 секундам.

На Windows укажите полный путь к culprit-mcp.exe или к python -m culprit.presentation.mcp_server, если Scripts не в PATH.

check_command: кроссплатформенно

Используйте интерпретатор, который точно есть на машине:

# Linux / macOS
python3 -c "…"

# Windows (или везде, если venv активирован)
python -c "…"

Контракт: 0 — бага нет (GOOD), ненулевой — бага есть (BAD), 125 — SKIP. Таймаут check-команды тоже = SKIP. Команду передаёт человек, не модель.

Пример разговора

Вы: Начиная с v2.3.0 тест test_login_timeout стал падать. Найди, какой коммит это сломал.

Claude: [start_bisect → run_bisect] Нашёл: a3f8c21 "Refactor session timeout handling". Рабочая копия не трогалась.

MCP Tools

Tool

Назначение

start_bisect(repo_path, good_ref, bad_ref, check_command)

Начать сессию

step_bisect(session_id)

Один кандидат в worktree

run_bisect(session_id)

До конца (≤50 шагов)

bisect_status(session_id)

Состояние сессии

list_bisect_sessions()

Все сессии

Ошибки инструментов приходят строкой error: … — удобно читать в чате.

Тесты

pytest -v

Покрытие: чистый алгоритм, use cases на фейках (включая timeout→SKIP), форматирование MCP-ответов, subprocess timeout, реальный git с внедрённым багом и доказательством, что HEAD/файлы не изменились.

Лицензия

MIT — см. файл LICENSE.

Available Tools

5 tools
bisect_statusC

Show status, candidate count, and culprit if found.

Inputs: session_id (required). Returns: result

list_bisect_sessionsB

List all stored bisect sessions.

Inputs: no named parameters. Returns: result

run_bisectB

Drive step_bisect until done/failed (max 50 steps).

Inputs: session_id (required). Returns: result

start_bisectA

Start an isolated first-parent bisect. check_command MUST be supplied by the human (never invent shell). Exits: 0=good, non-zero=bad, 125=skip. Working tree untouched — each probe uses a fresh git worktree.

Inputs: bad_ref (required), good_ref (required), repo_path (required), check_command (required). Returns: result

step_bisectC

Test one candidate in an isolated worktree; resume-safe across calls.

Inputs: session_id (required). Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.4/5.0

    Scored across 5 tools

    Disambiguation5/5

    Each tool has a clearly distinct role: start_bisect initializes a bisect, step_bisect tests one candidate, run_bisect drives stepping to completion, bisect_status reports the current session, and list_bisect_sessions enumerates stored sessions. There is no overlap that would cause misselection.

    Naming Consistency4/5

    start_bisect, step_bisect, and run_bisect follow a consistent verb_bisect pattern, but bisect_status inverts to noun_verb and list_bisect_sessions inserts bisect in the middle. The deviations are minor and the names remain readable and predictable.

    Tool Count5/5

    Five tools is well-scoped for git bisect automation, with each tool earning its place across initialization, stepping, driving, status, and session listing. No obvious bloat or thinness.

    Completeness4/5

    The core bisect lifecycle is covered: start, step, run, status, and list sessions. Minor gaps exist, such as no explicit abort/cleanup or delete-session operation, but agents can work around this by ignoring or overwriting sessions.

    Maintenance

    ActivitySlowing
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables AI coding agents to read and manage a Git-native decision ledger, providing tools for querying decisions, evidence, cross-repository workspaces, validation, and commit tracing, all operating locally and without a cloud service.
      MIT
    • A
      license
      B
      quality
      B
      maintenance
      Enables an agent to fan out a build into independent targets, each run by a headless coding agent in its own git worktree and gated by a shell-free kill check that must print an exact line. Exposes tools to validate requests, launch and track runs, inspect lane status, cancel or recover runs, and produce review-ready markdown reports, without ever merging or pushing.
      6
      Apache 2.0