В большинстве команд процесс code review превращается в хаос или откровенный эмоциональный обмен. Комментарий «этот код плохой» становится личной критикой, а кнопка «approved» остаётся просто контрольной точкой. За 8 лет Roibase видел десятки интеграций headless commerce, миграций CDN, внедрений data pipeline — и один вывод неизменен: без измеримых критериев нельзя построить культуру качества. Числовые пороги для time-to-review, comment density, PR size — это не просто метрики. Без них culture review — это конкурс вежливости, а не инженерия.
Time-to-Review: Первый Feedback за 4 Часа
Скорость review напрямую влияет на momentum команды. Если после открытия PR первый комментарий приходит позже чем через 4 часа, author переключается на другую задачу. На следующий день, вернувшись к коду, ему нужна 15-минутная разминка, чтобы вспомнить контекст.
В Roibase метрику time-to-review мы вытягиваем из GitHub API и отражаем в Linear board как таблицу. Если медиана review time в спринте превышает 4 часа, в следующем спринте мы переформируем ротацию назначения reviewer'ов. Так никто не попадает в ситуацию «я не могу делать review», и в календаре каждого есть блок для review.
Второй метрик — merge time: от открытия PR до merge в main. PR на e-commerce функцию не ждёт дольше 48 часов, иначе это мешает A/B тест планам. Если PR лежит более 48 часов, значит произошёл scope creep (reviewer потребовал изменение функции). Тогда правильнее открыть дополнительный story и закрыть текущий PR.
Alert система: Через 24 часа — Slack уведомление
Через Linear webhook при открытом PR более 24 часов reviewer получает автоматический пинг. Эта простая автоматизация выводит review из теории в операционную практику. Slack bot вежливо напоминает: «PR #342, открыт 28 часов — scope большой или недостаёт времени на review?» Вопрос сам по себе открывает диалог.
Comment Density: 2–5 Комментариев на 100 Строк
Слишком много комментариев — reviewer мониторит каждую деталь, но блокирует автора. Слишком мало — rubber stamp approve. Сбалансированный review оставляет 2–5 комментариев на 100 строк изменений.
В Roibase на PR dashboard отслеживаем comment density для каждого reviewer. Если 10+ комментариев на 100 строк — reviewer возможно не понял scope и просто критикует. Если 1 комментарий на 100 строк — reviewer только одобряет формально.
Контролируем density через PR template с чек-листом. «Изменена ли логика?», «Не упал ли coverage тестов?», «Добавлены ли переменные окружения?» — 7 пунктов. Reviewer не может одобрить, не пройдя список. Так комментарии перестают быть случайной эмоцией и становятся систематической контрольной точкой.
## Reviewer Checklist
- [ ] Изменена ли логика обратно совместимо?
- [ ] Добавлены ли новые переменные окружения? .env.example обновлён?
- [ ] Есть ли миграция БД? Добавлен ли скрипт rollback?
- [ ] Coverage тестов не упал ниже 80%?
- [ ] Размер бандла увеличился более чем на 5 KB? (frontend)
- [ ] Breaking API изменение? Написан ли changelog?
- [ ] Новая внешняя зависимость? Лицензия совместима?
Благодаря этому шаблону вместо «этот код плохой» приходит точный комментарий: «миграция БД без скрипта rollback».
PR Size Rule: Более +300 / −100 Строк — Раздели
Большой PR невозможно properly review. На GitHub diff из 600 строк reviewer просто просматривает, ставит «LGTM» и уходит. В Roibase лимит PR size: +300 добавленных строк, −100 удалённых. Если PR превышает, CI bot автоматически комментит: «PR большой — используй feature flag для incremental merge или разбей на два story».
Для разделения больших изменений используем feature flag. Например, новый checkout flow требует 450 строк в 8 файлах. Первый PR — только API layer (100 строк), второй — UI компоненты (120 строк), третий — интеграция (150 строк). Каждый PR может быть merged отдельно, в production флаг закрыт. На последнем PR открываем флаг — flow активируется.
| Тип PR | Строк Изменений | Median Review Time | Bug После Merge |
|---|---|---|---|
| Micro (<150) | +120 / −30 | 1.8 часа | 2% |
| Normal (<300) | +280 / −90 | 3.5 часа | 5% |
| Большой (>300) | +450 / −200 | 12 часов | 18% |
На большом PR bug rate в 3 раза выше — reviewer не видит детали. После разделения каждый PR менее рисковый, возможность rollback'а снижается.
Conflict-Free Feedback: Комментируй Код, не Ситуацию
Вместо «такой подход неправильный» — «эта функция создаёт N+1 queries, добавь eager loading». Не личная критика, а техническая. В Roibase в комментариях code review запрещены слова: «неправильно», «глупо», «ужасно», «что это». Вместо этого — шаблонная фраза: «Это изменение как влияет на метрику X? В сценарии Y это может создать проблему Z».
Для проверки тона используем GitHub Actions bot. Если в комментарии встречаются слова типа «неправильно», «плохо», «отвратительно» — bot автоматически пишет reviewer'у: «Этот комментарий не конструктивен — опиши конкретную проблему или предложи альтернативу». Это не enforced politeness, а инженерная дисциплина.
Другая тактика: открыть follow-up issue после одобрения. Если в PR заметили minor improvement, не блокируем текущий PR, а открываем issue «Post-merge improvement: Refactor cache invalidation logic» и ссылаемся. PR быстро merge'ится, improvement попадает в backlog.
Pair Review: Два Reviewer'а, Разные Линзы
На критичных PR (платежи, аутентификация, миграция данных) два reviewer обязательны. Первый смотрит логику, второй — security и performance. При таком split review каждый комментирует из своей области, без пересечений. Review не удваивается по времени, а качество удваивается.
Async Review: Асинхронная Дискуссия, не Синхронное Совещание
Code review meetings не проводим. PR thread достаточно. Reviewer оставляет комментарий, author отвечает в течение 4 часов, при необходимости пушит коммит. Вопрос на встрече требует 5 минут обсуждения, в асинхронном thread — 2 строки + код сниппет.
Для внедрения асинхронной culture интегрировали Slack. На комментарий в PR author получает уведомление, но не встречу. Author переходит в thread на своём context switch point (когда закончилась текущая задача). Особенно критично для remote команд с разницей в 3+ часовых пояса. В Roibase — Istanbul-Berlin-San Francisco. Синхронный review невозможен. Асинхронный thread: Берлин (9 утра) комментирует, Istanbul (полдень) отвечает, San Francisco (вечер) merge'ит.
Когда code review ставится на измеримые критерии, в команде исчезает язык типа «твой код плохой». Метрики time-to-review, comment density, PR size создают нейтральное поле. Когда всем ясно, как измеряется качество, все держат один стандарт. Брендинг & Identity требует той же измеримой дисциплины — код review culture — техническая сторона той же дисциплины. Без правил review — не культура, а случайная вежливость. С правилами review ускоряется, качество растёт, конфликты уходят.