JavaRush /Курси /Claude code /Обмеження та межі змін

Обмеження та межі змін

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

1. Без constraints task spec залишається проблемним

Після Goal, Current behavior, Desired behavior, Scope, Non-goals і Affected area чорновик тримає задачу: зрозуміло, що змінюється і де. Залишається прогалина — як саме Claude працює всередині цієї зони. Агент чесно лишається всередині refund flow і приносить зайве: нову залежність, широкий рефакторинг, правку старих міграцій, здогадку замість перевірки схеми. Для цього потрібні constraints — вони не змінюють мету, а обмежують спосіб її виконання.

Claude ламає проєкти не зі зла, а від надмірної старанності. Ви просите поле notes — отримуєте ще й новий пакет для rich-text редактора, «заодно» перероблений RefundService, схему події, кілька перейменувань і косметику по всьому нерівному коду. Формально корисно. Практично — відкриваєте diff і хапаєтеся за голову.

Слабке формулювання:

Додай поле `notes` у refund-request і збережи його.

Формулювання з першими нормальними межами:

Додай опційне поле `notes` у refund-request.
Не змінюй public API refund endpoints, окрім безпечного розширення payload.
Не додавай залежності.
Не чіпай payment processing і approval thresholds.
Спочатку запропонуй план, потім внось зміни.

У другому варіанті ви задаєте периметр руху. Constraints відповідають не на «що зробити», а на «які способи нам не підходять» — часто це важливіше. Goal дає напрям, scope — територію, constraints — таблички «сюди не заїжджати». Без них задача зрозуміла, але занадто вільна.

2. Constraints vs goal, scope і non-goals

Легко вирішити, що goal, scope, non-goals і constraints різними словами кажуть «не робіть дурниць». У кожного блоку своя робота.

Блок На яке запитання відповідає Як виглядає в задачі F-03
Goal Що має змінитися і навіщо У оператора з’являється поле notes, нотатка зберігається і видна в картці повернення
Scope Де можна працювати Форма refund-request, detail view, RefundService, подія refund.created, пов’язані тести
Non-goals Що свідомо не робимо Не змінюємо пороги auto/manual approval, не чіпаємо оплату, не рефакторимо сусідні модулі
Constraints Як не вийти за межі змін Не змінювати public API, не додавати залежності, не робити broad refactor, спочатку запропонувати план

- Goal — що змінюємо.

- Scope — де змінюємо.

- Non-goals — що не змінюємо.

- Constraints — як не порушити межі, поки змінюємо.

Найтонша різниця між non-goals і constraints. Non-goals — про область («не чіпаємо payment processing»). Constraints — про правило зміни, навіть якщо Claude вважатиме інакше «логічніше» («не додавати залежності без схвалення»).

Іноді фраза стоїть на межі. «Одна нова міграція і жодних правок старих» читається і як область, і як правило. Допомагає запитання: навіщо ви додаєте це речення? Щоб тема не розповзлася — це non-goals. Щоб обмежити спосіб зміни і ризик — це constraints.

3. Жорсткі обмеження для нашої задачі в Commerce OS

Не кожна задача потребує важкого набору обмежень. Помилку в заголовку кодексом не обкладають. Але задача з формою, збереженням даних, подією і базою — інша річ: тут constraints економлять нервові клітини.

Для маленької задачі вистачить tiny spec:

Виправ опечатку в заголовку refund detail view.
Не змінюй логіку і стилі поза цим компонентом.
Покажи diff після зміни.

Але F-03 — не tiny spec: UI, backend, збереження запису, подія, потенційно міграція бази. Обмеження потрібні чіткіше:

## Обмеження

- не змінювати public API refund endpoints; payload розширювати лише безпечно;
- не додавати нові залежності; використовувати наявний стек форм і валідації;
- не чіпати обробку платежів і пороги approval повернень;
- не змінювати не пов’язані міграції бази; за потреби створити лише одну нову міграцію;
- тримати diff невеликим і reviewable; без широкого рефакторингу RefundService;
- зберегти зворотну сумісність для наявних повернень без notes.

Чому саме ці рядки:

Public API — зовнішній контракт для інших частин системи та клієнтів. Тихо змінили структуру відповіді endpoint — зламали фронтенд і інтеграції. Розширювати payload безпечно можна: нове поле — так, стару поведінку ламати не можна.

Dependency — зовнішня бібліотека. Розв’язувати кожну задачу новим пакетом спокусливо, але в реальному коді це шафа з погано підписаними коробками.

Migration — зміна структури бази. Потрібне нове поле — одна міграція; старі, не пов’язані із задачею, не чіпаємо.

Diff — зміни «до/після»; reviewable — людина спокійно читає і перевіряє. Одне поле розрослося в двадцять файлів і helper на пів екрана — задача втратила форму. Claude задоволений, ревʼюер — ні.

4. Constraints бувають і поведінковими

Під constraints зазвичай уявляють заборони: «не змінюй», «не чіпай». Але частина найкорисніших — про ритм роботи, а не про заборону. Вони роблять поведінку Claude передбачуваною.

## Робочі обмеження

- спочатку вивчи поточну схему і файли, яких це стосується, потім редагуй;
- спочатку запропонуй короткий план;
- якщо щось неоднозначне, став запитання замість здогадок;
- після реалізації переліч зміни у файлах, виконані перевірки та ризики, що залишилися.

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

Це корисно, поки ви ще не впевнено почуваєтеся в проєкті. Пінг-понг перетворюється на цикл: досліджуй, виклади план, змінюй, звітуй. Нудно — у цьому і сила: передбачуваний процес рятує проєкт частіше, ніж «креативний прорив». «Якщо не впевнений — запитай» — не слабкість, а запит на менше галюцинацій. Хороший обмін.

5. Правила в CLAUDE.md і TASK_SPEC.md

Почнете писати обмеження — постає питання: куди яке формулювання складати? Частина правил повторюється від задачі до задачі, частина потрібна один раз. Усе в TASK_SPEC.md — він розростеться; усе в CLAUDE.md — задача розмивається.

Де живе правило Для чого підходить Приклад
CLAUDE.md
Стабільні правила всього проєкту «Використовуємо наявний стек», «не чіпаємо .env», «показуй changed files після правок»
TASK_SPEC.md
Обмеження лише для цієї задачі «Не змінювати approval thresholds», «одна нова міграція», «зберегти backward compatibility для refunds без notes»
Session/permission boundary Що Claude взагалі може робити в цій сесії Наприклад, режим без самостійних правок
Автоматичні технічні межі Реальна жорстка блокада дій Блокування чутливих шляхів, обов’язкові перевірки перед прийманням

Нас цікавлять перші два рівні. Правило: повторюється в усіх задачах — місце в CLAUDE.md; потрібне лише для конкретної — TASK_SPEC.md.

У CLAUDE.md:

## Правила проєкту

- використовуй наявні патерни Spring Boot і React;
- не додавай залежності без узгодження;
- завжди повідомляй про змінені файли і виконані команди;
- ніколи не чіпай `.env` і файли із секретами.

А це вже про конкретну F-03 — у TASK_SPEC.md:

## Обмеження

- не змінювати пороги approval повернень;
- створити лише одну міграцію для `notes`, якщо потрібна зміна схеми;
- зберегти наявну поведінку картки повернення для старих записів.

Важливо: constraints — не жорстка блокада. «Не чіпай оплату» не бетонна стіна, Claude теоретично все одно може полізти не туди. Писати даремно? Ні: це дорожній знак — відбійник він не замінює, але без нього гірше. Ми ставимо знаки і малюємо розмітку, і цього вже достатньо, щоб задача стала набагато безпечнішою.

6. Фіналізуємо TASK_SPEC.md для F-03

Зберемо робочий чорновик цілком. Той самий F-03, але в ньому зійшлися цільовий результат, поточна і бажана поведінка, поверхня змін та обмеження. Він не описує весь світ — дає Claude зрозумілий інженерний вхід без конкуруючих шаблонів.

# TASK_SPEC.md

## Мета
Дозволити оператору додавати необов’язкове поле `notes` під час створення
refund-request в адміністративному інтерфейсі. Нотатка має зберігатися
разом із записом повернення, відображатися в деталях повернення і потрапляти в
payload події `refund.created`, щоб фінансовий ревʼюер бачив контекст
рішення під час подальшого аудиту. Поточна логіка порогів авто- і ручного
підтвердження повернення не змінюється.

## Поточна поведінка
Оператор створює refund-request із `admin/orders/{id}`.
Немає поля, щоб прикріпити контекстну нотатку, наприклад:
«клієнт зателефонував, погодили часткове повернення».

Наразі нотатка зберігається в окремому коментарі до саппорт-трекера
і не пов’язана із записом повернення.

У результаті фінансові ревʼюери не бачать логіку оператора
під час подальшого аудиту повернень.

## Бажана поведінка
- форма refund-request в `admin/orders/{id}` містить необов’язкове поле `notes`
  (textarea, до 1000 символів);
- під час надсилання форми `notes` зберігається разом із записом повернення;
- у картці повернення нотатка відображається в окремій секції;
- payload події `refund.created` містить поле `notes`;
- наявні повернення без нотатки рендеряться коректно, без помилок.

## Область змін
- форма запиту повернення в адмінці;
- екран деталей повернення;
- збереження поля `notes` у записі refund;
- включення `notes` у подію `refund.created`;
- оновлення пов’язаних тестів і короткої внутрішньої документації.

## Не-цілі
- не змінювати пороги auto/manual approval;
- не чіпати обробку платежів та інтеграцію з PSP;
- не змінювати логіку зв’язування трекера і повернення;
- не рефакторити `RefundService` поза межами нового поля;
- не правити форматування поза переліченою зоною задачі.

## Затронута область (попередньо)
- форма повернення;
- екран деталей повернення;
- `RefundController` / `RefundService`;
- подія `refund.created`;
- схема `refunds` / нова міграція, якщо поле ще відсутнє;
- тести refund flow.

## Обмеження
- не змінювати public API refund endpoints; payload розширювати лише безпечно;
- не додавати нові залежності; використовувати наявний стек форм і валідації;
- не змінювати не пов’язані міграції бази; за потреби створити лише одну нову міграцію;
- тримати diff невеликим і reviewable; без широкого рефакторингу `RefundService`;
- зберегти зворотну сумісність для наявних повернень без notes;
- спочатку вивчи поточну схему і файли, яких це стосується, потім редагуй;
- спочатку запропонуй короткий план;
- якщо щось неоднозначне, став запитання замість здогадок;
- після реалізації переліч зміни у файлах, виконані перевірки та ризики, що залишилися.

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

Якщо на шляху залишаються неперевірені версії на кшталт «стовпець, можливо, вже є», їх зручно тримати як робочі нотатки для дослідження до перевірки, а не перетворювати на обов’язкові постійні заголовки. Формальні критерії приймання і повний план перевірки — це окремий шар над цією ж заготовкою, а не привід переписувати її заново.

І ось тут task spec остаточно перестає бути проханням «будь розумником» і стає нормальною інженерною постановкою. Не ідеальною, не магічною, не самодостатньою без людини — але достатньо чіткою, щоб Claude працював у межах зрозумілих рамок, а ви потім не дивувалися, звідки в задачі на одне поле взявся diff на пів кварталу.

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