JavaRush /Курси /Claude code /Handoff Note та Fresh Reviewer Pattern

Handoff Note та Fresh Reviewer Pattern

Claude code
Рівень 6 , Лекція 4
Відкрита

1. «Начебто готово» — це не handoff

Довга задача ламається не під час написання коду, а пізніше — коли потрібно зрозуміти, що вже зроблено, які рішення прийняті, що перевірено. Handoff — не бюрократія, а спосіб зберегти зміст задачі, поки він не випарувався.

Уявіть: другий день виправляєте refund-flow в AI Commerce Growth OS. Учора винесли логіку з RefundController у RefundService, сьогодні додали тести, помітили дивний кейс із поверненням понад 1000 доларів, перемкнулися на інший баг. Зупиніться на «логіку майже винесли, лишився спірний момент» — і наступна людина заново побудує все дерево рішень у себе в голові. Знання приклеїлося до авторської сесії: поки діалог відкрито, все очевидно, закрили вкладку — і половина важливого була лише у вашій голові. А голова не підтримує git show.

«Начебто готово» не відповідає на жодне інженерне запитання. Що готово? Які файли змінювалися? Що перевірили? Де ризик? Що далі? Немає відповідей — handoff не відбувся.

flowchart TD
    A[Сесія автора] --> B[HANDOFF_NOTE.md]
    A --> C[git diff]
    A --> D[Лог тестів]
    B --> E[Свіжа сесія]
    C --> E
    D --> E
    B --> F[Людина-ревʼюер]
    C --> F
    D --> F
    E --> G[Продовження задачі]
    F --> H[Перевірка та зауваження]

Handoff — не один файл у вакуумі, а компактний пакет змісту: HANDOFF_NOTE.md, поруч TASK_SPEC.md, актуальний diff і результати перевірок. Є цей набір — наступна людина продовжує задачу. Є лише ваша впевненість — вона починає розслідування.

2. Структура HANDOFF_NOTE.md

Записка має бути структурованою: передбачуваний артефакт, де потрібне лежить на очікуваних місцях, інакше читання перетворюється на квест, тільки тепер у markdown. І пишеться вона не з нуля в останній момент, а збирається з накопиченого по ходу — milestone summary, decision log, checks, ризики, наступний крок. Практична структура для задач рівня нашого Commerce OS:

Поле Що в ньому писати Навіщо це потрібно
Мета
Однією фразою, який результат має вийти Щоб читач одразу зрозумів, про яку задачу взагалі йдеться
Специфікація задачі
Посилання на TASK_SPEC.md або коротке резюме scope Щоб не витягувати межі задачі з памʼяті автора
Змінені файли
Які файли вже зачеплено Щоб швидко відкрити потрібні місця й побачити реальний обсяг роботи
Рішення
Які рішення вже прийнято і чому Щоб не сперечатися заново з уже розвʼязаними речами
Припущення
Що поки вважається правильним, але не доведено повністю Щоб не плутати факти і робочі гіпотези
Докази
Які команди, логи, результати підтверджують поточний стан Щоб handoff спирався на докази, а не на тон автора
Тести/перевірки
Що запускали і з яким результатом Щоб наступний читач не гадав, наскільки зміну взагалі перевірено
Відомі збої / ризики
Що ще не покрито, що турбує, де тонке місце Щоб незавершеність була явною, а не спливала сюрпризом
Наступний крок
Один конкретний наступний крок Щоб handoff завершувався не туманом, а напрямком руху

Принцип: handoff розділяє факти, рішення, гіпотези і наступний крок. Злиті в один абзац — читач витрачає сили на відновлення структури, а не на роботу.

Приклад для refund-flow:

# HANDOFF_NOTE.md

## Мета
Винести refund decision logic з RefundController у RefundService без зміни API.

## Специфікація задачі
Див. TASK_SPEC.md: scope = refund-flow only, не чіпати payment provider integration.

## Змінені файли
- src/main/java/com/acme/commerce/refund/RefundController.java
- src/main/java/com/acme/commerce/refund/RefundService.java
- src/test/java/com/acme/commerce/refund/RefundControllerTest.java

## Рішення
- threshold > $100 залишено як property, не hardcode
- controller став тоншим, правила перенесено в service

## Тести/перевірки
- ./gradlew test --tests "*Refund*"  # 8 тестів пройшли

## Відомі ризики
- кейс refund > $1000 без approval поки що не покрито тестом

## Наступний крок
Додати тест на > $1000 і перевірити, чи потрібен audit log для bypass

Записка зберігає не кожну думку, а інженерну картину. І рядок Відомі ризики — не визнання провалу, а ознака зрілості: чесне «кейс > 1000 поки не покрито» краще, ніж дати читачеві наштовхнутися на це через сорок хвилин. Прозора незавершеність краща за красиву недомовленість.

3. Пишіть для іншого читача, а не для себе

Легко написати записку, зрозумілу вам і марну для інших: автор добудовує текст власною памʼяттю, у читача такої розкоші немає. Пишіть для того, хто бачить лише файл, diff і перевірки. Головне правило: прибирайте все, що спирається лише на контекст автора. Ваше «зробив основне» для іншого не означає нічого; те саме з «тести ок», «майже закінчив» — це розмовний шум, а не інженерна інформація.

Слабке формулювання Сильне формулювання
Тести зелені
Запущено ./gradlew test --tests "*Refund*" — 8 тестів пройшли
Лишився один спірний кейс
Не покрито кейс refund > $1000 без approval
Почистив контролер
Refund decision logic винесено з controller у RefundService
Нічого зайвого не змінював
Scope збережено: файли payment provider не чіпалися

Різниця здається косметичною, але насправді вона величезна. Сильне формулювання дає наступному читачеві те, що можна перевірити. Слабке просить повірити авторові на слово. А весь курс, якщо чесно, якраз і будується на звичці не вірити на слово — навіть якщо це слово сказали вчорашні ви.

Дуже допомагає додавати поруч короткий, але конкретний технічний слід. Наприклад, так:

git diff --stat main...refund-refactor
# 3 файли змінено, 48 вставок(+), 19 вилучень(-)

./gradlew test --tests "*Refund*"
# Збірка успішна за 8 с
# 8 тестів виконано, 8 пройшли

Ці дві команди вже дають новому читачеві набагато більше, ніж абзац «я тут трохи поправив і начебто не зламав». Особливо корисно це в задачах, які розтягнуті на кілька сесій: сьогоднішня впевненість дуже швидко перетворюється на вчорашню невизначеність.

І ще один нюанс, який постійно недооцінюють. У Next step не треба писати «продовжити роботу». Це не наступний крок, це філософський напрямок. Наступний крок має бути один і конкретний: «додати тест на кейс > 1000», «порівняти diff із main і переконатися, що payment files не зачеплено», «перевірити, чи потрібен audit log». Хороший Next step знижує ціну входу в задачу майже до нуля.

4. Fresh reviewer pattern: свіжий контекст

Коли ви довго ведете одну задачу, у вас неминуче з’являється авторська сліпота. Це не вада характеру, а звичайний побічний ефект довгої сесії. Ви памʼятаєте, чому прийняли саме таке рішення, знаєте, який глухий кут уже пробували, і автоматично «дочитуєте» зміст там, де новий читач побачить прогалину. Саме тут і потрібен fresh reviewer pattern.

Ідея дуже проста. Авторська сесія робить зміну. Потім інший контекст — нова сесія Claude або жива людина — отримує компактний пакет: TASK_SPEC.md, HANDOFF_NOTE.md, актуальний diff і результати перевірок. І перевіряє задачу не як автор, а як читач, який нічого не має вгадувати. Це важливий зсув: ми перестаємо питати «мені здається, все ок?» і починаємо питати «що видно з доказів?».

На практиці свіжий ревʼюер часто ловить три типи речей. По-перше, пропущені edge cases. По-друге, вихід за scope: наприклад, автор «заодно» зачепив файл, який не мав чіпати. По-третє, недоведені твердження: тести локально зелені, але потрібний сценарій взагалі не запускався. Writer усередині своєї сесії часто цього вже не помічає, бо його увага зайнята іншим — історією прийнятих рішень.

Дуже зручно запускати fresh reviewer ось так:

Прочитайте TASK_SPEC.md і HANDOFF_NOTE.md.
Подивіться поточний diff відносно main.
Перевірте лише refund-flow і не змінюйте файли.
Зосередьтеся на:
- виході за scope,
- пропущених тестах,
- кейсі refund > $1000,
- невідповідності між note і реальним diff.
Поверніть зауваження з привʼязкою до доказів.

У цьому запиті є дві сильні сторони. Перша — reviewer отримує scope і фокус, а не абстрактне «ну подивись». Друга — він працює від evidence: note, diff, tests. Це означає, що зауваження можна перевірити, а не сперечатися про них за інтонацією.

Уявіть дві ситуації. У першій авторська сесія пише: «Усе зелене, логіка винесена, можна мержити». У другій fresh reviewer читає handoff, відкриває RefundService, дивиться тести й помічає: тест на суму понад 1000 доларів відсутній, хоча ризик прямо зазначено в записці. У другій ситуації процес спрацював: handoff не сховав незавершеність, а reviewer не вдав, що її немає. Саме так народжується довіра до змін.

Тут корисно памʼятати різницю між fresh session і fresh reviewer. Fresh session можна відкрити просто щоб продовжити роботу в чистішому контексті. Fresh reviewer потрібен з іншою метою: не продовжити, а перевірити. І для цієї перевірки handoff особливо важливий, бо reviewer свідомо не занурюється глибоко в історію автора. Він має вміти побачити задачу ззовні.

Саме тому fresh reviewer не повинен отримувати всю переписку. Це поширена помилка. Здається, що «чим більше контексту, тим краще». Насправді відбувається протилежне: новий перевіряльник тягне до себе старі гіпотези автора і знову заражається тим самим забрудненим контекстом. Нам потрібен не перенос старої втоми, а новий погляд. Тому HANDOFF_NOTE.md і компактний diff корисніші за величезну переписку.

5. HANDOFF_NOTE.md vs PR description і changelog

Коли ви вперше починаєте оформлювати handoff, його дуже легко сплутати із сусідніми артефактами. Здається, що PR description уже пояснює зміни, commit message вже є, а changelog теж щось фіксує. Але в цих документів різні ролі. Якщо їх змішати, кожен починає працювати гірше.

Артефакт Для кого він написаний На яке запитання відповідає
HANDOFF_NOTE.md
Для наступної сесії або людини, яка продовжить/перевірить задачу
Що зроблено, що доведено, де ризик і що робити далі?
PR description
Для ревʼюера змін як готового пакета
Що змінилося і як це перевірити перед merge?
Commit message
Для історії Git
Який логічний крок було зафіксовано цим commit?
Changelog
Для користувача або команди релізу
Що змінилося в продукті на рівні версії/релізу?

Це дуже важлива різниця. HANDOFF_NOTE.md живе всередині процесу, поки задача ще рухається. PR description зазвичай з’являється на межі готової зміни. Changelog взагалі не має пояснювати, який тест ви не встигли написати для refund > 1000 — це інша площина розмови.

Із цієї різниці випливає простий практичний висновок. Якщо задача ще не закінчена, але ви вже пишете так, ніби готуєте реліз, ви втрачаєте зміст handoff. І навпаки, якщо PR description перетворюється на щоденник сумнівів і незавершених думок, reviewer’у буде важко ним користуватися. Документи мають залишатися у своїх ролях.

Дуже корисно тримати HANDOFF_NOTE.md трохи сухішим і точнішим, ніж PR description. У ньому важливіша інженерна картина. Не «ми добре попрацювали і зробили код чистішим», а «винесли refund decision logic, зачепили три файли, запускали такі-то тести, ось відомий ризик, ось наступний крок». Це звучить менш надихаюче, зате справді допомагає працювати.

6. Збірка handoff у Commerce OS на практиці

Тепер зберемо все в один живий сценарій, щоб handoff не лишився гарною теорією. Припустімо, ви ведете задачу по AI Commerce Growth OS: потрібно винести decision logic повернень із контролера в сервіс, не змінюючи API і не лізучи в інтеграцію з платіжним провайдером. Задача вже не поміщається в один промпт, отже без handoff вона майже гарантовано почне розвалюватися.

Спочатку авторська сесія працює у своїй гілці, робить перший milestone, запускає цільові тести й фіксує проміжний стан. У цей момент не потрібно чекати «повної готовності». Саме навпаки: handoff особливо корисний до повної готовності, коли вже є зроблена частина, є ризик і зрозумілий наступний крок.

Наприклад, після першого етапу у вас може вийти такий міні-ритм:

git add src/main/java/com/acme/commerce/refund/RefundController.java
git add src/main/java/com/acme/commerce/refund/RefundService.java
git add src/test/java/com/acme/commerce/refund/RefundControllerTest.java
git commit -m "Виніс refund decision logic до RefundService"

git status
# На гілці refund-refactor
# робоче дерево чисте

Після цього авторська сесія оновлює HANDOFF_NOTE.md, а fresh reviewer відкриває задачу вже не за памʼяттю автора, а за артефактами. Він бачить scope із TASK_SPEC.md, бачить, що зачеплено лише refund-flow, бачить тести й рядок про непокритий кейс > 1000. І саме тому замість розпливчастого «ну начебто мерджимо» з’являється нормальна інженерна розмова: спершу додамо відсутній тест, потім ще раз подивимося на diff.

Найцінніше тут у тому, що handoff робить задачу незалежною від одного носія знання. Якщо автор іде, задача не помирає. Якщо ви самі відкриваєте її завтра, вам не потрібно «згадувати, що я там мав на увазі». Якщо ви хочете подивитися на неї свіжими очима, reviewer отримує короткий і перевірний пакет замість десяти екранів переписки. У цей момент довга AI-assisted задача перестає бути особистою таємницею автора і стає керованою інженерною роботою.

1
Опитування
Довгі задачі і Git-recovery у Claude Code, рівень 6, лекція 4
Недоступний
Довгі задачі і Git-recovery у Claude Code
Довгі задачі і Git-recovery у Claude Code
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ