Якість і безпека
Огляд коду зі штучним інтелектом (AI): від diff до перевіреного рішення
У попередніх розділах ми розібрали, як обрати перевірки для зміни. Тепер розглянемо, як читати саму зміну перед злиттям: що саме має перевірити людина…
У попередніх розділах ми розібрали, як обрати перевірки для зміни. Тепер розглянемо, як читати саму зміну перед злиттям: що саме має перевірити людина або AI-рецензент, як довести знайдений дефект і як діяти, коли підозра не підтвердилася.
Огляд коду (code review) — це перевірка запропонованої зміни в контексті її вимог і системи. Мета — зменшити ризик дефекту й покращити зрозумілість підтримуваного коду. Огляд не є голосуванням за особистий стиль і не зводиться до кількості коментарів. Google Engineering Practices формулює близький критерій: схвалити зміну, щойно вона явно покращує здоров’я системи; дрібну недосконалість не слід перетворювати на причину затримки. Це настанова Google, а не універсальне правило для кожного ризику чи команди. The Standard of Code Review
Огляд має допомогти відповісти на практичні запитання: чи реалізовано потрібну поведінку; чи не зламався вже підтримуваний контракт; чи витримано межі доступу й даних; чи перевіряють тести важливу поведінку; чи зрозуміло, що треба зробити далі. Глибина залежить від можливого впливу зміни: короткий текстовий diff і зміна обробки ключів шифрування не потребують однакового маршруту.
50.1. Спершу зафіксуйте, що саме перевіряєте
Рецензія відповідає на запитання про конкретну ревізію. Зафіксуйте базову ревізію, поточний commit або head, а тоді читайте diff саме між ними. Якщо автор уже додав виправлення, старий висновок може бути застарілим; якщо невідомо, який commit перевірено, висновок важко відтворити.
До огляду зберіть:
- задачу, вимоги та критерії приймання;
- опис запиту на злиття змін (pull request/merge request, PR/MR) і перелік заявлених змін;
- diff та його базову ревізію;
- пов’язані модулі, типи, контракти інтерфейсу прикладного програмування (API), схему даних та записи архітектурних рішень (architecture decision records, ADR), якщо зміна їх зачіпає;
- релевантні тести, результати перевірок і спосіб запуску;
- важливі обмеження середовища: наприклад, чи бачить агент потрібну гілку, залежності, журнали або тестові дані.
Опис запиту допомагає зрозуміти намір, але не замінює первинних доказів. Перевірте сам diff, контракт або кодову гілку, на які спирається висновок. PR може неповно описувати поведінку, а запит агента — містити застаріле припущення. GitHub дає змогу лишати як коментарі до всього PR, так і коментарі до конкретних рядків; вибір місця обговорення має відповідати масштабу питання. Pull request reviews, Working with comments
Якщо критичного контексту бракує, назвіть його. Рецензія може завершитися висновком «недостатньо доказів», а не вигаданою певністю. Наприклад: «Не можу підтвердити міграційну сумісність: у доступному checkout немає попередньої версії схеми й тесту оновлення. Потрібні ці артефакти або окремий результат перевірки». Це конкретніше, ніж мовчки припустити, що міграція безпечна.
50.2. Читайте шлях зміни до користувацького результату
Починайте з вимоги й пройдіть шлях до результату: вхідний запит, перевірка, зміна стану, залежність, відповідь або побічний ефект. За потреби пройдіть його у зворотний бік — від місця, де користувач побачить результат, до коду, який його породжує. Перевірте не лише додані рядки, а й найближчий код, що визначає їхнє фактичне значення.
Корисні запитання:
- Який саме сценарій для користувача або іншої системи змінився?
- Чи викликається новий шлях у всіх потрібних місцях, і чи збережено старі сценарії, які мають працювати?
- Чи передаються аргументи в правильному порядку й типі? Чи всі виклики оновленої функції сумісні?
- Чи не змінився порядок транзакцій, надсилання подій, повторних спроб або очищення ресурсів?
- Чи збігається нова поведінка з API, схемою, протоколом і домовленостями споживачів?
- Які не змінені файли або залежності формують передумови цього коду?
Локально правдоподібна умова може порушити глобальний інваріант. Наприклад, функція правильно перевіряє формат власника, але маршрут викликає її до встановлення довіреної ідентичності; цикл коректно оновлює один запис, але повторна спроба відправляє подію двічі; новий аргумент є обов’язковим у підписі, але внутрішній виклик і далі використовує стару кількість аргументів.
Перевіряйте граничні й помилкові сценарії, якщо вони стосуються зміни: порожнє значення, відсутній запис, некоректний тип, дубльований запит, вичерпаний тайм-аут, повторна спроба, одночасний запит, частково виконана операція, скасування чи помилка залежності. Не треба механічно проходити довгий список на кожному рядку. Достатньо сформулювати реальний контрприклад і перевірити, чи код або тест його відкидає.
Фраза «тут може бути гонка» сама собою не є знахідкою. Покажіть дві операції, їхню послідовність і спільний ресурс: «Два запити читають вільний слот до запису. Кожен створює бронювання, бо перевірка доступності та вставка не атомарні. Запустіть обидва запити бар’єром до commit; результат має містити не більше одного підтвердження». Такий опис дає шлях до перевірки, а не залишає автора з абстрактною тривогою.
50.3. Перевіряйте відповідність вимогам і якість тестового доказу
Вимогу треба зіставити з поведінкою, а не лише з наявністю нового коду. Для кожного критерію приймання знайдіть, де він виконується і як помітити відхилення. Якщо вимога забороняє користувачу читати чужий рахунок, тест власника на власний рахунок не доводить виконання цієї вимоги. Потрібні окремий власник і сторонній користувач, а очікуваний результат має включати відмову й відсутність приватних даних у відповіді.
Тест є сильним доказом, коли його очікуваний результат походить від вимоги незалежно від коду, що перевіряється. Переконайтеся, що тест:
- перевіряє результат, який має значення, а не лише виклик мок-функції чи кількість рядків покриття;
- провалиться, якщо внесений дефект справді з’явиться;
- проходить через важливі межі системи, якщо саме вони створюють ризик;
- має конкретні передумови, дані та спосіб відтворення;
- запускався на тій самій ревізії, яку зараз переглядають.
Mock корисний для ізоляції контракту, але він не підтверджує поведінку реального постачальника, бази чи черги, якщо не перевіряє їхню інтеграцію. Тест, що дублює умову з production-коду як власне очікування, може повторити ту саму помилку. Перевірте незалежне джерело очікуваного результату: явну вимогу, задокументований контракт, зафіксований інваріант або перевірену модель даних. Google радить зважати на те, чи впаде тест тоді, коли код буде зламано, і чи справді зміна має відповідні тести; сама наявність тестового файла не відповідає на ці запитання. What to Look for in a Code Review
Зелений статус збірки, тестів чи статичного аналізу — важливий сигнал, але він доводить лише те, що саме ці перевірки дали успішний результат на певній ревізії. Звірте commit і перелік обов’язкових перевірок; якщо роботу пропущено або перевірявся інший commit, так і запишіть. Політика GitHub визначає, які перевірки та схвалення обов’язкові для конкретної гілки. Проходження безперервної інтеграції (continuous integration, CI) не скасовує підтвердженого дефекту, а схвалення людини не перетворює неповний CI на пройдений. Status checks, About protected branches
50.4. Оцінюйте доступ, дані й сумісність за конкретним шляхом
Для зміни, яка читає або змінює дані, з’ясуйте, хто може викликати шлях і яку саме сутність він зачіпає. Перевірте власника запису, роль, організацію чи орендаря (tenant), делегування та межу довіри — ті виміри, що присутні в продукті. Перевірка «користувач увійшов» не доводить «користувач має право на цей об’єкт»: Open Worldwide Application Security Project (OWASP) називає помилку перевірки цього права на API-об’єкті Broken Object Level Authorization (BOLA) і радить перевіряти повноваження для конкретної дії над конкретним об’єктом. Переконайтеся, що відповідь помилки не повертає поля, які мали бути приховані. About OWASP, OWASP API Security Top 10, API1:2023
У змінах сховища, журналювання, експорту чи міграції подивіться, де з’являються секрети й приватні дані: у логах, винятках, тестових дампах, телеметрії, тимчасових файлах, резервних копіях або нових дозволах. Для міграції перевірте напрямок оновлення, сумісність старого й нового коду, повторний запуск, часткову відмову та можливість відновлення. Незворотну дію варто розглядати з її фактичними обмеженнями, а не називати безпечною лише через те, що тестовий набір зелений.
Для API й залежностей перевірте не тільки компіляцію нової гілки. Сумісність стосується клієнтів, що ще використовують стару форму запиту або стару версію схеми; порядку подій, на який покладаються споживачі; часових меж; і фактичної поведінки бібліотеки в цій конфігурації. Якщо ризик перебуває на межі зовнішньої системи, назвіть, чи виконано контрактний тест, інтеграційний запуск або тільки локальну симуляцію.
Це не привід вставляти до кожного огляду повний перелік відомих категорій атак. Починайте з конкретної зміни та її шляху до впливу: які дані, хто їх контролює, де зникає перевірка, як це можна використати або як може відмовити система. Якщо потрібен повний аналіз зловмисного моделювання загроз, це окрема задача з власним обсягом і доказами.
50.5. Напишіть знахідку, яку можна відтворити
Корисна знахідка (finding) повідомляє про конкретний ризик, а не лише про незгоду з формою коду. Формат нижче — практичний синтез для цієї глави; ані Google Engineering Practices, ані GitHub не вимагають саме такого шаблону.
- Розташування й ревізія. Файл, рядки або шлях у зміненому diff; commit, який перевірено.
- Умова відтворення. Хто і що має зробити; передумови, дані, порядок подій чи тип помилки.
- Очікуване й фактичне. Яка поведінка має відбутися за вимогою і що відбувається натомість.
- Вплив. Хто втрачає дані, доступ чи функцію і за яких умов; наскільки серйозними є наслідки та ймовірним є сценарій.
- Доказ і впевненість. Посилання на контракт, стек, тест, кодовий шлях або відтворення; що лишається припущенням.
- Найменше корисне виправлення. Перевірка, зміна або додаткова інформація, яка закриє встановлений ризик.
Короткий приклад: «[P1, блокує] booking.py:84, commit abc123. Коли двоє користувачів бронюють останнє місце до фіксації першого запиту, обидва проходять перевірку вільного слота й обидва отримують підтвердження. Це порушує вимогу про одну бронь на місце. Додайте конкурентний тест із двома запитами, що стартують до першого commit, і забезпечте атомарне обмеження на записі. Перевірено за транзакційним шляхом; відтворення на двох паралельних запитах дає два рядки».
Твердження, гіпотезу й ідею слід відокремлювати. «Сервер повертає чужий номер телефону на шляху GET /users/{id} без перевірки власника» — твердження, яке має мати відтворення. «Можливо, логер пише пароль» — гіпотеза, доки не перевірено рівень логування та форму винятку. «Можна перейменувати змінну» — необов’язкова ідея, якщо назва не шкодить розумінню чи контракту. Не підвищуйте гіпотезу до критичної знахідки тільки через можливу тяжкість наслідку; серйозний можливий вплив є причиною швидко перевірити шлях і чітко пояснити невизначеність.
Виберіть пріоритет без перебільшення
Спершу користуйтеся домовленістю репозиторію: префіксами P0–P3, рівнями ризику або словами blocking, non-blocking, nit. Якщо командам потрібна компактна схема, один зручний варіант такий:
| Позначка | Значення для цього огляду |
|---|---|
| P0 / критичний | Підтверджений ризик безпеці, цілісності даних або доступності з великим впливом; потрібна негайна реакція за процесом команди. |
| P1 / високий | Підтверджений дефект основного сценарію, прав доступу, сумісності чи надійності; виправити до злиття. |
| P2 / помірний | Реальна проблема, але її вплив або умови обмежені; рішення про блокування залежить від наслідків і локальної політики. |
| P3 / пропозиція | Покращення читабельності чи майбутньої підтримки без підтвердженого дефекту; не маскувати його під обов’язкове виправлення. |
Це приклад локальної шкали, не стандарт GitHub і не шкала Google. Не кожна команда потребує чотирьох чисел. Важливо сказати, що є обов’язковим до злиття, що можна обговорити після, а що є необов’язковою порадою. Google наводить мітки на кшталт Nit, Optional і FYI, щоб відрізнити обов’язкову дію від пропозиції, але не встановлює цю P0–P3 схему. How to Write Code Review Comments
50.6. Визначте результат огляду, а потім перевірте нову ревізію
Після перевірки сформулюйте одне з трьох рішень:
- Схвалити. Переглянута ревізія відповідає важливим вимогам і не містить підтверджених блокувальних ризиків. Залишкові пропозиції позначені як необов’язкові.
- Попросити зміни. Є одна чи більше підтверджених знахідок, які за узгодженим правилом треба закрити до злиття.
- Недостатньо доказів. Неможливо обґрунтовано зробити висновок через відсутній контекст, неповний запуск або невідомий контракт. Назвіть, який доказ потрібен і хто може його надати.
Коли підозра не підтвердилася, відкличте її прямо: «Перевірив транзакцію й унікальне обмеження на slot_id. Два конкурентні вставлення не можуть обидва завершитися; мій коментар про дубльоване бронювання був хибним. Знімаю його». Видалення коментаря без пояснення лишає читача гадати, чи змінився код, чи знахідка зникла з поля зору.
Після виправлень перечитайте змінені рядки й пов’язані шляхи на новому head. Новий код міг розв’язати первинну проблему, але створити регресію, змінити поведінку суміжної гілки або лишитися без потрібного тесту. Зафіксуйте, яку ревізію перевірено, і закрийте обговорення з посиланням на виправлення чи доказ. Схвалення старої ревізії може стати нечинним після суттєвого нового commit — залежно від захисту гілки, налаштованого скидання застарілих схвалень і правила про останній push. Перевірте правила репозиторію, а не припускайте однакову поведінку всюди. About protected branches, Resolving reviews
Відсутність знахідок означає, що рецензент не має підтвердженої проблеми в межах перевіреної ревізії, контексту та доступних перевірок. Це не доказ того, що всі помилки відсутні. Якщо шлях не запускався або даних бракувало, звузьте формулювання: «На commit abc123 не знайшов помилок у перевірених вимогах; конкурентне навантаження не запускав».
50.7. Як використовувати AI-рецензента
AI зручний, коли йому чітко задано межу перевірки й доступний потрібний контекст. Він може швидко зіставити великі ділянки diff, знайти виклики зміненого інтерфейсу, пройти крайові стани або запропонувати контрприклад. Сприймайте це як підказку до перевірки, а не як доказ безпомилковості чи повного охоплення.
Перед запуском зафіксуйте:
- яку гілку, commit або незбережену зміну слід переглянути;
- вимогу, межі завдання й контракти, які не можна змінити мовчки;
- файли й середовища, доступ до яких насправді має агент;
- чи дозволено запускати команди й тести, чи доступні мережа та інтеграційні залежності.
Попросіть агента для кожної знахідки показати шлях від умови до наслідку, точні рядки й commit, доказ або відтворення, рівень упевненості та варіант найменшої перевірки. Окремо попросіть не повідомляти вигаданих запусків і не робити висновків із відсутніх файлів. Якщо він не може читати CI, приватну документацію або схему, це обмеження треба залишити видимим.
Другий AI-рецензент або паралельні агенти можуть додати незалежний кут огляду, але не доводять незалежності, коректності чи повноти. Моделі можуть поділити те саме хибне припущення або повторити однаковий шаблон. Перевірте кодовий шлях, офіційний контракт і фактичний результат тесту. В актуальній документації Codex /review працює над вибраним diff і повертає пріоритизовані зауваження; видимість відомостей про GitHub PR залежить від доступу, активної гілки та налаштованого gh. Довідка Anthropic станом на 2 вересня 2026 року називає Claude Code Review дослідницьким попереднім переглядом для планів Team та Enterprise, недоступним організаціям із zero data retention (ZDR); рецензія залишає коментарі, але не схвалює і не блокує PR. Доступність, дозволи й можливості продуктів змінюються, тож на момент роботи перевірте актуальну документацію та налаштування. Codex code review, Set up Code Review for Claude Code
У блозі про запуск Claude Code Code Review Anthropic навела власні внутрішні показники частки PR із предметними коментарями та позначок «incorrect». Це звіт постачальника про його продукт і процес, а не незалежна оцінка точності, відкликання (recall) чи результатів для іншої команди. Не переносіть ці числа як прогноз для свого репозиторію. Bringing Code Review to Claude Code
50.8. Розбір відкритого PR: коли перевірка знаходить власну регресію
У липні 2026 року автор відкритого PR openai/openai-python #3510 запропонував після події [DONE] дочитувати залишок потоку Server-Sent Events (SSE), щоб коректно звільнити з’єднання за протоколом передачі гіпертексту (HTTP). Початкове пояснення наводило логічний шлях до переваги: сервер уже позначив завершення, а буфер міг ще містити термінатор chunked-відповіді.
Перша перевірка Codex виявила, що дочитування стояло у finally, отже виконувалося навіть коли користувач навмисно припиняв ітерацію до [DONE]. Для довгого чи завислого потоку це перетворювало закриття на очікування решти мережевого тіла. Автор обмежив drain шляхом, на якому [DONE] уже спостерігали, і застосував зміну до синхронного й асинхронного ітераторів. PR #3510, перший коментар Codex і commit c789ceb
Наступна перевірка знайшла інший дефект у самому виправленні: якщо транспортна помилка стається після коректного [DONE], виняток із finally міг перетворити завершений результат на помилку й не дійти до response.close(). Автор назвав це реальною помилкою власної зміни, обмежив обробку транспортним винятком, забезпечив закриття, додав синхронний та асинхронний регресійні тести й описав різницю до/після. Пізніше виявилося, що скасування під час очікування залишкових байтів також могло пропустити закриття; commit 04fdd7d загорнув drain так, щоб з’єднання закривалося і за цього шляху. Цей цикл добре показує, чому рецензія перевіряє не лише початковий diff, а й виправлення. PR #3510, відповідь автора й commit f24d09a, commit 04fdd7d
Ще одна перевірка помітила, що обмеження кількості розібраних SSE-подій не зупиняє дочитування, якщо після [DONE] сервер лишає з’єднання відкритим і надсилає лише коментарні рядки. Вони не стають подіями, хоча декодер і далі споживає сирі байти. Автор обмежив drain до 64 КіБ сирих даних і додав тест із comment-only chunks: перевірка саме байтового потоку потрібна, бо коментарі не передають керування циклу подій. Межа перевіряється після споживання фрагмента, тому останній фрагмент може трохи перевищити номінальні 64 КіБ. Автор також зауважив, що одне читання, яке зависло без нових байтів, як і раніше, обмежується налаштованим HTTPX read timeout. PR #3510, обговорення межі drain, commit c8e39cbc4a
Далі автор не прийняв окрему пропозицію про idle-сокет, пояснивши, як HTTPX read timeout впливає на конфігурацію. У вересні мейнтейнер закрив PR без злиття: команда воліла розв’язати повторне використання з’єднання на рівні транспортного шару, де менше ризику пов’язати очищення з тайм-аутом чи скасуванням. Отже, історія не є простим «AI знайшов баг, PR змерджили». У ній є кілька відтворених регресій і тестів, аргументована незгода щодо межі виправлення та підсумкове рішення не приймати цей патч у такій формі. PR #3510, відповідь автора про тайм-аут і рішення мейнтейнера від 23 вересня 2026 року
Практичний висновок: вимагайте контрприклад до суттєвого зауваження; після виправлення знову пройдіть пов’язаний шлях і перевірте власні побічні ефекти; коли рекомендацію не прийнято, зафіксуйте умови й наслідки вибору. Тест має доводити потрібний інваріант, а не лише віддзеркалювати форму запропонованого коду.
50.9. Навчальний приклад: користувач змінює чуже бронювання
У PR додають зміну дати бронювання через PATCH /api/bookings/{booking_id}. Критерій приймання каже, що клієнт може змінювати лише власні бронювання у своїй організації. Форма приховує кнопку редагування для чужого запису, а позитивний тест перевіряє, що власник може змінити дату.
Рецензент проходить запит від маршруту до запису в базі й бачить, що сервер шукає бронювання лише за booking_id; перевірка автентифікації є, але зв’язок із principal.user_id та principal.tenant_id не перевіряється. Інтерфейс не є межею доступу: сторонній користувач може викликати API безпосередньо.
Повний коментар може виглядати так:
[P1, блокує]
bookings.py:84, commitabc123. Будь-який автентифікований користувач, який знає або вгадаєbooking_id, може надіслатиPATCH /api/bookings/{booking_id}і змінити дату бронювання іншого клієнта. Маршрут перевіряє вхід користувача, але завантажує запис лише заidі не звіряє власника чи організацію. Це може зірвати чужий візит. Додайте серверну перевірку доступу в запиті або політиці. Негативний API-тест має увійти як користувач Б, спробувати змінити бронювання користувача А, отримати відмову згідно з політикою, не змінити дату й не побачити вміст запису. Тест власника залиште як позитивний контроль.
Перед відправленням такого коментаря рецензент перевіряє фактичний виклик сервісу й джерело principal, а не припускає поведінку за назвою update_booking. Він також шукає перевірку в middleware, фільтрі об’єктно-реляційного відображення (object-relational mapping, ORM) або запиті до бази: вона може бути поза зміненим рядком. Якщо інваріант діє на цій межі й немає серверної перевірки, рішення — попросити зміни, бо це підтверджена помилка авторизації на зміненому маршруті. Якщо перевірку знаходить, тест має викликати справжню межу доступу з двома різними користувачами й показати відмову для стороннього запису.
Це синтетичний навчальний PR; шлях, рядки й commit є умовними, код тут не запускався. Він показує, як сформулювати конкретну умову, шлях впливу, негативний тест і рішення. Сам факт входу користувача в систему не доводить його право на конкретний об’єкт.
50.10. Навчальний приклад: підозра, яку спростовує обмеження бази
У PR сервіс бронювання перевіряє, чи вільний слот, а потім додає запис. Рецензент бачить два паралельні запити й пише: «Обидва можуть пройти перевірку до вставлення; користувачі отримають дві броні на одне місце. Блокує злиття».
Це правдоподібна підозра, але висновок ще не підтверджений. Інший рецензент перевіряє транзакцію, міграцію й обмеження UNIQUE(slot_id) у таблиці активних бронювань. База виконує перевірку унікальності атомарно; один із двох конкурентних записів завершується конфліктом і перетворюється на відповідь «слот уже зайнятий». Умова «два успішні записи для одного слота» неможлива в заявленій схемі.
Рецензент пробує негативний сценарій у тесті на рівні бази або перевіряє наявний конкурентний тест із двома клієнтами. Якщо тест справді підтверджує один успіх і один контрольований конфлікт, він відкликає блокувальну знахідку: «Я не врахував унікальне обмеження slot_id; вставлення серіалізується на рівні БД, дубльованого активного запису не виникає. Знімаю зауваження. Тест test_concurrent_booking_conflicts підтверджує очікуваний результат». Якщо тесту немає, доречна нова пропозиція — додати його, а не заявляти підтверджений дубль.
Обмеження доводить саме інваріант у тій схемі й умовах, де воно діє. Якщо бронювання архівується перед перевіркою, інший тип запису не має обмеження, або міграція ще не розгорнута на всіх середовищах, початкова підозра може лишитися слушною для іншого шляху. Перевірте фактичне визначення індексу, транзакційну межу та обробку конфлікту. Не приймайте назву функції create_unique_booking як доказ унікальності.
Це синтетичний навчальний приклад; він не описує реальний PR чи виконаний тут тест. Його мета — показати, як відрізняти можливий дефект від підтвердженого й відкликати хибне зауваження так само явно, як прийняте.
50.11. Навчальний приклад: не дозволяйте виправленню розростися без рішення
У PR із виправленням перевірки власника рахунку автор змінює умову доступу й додає негативний тест: користувач Б не може прочитати рахунок користувача А. Огляд підтвердив вузький шлях, а автор отримав прохання виправити лише його.
У новій ревізії автор також переписав універсальний клієнт бази, перейменував параметри у восьми API, відформатував сусідні модулі та змінив стандарт обробки тайм-аутів. Ці зміни можуть бути корисними, але збільшують обсяг без зв’язку з виправленням доступу. Зараз тест про власника не доводить збереження контрактів інших маршрутів чи сумісність усіх клієнтів.
Рецензент має перевірити diff після попереднього commit і назвати конкретний наслідок обсягу: «Після виправлення доступу PR додає зміну формату помилок у всіх маршрутах через новий ORM-клієнт. Це змінює спостережуваний API й не перевірене критерієм доступу. Будь ласка, винесіть рефакторинг в окремий PR або додайте контракти й тести для всіх змінених відповідей; поточне схвалення стосувалося іншого diff». Це прохання повернути огляд до перевірюваної межі, а не твердження, що будь-який суміжний рефакторинг заборонений.
Якщо команда вирішить залишити розширення, обсяг вимог теж має розширитися: перелік споживачів, контрактні тести, міграція клієнтів і обґрунтований план розгортання. Якщо ширше завдання не має власника чи доказів, його краще відокремити й зафіксувати посилання на окрему задачу. Після вибору рецензент перевіряє нову ревізію повністю в межах її нового обсягу.
Цей сценарій також навчальний. Він показує, що огляд відповідає за весь запропонований diff: додатковий код стає частиною рішення, навіть якщо початкове прохання було вузьким.
50.12. Тон і час зворотного зв’язку
Пишіть про код і наслідок, а не про здібності чи наміри автора. Поясніть, чому проблема має значення, запропонуйте прямий наступний крок і позначте обов’язковість. Формулювання «Ти забув про другого користувача» звинувачує людину; «Цей тест перевіряє власника, але не відхиляє доступ другого користувача до того самого booking_id» називає перевірювану прогалину. Google рекомендує конкретний, ввічливий коментар, який пояснює підставу й залишає простір для обговорення, коли впевненість неповна. How to Write Code Review Comments
Уточнювальне запитання корисне, коли відповідь може змінити висновок: «Чи є account_id з токена гарантовано тим самим власником, що й URL-параметр?» Питання без пояснення можуть здаватися загадкою. Якщо коментар лише радить напрямок, підпишіть його Optional, Nit або локальною міткою. Не додавайте десятки повторних дрібних зауважень, якщо одне узагальнене зауваження й лінтер вирішують той самий факт.
Швидкий зворотний зв’язок зменшує час очікування виправлення, але рецензія сама потребує зосередження. Google радить відповідати оперативно й наводить один робочий день як свій максимальний орієнтир, водночас не переривати глибоку роботу посередині зосередженого завдання. Це приклад практики Google, не вимога до кожної команди. Власний сервісний рівень має враховувати часові пояси, критичність, розмір diff і графік чергувань. Speed of Code Reviews
Accelerate розглядає швидкий зворотний зв’язок, невеликі партії змін і процеси погодження як можливості всієї організації постачати програмне забезпечення. У наведеній там моделі спроможностей вищі показники постачання мали й команди без окремого процесу погодження змін, і команди, що використовували рецензування колегами (peer review). Це результат на рівні організації, а не доказ, що окремий PR можна зливати без перевірки або що треба зняти обов’язкові правила гілки. Для команди він радше ставить запитання: чи скорочує черга реальну невизначеність і ризик, чи додає лише зайве очікування? Вимірюйте час до першої корисної відповіді й до завершення рецензії, зберігаючи контроль, потрібний за фактичним впливом зміни. Accelerate, Forsgren, Humble & Kim, 2018, авторизований фрагмент, Appendix A
Том ДеМарко й Тім Лістер у третій редакції Peopleware розглядають час на зосереджену роботу, відволікання й телефон як частини організації праці команд. Книжка дає контекст для поваги до уваги колег; це практичне джерело, а не вимірювання вартості кожного code review і не рецепт календаря. Для поведінки рецензента спирайтеся на конкретну домовленість команди, а не на гасло про терміновість. Peopleware: Productive Projects and Teams, 3rd ed., Chapter 12: “Bring Back the Door”
50.13. Завершений результат огляду
Добрий підсумок огляду коротко дає автору й команді підстави для рішення:
- яка ревізія перевірена;
- які вимоги й частини системи охоплено;
- які перевірки виконано, на якому commit і з яким результатом;
- які знахідки підтверджені, із пріоритетом та умовою відтворення;
- які зауваження відкликано або залишено як необов’язкові;
- чи є обмеження або потрібні додаткові докази;
- чи схвалено зміну, запитано виправлення або відкладено рішення.
Так коментарі стають трасованим доказом, а не списком вражень. Огляд завершено, коли команда може пояснити, чому ця ревізія відповідає вимогам і як вона обробила відомі ризики — навіть якщо рішенням стало відокремити частину роботи або зупинити конкретний патч.
Джерела та подальше читання
Джерела перевірено 24 вересня 2026 року. Документація GitHub і продуктові довідки є змінними; перед використанням конкретного процесу перевірте актуальні налаштування сховища й версію функції.
- Google Engineering Practices, The Standard of Code Review, What to Look for in a Code Review, How to Write Code Review Comments, Speed of Code Reviews — критерій якості, зміст перевірки, тон, розрізнення обов’язкових і необов’язкових коментарів, темп зворотного зв’язку.
- GitHub Docs, Pull request reviews, Working with comments, Status checks, About protected branches, Resolving reviews — види коментарів, статуси, вимоги політики й повторний огляд.
- Open Worldwide Application Security Project, API1:2023 Broken Object Level Authorization — перевірка повноважень над кожним об’єктом, до якого звертається API-код; About OWASP — офіційна назва й повна форма абревіатури.
- OpenAI, Codex code review — поточний обсяг і умови видимості для
/review; перевірено 24 вересня 2026 року. - Anthropic, Set up Code Review for Claude Code — продуктова довідка й опис наявного режиму; перевірено 24 вересня 2026 року. Відкритість та умови планів можуть змінитися.
- Anthropic, Bringing Code Review to Claude Code, 9 березня 2026 року — оголошення й власні метрики продукту; це не незалежне дослідження.
- openai/openai-python #3510, створений 16 липня й закритий без злиття 23 вересня 2026 року — реальний приклад ітеративного огляду, відтворених дефектів, регресійних тестів, аргументованої незгоди й рішення мейнтейнера; див. також commit
04fdd7dпро закриття після скасування та commitc8e39cbc4aпро обмеження дочитування. - Nicole Forsgren, Jez Humble, Gene Kim, Accelerate: The Science of Lean Software and DevOps, IT Revolution, 2018; авторизований фрагмент — зворотний зв’язок, розмір партій, процеси погодження й потік постачання; результати описують організаційний рівень і контекст дослідження.
- Tom DeMarco, Tim Lister, Peopleware: Productive Projects and Teams, 3rd ed., Addison-Wesley, 2013; видавничий фрагмент Chapter 12: “Bring Back the Door” — контекст про увагу й переривання в роботі.