Обзор¶
CodeGraph предоставляет автоматизированное ревью кода через два механизма:
- Хуки Claude Code — самостоятельные Python-скрипты в
.claude/hooks/, выполняемые автоматически в точках жизненного цикла (SessionStart, UserPromptSubmit, PreToolUse, PostToolUse, Stop). Взаимодействуют через JSON stdin/stdout. - CLI-конвейер ревью — команда
python -m src.cli reviewс собственным агрегатором, scope-фильтрацией и SARIF-выводом.
Оба механизма разделяют конфигурацию review_pipeline и scope-фильтрацию, но реализуют её по-разному.
Хуки¶
| Хук | Точка срабатывания | Таймаут | Назначение |
|---|---|---|---|
session_context.py |
SessionStart | 10с | Определение проекта, проверка актуальности CPG, загрузка scope |
enrich_prompt.py |
UserPromptSubmit | 15с | Внедрение CPG-контекста в промпты (макс. 3 сущности) |
pre_tool_use.py |
PreToolUse | 8с | Проверка сложности (CC > 15), fan-out, полнота регистрации |
commit_analysis.py |
PostToolUse (Bash) | 60с | Анализ качества после git commit с обновлением CPG |
post_analysis.py |
Stop | 10с | Мёртвый код, отсутствие тестов, скачки сложности, пробелы интерфейсов |
cli_error_monitor.py |
PostToolUse (Bash) | 5с | Обнаружение 6 паттернов ошибок CLI |
Паттерны cli_error_monitor¶
Монитор обнаруживает следующие паттерны ошибок в выводе Bash:
- Database not found
DatabaseNotConfiguredError- DuckDB
__spec__import bug ImportError/ModuleNotFoundError- Python traceback (общий)
RuntimeWarning(импорт модулей)
Бюджеты таймаутов¶
commit_analysis.py имеет внутренний бюджет 58с (2с запас от таймаута 60с):
| Фаза | Бюджет | Описание |
|---|---|---|
| Проверка актуальности CPG | 2с | Сравнение HEAD-коммита с БД |
| Обновление CPG (при устаревании) | 40с | Перепарсинг через gocpg |
| Анализ качества | 16с | CC, TODO/FIXME, радиус изменений |
Пороговые значения¶
| Хук | Порог | Значение |
|---|---|---|
pre_tool_use.py |
Цикломатическая сложность | 15 |
pre_tool_use.py |
Fan-Out | 30 |
commit_analysis.py |
Цикломатическая сложность | 10 |
commit_analysis.py |
Fan-Out | 30 |
commit_analysis.py |
Максимум файлов | 20 |
post_analysis.py |
Коэффициент скачка CC | 2.0x |
post_analysis.py |
Максимум файлов | 5 |
enrich_prompt.py |
Максимум сущностей | 3 |
Архитектура¶
stdin (JSON) → Скрипт хука → stdout (JSON)
↓
_utils.py (общие хелперы: запросы gocpg, загрузка scope)
_feedback.py (датаклассы ReviewFeedback/ReviewFinding)
_metrics.py (логирование производительности в JSONL)
_session_cache.py (файловый кеш контекста проекта, TTL=3600с)
_project_detector.py (автоопределение проекта по CWD/source_path)
Модули поддержки¶
| Модуль | Ключевые экспорты |
|---|---|
_utils.py |
read_stdin_json(), safe_json_output(), run_gocpg_query(), extract_entities(), load_parse_scope(), is_partial_scope(), tests_in_scope() |
_feedback.py |
ReviewFinding (8 полей), ReviewFeedback (9 полей), FINDING_TYPES, SEVERITY_ORDER |
_metrics.py |
timed_hook() — контекстный менеджер, log_hook_metric() |
_session_cache.py |
get_project_with_cache(), set_cached_project(), invalidate_cache() — TTL 3600с, хранится в .claude/.cache/session_project.json |
_project_detector.py |
detect_project(cwd) — сопоставление CWD с projects.registry[*].source_path, поддержка ${VAR:-default} |
Протокол структурированной обратной связи¶
Все хуки выводят JSON с необязательным полем additionalContext (markdown, отображается пользователю):
{
"additionalContext": "## Отчёт ревью\n..."
}
Класс ReviewFeedback в _feedback.py генерирует структурированный markdown с:
- Таблицей находок, отсортированных по severity
- Дисклеймером scope (когда scope парсинга ограничен)
- Счётчиком подавленных находок (отфильтрованных из-за scope)
- Длительностью и метаданными
Типы находок¶
Шесть типов находок определены в FINDING_TYPES:
| Тип | Описание | Используется в |
|---|---|---|
complexity |
Высокая цикломатическая сложность или fan-out | pre_tool_use, commit_analysis, post_analysis |
dead_code |
Недостижимый или невызываемый код | commit_analysis |
missing_test |
Отсутствует тестовый файл для модуля | post_analysis |
blast_radius |
Много вызывающих функций затронуто изменением | commit_analysis |
security |
Уязвимость безопасности | CLI-конвейер ревью |
interface_gap |
Публичные функции не экспонированы через интерфейс | pre_tool_use, post_analysis |
Scope-aware фильтрация¶
Когда CPG построен с исключениями (например, только бэкенд без тестов/фронтенда), применяется фильтрация с учётом scope. Поведение различается между хуками и CLI-конвейером:
Поведение хуков¶
| Тип находки | Условие | Хук | Действие |
|---|---|---|---|
dead_code |
Scope ограничен | commit_analysis.py |
Добавить disclaimer к отчёту |
blast_radius |
Scope ограничен | commit_analysis.py |
Добавить disclaimer к отчёту |
missing_test |
include_tests=false |
post_analysis.py |
Полностью подавить, увеличить suppressed_count |
complexity |
— | все | Не затронут (метрика per-method) |
security |
— | все | Не затронут (реальная уязвимость) |
interface_gap |
— | все | Не затронут |
Поведение CLI-конвейера ревью¶
Команда review использует ReviewAggregator (src/review/aggregator.py) с иной логикой:
| Тип находки | Условие | Действие |
|---|---|---|
dead_code |
Scope ограничен + demote_dead_code_partial_scope=true |
Понизить до info, установить scope_limited=True |
blast_radius |
Scope ограничен + demote_dead_code_partial_scope=true |
Понизить до info, установить scope_limited=True |
missing_test |
suppress_tests_outside_scope=true + тесты вне scope |
Подавить (вернуть None) |
При ограниченном scope в отчёт добавляется блок-дисклеймер.
CLI-команда ревью¶
# Ревью изменений относительно базового рефа
python -m src.cli review --base-ref HEAD~3
# Ревью с указанием базы данных
python -m src.cli review --db data/projects/myproject.duckdb --base-ref HEAD~3
# Ревью проиндексированных изменений
python -m src.cli review --staged
# Ревью конкретных файлов
python -m src.cli review --files src/api/main.py src/auth.py
# Форматы вывода
python -m src.cli review --format json --output-file report.json
python -m src.cli review --format sarif --output-file report.sarif
python -m src.cli review --base-ref HEAD~5 --sarif-file out.sarif
# Без анализа безопасности
python -m src.cli review --no-security
| Аргумент | Описание |
|---|---|
--db PATH |
Путь к базе данных DuckDB CPG (по умолчанию: активный проект) |
--base-ref REF |
Git-реф для diff-ревью (напр. HEAD~3, origin/main) |
--staged |
Ревью только проиндексированных изменений |
--files FILE... |
Ревью конкретных файлов |
--no-security |
Пропустить анализ безопасности |
--format {markdown,json,sarif} |
Формат вывода (по умолчанию: markdown) |
--output-file PATH |
Записать вывод в файл |
--sarif-file PATH |
Записать SARIF-вывод отдельно |
Коды возврата: 0 = чисто или только medium/low, 1 = обнаружены critical или high.
Метрики и мониторинг¶
Хуки логируют метрики выполнения в data/hook_metrics.jsonl:
{"timestamp": "2026-03-06T12:00:00Z", "hook": "commit_analysis", "duration_ms": 1234.5, "findings": 3, "project": "codegraph", "status": "ok"}
Просмотр статистики:
python -m src.cli dogfood hooks-status
python -m src.cli dogfood hooks-status --last 50
python -m src.cli dogfood hooks-status --hook commit_analysis
Устойчивость к сбоям¶
Все хуки следуют принципу fail-open: - Отсутствует бинарник gocpg: CPG-запросы пропускаются, выводится пустой контекст - Повреждённая или отсутствующая БД: анализ пропускается, предупреждение в метрики - Таймаут: частичные результаты возвращаются в пределах бюджета - Ошибки импорта: переключение на subprocess-путь (commit_analysis: DuckDB direct → gocpg subprocess) - Любое необработанное исключение: перехватывается на верхнем уровне, пустой JSON
Конфигурация¶
# config.yaml
review_pipeline:
# Определение проекта
auto_detect_project: true # Автоопределение проекта по CWD
detect_by_source_path: true # Сопоставление CWD с projects.registry[*].source_path
# Актуальность CPG
auto_reparse: prompt # Поведение при устаревшем CPG: prompt | auto | off
freshness_check_on_session: true # Проверка актуальности CPG при SessionStart
max_reparse_timeout_seconds: 60 # Таймаут перепарсинга
stale_threshold_commits: 0 # Коммитов до устаревания (0 = любой новый коммит)
# Вывод
max_findings_in_summary: 10 # Максимум находок в итоговом отчёте
# Scope-фильтрация
scope_aware_filtering: true # Включить scope-фильтрацию
suppress_tests_outside_scope: true # Подавлять missing_test когда тесты вне scope
demote_dead_code_partial_scope: true # Понижать dead_code/blast_radius в CLI review
show_scope_disclaimer: true # Показывать disclaimer при ограниченном scope
# Метрики
metrics_enabled: true # Включить JSONL-логирование метрик
metrics_file: data/hook_metrics.jsonl # Файл вывода метрик
fail_open: true # Продолжать при ошибках (fail-open)
# Dogfooding (используется commit_analysis.py)
dogfooding:
enabled: true
auto_update_cpg: true
cpg_update_timeout: 40 # Таймаут обновления CPG в commit_analysis
analysis_timeout: 16 # Таймаут фазы анализа качества
Добавление нового хука¶
- Создайте Python-скрипт в
.claude/hooks/ - Прочитайте JSON из stdin через
read_stdin_json()из_utils.py - Оберните логику в
with timed_hook("hook_name")из_metrics.py - Выведите JSON в stdout через
safe_json_output()из_utils.py - Зарегистрируйте в
.claude/settings.json
Формат settings.json¶
{
"hooks": {
"PreToolUse": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "python .claude/hooks/my_hook.py",
"timeout": 8000
}
]
}
]
}
}
| Поле | Описание |
|---|---|
| Ключ верхнего уровня | Событие жизненного цикла: SessionStart, UserPromptSubmit, PreToolUse, PostToolUse, Stop |
matcher |
Фильтр по имени инструмента (напр. "Bash"). Пустая строка = все инструменты |
type |
Всегда "command" |
command |
Полный путь к Python-скрипту |
timeout |
Таймаут в миллисекундах |
Директория: .claude/hooks/
Последнее обновление: март 2026