JavaRush /Курсы /Claude code /Diff-based verification, L1 review

Diff-based verification, L1 review

Claude code
18 уровень , 4 лекция
Открыта

1. Смотрим не на объяснение, а на diff

К этому моменту изменение уже собрано: root cause зафиксирован, regression evidence под рукой, diff разложен на commit'ы, а PR_DESCRIPTION.md объясняет суть. Но это ещё не значит, что PR можно молча отправлять дальше. Тесты зелёные, Claude бодро пишет «готово, всё работает» — и именно здесь тянет расслабиться. Инженерная дисциплина начинается там, где хочется закрыть ноутбук.

У diff есть очень полезное свойство: он не рассказывает историю, а показывает факт изменения. Diff — это кассовый чек вашей правки: потом не спорят, что именно вы «купили» у кода и почему в корзине оказались ещё три лишних файла.

Раньше мы читали маленький diff после каждого шага, чтобы удерживать implementation loop под контролем. Здесь масштаб другой: должны сходиться файлы, commit'ы, walkthrough и evidence — review всего изменения, а не проверка микрошага.

Здесь полезно на секунду напомнить разницу между verification и review: первое отвечает на «чем мы доказали корректность», второе — «кто посмотрел и принял локальное решение». Нас интересует review-слой.

Что сравниваем На какой вопрос отвечает
Verification Что мы запускали, чем проверяли, какие тесты и команды дали evidence
Layer 1 review Кто посмотрел на diff, что заметил и почему решил, что PR готов или не готов

Чтобы не говорить слишком абстрактно, возьмём сквозной пример из Commerce OS. Баг: пустая корзина приводила к 500 при checkout. Approved plan выглядел так:

## Утверждённый план

1. Добавить guard для пустой корзины в `OrderController`.
2. Добавить regression test в `OrderControllerTest`.
3. Не менять другие endpoints и не трогать логику `/orders/preview`.

А вот фрагмент реального diff:

public OrderResponse checkout(@RequestBody CheckoutRequest request) {
+   if (request.items() == null || request.items().isEmpty()) {
+       throw new InvalidRequestException("Корзина пуста");
+   }
+   return checkoutService.checkout(request.items());
}

С этого момента ваша задача — не радоваться тому, что «guard же добавили», а задать спокойные инженерные вопросы. Совпадает ли это с approved plan? Не уехал ли diff куда-то ещё? Изменили ли поведение шире, чем собирались? Есть ли тест? Не сломали ли соседний путь? Вот точка входа в локальное review.

2. Состав Layer 1 review

Само слово review иногда звучит пугающе, как будто сейчас придёт сердитый сеньор, увидит лишнюю строчку и отправит переписывать карьеру. На деле Layer 1 review — локальная последовательность шагов, которая не даёт выпустить сырой PR и делает его чистым и объяснимым уже на вашей стороне. Удобно видеть его как маленький конвейер:

flowchart TD
    A[Approved plan + diff] --> B[Self-review]
    B --> C[Claude-assisted review]
    C --> D[Fresh-context review]
    D --> E[Review notes]
    E --> F[Human decision]

Если в проекте уже одобрен какой-то review-плагин, его можно встроить между fresh-context review и итоговым решением. Но важно не путать инструмент с судьёй: плагин или Claude помогают заметить проблему, а не принимают решение за вас.

Ниже — вся логика в одной таблице.

Шаг Кто смотрит Зачем нужен Что получается на выходе
Self-review Вы как автор Проверить, совпадает ли diff с планом и смыслом задачи Первичная локальная оценка diff
Claude-assisted review Claude в writer-сессии или отдельном запросе Быстро подсветить scope creep, missing tests, edge cases Список находок с уровнем важности
Fresh-context review Другая сессия или reviewer-subagent Снять замыленность автора и confirmation bias Второй взгляд без авторской истории
Plugin-assisted review Опционально, если plugin уже одобрен Добавить ещё один автоматизированный прожектор Дополнительные замечания
Облачное ревью Опциональный ускоритель: многоагентный разбор сложного diff в облаке Получить расширенный контекст и сразу несколько специализированных взглядов Единый отчёт со сведёнными находками
Human decision Вы или живой ревьюер Принять решение: готово, исправляем, делим PR Осознанный go / no-go

Самое важное здесь — порядок: сначала вы сами читаете свой diff, потом подключаете Claude, потом даёте diff «свежей голове», и только затем формируете REVIEW_NOTES.md. Пропустите self-review, сразу спросив модель «ну как там?» — и вы назначаете Claude своим заместителем по ответственности. Плохая кадровая политика.

3. Self-review: сначала вы, потом уже Claude

Self-review кажется скучным ровно до первого раза, когда вы находите в своём PR лишний файл, случайный rename или правку «заодно», которую вчера даже не заметили. Он снимает самые дешёвые ошибки — те, что потом обидно ловить на чужом review.

Если вы пока чувствуете себя неуверенно, не пытайтесь читать diff как Матрицу. Начните с простой схемы: сначала масштаб, потом затронутые файлы, потом поведенческий смысл, потом тесты.

git diff --stat                                 # быстро смотрим масштаб изменений
git diff src/orders/OrderController.java        # читаем смысл production-правки
git diff src/orders/OrderControllerTest.java    # отдельно проверяем regression test
git status                                      # нет ли случайно лишних файлов

Теперь полезно сверять diff с approved plan почти как по чек-листу, но без бюрократического фанатизма.

Что сверяем Какой вопрос задаём себе
Список файлов Все ли эти файлы действительно были в плане?
Поведение Исправляю ли я именно тот сценарий, ради которого открыл задачу?
Тесты Есть ли явный regression test или хотя бы обновлённая проверка?
Scope Не затронул ли я соседние endpoint'ы, конфиги или рефакторинг «за компанию»?
Читаемость Могу ли я объяснить этот diff за минуту без фразы «ну тут Claude сам решил»?

Допустим, кроме guard в OrderController вы внезапно видите ещё и изменение в OrderPreviewController. Вот здесь self-review и должен вас остановить: Claude «хотел помочь» — сделать поведение единообразным, но approved plan прямо сказал /orders/preview не трогаем. Это не улучшение, а scope creep.

Полезно также смотреть не только на добавленные и удалённые строки, но и на изменившийся смысл. Например, вот маленький тест:

import org.junit.jupiter.api.Test;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@Test
void rejectsEmptyCart() throws Exception {
    mockMvc.perform(post("/api/orders")
            .contentType("application/json")
            .content("{\"items\":[]}"))
        .andExpect(status().isBadRequest());
}

Сам по себе он выглядит хорошо. Но self-review подталкивает к ещё одному вопросу: тест закрывает старую болевую точку из root cause — или мы просто повесили зелёную лампочку на похожий сценарий? Если баг проявлялся на HTTP-уровне, а тест уходит только во внутренний exception, часть проблемы всё ещё рядом. Финальная самопроверка: если бы этот PR открыл не я, а коллега, смог бы я по diff быстро понять, что произошло и зачем? Ответ «примерно, но пришлось бы вспоминать контекст чата» означает — PR ещё сыроват.

4. Claude-assisted review: правильный фокус

После self-review очень удобно подключить Claude как второго читателя diff. Но здесь есть тонкая ловушка: спросите просто «проверь PR» — и модель начнёт помогать слишком широко. А «слишком широко» в review почти всегда значит «слишком расплывчато». Давайте Claude не свободу, а фокус:

Проверь текущий diff против approved plan.
Смотри только на:
- расползание scope,
- отсутствующие тесты,
- крайние случаи,
- обратную совместимость,
- чувствительные изменения в валидации,
- неясные места в коде.
Сгруппируй находки по важности: blocker / major / minor.
Укажи file:line, если это возможно.
Файлы не редактируй.

Здесь важны сразу три вещи: связь с approved plan, список зон внимания, запрет на редактирование. Вам сейчас нужен reviewer, а не «ревьюер, который на всякий случай уже всё сам поправил». Claude в этом режиме быстро сканирует diff и приносит список гипотез, которые вы дальше либо подтверждаете, либо отклоняете.

Уровень Что означает Как обычно реагируем
Blocker PR нельзя считать готовым Исправляем до любого движения дальше
Major Существенный риск или заметный пропуск Обычно правим в этом же PR
Minor Улучшение читаемости, имени, формулировки Исправляем по ситуации

Представим, что Claude вернул major/orders/preview по-прежнему позволяет пустую корзину») и minor («имя теста rejectsEmptyCart можно точнее»). Но это ещё не приговор: вы читаете, соотносите со scope и решаете.

Очень полезная привычка — фиксировать не только принятые, но и отклонённые замечания. Потому что Claude иногда звучит так уверенно, будто уже сам себе одобрил PR и пошёл за кофе. А часть замечаний может не иметь отношения к текущему scope.

## Claude-assisted ревью

- Major: endpoint `/orders/preview` не покрыт новой валидацией — принято, открываем follow-up issue
- Minor: тест `rejectsEmptyCart` можно переименовать в `returnsBadRequestForEmptyCart` — принято
- Minor: добавить логирование в controller — отклонено, вне scope текущего PR

Так review перестаёт быть размытым разговором «что-то где-то не понравилось» и становится набором решений. А решения любят быть записанными.

5. Fresh-context review: свежий взгляд

После пары часов работы над одной задачей происходит очень человеческая вещь: вы видите в diff не то, что написано, а то, что хотели написать. Именно поэтому fresh-context review так полезен — это не недоверие к себе, а нормальная инженерная прививка от замыленного взгляда.

Самый простой вариант — открыть новую Claude-сессию и дать ей только нужные артефакты: approved plan, PR_DESCRIPTION.md, diff и test plan. Ещё удобнее reviewer-subagent из Workflow Kit — заново мы его не настраиваем, просто используем как свежую пару глаз.

Ты — reviewer свежим контекстом.
У тебя нет истории writer-сессии.
Проверь текущий diff против approved plan и PR walkthrough.
Сфокусируйся на:
- несоответствии plan ↔ diff,
- пропущенных крайних случаях,
- неочевидных изменениях поведения,
- тестовых пробелах.
Верни findings с важностью и коротким обоснованием.
Файлы не редактируй.

Почему fresh-context review работает лучше, чем «тот же Claude, но ещё раз»? Потому что writer-сессия уже накопила историю решений, гипотез, отвергнутых путей и эмоциональное ощущение «ну я же знаю, что тут происходит». Новая сессия этого багажа не имеет — она смотрит на PR так же, как потом посмотрит живой ревьюер.

В нашем примере с Commerce OS свежий reviewer замечает то, что writer уже перестал видеть: walkthrough обещает HTTP 400 для POST /api/orders, а в проверках рядом указан только targeted test. Ручную HTTP-проверку правда прогоняли — или её надо добавить в evidence либо убрать из walkthrough? Это и есть золото fresh-context review.

Если diff заметно многослойный — задевает безопасность, тесты и производительность одновременно, — можно сделать ещё один шаг и запустить несколько специализированных reviewer-агентов параллельно: один на security-угол, другой на тесты, третий на архитектуру. Но это уже опция, а не обязанность: для большей части PR хватит одного свежего reviewer'а.

И ещё одна важная мысль: свежий reviewer не должен превращаться в «третейского судью, который всегда прав». Он приносит новый сигнал. Решение по сигналу по-прежнему за человеком.

6. REVIEW_NOTES.md и человеческое решение

Когда self-review, Claude-assisted review и fresh-context review закончены, важно не оставить результат распылённым по чату, памяти и вкладкам терминала. В этот момент появляется второй главный артефакт лекции — REVIEW_NOTES.md. Если PR_DESCRIPTION.md рассказывает ревьюеру что и зачем вы поменяли, то REVIEW_NOTES.md фиксирует, как именно вы локально проверяли PR и к чему пришли.

# REVIEW_NOTES.md

## Self-review
- diff совпадает с шагами approved plan
- изменены только `OrderController` и `OrderControllerTest`
- unrelated files отсутствуют

## Claude-assisted ревью
- Minor: переименовать тест для большей ясности — принято
- Major: проверить согласованность с `/orders/preview` — follow-up issue создан

## Ревью на свежем контексте
- подтверждено: scope не расползся
- найдено: manual check в PR walkthrough стоит уточнить — принято

## Финальное решение
PR готов к отправке на внешний review.
Открытые follow-up задачи не блокируют текущий bugfix.

Обратите внимание на последнюю секцию. Она называется не «одобрено Claude», не «всё отлично» и не «ну вроде можно». Она называется Final decision. Потому что именно здесь заканчивается локальная автоматизация и начинается человеческая ответственность.

По сути, разумных решений обычно четыре. PR готов. Либо требует ещё одного небольшого исправления. Либо его лучше разбить на два — diff вырос или затесалась лишняя идея. Либо review возвращает вас в debugging: root cause описан слабо. Все четыре нормальны. Ненормален только пятый: «ничего не понял, но ладно, отправлю так».

Человеческое решение и есть точка, в которой локальный Layer 1 review заканчивается. У вас чистый diff, понятный PR_DESCRIPTION.md, зафиксированный REVIEW_NOTES.md, список принятых и отклонённых замечаний. Три взгляда — свой, Claude и свежий контекст — уже отсеяли лишние файлы, scope creep и дыры в тестах, но последнее слово осталось не за ними. Self-review, Claude и fresh-context только подсвечивают проблемы; строку Final decision пишете вы. И именно эта подпись, а не зелёные галочки инструментов, превращает «то, что Claude где-то нагенерировал» в изменение, за которое отвечает человек.

7. Облачное ревью как ускоритель

Облачное ревью — это естественное продолжение ревью со свежим взглядом для случаев, когда локального reviewer-subagent уже не хватает. Запускается одной командой (условно /ultrareview или похожая облачная команда; точное имя и доступность могут меняться от версии к версии). Ментальная модель та же: это то же самое ревью со свежим взглядом, что и в шаге fresh-context, только вынесенное в облачное окружение.

Чем это отличается от многоагентного ревью, которое вы и так можете поднять локально из Workflow Kit? Расширенным контекстом. На один и тот же diff параллельно смотрят несколько специализированных агентов — по безопасности, производительности, тестам и архитектуре, — и всё сводится в размеченный diff с находками, ссылками на файлы и уровнем серьёзности. Отчёт ложится в тот же REVIEW_NOTES.md, что и обычные находки.

Когда облачное ревью уместно

Есть несколько ситуаций, где облачное ревью оправдывает себя. Diff большой или трогает несколько слоёв сразу — аутентификация, база, API в одном PR. PR в чувствительной зоне — платежи, секреты, данные клиентов: нужен отдельный взгляд на безопасность и риск. Ревью нужно запустить параллельно с другой работой — облачный агент идёт в фоне. Diff несёт регрессионный риск, который трудно поймать одним ревьюером, — многофайловый рефакторинг или совместимость при миграции, к этим темам мы ещё вернёмся в следующих уровнях курса. Наконец, PR относится к новому или сложному модулю, где у локального ревьюера нет полного контекста архитектуры.

Каждый запуск ultrareview оплачивается отдельно и стоит от $5 до $25 в зависимости от размера. Знать, что этот инструмент существует, важно; запускать его на каждый PR — нет.

Когда облачное ревью не уместно

И столько же ситуаций, где облачное ревью только мешает. Маленький PR с очевидным diff — расходы и задержка больше выигрыша. Репозиторий или данные нельзя выгружать в облако — чувствительные данные или регулируемая среда: вопрос политики, а не качества ревью. Вы не сможете осмысленно прочитать находки задним числом — облачное ревью не отменяет обязанности читать diff и принимать решения. Срочный hotfix — на разбор отчёта нет времени.

Отдельная история — разрешения для облачного ревью, к которой мы ещё вернёмся в курсе. У облачного ревьюера своя модель разрешений: отдельный биллинг, отдельный журнал аудита, отдельный набор разрешённых файлов и путей. Командная политика должна явно описывать, какие PR допустимо туда отправлять; чаще всего это доступ только на чтение к diff и связанным файлам, без записи.

И напоследок — главное правило, которое не меняется ни на одном уровне ревью: AI-ревью любого уровня — от self-review до облачного — помогает найти проблемы, но не заменяет чтение diff и ответственность разработчика.

1
Задача
Claude code, 18 уровень, 4 лекция
Недоступна
Claude-assisted review по focus list
Claude-assisted review по focus list
1
Задача
Claude code, 18 уровень, 4 лекция
Недоступна
Принятие review comment в production-коде
Принятие review comment в production-коде
1
Опрос
Реализация, отладка и review с Claude, 18 уровень, 4 лекция
Недоступен
Реализация, отладка и review с Claude
Реализация, отладка и review с Claude
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ