1. Сирий тікет — це ще не задача
Дуже спокусливо відкрити issue, побачити знайомі слова на кшталт error, 500, не працює — і відразу попросити Claude «подивитися й пофіксити». Це дуже людське бажання, особливо коли хочеться відчувати себе продуктивним. Але саме тут і починається маленька інженерна катастрофа: коду ніхто не торкався, а ви вже лікуєте свою інтерпретацію проблеми.
Подивіться на типовий сирий тікет із Commerce OS:
# Issue #482
Не оформлюється замовлення, якщо кошик порожній.
На фронті показується загальна помилка.
Очікуємо зрозуміле повідомлення для користувача.
Мабуть, треба додати перевірку в OrderController.
Скріншот і stack trace додано.
На перший погляд усе зрозуміло. Але якщо придивитися уважніше, швидко стає видно: факти, очікування й чужа гіпотеза про реалізацію звалені докупи. Факт — замовлення не оформлюється. Факт — на фронті загальна помилка. Побажання — зрозуміле повідомлення. А фраза про OrderController — уже не вимога, а здогад автора, як саме це виправляти.
Саме тому сирий тікет не можна вважати готовою задачею. Він схожий на голосове повідомлення в сімейному чаті: емоцій багато, контекст втрачено, хто винен — незрозуміло. Ваше завдання — не «повірити тікету», а акуратно розібрати його на частини. Тоді зʼявляється артефакт для планування: Issue Intake Note, по суті чернетка TASK_SPEC.md, збагачена контекстом тікета.
Якщо пропустити цей крок, Claude майже напевно почне допомагати занадто завзято. Він побачить «додати перевірку в OrderController» і побіжить змінювати контролер, хоча проблема може жити в сервісі, у контракті API або в очікуваннях фронтенду. Фікс зроблено, коміт красивий, задача зрозуміла неправильно.
2. Вміст issue для розбору
Коли ви читаєте вхідну задачу як інженер, ви не намагаєтеся одразу вигадати рішення: спочатку збираєте з тікета відоме, а окремо позначаєте все, що поки залишається припущенням. Звучить сухо, але на практиці це сильно економить нерви — особливо коли до задачі підключається інша людина або її перевіряють свіжим поглядом.
Розбір issue зручно тримати в такій сітці:
| Що витягуємо | Що це означає | Навіщо це потрібно |
|---|---|---|
| Problem | Що спостережувано зламано або чого бракує | Щоб задача не розмивалася |
| User impact | Кому й чим заважає проблема | Щоб розуміти пріоритет і сценарій |
| Known evidence | Логи, скріншоти, stack trace, кроки відтворення | Щоб спиратися на факти |
| Requirements | Який результат справді потрібен | Щоб не лікувати не той біль |
| Assumptions | Що ми поки припускаємо, але не довели | Щоб не видавати здогад за факт |
| Open questions | Що ще потрібно уточнити | Щоб не писати план поверх невідомості |
| Out of scope | Що в задачу не входить | Щоб не було розповзання scope |
| Risk notes | Що можна випадково зламати | Щоб памʼятати про межі змін |
Дуже важливо помітити: хороший intake майже ніколи не буває «повністю заповненим від самого початку». Якщо після читання тікета у вас вийшов ідеально рівний документ без жодної assumption і без жодного open question, зазвичай це означає одне з двох: або тікет писала дуже дисциплінована людина, або ви повірили занадто швидко.
Наприклад, для нашого issue про порожній кошик користувацький ефект можна зафіксувати вже зараз: покупець не може завершити checkout, інтерфейс показує марну загальну помилку. Це важливо, тому що технічно баг — це NullPointerException, але з точки зору бізнесу справа зовсім в іншому: поганий UX і незрозуміло, що далі.
А от формулювання «має повертатися зрозуміле повідомлення» вже просить уточнень. Що означає «зрозуміле»? Потрібен код помилки? Очікуємо 400 Bad Request? Логувати як попередження? Нормальні open questions, соромитися їх не треба.
3. Симптом, причина та «улюблене рішення автора»
Саме тут найчастіше й захлопуються логічні пастки. Тікет майже завжди пише про симптом, іноді — про бажаний результат, а іноді ще й про «як це точно треба виправити». Звалите все в одну купу — отримаєте кашу, з якої народжуються дуже впевнені, але дуже криві плани.
Подивіться на різницю:
| Пара | Помилковий підхід | Нормальний інженерний підхід |
|---|---|---|
| Симптом vs причина | «500 помилка означає проблему в контролері» | «500 помилка — це симптом; причина поки невідома» |
| Requirement vs assumption | «Потрібно повернути 400, це очевидно» | «Ймовірно, потрібен 400, але це треба підтвердити» |
| Proposed solution vs real problem | «Автор сказав додати перевірку в OrderController — так і зробимо» | «Автор запропонував рішення; спочатку перевіримо, чи справді проблема там» |
Іноді автор тікета, QA або менеджер пише рішення просто тому, що так йому здається логічним. Це не погано, це навіть корисно — дає стартову гіпотезу. Але гіпотеза — не контракт. Запишете «Додати перевірку в OrderController» так, ніби це вже вимога, — і непомітно підміните задачу: замість «зробити поведінку коректною» вийде «змінити файл».
У нашому прикладі нормальний інженерний запис виглядає так:
Симптом: POST /api/orders з порожнім items[] приводить до 500.
Кандидат у кореневу причину: calculateTotal не обробляє empty list.
Статус: гіпотеза, потребує перевірки.
Цей короткий запис дуже цінний: він дисциплінує і вас, і Claude. Ви прямо говорите — ось що ми бачимо, ось що припускаємо, і не робите вигляд, ніби це одне й те саме. Інакше, якщо трохи самоіронічно, ви виправляєте не баг, а власну фантазію про баг.
Тут же корисно памʼятати про ще одну різницю: must-have проти nice-to-have. Для порожнього кошика must-have — коректна відповідь API та зрозуміла поведінка. А «заодно покращити текст помилки в трьох сусідніх сценаріях» — це вже додаткове покращення, яке легко зводить убік. Відокремлюйте одразу.
4. Збираємо Issue Intake Note для Commerce OS
Коли тікет уже розібрано на складові, час збирати це в документ: короткий, але корисний іншому інженеру, ревʼюеру й самому Claude. Хороший Issue Intake Note не переказує тікет, а перетворює його на робочу інженерну записку, з якої вже можна будувати план.
Схема тут проста:
flowchart LR
A[Сирий тікет] --> B[Факти та evidence]
B --> C[Assumptions і open questions]
C --> D[Issue Intake Note]
Базовий шаблон виглядає так:
# Нотатка про приймання issue
## Проблема
...
## Вплив на користувача
...
## Відомі докази
...
## Вимоги
...
## Припущення
...
## Відкриті питання
...
## Поза межами
...
## Нотатки про ризики
...
А ось так цей документ може виглядати вже в привʼязці до нашого issue:
# Нотатка про приймання issue
## Проблема
POST /api/orders повертає 500, якщо items[] порожній.
## Вплив на користувача
Покупець не може завершити оформлення замовлення й отримує загальну помилку
без зрозумілого пояснення.
## Відомі докази
- stack trace вказує на OrderService.calculateTotal
- баг відтворюється при POST /api/orders з порожнім items[]
## Вимоги
- користувач отримує зрозумілу реакцію на порожній кошик
- backend не падає з 500 у цьому сценарії
## Припущення
- очікуваний статус відповіді має бути 400
- порожній кошик вважається невалідним checkout-сценарієм
## Відкриті питання
- чи потрібен окремий код помилки EMPTY_CART?
- чи залежить фронтенд від поточного формату помилки?
## Поза межами
- редизайн кошика
- зміна логіки checkout для непорожнього кошика
## Нотатки про ризики
- зміна контракту помилки може зачепити frontend
Зверніть увагу: тут немає жодного передчасного технічного рішення. Ми не написали «змінювати OrderController» і не вдавали, ніби знаємо кореневу причину. Зате є все для наступного кроку.
І ще один маленький, але важливий нюанс. Assumptions і Open questions — це не «слабке місце документа», а навпаки, ознака зрілості. Поганий intake приховує невизначеність. Хороший — чесно її показує.
5. Claude Code як асистент аналізу
На цьому етапі Claude Code дуже корисний, але лише якщо ви правильно ставите йому задачу. Напишете «подивися issue й виправ» — він майже напевно перескочить через етап аналізу. А нам зараз потрібно зовсім інше: нехай Claude розбере тікет, але не торкається файлів і не перетворює гіпотези на нібито підтверджені факти.
Зручний запит може виглядати так:
Відкрий issue #482 через issue-tracker.
Не редагуй файли й не пропонуй фікс.
Склади чернетку Issue Intake Note.
Явно розділи:
1. підтверджені факти,
2. assumptions,
3. open questions.
Якщо в issue є запропоноване рішення, познач його як hypothesis.
Такий запит робить відразу три хороші речі: утримує Claude в аналітичному режимі, змушує явно позначати невизначеність, не дає сплутати запропоноване рішення з реальною проблемою.
Якщо у вас уже є skill issue-analysis, можна використовувати його як стандартну оболонку для такого розбору. Точні команди й способи виклику можуть трохи відрізнятися у вашій версії середовища, але звичка залишається тією самою: підтягнути issue в контекст, зібрати чернетку intake, потім читати її як інженер, а не як стенограму святого оракула.
Іноді корисно зробити другий прохід свіжим поглядом — наприклад, через reviewer-agent. Не для code review, а саме для перевірки якості intake:
Перевір чернетку Issue Intake Note.
Знайди місця, де assumption видано за факт.
Познач, якщо бракує user impact, out of scope або risk notes.
Файли не редагуй.
Тут Claude виступає вже не як автор, а як критик. Це хороший патерн: один AI збирає матеріал, другий перевіряє межі. Але фінальне рішення все одно залишається за вами. Reviewer пише «Ймовірно, потрібен статус 400» — це не робить 400 істиною. Це лише привід або підтвердити далі, або зафіксувати як assumption.
Корисно також памʼятати, що intake — не місце для довгого технічного розслідування. Якщо Claude починає розписувати пів сторінки про архітектуру сервісу й можливий рефакторинг, мʼяко поверніть його назад: зараз ми не лікуємо систему, а наводимо лад у вхідному хаосі.
6. Ознаки готового до планування intake
Найприємніший момент у цій роботі — коли з неохайного тікета раптом виходить документ, з яким уже не страшно жити. І тут важливо не шукати абстрактну досконалість, а перевірити, чи витримує ваш intake кілька дуже практичних запитань.
| Питання до документа | Якщо відповідь «ні» |
|---|---|
| Чи зрозуміло, що саме зламалося або чого не вистачає? | Отже, Problem сформульовано розпливчасто |
| Чи зрозуміло, хто страждає й як це проявляється? | Отже, втрачено User impact |
| Чи видно, де факт, а де гіпотеза? | Отже, змішані Known evidence і Assumptions |
| Чи зафіксовано, що в задачу не входить? | Отже, високий ризик scope creep |
| Чи є хоча б первинне розуміння ризиків? | Отже, план потім буде занадто наївним |
Є й ще один, майже побутовий тест. Якщо після читання Issue Intake Note іншому інженеру не хочеться запитати «постривайте, а що взагалі мається на увазі?» — отже, ви вже сильно просунулися. А якщо документ читається окремо від тікета, без біганини очима туди-сюди, — отже, він справді працює як вхідний інженерний артефакт.
У цей момент задача перестає бути емоційною нотаткою в трекері й стає чернеткою інженерного контракту. Далі задача йде не одразу в план, а в read-only investigation: пройтися по коду, перевірити маршрут, тести й точки зміни, щоб припущення перестали бути здогадками. План зʼявляється вже після цього проходу по фактах.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ