Планування роботи
Вертикальні зрізи: невеликий, але наскрізний результат
Вертикальний зріз — це обмежена частина функції, яка проводить одну змістовну поведінку через потрібні частини системи й дає змогу перевірити конкретний…
Вертикальний зріз — це обмежена частина функції, яка проводить одну змістовну поведінку через потрібні частини системи й дає змогу перевірити конкретний результат. Наприклад, клієнт бачить своє майбутнє бронювання з правильним часом і не бачить записів інших людей. Для цього може знадобитися екран, серверна перевірка доступу, читання даних і тест. Якщо наявний інтерфейс уже придатний, новий екран не потрібен; якщо інформація зберігається в тій самій таблиці, окрема міграція теж може бути зайвою.
Вертикальність описує цілісність поведінки, а не обов’язкову кількість папок, компонентів чи сервісів. Мета — рано довести до зрозумілого стану невелике важливе припущення, а не вкласти в кожну задачу формально повний набір технічних шарів.
У цьому розділі використано умовну службу бронювання. Імена, дати, суми, відповіді системи й показники вигадані для навчання; вони не є фактами про реальну компанію.
Після розділу читач може:
- відрізнити горизонтальний технічний етап від перевірюваного вертикального зрізу;
- назвати користувацьку поведінку, межу обсягу й докази приймання одного зрізу;
- зменшити обсяг функції, зберігши її коректність, доступ і захист даних;
- виявити технічні передумови, спільні контракти й порядок інтеграції;
- відрізнити готовність коду до перевірки від готовності показати функцію користувачам;
- застосувати принцип малих партій і до агентської роботи, не вважаючи малий набір змінених рядків доказом правильності.
19.1. Що саме проходить «вертикально»
У системі бронювання можна провести горизонтальні межі за типом роботи:
- додати поле статусу до бази даних;
- реалізувати серверні операції;
- намалювати сторінки;
- пізніше з’єднати все разом.
Кожен крок може бути потрібним, але після перших трьох клієнт іще не обов’язково здатен виконати дію. Поле існує, сервер має маршрут, екран намальований — та немає завершеного сценарію, який поєднав їх так, щоб людина одержала потрібний результат. Це ситуація, де «багато зроблено» не тотожне «одна річ працює».
У вертикальному зрізі командна межа проходить через поведінку. Наприклад: «Клієнт відкриває сторінку, бачить дату й час свого наступного бронювання у визначеному часовому поясі; якщо бронювання немає, система пояснює це; чужий запис не розкривається». Зріз може охопити маршрутизацію, авторизацію, запит до бази, подання й перевірку. Але не мусить змінювати всі ці складові: якщо база вже зберігає потрібні дані, робота над схемою не додає цінності.
| Запитання | Горизонтальна купа роботи | Перевірюваний зріз |
|---|---|---|
| Що завершуємо? | Шар або технологічний компонент | Поведінку з названим споживачем |
| Що можна показати чи перевірити? | Часто тільки внутрішню деталь | Конкретний позитивний та негативний сценарій |
| Який ранній сигнал отримуємо? | Компіляція чи перевірка окремої частини | Чи працює важливий шлях і чи узгоджені частини |
| Що може виявити робота? | Помилку всередині одного компонента | Неправильне припущення на стику компонентів |
Ця таблиця не принижує технічну роботу. Схема даних, доступність, резервне копіювання, інструмент спостереження чи оновлення бібліотеки можуть самі бути важливим результатом. Питання лише в тому, чи назвали ми реальну мету і чи відповідає одиниця роботи цій меті.
Вертикальний зріз — не обов’язково зміна видимого інтерфейсу. Наприклад, ізольована серверна операція з гарантованим ідемпотентним повтором може бути завершеною й перевірюваною можливістю для іншого сервісу. Натомість гарна кнопка, що поки не виконує дію, може бути прототипом, але не завершеною функцією. Назва одиниці роботи має відповідати тому, що готове насправді.
19.2. Зріз починається з обіцянки користувачу
Перед поділом на технічні кроки сформулюйте речення: «Хто може зробити що, за яких умов, і як зрозуміти результат?» Це зовнішній край зрізу — видима або споживана поведінка. Наприклад:
Авторизований клієнт бачить одне актуальне майбутнє бронювання зі своїм підтвердженим часом і часовим поясом. Якщо майбутнього запису немає, система показує це без вигаданих деталей. Клієнт не може прочитати бронювання іншої особи, підмінивши ідентифікатор.
У цій обіцянці є позитивний результат, порожній стан і межа безпеки. Далі з’ясуйте, як система визначає клієнта й авторитетний час, що показує у станах «немає даних» і «дані застаріли», та який доказ підтвердить перевірку доступу. Компонентні запитання допомагають знайти потрібні рішення:
- де система визначає поточного клієнта;
- як знаходить саме його найближче майбутнє бронювання;
- яке поле задає авторитетний час і чи є визначеним часовий пояс або правило перетворення;
- як виглядає сторінка або відповідь для наявного споживача;
- що побачить клієнт без бронювання або з застарілими даними;
- як перевірка доведе, що підміна чужого ідентифікатора не відкриває даних.
Це пошук необхідних правил і доказу, а не готовий список технологічних задач. Потрібне поле може вже бути доступним через серверний метод, тож зміна бази відпаде; або неоднозначне поле часу потребуватиме окремого уточнення джерела істини. Контроль доступу та коректність даних не є необов’язковим обсягом.
Не додавайте дії лише тому, що вони «логічно поруч»: перегляд не означає перенесення, оплату, повідомлення, календарний експорт, адміністративне редагування чи звітність. Обов’язкове ядро — правильний час, перевірка власника й чесний стан «бронювання немає»; експорт календаря може зачекати. У главі 12 Shape Up автор позначає необов’язкові поліпшення символом тильди (~). Повний приклад із доказами — у §19.7.
19.3. Чим малий зріз відрізняється від малої кількості рядків
Десяток змінених рядків може ламати критичну перевірку прав. Великий перелік змін може містити ізольовані переклади, потрібне перейменування чи механічне оновлення. Розмір зміни впливає на складність огляду, але не є мірою впливу, повноти або безпечності.
Корисний зріз невеликий за невизначеністю та наслідками незавершеності:
- людина може описати, що вже працює;
- команда знає, кому це допомагає;
- результат має видиму межу;
- невиконана частина функції не маскується під завершену;
- важливу поведінку можна перевірити, навіть якщо наступне розширення відбудеться пізніше.
Це і відрізняє малу партію роботи від «маленького квитка». «Створити об’єкт для передавання даних», «намалювати картку» або «додати поле» можуть бути кроками реалізації. Вони стають самостійними зрізами тільки тоді, коли для них є окремий споживач, операційна користь або цілеспрямований доказ ризику. Якщо цього немає, краще показати їх як частини батьківського сценарію.
19.4. Яку частину зробити першою
Команда часто не знає, з якого кінця почати. У главі 11 Shape Up автор Ryan Singer описує власний приклад функції доступу клієнтів до окремих матеріалів проекту Basecamp. Команда вибрала перемикач видимості як ранню точку інтеграції: дизайнер перевірив спосіб взаємодії, програміст одночасно дослідив модель доступу, а потім перемикач було пов’язано зі збереженням. Автор описує це як конкретний досвід Basecamp, а не гарантований порядок для будь-якого продукту.
Звідси практичні запитання, не універсальний рейтинг:
- Чи є ця поведінка центральною? Якщо її немає, чи лишається цільова функція осмисленою?
- Чи мала її межа? Чи може команда відокремити результат, не імітуючи недороблене ціле?
- Чи знімає вона суттєву невідомість? Наприклад, чи зрозуміє клієнт, який текст означає «бронювання підтверджено»?
- Чи можна побачити реальну інтеграцію? Самі макет, схема або тимчасова заглушка можуть приховати важливу проблему.
- Що буде, якщо перевірка не підтвердить припущення? Чи зможемо ми змінити напрям до того, як інвестували в інші залежні частини?
Перевірка центрального ризику не завжди має першою стати функція, яку можна віддати користувачу. Наприклад, перевірка договору постачальника оплати може завершитися висновком і рішенням, а не кнопкою. Для вибору першого кроку корисніше знати, яке припущення може змінити напрям роботи, ніж механічно прагнути демонстраційного екрану.
Shape Up розрізняє цілісну частину, яку можна показати, та список частково готових елементів; також застерігає від очікування великої інтеграції наприкінці. Слова автора про демо не слід трактувати як вимогу показувати кожну функцію зовнішнім клієнтам. Демонстрація команді, перевірка тестом, обмежене внутрішнє розгортання та публічне включення — різні події.
19.5. Зменшуйте обсяг, а не гарантії
Обсяг можна звузити, зберігаючи правильну поведінку. Можна підтримати спершу один тип користувача, одну операцію, один канал, просте правило або обмежений діапазон даних. Важливо чітко назвати, що тепер працює, кому і за яких умов.
Для бронювання можливі такі обмеження:
- показати лише наступне майбутнє бронювання, а не всю історію;
- показати спершу клієнту його дані, а не розробити адміністративну панель;
- підтримати один погоджений часовий пояс представлення, якщо правило системи це дозволяє;
- відкласти календарний експорт, автоматичні нагадування й фільтри;
- використати чинний механізм автентифікації замість створення нового способу входу.
Це обмежує цільову функцію. Воно не дозволяє пропустити перевірку власника, приховати непідтверджену дату чи віддати персональні дані через неперевірений параметр.
Дві версії «спростити скасування»
Безпечне звуження обмежує скасування погодженим сценарієм, але сервер усе одно перевіряє власника й поточний стан та показує результат лише після збереження зміни. Небезпечне обрізання ховає кнопку від сторонніх, але дозволяє серверу прийняти підставлений ідентифікатор або показати успіх без збереженої зміни. Докладний приклад меж і повторних запитів наведено в 19.8.
MVP (Minimum Viable Product — мінімально життєздатний продукт) — обмежений спосіб перевірити гіпотезу, а не привід прибирати коректність. Якщо безпечне скасування ще неможливе, перший результат може дозволяти лише перегляд і звернення до працівника.
Безпечне звуження. Скасування спершу дозволене тільки клієнту для власного бронювання, яке має статус «підтверджено» і починається пізніше ніж через 24 години. Команда відкладе скасування через працівника, зміну часу, повернення коштів та виняток для термінових випадків. Сервер перевіряє власника, поточний стан і часову межу; при гонці між двома запитами лише один коректно змінює запис. Клієнт бачить остаточний стан.
Небезпечне обрізання. Щоб швидше показати кнопку, команда приховує її в інтерфейсі для чужих бронювань, але сервер приймає підставлений ідентифікатор і змінює будь-який запис. Візуальне обмеження не є контролем доступу. Так само не можна зберігати дію як успішну, якщо база не підтвердила зміну.
MVP (Minimum Viable Product — мінімально життєздатний продукт) означає обмежену можливість перевірити гіпотезу, а не загальне право прибрати перевірку коректності. Малий результат лишається мінімально придатним для своєї обіцянки. Якщо система поки не підтримує безпечне скасування, чесний перший результат може бути лише переглядом із каналом звернення, а не імітацією скасування.
19.6. Незалежні частини — не розподіл за фахом
У Shape Up глава 12 радить ділити роботу за змістовними межами й залежностями, а не за ролями на кшталт «дизайн», «сервер» і «база». Для скасування бронювання можна окремо уточнити правило й погодити контракт між сервером та інтерфейсом; саме по собі «переробити всі моделі» не називає завершеного результату.
Не кожна область потребує окремого квитка, а сам поділ не задає чергу: сервер та інтерфейс можуть готуватися паралельно навколо спільного контракту. Незалежність реалізації не означає незалежності розгортання — спільна схема, дані чи формат помилки можуть вимагати узгодженого випуску; порядок залежностей докладніше розглядає глава 20.
У Shape Up глава 12 пропонує відображати реальні межі й залежності в роботі, а не креслити план за ролями «дизайн», «сервер», «база». Область роботи корисна, коли її можна завершити окремо й зрозуміло сказати, що вона змінила. Наприклад, «видимість одного типу повідомлення для клієнта» може бути змістовною областю; «усі моделі даних» — це технологічна категорія, не користувацький результат.
Команда не мусить надавати кожній області окремий номер задачі. Іноді одна команда разом змінює сервер і сторінку в одному зрізі; інколи загальний контракт та спільна міграція об’єднують роботи, які технічно торкаються різних каталогів. Декомпозиція — спосіб зробити залежність і результат зрозумілими, а не бюрократична вимога на більше квитків.
Умовна функція «клієнт скасовує власне бронювання» може мати такі області:
- Знайти правило. Власник продукту підтверджує межі часу, статуси й можливий вплив на оплату; команда фіксує, що ще не вирішено.
- Безпечна серверна зміна. Для одного дозволеного статусу сервер атомарно перевіряє власника, стан і часову умову, зберігає результат і повертає його клієнту.
- Доступний шлях для клієнта. На сторінці підтвердженого бронювання відображено умови скасування, запит на підтвердження та кінцевий статус.
- Спостережуваний результат. У межах визначеної політики команда може з’ясувати, скільки спроб пройшли, скільки відхилилися та чи є помилки, не зберігаючи зайві чутливі дані.
Це не обов’язкова черга «спершу сервер, потім інтерфейс». Уточнення правила може виявити, що самообслуговуване скасування без обробки повернення платежу взагалі не можна включати. Серверний контракт і форма підтвердження можуть паралельно прояснювати один одного. Важливо не заявити готовність сценарію, доки його межі не підтримують кінцевий результат.
Список областей також не обов’язково дорівнює списку незалежних релізів. Їх можуть з’єднувати одна схема, спільний компонент, дані або домовленість про помилку. Незалежність означає можливість завершити частину без прихованої незавершеної залежності, а не те, що її можна безпечно розгорнути чи віддати користувачам ізольовано.
19.7. Повний приклад: перегляд власного майбутнього бронювання
На прикладі умовної системи бронювання перевіримо зріз для перегляду наступного запису.
Потреба та межа
Користувацький результат. Після входу клієнт може перевірити час найближчого майбутнього бронювання, на яке має право.
У зріз входить:
- визначення поточного клієнта перевіреним механізмом автентифікації;
- пошук тільки його майбутнього бронювання;
- показ підтвердженого часу із визначеним часовим поясом або недвозначним правилом відображення;
- зрозумілий стан, коли майбутнього бронювання немає;
- серверна перевірка доступу навіть за підміни ідентифікатора у запиті;
- перевірки позитивного й негативного сценарію та фактичного джерела даних.
Поза межами:
створення, перенесення й скасування запису, оплата, експорт календаря, історія та адміністративне редагування.
Мінімальна карта контракту
| Умова | Очікувана поведінка |
|---|---|
| Клієнт увійшов і має майбутній запис | Показати правильне бронювання і підтверджений час |
| Клієнт увійшов, майбутнього запису немає | Показати стан «майбутніх бронювань немає» |
| Неавторизована людина | Не видати приватні дані; застосувати визначену системою політику входу |
| Клієнт передає ідентифікатор іншого запису | Не розкрити його дані; не покладатися на приховану кнопку |
| Час у базі не можна перетворити за правилом | Показати контрольовану помилку |
| Дані застаріли через паралельну зміну | Оновити дані або пояснити фактичний стан |
Команда має з’ясувати, чи маршрут взагалі приймає ідентифікатор бронювання. Якщо поточний сервер дістає власника з сесії й сам обирає один дозволений запис, негативний тест на підміну може перевіряти іншу наявну операцію або серверний запит доступу. Не слід додавати небезпечний параметр лише для того, щоб у прикладі був «тест на підміну».
Якщо час неможливо перетворити, помилка має бути контрольованою й діагностованою без зайвих персональних даних. Після паралельної зміни старий час не можна називати підтвердженим: система перечитує запис або пояснює його фактичний стан.
| Час у базі не може бути перетворений за правилом | Показати контрольовану помилку й записати діагностичний факт без зайвої персональної інформації | | Дані застаріли через паралельну зміну | Не називати старий час новим підтвердженим часом; повторно прочитати або пояснити фактичний стан |
Реалізація як послідовність перевірюваних доказів
Спершу називають джерело істини для часу й способу встановити власника. Потім простежують один запит від активної сесії до запису й назад до представлення. Якщо шар доступу до даних повертає список усіх майбутніх записів, а серверний маршрут сподівається, що інтерфейс відфільтрує чужі, межа доступу стоїть неправильно.
Перевірка даних має використовувати два різні набори: один клієнт із власним записом та інший власник із окремим записом. У прикладі перевірка підтверджує, що сесія першого клієнта не дає прочитати другий запис. Звичайне твердження «сторінка повернула 200» цього не доводить. Сторінка, яка показує чужі дані зі статусом 200, технічно відповіла, але порушила результат.
Перевірка відсутності запису має переконатися, що порожній список не відображається як неіснуюча помилка. Відповідь користувачу і лог для діагностики можуть відрізнятися: зовнішній текст не має розкривати SQL (Structured Query Language — мова структурованих запитів), інші записи або внутрішній токен.
У підсумку перший зріз справді може бути невеликим: «побачити свій наступний запис». Він не обіцяє повну систему бронювання. Він закінчений для своєї заявленої поведінки й залишає перенесення та скасування для окремих рішень.
Уявімо, що клієнти телефонують студії, щоб уточнити час наступного запису. Це вигаданий навчальний мотив, а не вимірювання реального сервісу. Команда хоче дати клієнту доступ до бронювання у вебзастосунку.
19.8. Повний приклад: скасування без «кнопки, яка робить вигляд»
Тепер команда додає ще одну дію до того самого продукту. Власниця бізнес-рішення визначила, що клієнт може самостійно скасувати власний підтверджений запис, якщо до початку більше доби. Повернення оплати до цього правила не входить: бронювання в прикладі неоплачене. Правило про платні бронювання не можна переносити сюди припущенням.
Обіцянка
Клієнт переглядає власний майбутній запис, бачить умову скасування й підтверджує дію. Система записує перехід стану, показує результат і не скасовує бронювання іншої людини. Після початку запису скасування за цим каналом відхиляється. Повторний запит не створює кілька різних станів.
До початку реалізації треба визначити граничний час, зону часу, дозволені стани та повторення запиту. Якщо запис рівно за 24 години, правило має однозначно сказати, що станеться. Якщо паралельно надходить скасування з адміністративного каналу або запис уже змінено, сервер перевіряє поточний стан у момент зміни, а не лише під час відкриття сторінки.
Перевірка власника, статусу й часової межі та зміна стану мають бути атомарними: якщо інший запит устиг змінити запис, цей перехід відхиляється або повертає фактичний стан без заяви, що поточний запит його скасував.
Перевірювані приклади
| Ситуація | Результат |
|---|---|
| Власник скасовує підтверджений запис за 30 годин | Статус змінено на «скасовано», користувач бачить результат |
| До початку запису рівно 24 години | Відмовити: правило дозволяє скасування лише коли лишилося більше доби |
| Власник скасовує запис за 10 годин | Відмовити згідно з правилом; статус не змінено |
| Сторонній користувач намагається скасувати | Не змінювати запис; відповідь не видає його приватні деталі |
| Повтор запиту після вже успішного скасування | Повернути визначений кінцевий стан або безпечну відмову без другої побічної дії |
| Запис уже завершився або раніше скасований | Не перезаписати попередній стан довільно |
| У той самий момент адміністратор змінив запис | Показати фактичний збережений стан, не стверджувати, що клієнт змінив його |
Покажіть фактичний збережений стан. Сповіщення можна відкласти лише якщо бізнесове правило його не вимагає; інакше без нього обіцянка неповна.
Статус, що зберігається, — тільки частина результату. Інтерфейс має пояснити наслідок дії, а логічна перевірка — довести власника, дозволений перехід і збереження кінцевого стану. Сповіщення може бути відкладеним додатком, але якщо політика бізнесу вимагає підтвердження скасування, то без нього обіцянка неповна; «спростити MVP» не скасовує затвердженої вимоги.
Що тут означає «якісно скоротити»
Першу версію можна обмежити одним статусом і каналом, відкласти адміністративне керування та не включати платні бронювання, доки не визначено повернення коштів. Таке звуження не прибирає узгоджених із бізнесом вимог і має показувати фактичний збережений стан.
Якщо власник процесу ще не визначив часову межу або платіжні наслідки, повноцінним результатом поточного етапу може бути документований варіант правила, обмежена технічна розвідка інтеграції чи обмежений перегляд. Він не повинен видаватися за готове скасування. Незавершене припущення краще видно в рішенні, ніж заховане в коді.
Можна почати з одного статусу та одного каналу; не надавати адміністративне керування; не підтримувати платне бронювання до вирішення повернень; не відправляти кілька видів сповіщень, якщо користувацький контракт не обіцяє їх. Не можна пропускати серверний контроль власника чи зберегти кнопку, що завжди показує «скасовано», незалежно від відповіді сховища.
19.9. Технічні передумови та нескінченний фундамент
Інколи потрібен технічний крок до першої завершеної можливості. Наприклад, сервіс бронювання не має достовірного способу визначити власника, база не зберігає часовий пояс, або міграція обов’язкового поля зупинить стару версію застосунку. Такий крок може бути потрібним. Але для нього слід назвати питання, яке він розв’язує, потрібну межу та спосіб з’ясувати, що передумова справді виконана.
Порівняймо:
- «Перебудувати систему доступу» — зміна без видимого критерію завершення.
- «Встановити й продемонструвати, що сервер може безпечно отримати поточного клієнта, а запит до таблиці повертає тільки його майбутній запис; якщо ні — визначити блокер і рішення» — обмежений результат.
Технічна передумова може мати тест, аналіз схеми, прототип сумісної міграції, замір, конфігурацію середовища або документований висновок. Вона не мусить бути релізною функцією. Її доказ відповідає на власне питання й має не симулювати користувацьке завершення.
Для міграції даних важливо врахувати версії, які перетинаються під час розгортання. Поширений шаблон із додаванням нового поля, поступовим заповненням і подальшою відмовою від старого поля може бути доречним, але не завжди. Спершу з’ясовують розмір даних, правила відкату, поведінку старого коду й наявність дублювання. Додавати інфраструктуру «на майбутнє» до кожної маленької функції — не доказ обережності, якщо немає конкретної загрози чи користі.
Окрема технічна розвідка також не гарантує, що наступна задача піде без ризику. Ця розвідка зменшує невідомість лише настільки, наскільки її спостереження стосуються реальної системи. Перевірка на моках, наприклад, не підтверджує поведінку реального постачальника оплати. Документуйте умови, за яких висновок дійсний.
19.10. Контракти, сумісність і порядок інтеграції
Два зрізи можуть виглядати незалежними, але змінювати спільний контракт. Узгодьте типи ідентифікаторів, значення полів, статуси й дозволені переходи, формати запитів, повідомлень і помилок, власника перевірки доступу та сумісність версій API (Application Programming Interface — програмний інтерфейс взаємодії) і міграцій.
Умовний конфлікт двох змін
Агент А додає серверний маршрут для скасування. Він повертає об’єкт у форматі JSON (JavaScript Object Notation — формат текстового подання структурованих даних) із полем «status» зі значенням «cancelled». Агент Б додає екран, очікуючи поле «state» зі значенням «canceled». Кожна гілка має власний тест: серверний перевіряє першу форму відповіді, інтерфейсний тест використовує тестову заглушку з другою формою. У кожній гілці перевірка зелена, бо вона відтворює лише власне припущення. Після інтеграції клієнт не читає потрібного поля.
Це приклад прихованої залежності, а не конкретна реальна подія. Тести ізольованих частин не доводять узгодженості контракту. До паралельної роботи команда фіксує одну схему відповіді та додає перевірку реальної межі або спільний контрактний тест між споживачем і постачальником. Після інтеграції перевіряє саме той шлях, який сполучає API з інтерфейсом.
Тут також є розрізнення між незалежністю реалізації й незалежністю розгортання. Два розробники можуть писати код паралельно, якщо домовилися про формат контракту. Але їхні зміни можуть вимагати спільного випуску, якщо старий сервер не розуміє нове поле або новий клієнт не знає попередній статус. І навпаки: одна гілка може містити кілька компонентів, але нова функція може залишатися вимкненою до підготовки сумісності.
Зафіксуйте контракт і залежності, визначте власника інтеграції та перевірте з’єднаний сценарій із реальною частиною системи. Якщо старі й нові версії можуть співіснувати, перевірте їхню сумісність; готовність коду до розгортання й доступність для користувачів мають окремі критерії.
Практичний порядок:
- Зафіксувати зовнішню поведінку та контракт, до якого прив’язуються частини.
- Назвати технічну залежність, власника її вирішення та спосіб перевірки.
- З’ясувати, чи має спершу бути розгорнутий сумісний читач, записувач, схема чи прапорець.
- Зробити одну інтегровану зміну й перевірити її з іншою реальною частиною системи, не тільки з тестовою заглушкою.
- Перевірити стару й нову сумісність у тих станах, де версії можуть співіснувати.
- Розгортати та відкривати для користувачів за окремими, узгодженими критеріями.
Це не універсальна послідовність компонентів. Вона нагадує, які питання не можна вгадати з назв файлів. Якщо контракти не впливають один на одного, паралельність допустима; якщо впливають, паралельно можна готувати роботу, але інтеграцію не оголошують виконаною до перевірки спільної поведінки.
Два зрізи можуть виглядати незалежними, але змінювати спільний контракт. Перевірте не лише перелік файлів, а й те, що одна частина обіцяє іншій:
- назви й семантику полів;
- ідентифікатори та їхні типи;
- статуси і дозволені переходи;
- повідомлення та формат помилок;
- власника відповідальності за перевірку доступу;
- версію API (Application Programming Interface — програмний інтерфейс взаємодії), повідомлення події чи схему бази;
- вимоги до порядку міграцій та випуску.
19.11. Критерії приймання — це докази поведінки
Для кожного зрізу потрібні очікуваний результат, важливі відмови й достатнє свідчення. Упевненість агента, вигляд сторінки або ізольовані зелені тести не доводять, що дані, доступ і спільний контракт працюють у застосунку. Перед реалізацією погодьте:
- початкові умови, учасника й межу сценарію;
- дію та дані, які вона читає або змінює;
- позитивний кінцевий стан і заборонений чи невалідний випадок;
- що користувач побачить при очікуваній помилці;
- як перевірити, що стан збережено або не змінено;
- зовнішні залежності й спосіб відрізнити їхню недоступність від порожніх даних чи відмови в доступі;
- що не входить до поставки.
| Вид свідчення | Що підтверджує | Чого сам по собі не підтверджує |
|---|---|---|
| Огляд інтерфейсу | Текст, розміщення і шлях взаємодії | Права доступу чи збереження |
| Модульний тест | Локальне правило в заданих умовах | Сумісність цілого сценарію або дані в продукції |
| Інтеграційна перевірка | Взаємодію кількох частин і спільний контракт | Коректність невипробуваних граничних правил |
| Тест дозволів | Визначену політику в обраних випадках | Відсутність усіх можливих витоків |
| Розгортання в обмеженому середовищі | Роботу конфігурації й обраного шляху | Фактичне використання чи вигоду всіх клієнтів |
| Відгук користувача або спостереження | Реакцію на доступну поведінку | Причину зміни показника без окремого аналізу |
Обирайте свідчення за ризиком: текстову підказку можна перевірити оглядом і навігацією, а скасування — доступом, дозволеним переходом, збереженим результатом і відмовою. Для повтору платежу окремо перевіряйте ідемпотентність та невизначену мережеву відповідь; універсальний чекліст не замінює судження про наслідки.
Наприклад, якщо постачальник даних про бронювання відповів тайм-аутом, клієнт має побачити тимчасову помилку завантаження, а не хибне «майбутнього бронювання немає». Читання не змінює стану, а система не показує успіх. Інтеграційна перевірка з навмисним тайм-аутом підтверджує, що відповідь відрізняється від порожнього результату, записів до сховища немає, а діагностика містить ідентифікатор запиту, залежність і час без персональних даних.
У критерії включайте передумови так, щоб наступний читач або агент міг їх відтворити. «Скасувати власне майбутнє бронювання» ще не визначає часової межі, статусу чи повтору. Якщо це невідомо, позначте його як рішення або обмежену розвідку, а не змушуйте виконавця вгадувати.
19.12. Готове до включення — не завжди готове для користувача
Готовий зріз може бути злитим, розгорнутим, увімкненим частині аудиторії або повністю доступним. Це різні стани. Feature flag (прапорець функції) може відокремити наявність коду від доступності поведінки. Наприклад, маршрут уже є в системі, але показаний лише внутрішнім обліковим записам до перевірки журналів і міграції. Це корисно тільки за правильно визначеної межі, власника й плану прибирання прапорця.
Прапорець не виправляє несумісну схему. Якщо розгортання коду запускає руйнівну міграцію або змінює обов’язкове поле для старих клієнтів, схована кнопка не захистить від збоїв у базі. Перевірте окремо:
- чи безпечне саме розгортання;
- чи можуть стара й нова версії працювати поруч;
- що контролює прапорець: сервер, інтерфейс, конкретна роль чи середовище;
- чи не витікають дані через API, навіть коли екран прихований;
- що дасть вимкнення прапорця після появи даних нового формату;
- коли прапорець буде видалений або остаточно затверджений.
Поняття «готово» має називати свій поріг. «Перевірено на тестовому середовищі», «готове до включення для співробітників», «пройшло обмежений випуск», «готове для всіх клієнтів» — ясніші фрази, ніж одне непояснене «done». Не називайте перший стан останнім, якщо потрібний власник або перевірка ще попереду.
19.13. Малі партії, інтеграція та зворотний зв’язок
DORA (DevOps Research and Assessment — дослідницька програма Google Cloud про розробку, постачання й експлуатацію програмного забезпечення) у звіті за 2023 рік наголошує на потребах користувачів і балансі постачання програмного забезпечення з операційними результатами. Їхня пізніша рекомендація описує малі партії як спосіб скоротити затримку зворотного зв’язку й радить робити одиниці незалежними, цінними, невеликими та перевірюваними. Це рекомендаційна модель, а не обіцянка, що будь-яке завдання вміститься в день або що малий розмір усуне дефекти.
Користь зменшується, якщо команда знову збирає партії у великий пакет перед тестуванням чи випуском: зворотний зв’язок приходить пізно, а реагувати на проблеми складніше. Спершу визначте потрібні для класу змін контролі, а потім оберіть малу одиницю, яку можна перевірити. Малий diff легше оглянути, але він не доводить правильності: потрібні перевірки за ризиком із 19.11, а частий випуск сам по собі не є метою. Звіт і рекомендація не гарантують однакової користі для кожної зміни.
Невеликий перелік змін допомагає людині побачити зміну та її контекст. Він не доводить, що:
- не порушено важливий інваріант;
- перевірки охоплюють неправильний і позитивний випадки;
- дві незалежні гілки узгодили формат;
- міграція сумісна з розгорнутою версією;
- реалізація дає саме продуктове значення;
- помилковий результат помітять після випуску.
Кожну з цих умов перевіряють відповідним доказом. DORA пов’язує малі партії з іншими практиками, як-от безперервною інтеграцією та зворотним зв’язком; не можна приписувати одній мірі всю причинність із досліджень.
19.14. Реальний приклад невеликого наскрізного виправлення
У FastAPI pull request (PR — запит на зміну до репозиторію) #14306 «Improve tracebacks by adding endpoint metadata» додав контекст маршруту до повідомлень про помилки перевірки даних. Зміна торкалася формування помилки, передачі контексту кінцевої точки та перевірок HTTP (Hypertext Transfer Protocol — протокол передавання гіпертексту), WebSocket і змонтованих підзастосунків. У порівнянні змін цього запиту було 289 доданих і 16 вилучених рядків у трьох файлах; автор додав окремі регресійні приклади для запиту, відповіді, WebSocket та підзастосунків. Pull request об’єднано 6 грудня 2025 року.
Це не приклад функції з новою користувацькою кнопкою. Його обмежений результат — діагностичний контекст помилки з назвою маршруту й функції, без зміни стандартної клієнтської відповіді. Регресійні тести охоплювали обчислення метаданих, винятки, логування, запити, відповіді, WebSocket, підзастосунки й випадки без повного контексту. Так межа поведінки проходила через кілька пов’язаних потоків, а не один технічний шар.
PR також має обмеження як джерело. Його власні бенчмарки, що містяться в описі, не є незалежно перевіреним вимірюванням; зміна не доводить, що кожен невеликий PR легко переглядати; злиття не виключає наступних виправлень. Корисний урок вужчий: команда може зробити одну локально обмежену поведінку корисною одразу в кількох пов’язаних контекстах і перелічити ті контексти, які перевіряє регресіями.
Коли ви читаєте PR як навчальний приклад, розділяйте чотири запитання: що було обіцяно, які частини змінили, які випадки перевірили, що реально сталося із запитом. Назва, кількість рядків і зелений статус автоматизованих перевірок не заміняють читання опису й порівняння змін.
19.15. Агентська робота: план розбиває, інтеграція доводить
Кодинговий агент може запропонувати межі, контракти, перевірки й порядок роботи або паралельно підготувати інтерфейс і серверну операцію. Але окремі правильні плани не гарантують сумісного результату: він залежить від спільного контракту, реальних інтеграційних доказів і порядку розгортання. Документація OpenAI Multi-agent рекомендує паралелити незалежні задачі з чітким результатом, а короткі залежні кроки залишати координатору; це рекомендація конкретного засобу, не доказ універсального прискорення.
Перед запуском кількох виконавців:
- Зафіксуйте одну очікувану відповідь або структуру даних для всіх частин.
- Позначте файли, схеми, типи, маршрути та спільні ресурси, які вони можуть зачепити.
- Дайте кожному перевірювану межу й виключення; не діліть роботу на «все серверне» та «весь інтерфейс» без плану сумісності.
- Визначте власника, який розв’язує конфлікти й збирає спільний сценарій.
- Після виконання звірте фактичні зміни з контрактом, а не тільки зі звітом агента.
- Перевірте з’єднаний сценарій і важливі негативні умови доступу; лише після цього вирішуйте, чи можна зміни об’єднати, розгорнути або відкрити.
Поточна документація Codex CLI (Command-Line Interface — інтерфейс командного рядка) описує дослідження репозиторію, планування зміни, редагування й локальні перевірки. Офіційний матеріал OpenAI Codex Plan mode описує пропозицію шляху реалізації до зміни коду; Claude Code CLI reference документує параметр --permission-mode plan. Доступність залежить від продукту, поверхні, версії й облікового запису. Режим планування не доводить правильності плану чи сумісності гілок. Якщо інтеграцію не можна було перевірити через відсутність тестового середовища, даних або доступу, назвіть це обмеження: статус «агент сказав, що код готовий» не замінює перевірку й не дає підстав оголосити зріз завершеним.
19.16. Коли інша одиниця роботи доречніша
Не кожна ціль створює нову поведінку для користувача; внутрішня робота також має власний обмежений результат і відповідне свідчення:
- Дослідження. Результат — відповідь на вузьке питання, докази, невідоме й наступне рішення.
- Ремонт інфраструктури. Результат — відновлений процес або конкретна характеристика служби, з доказом до і після.
- Виправлення безпеки. Результат — закритий шлях атаки, відсутність витоку та регресійна перевірка; видима функція може не змінитися.
- Міграція. Результат — сумісний стан даних і підтримуваний порядок версій, а не лише нова колонка.
- Відмова від застарілої функції. Результат може бути вимкнення й очищення, з повагою до залежностей, користувацьких даних і плану повідомлення.
- Оглядовість системи. Результат — сигнал, який допомагає черговому розрізнити конкретну помилку, а не збільшення кількості логів як самоціль.
Для будь-якого такого типу роботи лишаються потрібними обмежений результат, умови завершення й відповідне свідчення. Не кожна зміна має окремо приносити нове продуктове значення, але кожна повинна відповідати на питання, заради якого команду попросили її зробити.
19.17. Підсумок
Вертикальний зріз завершує маленьку, змістовну поведінку з потрібними правилами доступу та доказами, проходячи необхідні частини системи без штучного поділу за шарами. Його межу починають з обіцянки споживачу, правил і критеріїв; звуження сценаріїв має зберегти коректність, права доступу та потрібну якість.
Завершення частин не гарантує незалежності релізу: потрібні спільні контракти, перевірка прихованих залежностей, порядок міграції та інтеграційний доказ. Малі партії скорочують шлях до зворотного зв’язку, але не гарантують правильності; агент може допомогти з планом, а команда має перевірити з’єднаний результат.
Джерела та подальше читання
Основні матеріали перевірено 23 вересня 2026 року; рекомендацію DORA щодо малих партій повторно звірено 26 вересня. Нижче вказано, яке твердження підтримує кожне джерело. Приклади бронювання й агентських гілок — навчальні, не звіти про реальні інциденти.
- Ryan Singer, Shape Up: Stop Running in Circles and Ship Work that Matters, оригінальна вебкнига Basecamp; переглянуто 23 вересня 2026 року. Прочитані глави 11: Get One Piece Done та 12: Map the Scopes. Перша описує ранню інтеграцію одного сценарію та досвід Basecamp із перемикачем видимості; друга — виявлення завершуваних областей за структурою роботи, а не за ролями; також автор позначає бажані, необов’язкові доповнення символом ~. Приклад Basecamp атрибутований автору й не поданий як універсальний закон.
- DORA, Working in small batches, сторінка востаннє оновлена 8 грудня 2025 року; переглянуто 26 вересня 2026 року. Описує коротші цикли зворотного зв’язку, незалежні, цінні й перевірювані невеликі одиниці, а також застерігає від повторного об’єднання партій перед перевіркою. Рекомендації DORA не перетворені тут на вимогу щодо однакової тривалості задач у всіх командах.
- FastAPI contributors, PR #14306: Improve tracebacks by adding endpoint metadata, об’єднаний 6 грудня 2025 року; переглянуто 23 вересня 2026 року. У порівнянні змін — три файли, 289 доданих і 16 вилучених рядків, включно з регресійними тестами запитів, відповідей, WebSocket та підзастосунків. PR підтверджує конкретну реалізацію й перелік тестів, а не незалежну точність власних бенчмарків автора.
- OpenAI, Codex Plan mode, офіційний матеріал про режим планування в Codex; переглянуто 10 жовтня 2026 року. Описує попередню пропозицію шляху реалізації та зазначає залежність доступності від продуктового середовища й облікового запису; не є доказом точності планів.
- OpenAI, Run long horizon tasks with Codex, офіційний матеріал OpenAI Developers; переглянуто 10 жовтня 2026 року. Наводить приклад плану з цілями, обмеженнями, етапами та перевірками; описує досвід автора, не незалежний вимір продуктивності.
- Anthropic, Claude Code CLI reference, поточна офіційна документація; переглянуто 10 жовтня 2026 року. Описує параметр
--permission-mode plan; це можливість Claude Code, а не гарантія правильності плану чи дозволу діяти. - OpenAI, Multi-agent, поточна документація OpenAI Agents API; переглянуто 10 жовтня 2026 року. Рекомендує віддавати паралельним агентам незалежні обмежені задачі, а залежні кроки залишати координатору; це рекомендація продукту, не незалежний доказ прискорення.