Пятничный релиз, запрос на слияние уже с комментарием от ИИ, обязательная проверка горит зелёным. Если открыть сам комментарий, там замечания про имена переменных и оформление. На первый взгляд всё выглядит так, будто изменение уже кто-то просмотрел.
Но в тикете было не про стиль. В тикете было сказано, что частичный возврат должен записывать строку в ledger. В diff меняются контроллер и ветка возврата, а записи в ledger там нет. Тег всё равно уходит в релиз, потому что ответственный за выпуск видит зелёный статус и не открывает комментарий.
Снаружи это выглядит как установленная интеграция ИИ в процесс разработки. По факту изменение никто не удержал. Проверка не остановила слияние, не назвала пропуск и не заставила никого зафиксировать исключение.
Такая интеграция должна жить на пути поставки: тикет, запрос на слияние, пайплайн, релиз. Не в чате для посетителей сайта и не в декоративном комментарии под кодом. Полезная проверка называет конкретный пропуск, который человек может быстро подтвердить до слияния. Если статус зелёный даже тогда, когда модель не ответила, это не контроль, а наклейка.
Когда зелёный статус ничего не гарантирует
Самая неприятная поломка здесь простая: шаг с ИИ работает по принципу fail-open. Команда ожидает, что он спросит модель, не пропущено ли в diff то, что у вас и так считается обязательным. Но если у провайдера таймаут, закончилась квота или пришла ошибка, задача всё равно завершается успешно. Бывает и мягкий вариант той же проблемы: комментарий красный, но сам шаг не обязательный, поэтому слияние всё равно разрешено.
В интерфейсе пайплайна оба случая часто выглядят одинаково спокойно. Ответственный за релиз видит зелёный и читает это как «проверка была». Лог задачи при этом говорит другое: ответа модели не было вовсе. То есть система сообщает о ревью, которого не происходило.
Проверить это можно без большой аудиторской кампании. Откройте лог любой задачи по изменению, которое уже влили на этой неделе. Если модель упала по таймауту, вернула пустой ответ или не отработала из-за ошибки, а шаг всё равно зелёный, значит проверка пропускает всё подряд. Если комментарий ругается, но merge не блокируется, перед вами заметка, а не барьер.
Рядом часто лежит ещё один симптом: пропущенный тест. Раньше репозиторий требовал конкретную задачу в пайплайне, а теперь тот же diff либо помечает её как allowed to fail, либо вообще убирает файл теста. ИИ в комментарии в это время хвалит стиль и никак не отмечает, что автоматический свидетель качества исчез. В результате релиз теряет реальную защиту, а зелёный статус продолжает изображать проверку.
Почему человек не может вручную закрыть каждый diff
Техлид или владелец релиза физически не может внимательно прочитать каждый diff перед выпуском и при этом прожить обычную рабочую неделю. Проблема здесь не в квалификации и не в дисциплине. Проблема в объёме. Именно поэтому команды вообще покупают и внедряют автоматического ревьюера: чтобы часть повторяемой проверки происходила до того, как человек потратит на неё время.
Плохая подмена возникает тогда, когда вместо барьера команда получает комментарий, который можно спокойно проигнорировать. Час проверки просто переезжает в текст под запросом на слияние, который кто-то, возможно, откроет уже после merge. Если откроет вообще.
Тогда пропуск обнаруживается уже после тега. В тикете было явно сказано, что путь частичного возврата должен появиться для клиентов, но нужной записи нет. Или запрос в коде уже ожидает колонку, которую релиз так и не добавил, потому что миграции в diff не было. На словах канал пишет: «ИИ проверил запрос на слияние». В логе видно другое: модель не ответила или ответила про форматирование. А пропуск был не стилистический, а поставочный — он касался того, что реально уходит в релиз.
Что именно должна отмечать проверка
Начинать стоит не с фантазий про универсальный код-ревью, а с трёх фактов, которые команда уже считает обязательными. Первый — строка приёмки в тикете. Второй — тесты, которые репозиторий и так обязан прогонять. Третий — релизные пункты, без которых вы не режете тег: feature flag в безопасном значении по умолчанию, миграция при изменении запросов, заметка об откате рядом с тегом. Проверка может назвать, чего из этого не хватает. Она не должна придумывать четвёртое правило про тон, вкус или «более красивую» реализацию.
На стыке тикета и diff это работает особенно понятно. Рядом с изменением должна лежать одна короткая строка приёмки на языке тикета: «частичный возврат записывает строку в ledger». Тогда проверка может сказать: в изменённых файлах эта строка не отражена. Человек за минуту подтверждает пропуск или показывает, что запись живёт в общем пакете, который в этом diff не виден.
Вот где такая проверка действительно останавливает релиз. В тикете есть условие приёмки. В diff меняется контроллер возврата, но записи в ledger нет. Модель возвращает конкретный пропуск. Шаг обязательный, значит merge останавливается. Автор либо добавляет запись, либо ответственный за релиз фиксирует исключение с именем, временем и ссылкой. Это уже контроль. Зелёный таймаут на прошлой неделе был просто ярлыком.
Замечания про стиль и нейминг не должны жить в обязательной задаче. Их можно оставить обычным комментарием. Как только вкус начинает красить обязательную проверку в красный, команда быстро усваивает вредную привычку: красный — это не риск, а чьё-то мнение, значит его можно машинально снять. Именно так полезный сигнал тонет в лишнем шуме. Об этом подробнее — когда проверка качества через ИИ только добавляет шум.
То же правило действует и на уровне пайплайна с релизом. Проверка может прямо сказать, что ранее обязательный тест теперь пропускается, переведён в allowed to fail или удалён. Она может честно сообщить и о себе: модель не ответила, поэтому результата нет. Этого достаточно. Не нужен балл, не нужен длинный архитектурный разбор. При создании тега задача может также назвать конкретный релизный пункт, который ещё открыт. Но это должен быть пункт из вашего реального списка, а не новый список, придуманный ИИ. Открытый пункт — это проверяемый пропуск. Закрытый пункт не требует комментария. Если под каждым тегом появляется длинный текст «на всякий случай», у команды появляется второй почтовый ящик, который все перестают читать именно в тот день, когда там было важное.
Что остаётся за человеком
Даже честная и узкая проверка не выносит продуктовый вердикт. Ответственный за релиз всё равно решает, важен ли этот пропуск для конкретного тега, действительно ли поведение реализовано в коде, который текущий diff не показывает, и можно ли выпускать изменение сейчас.
Модель будет ошибаться в обе стороны. Иногда она не увидит запись в ledger, потому что та живёт в общем пакете. Иногда она поднимет флаг по строке приёмки, которую команда вчера уже убрала из тикета. Это обычные рабочие ошибки. Они терпимы, пока человек может быстро отметить, что именно произошло. Они становятся токсичными, когда от количества флагов начинают зависеть деньги, рейтинг команды или публичная оценка недели.
Поэтому исключение должно быть оформлено явно: кто принял решение, когда именно и на что есть ссылка. Например: «принято ответственным за релиз, запись находится в общем пакете, дата, ссылка». Проверка должна удерживать именно эту запись об исключении. Она не должна молча запоминать, что все будущие комментарии со словом ledger можно автоматически пропускать. Постоянное игнорирование по шаблону — прямой путь к тому, что через месяц настоящий пропуск уйдёт под тем же ярлыком.
И главное: за человеком остаётся продуктовый смысл. Нужен ли вообще такой возврат, можно ли включить feature flag только для одного аккаунта, стоит ли задержать пятничный тег до понедельника — это не вопрос к ИИ-проверке. Она может показать, что обязательная строка не подтверждена изменением. Решение «выпускаем всё равно» должно приниматься владельцем и оставаться в письменном виде с датой и временем. Ни чат на сайте, ни оценка в запросе на слияние этого решения за вас не примут.
Один репозиторий, одна неделя, две цифры
Не пытайтесь раскатать такую механику на все сервисы сразу в понедельник. Возьмите один репозиторий, из которого на этой неделе точно выйдет релиз. Сделайте один обязательный шаг и жёстко ограничьте, что он вообще имеет право сообщать: отсутствует строка приёмки в diff, обязательный тест больше не обязателен, модель не вернула ответ. Всё остальное пусть остаётся комментарием, который не блокирует merge.
Дальше посчитайте две цифры. Первая: сколько раз модель не ответила, а пайплайн всё равно остался зелёным. Эта цифра должна быть нулевой. Если она не ноль, у вас ещё нет проверки — у вас есть интеграция, которая пропускает всё подряд.
Вторая цифра: сколько замечаний человек подтвердил как реальные пропуски, которые иначе ушли бы в релиз. Если там ноль, а все тексты ИИ сводятся к стилю и общим советам, значит перед вами рассказчик, а не контрольный шаг. Рассказчику не место в списке обязательных задач.
Пока вы это считаете, держите рамку простой. Проверка следует за запросом на слияние. Она не заменяет существующие тесты. Она не разговаривает с посетителями сайта. Её аудитория — люди, которые вливают изменения, и люди, которые отвечают за релиз.
Когда стоит позвать помощь
Лог одной задачи можно открыть и самому. Помощь обычно нужна в четырёх случаях: шаг ИИ остаётся зелёным при ошибке, красный комментарий не может остановить merge, команда не может отделить обязательный факт от стилистического замечания, или поставщик пытается продать чат на сайте как будто это то же самое, что проверка в запросе на слияние.
Это действительно разные продукты. Чат разговаривает с человеком, который ещё не открыл тикет и ничего не собирается вливать в main. Проверка в delivery-процессе смотрит на изменение, которое почти уходит в релиз. Она должна работать по правилам репозитория и релиза, а не по логике поддержки посетителей.
Услуги покрывают настройку такого барьера в репозитории, из которого вы уже выпускаете изменения. Чтобы таймаут модели ронял задачу, а не оставлял её с зелёным статусом, переделывают схему AI-интеграции. В Выбранные работы есть примеры, где путь от тикета до релиза выстроен как рабочая операция, а не как набор разрозненных инструментов. Если будете писать, назовите саму проверку, скажите, что делает задача при таймауте модели, и приведите один релиз, который ушёл зелёным при понятном пропуске. Данные клиентов и секреты репозитория в первом сообщении не нужны.