«Замечаний нет» — а бот вообще смотрел?
Пустая сводка — это не одно сообщение. У бота четыре разных способа сказать «ничего», и значат они разное: до модели не дошёл ни один файл; модель нашла кандидатов, а судья снял всех; модель посмотрела и ничего не нашла; или новых замечаний нет, но остались открытые с прошлых прогонов.
Различить эти случаи можно по самой сводке: у каждого своя строка. А вот объяснить, почему вышло пусто, сводка по умолчанию не может: настройка diagnostics выключена, и без неё бот оставляет при себе самую полезную часть ответа — каких кандидатов подняли и почему каждого сняли. Включайте её заранее: следующий прогон того же MR будет уже другим — например, проверит только новые изменения.
Для MR, который уже вышел пустым, есть обходной путь: прогоните ту же ветку через CLI с флагом --json. В этом отчёте, как и в ответе MCP, снятые кандидаты с причинами есть всегда, включён diagnostics или нет. Прогон будет новым, но через сервер ревью он идёт на том же движке и тех же моделях, что и у бота. Обычный вывод CLI снятых не печатает, а хук передаёт агенту не больше пяти находок — и без снятых.
Как включить блок диагностики
Хватит одной строки в конфиге репозитория:
# .reviewgate/config.yml
diagnostics: trueНа всю инсталляцию — DIAGNOSTICS=true в окружении бота. Но если в конфиге репозитория стоит diagnostics: false, побеждает он. Отдельного вызова модели за блоком нет: он показывает числа, которые прогон уже собрал, и стоит только нескольких строк в сводке.
Со следующего прогона в сводке появится свёрнутый блок «🔬 Диагностика прогона». Вот такой он был на живом прогоне в нашем учебном репозитории:
**Контекст модели**: дифф: 2 файлов · полные файлы: 3 (6K симв.) · окружение: ✓ · по правилам команды (6 шт.): 1 из 1 находок
**Вызовы**:
- генератор `claude-sonnet-5` — 11,7K→1,9K токенов · 22 с · находок: 1
- валидатор `claude-opus-5` — 11,1K→359 токенов · 8,3 с · дропнуто: 0 · понижено: 0
**Судья дропнул / понизил / снял fix (✂️)**:
- ✂️ `src/reports/reports.service.ts:23` `periods-in-customer-zone` — «фикс не подтверждён (keepSuggestion=false): Границы квартала считаются в UTC вопреки правилу periods-in-customer-zone; фикс меняет публичную сигнатуру, вызывающий код не показан.»В блоке три части, и каждая отвечает на свой вопрос о пустоте. Контекст модели — что модель на самом деле получила: сколько файлов в диффе, сколько из них скрыл ignore, сколько полных файлов получил генератор (при full_file_context), не остались ли файлы за бюджетом и сколько находок совпало с правилами команды. Вызовы — кто отработал, на какой модели, сколько времени и сколько находок дал каждый. Если у генератора находок: 0, пусто стало ещё до судейства: судья в таком прогоне не вызывается. Третья часть — что судья снял, понизил или лишил фикса, с причиной для каждого кандидата, чаще всего словами самого судьи.
Строка выше — третий вид вердикта: находку судья оставил, а готовый фикс к ней отозвал. Фикс меняет публичную сигнатуру, а кода, который её вызывает, судья не видит, и проверить, что правка ничего не сломает, ему нечем. Как читать такие причины, разберём ниже, в главе «Как читать вердикты судьи».
Четыре разных «ничего»
| Что говорит сводка | Что произошло | Куда смотреть |
|---|---|---|
🤖 ReviewGate — после фильтра ignore файлов для ревью не осталось. (или вариант про маркер) | до модели не дошёл ни один файл: все отсеялись ещё до вызова | список ignore и маркеры reviewgate-ignore-file в файлах; сюда же попадают бинарные файлы и изменения без строк кода — переименования, смена прав, удаления. Разбивка по причинам есть только в логе бота |
➖ Новых замечаний нет: кандидатов было 5, все сняты проверяющей моделью | генератор нашёл кандидатов, а судья снял всех. Такая строка бывает, только если настроен судья | блок 🔬 — у каждого снятия есть причина |
✅ Замечаний не найдено. | модель посмотрела и ничего не нашла | Контекст модели в блоке и строка ⚠️ о бюджете в сводке: какую часть изменения модель на самом деле увидела |
Ранее найденные и не закрытые замечания (3) остаются в тредах ниже. | приходит вдобавок ко второй или третьей: нового прогон не нашёл, но прежние замечания не закрыты | сами треды — и гейт, если он включён: из-за них он может остаться красным |
Чистой здесь можно назвать только третью строку, и то с оговоркой: полноту обзора она не проверяет — об этом глава «Пусто, но не чисто». Первая значит, что ревью не было, вторая — что оно было, но судья снял всё, четвёртая — что смотреть надо в старые треды. А если сводка не обновилась вовсе, это другой случай: бот промолчал.
Как читать вердикты судьи
Судья умеет только отнимать: снять кандидата, понизить его уровень или отозвать готовый фикс. Добавлять находки и повышать уровень он не может. Поэтому пустой результат после судейства значит одно: судья снял всех кандидатов. Причины снятия условно делятся на три семейства. Кроме блока 🔬 их можно прочитать в отчёте --json: снятые лежат там в dropped — файл, заголовок и причина, без номера строки.
О самой находке: «домысел», «нет доказательств». Здесь судья делает ровно то, ради чего он нужен: генератор многословен, и судья отсеивает то, что команде читать незачем.
О том, что судья смог увидеть: «вызывающий код не показан», «содержимое не видно». Судья получает файлы с находками и определения того, что они импортируют, — и только. Кода, который вызывает изменённое место, он не видит никогда, поэтому находку, чьё доказательство лежит там, снимает как домысел; настройкой бюджета это не лечится. Импорты он разбирает в TypeScript и JavaScript, а в Python, Go, Java и многих других стеках видит одни файлы с находками — там таких снятий будет больше.
О ваших правилах: «правило этого не говорит», «вне стандартов команды». Если с такой причиной регулярно снимаются как раз те находки, которые вам нужны, значит, правило сформулировано не так, как вы думаете: чинить надо конфиг, а не модель.
Бывает и так, что судья не отработал вовсе. Тогда находки публикуются без проверки, и сводка говорит об этом сама, прямо под вердиктом, без всякого блока диагностики: «⚠️ судейство упало целиком — находки опубликованы без валидации». Ничего не потеряно, но ничего и не проверено; если включены готовые фиксы, они тоже уйдут с кнопкой «Применить» без проверки.
Пусто, но не чисто
Пустая сводка или MR без новых тредов ещё не значат, что всё проверено и чисто. Вот четыре случая, когда это не так.
Прогон смотрел только часть изменения. Сводка об этом говорит: Инкрементальное ревью: проверено 2 из 4 изменённых файлов (остальные не трогались с прошлого ревью). Два других файла отревьюены раньше, и их находки остались в своих тредах. Гейт, если он включён, их учитывает: ❌ Severity gate (`major`) НЕ пройден: блокирующих замечаний 3 (из них 2 — ранее открытые, этот прогон их файлы не перепроверял).
Обзор был неполным. Часть файлов модель не видела, и сводка говорит об этом по-разному. Бюджет отмечен своей строкой: «⚠️ MR превышает бюджет ревью: покрыто 4 из 11 файлов». Маркер в файле — тоже своей: «ℹ️ Исключено маркером в файле: 2». Скрытые ignore видны только в блоке диагностики, как ignore: 3 файлов рядом с числом файлов диффа. А бинарные файлы бот отбрасывает молча: их нет ни в сводке, ни в блоке, только в логе бота.
Находки есть, но новых тредов нет. Сводка тогда показывает «Замечаний: N» и «новых строчных: 0», а почему — объясняет отдельной строкой или свёрнутым блоком. Находки ниже порога min_severity уходят в блок «🔇 Ниже порога min_severity» (по умолчанию порог — info, и ниже него ничего не бывает). Уже открытые треды бот не дублирует, а закрытые вами не поднимает снова — об этом строка «Из ранее найденного — уже на ревью, не дублирую: N; закрыто вами (resolved), не поднимаю: M».
Ревью задало вопрос, а не сделало замечание. При questions: true кандидат, которого судья снял как недоказанный, может вернуться ❓-тредом. Это вопрос к автору, а не находка, и в счётчики и гейт он не входит. В сводке для него своя строка: «❓ Вопросов к автору: N (вне severity gate — см. треды)». Вопросы работают только при настроенном судье. «Замечаний не найдено» и ждущий вас вопрос друг другу не противоречат.
Дальше
- Правила, которые линтер проверить не может— если находки снимаются с причиной «вне стандартов»
- Куда уходят токены— из чего состоит контекст и что режет бюджет
- Справочник конфига— diagnostics, min_severity, questions
- Бот промолчал: как найти место обрыва— если сводка не обновилась вовсе