Руководство по самоанализу: анализ коммитов на базе CPG

CodeGraph анализирует собственную кодовую базу через граф свойств кода (CPG) после каждого коммита, создавая цикл обратной связи Планирование-Действие-Проверка. Claude Code получает метрики качества, данные о зоне поражения, анализ влияния на интерфейсы и сравнение до/после как контекст сразу после коммита.

Содержание

Как это работает

Конвейер самоанализа связывает три системы:

  1. GoCPG строит и поддерживает граф свойств кода (CPG) в DuckDB с предвычисленными метриками для каждого метода: цикломатическая сложность, входящая/исходящая связность, флаги TODO/FIXME, отладочный код, устаревшие вызовы.

  2. Git-хуки запускают обновление CPG после каждого коммита, поддерживают базу данных в синхронизации с кодом и могут сохранять трассируемые артефакты ревью по каждому коммиту.

  3. Хуки Claude Code срабатывают после команд git commit, запрашивают CPG по изменённым методам, вычисляют метрики качества, зону поражения, анализ влияния на интерфейсы и межмодульные предупреждения, затем внедряют отчёт обратно в диалог как дополнительный контекст.

Результат: каждый коммит может получать видимую и трассируемую оценку качества без выхода из IDE и запуска отдельных инструментов.

Сценарии использования

Сценарий 1: Автоматическая обратная связь после коммита

Основной сценарий. Вы работаете в Claude Code, вносите изменения, коммитите:

Вы: "Закоммить эти изменения"
Claude: git add src/intent/classifier.py && git commit -m "refactor: extract pattern table"

Хук PostToolUse срабатывает автоматически и внедряет отчёт:

## Commit Analysis Report
**Summary:** 1 files, 45 methods, 2 high-CC, 3 TODO/FIXME, 128 affected callers
**CPG status:** fresh

**Impact of changes:**
- `_get_fallback_domain`: CC 29->8 (-21), FanOut 18->5 (-13)

**High complexity methods:**
- `classify` (CC: 17)
- `_score_domain` (CC: 16)

**Blast radius:** 128 callers affected
- `classify` called by: `run_intent_classifier`, `IntentBenchmark._evaluate_single` +126 more

**Interface changes detected:**
- **CLI**: `src/cli/intent_commands.py` (`add_intent_commands`, `_run_classify`)

**Cross-module alert** — related interfaces may need updates:
- Changed CLI → check MCP: `codegraph_intent`, `register_intent_tools`

Claude видит этот контекст и может отреагировать: “Рефакторинг снизил сложность _get_fallback_domain с 29 до 8. Два метода всё ещё имеют CC>10: classify и _score_domain. CLI был изменён — проверьте, нужно ли обновить инструмент MCP.”

Что запускает хук: Любая команда git commit, выполненная через инструмент Bash. Хук обнаруживает "git commit" в строке команды. Другие Bash-команды (git status, ls) игнорируются.

Что НЕ запускает хук: Прямые коммиты из терминала вне Claude Code, git commit --amend, коммиты через другие инструменты.

Сценарий 1b: Устойчивый post-commit trace вне диалога

Для обычных терминальных коммитов, локальных CI-подобных сценариев и случаев, где нужен долговечный цифровой след, включайте GoCPG review trace:

gocpg/gocpg.exe hooks install --repo=. --db=data/projects/codegraph.duckdb --review-trace
python scripts/review_trace_status.py <commit-sha> --watch

Для каждого коммита в data/reviews/ появляются файлы:

  • <sha>.log — хронологический лог worker с heartbeat-сообщениями
  • <sha>.status.json — текущая фаза и снимок прогресса
  • <sha>.meta.json — финальный итог (gocpg_update_ok, db_unlocked_after_update, статус ревью)
  • <sha>.json / <sha>.md — машиночитаемый и человекочитаемый отчёт ревью

Worker с трассировкой сужает область ревью до реально изменённых файлов, поэтому post-commit review обычно завершается за секунды, а не пересканирует весь diff-base.

Сценарий 2: Поиск и исправление проблем качества

Используйте CPG-запросы для поиска целей по улучшению качества, затем исправляйте их с обратной связью от конвейера:

Вы: "Запроси CPG для методов с CC > 15 и флагами TODO/FIXME в src/workflow/"
Claude: [выполняет запрос к DuckDB]
  Найдено: _get_fallback_domain (CC=29, TODO), PolicyViolationsHandler.handle (CC=68, TODO)

Вы: "Отрефактори _get_fallback_domain для снижения сложности"
Claude: [извлекает шаблоны в таблицу данных, заменяет цепочку if/else на цикл]

Вы: "Закоммить"
Claude: git commit -m "refactor: extract fallback patterns to class-level table"
  -> Хук срабатывает, отчёт показывает: CC 29->8 (-21)

Это полный цикл Планирование-Действие-Проверка: 1. Планирование: CPG-запрос выявляет проблему 2. Действие: Рефакторинг снижает сложность 3. Проверка: Хук подтверждает улучшение конкретными метриками

Сценарий 3: Валидация влияния рефакторинга

Перед крупным рефакторингом проверьте зону поражения:

Вы: "Какова зона поражения при изменении HierarchicalIntentClassifier.classify?"
Claude: [запрашивает call_containment]
  213 прямых вызывающих методов в рабочем коде и тестах

Вы: "Продолжай рефакторинг"
Claude: [вносит изменения, коммитит]
  -> Хук показывает: 213 затронутых вызывающих, CC без изменений, регрессий нет

Отчёт о зоне поражения помогает оценить риск изменений до их применения.

Сценарий 4: Анализ по запросу

Запуск анализа без коммита:

# Анализ последнего коммита
python -m src.cli.import_commands dogfood analyze --base-ref HEAD~1

# Анализ изменений между ветками
python -m src.cli.import_commands dogfood analyze --base-ref origin/main

# Генерация полного отчёта о качестве
python -m src.cli.import_commands dogfood report --format markdown

# Валидация числовых утверждений в документации
python -m src.cli.import_commands dogfood validate-claims --path docs/

# Показать тренд качества по последним коммитам
python -m src.cli.import_commands dogfood trend --commits 20

Архитектура конвейера

Поток данных

git commit (через инструмент Bash в Claude Code)
    |
    v
Хук PostToolUse срабатывает (.claude/hooks/commit_analysis.py, время ожидания 58с)
    |
    +-- Проверка актуальности CPG
    |       Запрос cpg_git_state.commit_hash, сравнение с git rev-parse HEAD
    |
    +-- Захват метрик до обновления (для дельта-отчёта)
    |       Запрос nodes_method для изменённых файлов ДО обновления CPG
    |       Сохранение {full_name: {cc, fan_out, ...}} для последующего сравнения
    |
    +-- Обновление CPG если устарел
    |       gocpg update --input=<source> --output=<db>
    |
    +-- Фаза 1: Получение изменённых файлов
    |       git diff --name-only HEAD~1 HEAD, фильтрация по расширениям кода
    |
    +-- Фаза 2: Получение изменённых методов из CPG
    |       Запрос nodes_method для изменённых файлов, дедупликация
    |
    +-- Фаза 3: Сводка качества
    |       Подсчёт high-CC, high-fan_out, TODO, debug, deprecated
    |
    +-- Фаза 4: Зона поражения
    |       Запрос call_containment (или nodes_call в качестве запасного варианта)
    |
    +-- Фаза 5: Обнаружение влияния на интерфейсы
    |       Проверка принадлежности изменённых файлов к слоям интерфейсов (CLI, REST API, MCP, ACP)
    |
    +-- Фаза 6: Межмодульные предупреждения
    |       Поиск связанных функций в ДРУГИХ слоях по совпадению ключевых слов
    |
    +-- Фаза 7: Дельта покрытия историй
    |       Определение изменённых слоёв и непокрытых слоёв
    |
    +-- Запись снимка качества (таблица cpg_quality_history)
    |
    +-- Вывод: {"additionalContext": "## Commit Analysis Report\n..."}
            Внедряется обратно в диалог Claude Code

Бюджет ограничений по времени

Хук имеет общее ограничение по времени 58 секунд (2с запас от лимита Claude Code в 60с):

Фаза Бюджет Действие
Проверка актуальности Сравнение cpg_git_state.commit_hash с git rev-parse HEAD
Метрики до обновления ~1с Запрос текущих метрик для изменённых файлов (для дельта-отчёта)
Обновление CPG если устарел 40с Запуск gocpg update --input=<source> --output=<db>
Фазы 1–7 ~15с Изменённые файлы, методы, качество, зона поражения, интерфейсы, межмодульные, истории

Если какая-либо фаза превышает бюджет, хук корректно снижает функциональность: выдаёт имеющиеся данные или возвращает пустой {}.

Актуальность CPG и автоматическое обновление

Хук проверяет актуальность CPG, сравнивая cpg_git_state.commit_hash с git rev-parse HEAD. Если CPG устарел, запускается gocpg update:

gocpg update --input=<source_path> --output=<db_path>

Это запускает инкрементальное обновление базы данных CPG. Класс CPGFreshnessChecker в src/dogfooding/cpg_freshness.py управляет этим процессом:

from src.dogfooding.cpg_freshness import CPGFreshnessChecker

checker = CPGFreshnessChecker(db_path, repo_path=".", gocpg_binary="gocpg/gocpg.exe")
checker.is_fresh()           # True если CPG commit == HEAD
checker.commits_behind()     # Количество коммитов отставания CPG
checker.ensure_fresh(timeout=40.0, source_path=".")  # Обновить если устарел
checker.status()             # Полный словарь статуса

Проверка актуальности теперь включает резервное определение git HEAD для окружений, где git rev-parse HEAD из подпроцесса нестабилен. Проверка читает .git/HEAD, refs и packed-refs (включая gitdir: для worktree) до того, как вернуть head_commit=unknown.

При ошибках блокировки DuckDB возвращается детальная диагностика: классификация сбоя, PID процессов-блокировщиков, результаты попытки auto-unlock и рекомендации next_step / next_command.

Актуальность выводится в двух вариантах: - is_fresh_strict: строгое совпадение коммитов (cpg_commit == head_commit) - is_fresh: эффективная актуальность (строгое совпадение ИЛИ отсутствие CPG-релевантных изменений файлов между коммитами, например при изменениях только документации)

Автоматический и явный контроль актуальности

Механизм Триггер Типичный сценарий
Хук коммита (.claude/hooks/commit_analysis.py) Автоматически на git commit через Bash Стандартный цикл Планирование-Действие-Проверка после коммита
Post-commit webhook-триггер плагина Автоматический best-effort Сценарии OpenCode с запущенным API
codegraph_watch check / codegraph_watch update Явный/ручной Детерминированная проверка актуальности в headless и CI
CPGFreshnessChecker.ensure_fresh_with_details() Явный/ручной Программный контроль и машиночитаемая диагностика сбоев

Если требуется гарантированная актуальность перед анализом, используйте явный codegraph_watch update, а не фоновые хуки.

Дедупликация методов

GoCPG может хранить один и тот же метод с разными форматами имени файла (прямой слеш src/file.py vs обратный src\file.py). Анализатор дедуплицирует путём нормализации слешей в full_name и сохранения записи с наибольшим значением CC:

# До дедупликации: 2 записи для одного метода
src\intent\classifier.py:Classifier.classify  CC=17
src/intent/classifier.py:Classifier.classify   CC=0  (из инкрементального обновления)

# После дедупликации: 1 запись, наибольший CC побеждает
src\intent\classifier.py:Classifier.classify  CC=17

Дельта-отчёт

Когда CPG устарел (требует обновления), хук захватывает метрики до обновления перед запуском gocpg update, затем сравнивает с метриками после обновления. Это создаёт дельту, показывающую реальное влияние изменений:

**Impact of changes:**
- `_get_fallback_domain`: CC 29->8 (-21), FanOut 18->5 (-13)
- `_build_quality_summary`: CC 5->3 (-2)

Методы без изменений метрик пропускаются.

Обнаружение влияния на интерфейсы

Анализатор отслеживает 4 слоя интерфейсов, определённых в INTERFACE_LAYERS:

Слой Шаблоны путей Описание
CLI src/cli/ CLI-команды
REST API src/api/routers/ API-эндпоинты
MCP src/mcp/tools/, src/mcp/ MCP-инструменты
ACP src/acp/server/, src/acp/ ACP-обработчики

Когда изменённый файл принадлежит слою интерфейса, отчёт включает секцию «Interface changes detected» со списком затронутых слоёв и методов.

Межмодульные предупреждения

Когда файл в одном слое интерфейса изменяется, анализатор ищет связанные функции в ДРУГИХ слоях, извлекая ключевые слова из имени изменённого файла и запрашивая CPG. Например, при изменении src/cli/reindex_commands.py он ищет функции с “reindex” в имени в MCP, REST API и т.д.

Отчёт включает секцию «Cross-module alert» с рекомендациями по проверке:

**Cross-module alert** — related interfaces may need updates:
- Changed CLI → check MCP: `codegraph_reindex`, `register_reindex_tools`

Дельта покрытия историй

При изменении слоёв интерфейсов анализатор определяет, какие другие слои могут потребовать обновления для поддержания паритета функциональности. Отчёт включает секцию «Story coverage check»:

**Story coverage check** — verify other interfaces:
- CLI changed (`reindex`), check: MCP, REST API, ACP

Инфраструктура хуков

Модули хуков

Директория .claude/hooks/ содержит хук анализа коммитов и 4 вспомогательных модуля:

Модуль Назначение
commit_analysis.py Хук PostToolUse — анализ коммитов (время ожидания 58с)
_feedback.py Датаклассы ReviewFinding и ReviewFeedback
_metrics.py Телеметрия хуков — log_hook_metric(), контекстный менеджер timed_hook()
_utils.py Общие утилиты — get_active_project(), run_gocpg_query(), safe_json_output(), load_parse_scope()
_session_cache.py Кеш проекта с TTL 1 час

ReviewFinding и ReviewFeedback

Структурированный протокол обратной связи для хуков Claude Code:

@dataclass
class ReviewFinding:
    file: str = ""
    line: Optional[int] = None
    type: str = ""          # "complexity", "dead_code", "blast_radius", "interface_gap" и др.
    severity: str = "info"  # "critical", "high", "medium", "low", "info"
    message: str = ""
    suggestion: Optional[str] = None
    metric_value: Optional[float] = None
    scope_limited: bool = False  # True если результат зависит от области видимости

@dataclass
class ReviewFeedback:
    status: str = "ok"      # "ok", "warning", "block"
    hook_name: str = ""
    project: Optional[str] = None
    cpg_status: Optional[str] = None
    findings: List[ReviewFinding] = field(default_factory=list)
    summary: str = ""
    duration_ms: float = 0.0
    scope_disclaimer: str = ""
    suppressed_count: int = 0

    def to_markdown(self) -> str: ...
    def output(self): ...  # Записывает в stdout как additionalContext JSON

Метрики хуков

_metrics.py записывает телеметрию выполнения в data/hook_metrics.jsonl (формат JSONL, один JSON-объект на строку):

{"timestamp": "2026-03-07T12:34:56.789Z", "hook": "commit_analysis", "duration_ms": 3250.5, "findings": 5, "project": "codegraph", "cpg_status": "fresh", "status": "ok"}

Контекстный менеджер timed_hook() автоматически замеряет длительность и записывает результат:

from _metrics import timed_hook

with timed_hook("commit_analysis") as mctx:
    mctx["project"] = "codegraph"
    mctx["findings_count"] = 5
    # длительность записывается автоматически при выходе

Просмотр агрегированной статистики через CLI: python -m src.cli.import_commands dogfood hooks-status.

Кеш сессии

_session_cache.py кеширует активный проект в .claude/.cache/session_project.json с TTL 1 час для ускорения определения проекта при каждом вызове хука:

from _session_cache import get_project_with_cache, invalidate_cache

project = get_project_with_cache()  # Возвращает из кеша или определяет заново
invalidate_cache()                   # Принудительное переопределение

Установка

Установка одной командой

python -m src.cli.import_commands dogfood setup --repo . --db data/projects/codegraph.duckdb

Это устанавливает git-хуки (через gocpg) и настраивает хук Claude Code.

Примечание: Команда setup записывает хук под ключом SubcommandResult в .claude/settings.json. Реальная конфигурация использует PostToolUse с "matcher": "Bash". После запуска setup может потребоваться ручная корректировка ключа хука.

Ручная установка

  1. Установка git-хуков (фоновое обновление CPG при коммите): bash gocpg/gocpg.exe hooks install --repo=. --db=data/projects/codegraph.duckdb

  2. Настройка хуков Claude Code в .claude/settings.json: json { "hooks": { "PostToolUse": [{ "matcher": "Bash", "hooks": [{ "type": "command", "command": "python .claude/hooks/commit_analysis.py", "timeout": 60000 }] }] } }

Примечание: Поле matcher должно быть строкой (регулярное выражение), а не объектом. "Bash" соответствует конкретно инструменту Bash.

Полный .claude/settings.json в рабочей конфигурации включает 5 хуков на всех точках жизненного цикла:

Точка жизненного цикла Хук Время ожидания
UserPromptSubmit enrich_prompt.py 15с
SessionStart session_context.py 10с
Stop post_analysis.py 10с
PreToolUse pre_tool_use.py
PostToolUse (Bash) cli_error_monitor.py + commit_analysis.py 5с + 60с

Проверка установки

python -m src.cli.import_commands dogfood status

Ожидаемый вывод показывает актуальность CPG, статус хуков и путь к базе данных.

CLI-команды

Все команды доступны через python -m src.cli.import_commands dogfood <подкоманда>.

dogfood setup

Установка git-хуков и настройка хуков Claude Code:

python -m src.cli.import_commands dogfood setup [--repo PATH] [--db PATH] [--language LANG]

dogfood status

Проверка актуальности CPG и статуса хуков:

python -m src.cli.import_commands dogfood status [--db PATH]

dogfood analyze

Запуск анализа коммита по запросу:

python -m src.cli.import_commands dogfood analyze [--base-ref HEAD~1] [--db PATH]

dogfood report

Генерация отчёта о качестве (markdown или JSON):

python -m src.cli.import_commands dogfood report [--format markdown|json] [--db PATH]

dogfood validate-claims

Валидация числовых утверждений в документации против CPG. Извлекает числа из markdown (например, «95 обработчиков», «12 сценариев») и проверяет через SQL:

python -m src.cli.import_commands dogfood validate-claims [--path PATH] [--db PATH]

Правила валидации определяются в config.yamldogfooding.claims_validation.rules[]. Каждое правило связывает ключевые слова (русские + английские) с SQL-запросом:

claims_validation:
  enabled: true
  timeout: 5.0
  rules:
    - keywords: ["handlers", "обработчиков"]
      sql: "SELECT COUNT(DISTINCT full_name) FROM nodes_method WHERE ..."
      description: "Scenario handler methods"

dogfood trend

Показать тренд качества по последним коммитам из таблицы cpg_quality_history:

python -m src.cli.import_commands dogfood trend [--commits N] [--db PATH]

Выводит ASCII-таблицу с колонками: Commit, Date, Methods, Avg CC, Dead, Hi-CC, TODO.

Снимки качества записываются автоматически после каждого анализа коммита через record_snapshot() в src/dogfooding/quality_history.py.

dogfood hooks-status

Показать статистику выполнения хуков из JSONL-лога метрик (data/hook_metrics.jsonl):

python -m src.cli.import_commands dogfood hooks-status [--last N] [--hook NAME]

Агрегирует по имени хука: запуски, ok/error/warning, процент ошибок, средняя/максимальная длительность, общее количество замечаний.

dogfood validate-stories

Валидация покрытия интерфейсов пользовательскими историями через CPG с использованием StoryValidationRunner:

python -m src.cli.import_commands dogfood validate-stories [--stories 2,8,11] [--path FILE] [--output FILE] [--db PATH] [--go-db PATH]

dogfood config-check

Обнаружение конфигурационных параметров-сирот путём перекрёстной проверки YAML-конфигурации, схемы и использования в коде:

python -m src.cli.import_commands dogfood config-check [--format text|json|csv] [--level error|warning|info|all] [--fix-suggestions] [--config PATH] [--schema PATH] [--source DIR...]
Параметр По умолчанию Описание
--format text Формат вывода: text, json или csv
--level all Минимальный уровень серьёзности для отображения
--fix-suggestions выкл. Показать предложения по исправлению для каждого обнаружения
--config config.yaml Путь к YAML-файлу конфигурации
--schema src/config/unified_config.py Путь к файлу схемы
--source src/ Каталоги для сканирования (можно несколько)

Обнаруживает 6 типов сирот: yaml_unused, yaml_missing, code_orphan, path_mismatch, orphaned_dataclass, unused_default. Использует ConfigOrphanAnalyzer из src/analysis/config_analyzer.py.

dogfood maintain-db

Выполнить плановое обслуживание и очистку CPG-базы:

python -m src.cli.import_commands dogfood maintain-db [--db PATH] [--vacuum] [--force]
Параметр По умолчанию Описание
--db определяется автоматически Путь к базе DuckDB
--vacuum выкл. Запустить VACUUM после обслуживания
--force выкл. Продолжить даже при потенциально рискованном состоянии

Эту команду используют, когда таблицы истории качества, review trace или маркеры обслуживания требуют контролируемой очистки.

dogfood continue

Продолжить прерванный сценарий самоанализа из сохранённого состояния ревью:

python -m src.cli.import_commands dogfood continue [--db PATH] [--review-dir PATH] [--json]
Параметр По умолчанию Описание
--db определяется автоматически Путь к базе DuckDB
--review-dir data/reviews Каталог с сохранённым состоянием ревью
--json выкл. Вернуть машиночитаемый результат для автоматизации

Это путь восстановления, когда post-commit review был прерван и нужно продолжить его с последней сохранённой контрольной точки.

dogfood unlock-db

Снять блокировку DuckDB после диагностики конфликта блокировок:

python -m src.cli.import_commands dogfood unlock-db [--db PATH] [--force] [--json]
Параметр По умолчанию Описание
--db определяется автоматически Путь к базе DuckDB
--force выкл. Принудительно запустить процедуру разблокировки
--json выкл. Вернуть машиночитаемую диагностику

Используйте эту команду, когда dogfood status, dogfood analyze или post-commit hook сообщают о конфликте блокировок DuckDB и рекомендуют явную разблокировку.

Конфигурация

В config.yaml:

dogfooding:
  enabled: true
  auto_update_cpg: true          # Запускать gocpg update если CPG устарел
  cpg_update_timeout: 40         # Секунды на обновление CPG
  analysis_timeout: 16           # Секунды на анализ качества + зону поражения
  cc_threshold: 10               # Отмечать методы с CC выше этого значения
  fan_out_threshold: 30          # Отмечать методы с fan_out выше этого значения
  blast_radius_depth: 2          # Максимальная глубина обхода вызывающих
  max_files_per_commit: 15       # Максимум файлов для анализа за коммит
  report_format: markdown        # markdown или json
  record_quality_history: true   # Записывать QualitySnapshot по каждому коммиту
  quality_history_db_path: data/quality_history.duckdb  # Необязательная отдельная БД для снимков качества
  include_paths:                 # Ограничить самоанализ выбранными корнями исходников
    - src
    - tests
  exclude_paths:                 # Исключить сгенерированный и сторонний код
    - .venv
    - node_modules
  claims_validation:
    enabled: true
    timeout: 5.0                 # Секунды на запрос по каждому утверждению
    rules:                       # Привязки ключевое_слово→SQL для validate-claims
      - keywords: ["handlers", "обработчиков"]
        sql: "SELECT COUNT(...) FROM nodes_method WHERE ..."
        description: "Scenario handler methods"

CommitReport

Датакласс CommitReport (src/dogfooding/commit_analyzer.py) содержит полный результат анализа:

Поле Тип Описание
changed_files List[str] Файлы с кодом, изменённые в коммите
changed_methods List[dict] Методы в изменённых файлах (дедуплицированные)
blast_radius Dict {"callers": {метод: [вызывающие]}, "total_affected": N}
quality_summary Dict Подсчёт high-CC, high-fan_out, TODO, debug, deprecated
interface_impacts List[dict] Затронутые слои интерфейсов (CLI, REST API, MCP, ACP)
cross_module_alerts List[dict] Связанные функции в других слоях интерфейсов
story_coverage_delta List[dict] Пробелы покрытия историй между слоями
is_cpg_fresh bool Был ли CPG актуален
analysis_time_ms int Общее время анализа в миллисекундах
deltas List[dict] Изменения метрик до→после

Формат отчёта

Хук возвращает markdown-отчёт как additionalContext в JSON:

{"additionalContext": "## Commit Analysis Report\n**Summary:** ..."}

Полная структура отчёта (секции пропускаются если пустые):

## Commit Analysis Report
**Summary:** 3 files, 45 methods, 2 high-CC, 1 TODO/FIXME, 128 affected callers
**CPG status:** fresh

**Impact of changes:**
- `_get_fallback_domain`: CC 29->8 (-21), FanOut 18->5 (-13)

**High complexity methods:**
- `classify` (CC: 17)
- `_score_domain` (CC: 16)

**High fan-out methods:**
- `classify` (fan_out: 39)

**Blast radius:** 128 callers affected
- `classify` called by: `run_intent_classifier`, `IntentBenchmark._evaluate_single` +126 more
- `_classify_domain` called by: `classify`, `get_morph` +4 more

**Interface changes detected:**
- **CLI**: `src/cli/intent_commands.py` (`add_intent_commands`, `_run_classify`)

**Cross-module alert** — related interfaces may need updates:
- Changed CLI → check MCP: `codegraph_intent`, `register_intent_tools`

**Story coverage check** — verify other interfaces:
- CLI changed (`intent`), check: MCP, REST API, ACP

*Analysis completed in 95ms*

Масштабирование на другие проекты

Конвейер самоанализа не привязан к конкретному проекту. Для настройки на любой проект:

  1. Импортируйте проект для создания базы данных CPG: bash python -m src.cli import /path/to/project --language python

  2. Зарегистрируйте проект в config.yaml: yaml projects: active: my_project registry: my_project: db_path: data/projects/my_project.duckdb source_path: /path/to/project language: python domain: python_generic

  3. Запустите установку: bash python -m src.cli.import_commands dogfood setup --repo /path/to/project --db data/projects/my_project.duckdb

Хук читает активный проект из config.yaml и автоматически определяет правильный путь к базе данных.

Устранение неполадок

Хук возвращает пустой {}: - Проверьте, что файл базы данных существует по настроенному db_path - Убедитесь, что активный проект в config.yaml имеет валидный db_path - Запустите python -m src.cli.import_commands dogfood status для проверки актуальности - Убедитесь, что коммит изменил файлы с кодом (.py, .go, .c и т.д.), а не только документацию или конфигурации

CPG всегда показывает устаревший статус: - Убедитесь, что бинарник gocpg существует по пути gocpg/gocpg.exe (или настроенному GOCPG_PATH) - Проверьте, что git-хуки установлены: ищите .git/hooks/post-commit - Попробуйте ручное обновление: gocpg/gocpg.exe update --input=. --output=<db>

Значения CC равны 0 после инкрементального обновления: - Инкрементальное gocpg update может пропустить MethodMetricsPass для некоторых записей. Новые записи могут иметь cyclomatic_complexity=0. - Логика дедупликации сохраняет запись с наибольшим CC, смягчая эту проблему. - При постоянных проблемах переимпортируйте проект с нуля: python -m src.cli import /path/to/source

Ошибка блокировки DuckDB (“file is being used by another process”): - Другой процесс gocpg.exe запущен (например, от gocpg watch или параллельного вызова хука). - Хук использует соединения в режиме только для чтения и обрабатывает ошибки блокировки, переключаясь на запросы через подпроцесс. - codegraph_watch update / ensure_fresh_with_details() возвращают диагностику блокировки (failure_kind=db_lock, locker_pids, auto_unlock_*, next_command) для ускорения восстановления. - Если PID блокировщика совпадает с текущим Python-процессом, auto-unlock преднамеренно не завершает сам себя; выполните предложенный next_command после закрытия блокирующего процесса.

Дельта-отчёт не появляется: - Дельта-отчёт появляется только когда CPG был устаревшим до обновления (были захвачены метрики до обновления). - Если CPG уже актуален (например, gocpg watch обновил его), метрики до обновления отсутствуют для сравнения.

Превышение времени ожидания: - Бюджет в 58с (лимит Claude Code 60с минус 2с запас) достаточен для большинства коммитов. Для очень больших проектов gocpg update может превысить бюджет фазы в 40с. - Уменьшите max_files_per_commit в конфигурации. - Убедитесь, что индексы GoCPG актуальны: gocpg/gocpg.exe index --db=<db>

Метрики хуков не отображаются: - Проверьте, что data/hook_metrics.jsonl существует и доступен для записи. - Запустите python -m src.cli.import_commands dogfood hooks-status для просмотра агрегированной статистики.