harnsy

Ревью кода в Claude Code вторым агентом: что поймал ревьюер

В команде агентов Claude Code ревьюер — второй агент, который проверяет коммит другого до попадания в код: собирает именно этот коммит в чистой копии, запускает тесты и отвечает ACCEPT или REJECT с файлом и строкой. За один рабочий день он выдал 55 принятий и 11 отказов. Лучшей находкой стала гонка, которую он записал необязательным замечанием; единственный известный промах — одна неотформатированная строка.

8 мин чтенияPavel Buchnev

Главные цифры

66
вердиктов по 22 задачам примерно за десять часов одного рабочего дня: 55 ACCEPT и 11 REJECT
13 из 25
проектов остались ссылаться на компанию, которой больше нет, в тесте гонки из 25 раундов, до исправления; после — ни одного, в пяти запусках
4
мутанта выжили, когда автор сказал, что падающий тест «падает так же на чистом master»
1
известный нам промах: принят коммит с одной неотформатированной строкой
В этой статье
  1. Зачем второй агент
  2. Что ревьюер делает с коммитом
  3. Гонка, которая пришла сноской
  4. Другие находки
  5. Что он пропустил
  6. Как завести своего
  7. Чего мы не знаем

Зачем второй агент

Агент, который написал изменение, только что потратил на него весь свой контекст. Он знает, зачем там каждая строка, и из-за этого его собственная проверка обычно слабая: он читает то, что хотел написать, а не только то, что лежит на диске. Ревьюер — второй контекст, который открывает коммит с нуля. По той же причине ревью есть в командах людей.

Полезным его делает метод. Ревьюер, который только читает разницу, — ещё один агент, говорящий «выглядит нормально». Тот, о ком эта статья, запускает коммит.

Что ревьюер делает с коммитом

  • Берёт именно этот коммит и собирает его в чистой копии, чтобы ничто, оставшееся в рабочей папке автора, не могло помочь ему пройти.
  • Запускает тесты в песочнице: временная домашняя папка, а терминальные инструменты заменены заглушками, которые записывают каждый вызов и отказываются запускаться.
  • Проверяет форматирование, запускает статические проверки для Linux, macOS и Windows и полный набор тестов.
  • Запускает мутационные проверки: меняет одну строку кода, и тесты должны покраснеть; затем возвращает строку. Тест, который остаётся зелёным при сломанном коде, эту строку не проверяет.
  • Если у изменения есть часть в дашборде, собирает дашборд и сравнивает.

У ответа жёсткая форма. Первое слово — ACCEPT или REJECT. REJECT называет файл и строку, что именно не так и насколько это серьёзно. Всё, что ревьюер хочет изменить, но из-за чего не стал бы блокировать, идёт замечанием к ACCEPT.

ВердиктЧто в нём
ACCEPTКоммит прошёл. Могут следовать необязательные замечания.
REJECTФайл и строка, что не так, серьёзность.
Формат вердикта ревьюера.

Гонка, которая пришла сноской

Самой наглядной находкой стала гонка: компания, удалённая в момент регистрации проекта, оставляла проект со ссылкой на компанию, которой уже нет. Код сначала искал компанию и только потом открывал запись, сохраняющую проект, а удаление попадало в промежуток между этими шагами.

Ревьюер не отклонил коммит. Он записал это необязательным замечанием к ACCEPT. Автор сначала отказался, затем исправил: теперь компания читается внутри самой записи. Тест на это прогоняет 25 раундов регистрации проекта против удаления его компании. До исправления 13 проектов остались с мёртвым id компании. После — ни одного, в пяти запусках. Комментарий самого ревьюера к тесту: он «fails every run without it», то есть без исправления падает в каждом запуске.

Необязательное замечание — тоже находка: лид команды позже превратил её в проверку задачи, чтобы о ней не забыли. И автору позволили сначала не согласиться: ревью — это разговор, и спор решил тест.

Другие находки

  • Изменение, которое превратило бы около 18 ссылок на имена агентов в нерабочие кнопки копирования. Ревьюер остановил его до попадания в код.
  • Сохранённый ключ, который мог уйти не на тот хост, которому принадлежит, и маршрут, который пропускал проверку, которую должен был делать.
  • Автор сказал, что падающий тест «падает так же на чистом master». Ревьюер запустил master: зелёный, ветку автора: красная. Четыре мутанта выжили, то есть тесты проверяли не то, что думал автор.

Что он пропустил

Ревьюер принял один коммит, в котором была одна неотформатированная строка. Это была косметика, и автор её исправил. С тех пор проверка форматирования входит в метод ревьюера. Ревьюер — метод, который улучшается, когда промахивается, а не гарантия.

Как завести своего

Ничего из этого не требует конкретного инструмента. Если вы запускаете больше одного агента, это подходит к любой настройке:

  • Дайте ревьюеру свою сессию и свою чистую копию репозитория. Никогда не давайте ему проверять в рабочей папке автора.
  • Запишите метод как инструкцию, а не как надежду: команды, которые он запускает, и формат вердикта, где ACCEPT или REJECT идёт первым.
  • Просите мутационные проверки. Именно они превращают «тесты проходят» в «тесты заметили бы».
  • Разрешите необязательные замечания и следите, чтобы кто-то превращал хорошие в проверки.
  • Когда ревьюер что-то пропустил, добавьте недостающий шаг в его метод.

В harnsy ревью — это состояние задачи. Сданная задача уходит тому, кто её поставил; доработка возвращается автору с замечанием; итог принимает человек. См. роли и задачи.

Чего мы не знаем

  • Мы не считали, сколько настоящих дефектов ревьюер пропустил. Тот, что выше, мы знаем потому, что его заметили.
  • 66 вердиктов — один день, а не показатель. Другой день, другая команда или другой тип изменений дадут другую картину.

Заведите своей команде ревьюера

В harnsy ревьюер — это роль: своя сессия, свои инструкции и состояние проверки у каждой задачи.

Установить harnsy

harnsy не связана с Anthropic, OpenAI и OpenCode; их названия принадлежат им.

site-3fлид · Claude Codeна связитолько смотреть
❯ Распланируй #42 с командой.

Жду разбор от analyst-7a…

от analyst-7a через harnsy❯ #42 разобрана: три критерия приёмки, включая повтор через 24 ч.

Передаю #42 разработчику site-9a.

❯