У п’ятницю команда готує реліз. У запиті на злиття вже є коментар від ШІ, а обов’язкова перевірка світиться зеленим. Сам коментар говорить про назви й стиль. На перший погляд усе виглядає так, ніби зміни вже пройшли додатковий контроль.
Але в тікеті була конкретна умова: часткове повернення має записувати окремий рядок у ledger. У diff немає жодної зміни, яка цей запис додає. Попри це тег іде далі, бо власник релізу довіряє зеленому статусу й не відкриває коментар детально.
З боку це схоже на встановлену інтеграцію ШІ. Насправді ж вона не втримала зміну в точці, де це мало статися. Якщо перевірка не може назвати конкретний пропуск, який людина швидко звіряє до злиття, вона не стоїть на шляху доставки. Вона просто висить поруч.
Саме тому таку інтеграцію треба розглядати не як декоративний коментар у PR і точно не як чат для відвідувачів сайту, а як частину ланцюжка тікет → запит на злиття → пайплайн → реліз. Зелений статус у момент, коли модель узагалі не відповіла, — це не quality gate. Це лише позначка, яка створює хибне відчуття перевірки.
Коли зелений статус не означає, що перевірка була
Найнебезпечніший сценарій тут простий: команда бачить зелений статус і читає його як «хтось уже подивився». Насправді ж задача могла спрацювати у режимі fail-open: вона відправила запит до моделі, отримала таймаут, вперлася в ліміт, дістала помилку постачальника — і все одно завершилася успішно. У списку перевірок це виглядає так само зелено, як і справжня відповідь моделі.
Є й другий варіант тієї самої проблеми: ШІ щось написав, навіть позначив ризик, але сама задача не є обов’язковою. Тоді червоний коментар не зупиняє злиття. Формально інтеграція встановлена, повідомлення є, але на шлях доставки вона не впливає. Це примітка, а не бар’єр перед релізом.
Перевірити це легко на одному недавньому прикладі. Відкрийте лог задачі для зміни, яку вже злили цього тижня. Якщо модель не відповіла, стався таймаут або повернулася порожня відповідь, а задача все одно зелена — перевірка пропускає помилки. Якщо коментар був негативний, але злиття все одно дозволили — це теж не контроль, а супровідний текст.
Поруч часто лежить ще один симптом. Репозиторій раніше вимагав певний тест, а тепер цей job позначили як allowed to fail, пропустили або взагалі прибрали файл тесту. ШІ при цьому може чемно похвалити назви змінних чи форматування і нічого не сказати про те, що автоматичний свідок зник. У результаті збірка зелена, а команда помилково читає це як підтвердження якості.
Чому людина не може вручну перекривати кожен diff
Багато команд заспокоюють себе так: якщо щось важливе, техлід або власник релізу все одно подивиться руками. На практиці це не працює не тому, що люди погано мислять, а тому, що обсяг змін перемагає будь-яку дисципліну. Людина не може вичитувати кожен diff перед релізом і паралельно вести тиждень: зустрічі, інциденти, пріоритети продукту, підтримку команди.
Саме через це й купують або збирають автоматичну перевірку. Але якщо вона зводиться до коментаря, який усі можуть спокійно проігнорувати, навантаження нікуди не зникає. Ви просто переносите ще одну годину роботи в абзац тексту, який хтось відкриє вже після злиття — якщо відкриє взагалі.
Проблема проявляється не в момент коментаря, а після тега. Тікет прямо казав, що часткове повернення має записувати рядок у ledger для клієнтського обліку, а в diff немає жодної зміни, яка це робить. Або запит у коді вже очікує нову колонку, але міграції в наборі змін немає. До релізу всі бачили зелений статус. Після релізу команда стикається з фактом, що важлива умова доставки не була перевірена.
Тоді в каналі з’являється знайома фраза: «ШІ ж перевірив цей PR». Але лог задачі показує інше: або модель не відповіла, або відповіла про стиль і назви. Пропуск був не стилістичний. Це був факт доставки, а перевірка взагалі не була націлена на такі факти.
Що саме має право позначати така перевірка
Найкращий старт — не вигадувати нові правила, а взяти три речі, які команда вже й так вважає обов’язковими. По-перше, рядок приймання в тікеті. По-друге, тести, які репозиторій уже вимагає. По-третє, пункти релізу, без яких ви не випускаєте тег: безпечне значення feature flag, наявна міграція, якщо змінилися запити, або примітка про rollback поруч із релізом.
Така перевірка має право сказати лише одне: який саме з цих уже відомих пунктів зараз відсутній. Вона не повинна вигадувати четверте правило про тон, кмітливість, красу коду чи смак у найменуваннях. Щойно обов’язкова задача починає карати за стиль, команда вчиться сприймати червоний статус як суб’єктивний шум і перестає розрізняти справжній ризик.
На стику тікета й PR це працює дуже приземлено. Поруч із diff має бути одна коротка умова словами тікета: «часткове повернення записує рядок у ledger». Тоді перевірка може сказати, що ця умова не відбита у змінених файлах. Людина за хвилину або підтвердить пропуск, або покаже, що запис живе в спільному пакеті, який у цьому diff не видно.
Ось коли така інтеграція справді зупиняє реліз. У тікеті є умова про часткове повернення. У diff змінено контролер, але немає запису в ledger. Модель повертає повідомлення про відсутній рядок приймання. Задача обов’язкова — злиття зупиняється. Автор або додає потрібний запис, або власник релізу фіксує виняток із іменем, часом і посиланням. Це вже перевірка. Зелений таймаут минулого тижня був лише наліпкою.
Окремо варто відрізати все, що не має блокувати злиття. Зауваження про стиль можуть лишатися коментарем. Але вони не повинні фарбувати обов’язкову задачу в червоний. Інакше у вас з’являється ще одна черга повідомлень, яку всі машинально розгрібають без довіри до змісту. Саме так перевірка перетворюється на шум. коли перевірка якості через ШІ лише додає шуму.
Те саме стосується фактів у пайплайні та релізі. Перевірка може вказати, що раніше обов’язковий тест тепер пропущений, дозволений до падіння або видалений. Вона також може чесно сказати, що сама не отримала відповіді від моделі. На етапі тега вона може назвати конкретний незакритий пункт релізного списку, який команда й так використовує. Якщо пункт закритий — перевірка мовчить. Якщо на кожен тег вона пише довгий універсальний текст, команда починає його ігнорувати, зокрема й того ранку, коли він був би доречний.
Що все одно лишається за людиною
Навіть справедлива позначка від ШІ не є вироком для продукту. Власник релізу все одно вирішує, чи справді цей відсутній рядок важливий саме для цього тега, чи потрібна поведінка живе в коді, який поточний diff не показує. Перевірка має підсвітити місце для розмови, а не підмінити рішення.
Модель помилятиметься звичайними способами. Вона може не побачити запис у ledger, якщо той винесений у спільний пакет. Може послатися на рядок приймання, який команда вчора прибрала з тікета. Це не катастрофа, поки людина може швидко позначити виняток або спростувати сигнал. Проблема починається тоді, коли відсутність позначок стає KPI, публічним рейтингом або підставою для премії. Тоді система починає заохочувати не точність, а тишу.
Тому виняток має бути письмовим і прив’язаним до конкретного моменту. Наприклад: «погоджено власником релізу, запис є у спільному пакеті», далі дата і посилання. Перевірка зберігає саме цю примітку для цього випадку. Вона не повинна мовчки навчитися пропускати всі майбутні згадки про ledger. Постійне ігнорування за шаблоном призводить до того, що наступного місяця реальний пропуск піде під тією самою етикеткою.
Продуктове рішення завжди лишається за людиною. Чи потрібне взагалі це часткове повернення. Чи можна ввімкнути feature flag лише для одного акаунта. Чи варто відкласти п’ятничний тег. Перевірка може показати, що обов’язковий пункт відсутній. Розмова про те, чи випускати попри це, має відбутися письмово, з відповідальним і часом. Ні чат на сайті, ні оцінка в PR цього не роблять.
Один репозиторій, один тиждень, дві цифри
Не треба починати з розгортання на всі сервіси в понеділок. Візьміть один репозиторій, у якому цього тижня точно буде реліз. Зробіть одну задачу обов’язковою і жорстко обмежте її словник трьома фактами: відсутній рядок приймання у diff, раніше обов’язковий тест більше не є обов’язковим, або модель не повернула відповіді. Усе інше нехай лишається коментарем, який не блокує злиття.
Далі порахуйте дві цифри. Перша: скільки разів модель не відповіла, а пайплайн усе одно лишився зеленим. Ця цифра має бути нуль. Якщо вона не нульова, перевірка ще не стала перевіркою. Вона досі пропускає помилки у відкритому режимі.
Друга цифра: скільки позначок людина підтвердила як реальний пропуск, який інакше поїхав би в реліз. Якщо там нуль, а всі повідомлення стосуються лише стилю, у вас не контроль, а оповідач поверх PR. Такого оповідача не треба ставити до списку обов’язкових задач.
Поки ви це рахуєте, важливо не підмінити одну систему іншою. Така перевірка йде поруч із PR, не замінює наявні тести і не розмовляє з відвідувачами сайту. Її аудиторія — люди, які зливають зміни, і люди, які відповідають за реліз.
Коли варто звернутися по допомогу
Один лог задачі можна прочитати самостійно. Але допомога потрібна швидко, якщо зелений статус з’являється навіть після помилки моделі, якщо червоний коментар не може зупинити злиття, якщо команда не може відділити обов’язковий факт від стилістичного зауваження, або якщо постачальник продав чат на сайті в одному пакеті з перевіркою PR і це почали називати однією інтеграцією.
Тут важливо не змішувати два різні продукти. Чат спілкується з людьми, які ще не відкрили тікет. Перевірка дивиться на зміну, яка вже майже їде в main і далі в реліз. Це різні місця в процесі, різні ризики й різні критерії користі.
Послуги охоплюють саме такий бар’єр у репозиторії, який у вас уже бере участь у релізах. Щоб таймаут моделі роняв задачу, а не залишав її зеленим статусом, переробляють схему AI-інтеграції. У Обрані роботи є приклади, де шлях доставки розглядається як операційна система команди, а не як набір розрізнених інструментів. Якщо пишете вперше, назвіть саму перевірку, скажіть, що задача робить під час таймауту моделі, і наведіть один реліз, який вийшов із зеленим статусом попри конкретний пропуск, на який можна вказати. Дані клієнтів і секрети репозиторію в першому повідомленні не потрібні.