1. Одного goal мало
Хорошая цель оставляет дыры. «Добавить поле notes в refund-request» не отвечает: поля нет совсем или оно есть, но не сохраняется? notes только в форме или ещё и в деталях возврата? попадает в событие для других сервисов? есть обходной путь? В этих дырах Claude импровизирует — закрывает пустоты догадками. Чем больше пустот, тем сильнее он «лечит проект по фотографии»: видит идею, не видит проблему.
Goal задаёт направление, но не разрыв между «сейчас» и «надо». Разрыв описывают ещё два блока:
Goal — «Куда хотим прийти?»
Current behavior — «Что происходит сейчас?»
Desired behavior — «Как должно выглядеть правильное состояние?»
Три части рядом — и задача перестаёт быть пожеланием.
2. Current behavior: фиксируем реальность
Задача блока одна: описать, что наблюдается сейчас, без догадок о причине. Сначала факты, потом версии. Иначе в spec уедет ваша интерпретация, а Claude схватится за неё.
Для бага сюда входят симптом, шаги воспроизведения, фактический результат, иногда окружение, логи, влияние на пользователя. Для фичи — текущее ограничение, обходной путь и бизнес-проблема. Current behavior — не только для багфиксов.
Одни и те же элементы в задачах двух типов:
| Что фиксируем | Если это bugfix | Если это feature |
|---|---|---|
| Точка входа | Где воспроизводится ошибка | Где пользователь упирается в ограничение |
| Текущее действие | Какие шаги выполняют | Что пользователь делает сейчас |
| Actual result | Что реально произошло | Чего сейчас в системе нет |
| Workaround | Как обходят проблему | Как команда живёт без нужной возможности |
| Impact | Чем мешает баг | Почему отсутствие функции создаёт проблему |
Крошечный bugfix:
## Текущее поведение
1. Открыть `/login`
2. Ввести корректный email и неверный пароль
3. Нажать кнопку «Войти»
Фактический результат: экран становится пустым, сообщения об ошибке нет.
Наблюдается в: локальный запуск и staging.
Ни «сломалась backend-валидация», ни «React где-то падает». Пока не доказано — это не факт, а версия.
Для фичи логика та же: не решение, а текущее состояние — чего нет, как обходятся, почему неудобно.
3. Desired behavior: наблюдаемый результат
Вторая сторона разрыва. Ловушка — абстракции «должно работать нормально», «сделать удобно»: Claude не знает, где у вас «нормально». Хороший desired такой, что после реализации проходишь глазами по пунктам: да, есть; нет, нет.
Описывайте результат со стороны пользователя, интерфейса, API, данных, граничных случаев — без технического решения. «Использовать такую-то библиотеку» это путь реализации; desired отвечает на «что станет истинным после изменения».
| Слабая формулировка | Почему слабая | Сильная формулировка |
|---|---|---|
| «Добавить удобные заметки» | Неясно, что считается удобством | «Оператор может ввести заметку при создании refund-request и увидеть её в деталях возврата» |
| «Починить отображение ошибки» | Неясно, где и как она должна выглядеть | «При неверном пароле форма остаётся на странице логина и показывает текст ошибки под полем пароля» |
| «Улучшить сохранение данных» | Нет наблюдаемого результата | «После отправки формы значение notes сохраняется в записи возврата и доступно при повторном открытии детали» |
Хороший desired бывает коротким, но точным:
## Желаемое поведение
После неверного пароля страница не становится пустой.
Пользователь остаётся на `/login` и видит понятное сообщение об ошибке.
Успешный логин продолжает работать без изменений.
Последняя строка — про то, что не должно случайно сломаться. Ещё не раздел про границы задачи, а напоминание о существующем корректном поведении.
Для фич desired не даёт Claude ограничиться половиной. Не напишете, что поле должно и сохраняться, и отображаться, и попадать в событие — сделает одну часть и решит, что молодец.
4. Hypothesis vs evidence: догадка и факт
Мозг мгновенно подсовывает объяснение: «наверное, валидация», «скорее всего, миграция», «событие не обновили». Без гипотез инженерии нет. Беда — когда гипотеза попадает в spec как факт.
Разница между «наблюдаем X» и «причина в Y» для Claude критична. Запишете предположение в current behavior без маркировки — агент примет его за данные и начнёт чинить эту область. Так рождается random patching: причина не проверена, код уже правят.
Evidence — то, что наблюдаем и можем показать.
Hypothesis — то, как объясняем наблюдаемое.
Ориентир по формулировкам:
| Формулировка | Это что? | Как с ней обращаться |
|---|---|---|
| «После submit экран пустой» | Evidence | Можно писать прямо в current behavior |
| «В логах есть NullPointerException в AuthController» | Evidence | Можно писать прямо в current behavior |
| «Похоже, ломается backend validation» | Hypothesis | Пометить явно и попросить проверить |
| «Наверное, в таблице уже есть колонка notes» | Hypothesis | Не считать фактом до проверки схемы |
Рабочая форма записи:
Гипотеза: проблема может быть в backend-валидации.
Сначала проверь, прежде чем редактировать.
Приписка делает две вещи: сохраняет мысль и не превращает её в команду «иди правь backend». Claude получает сигнал: версия есть, сначала подтверди.
Процесс:
flowchart TD
A[Наблюдение] --> B[Гипотеза]
B --> C{Есть проверка?}
C -- Нет --> D[Не редактируем код как будто причина уже доказана]
C -- Да --> E[Получаем evidence]
E --> F[Только потом меняем код]
Маленькая схема, а экономит время — особенно там, где хочется «сразу начать исправлять».
5. Commerce OS: F-03, current и desired
Переносим всё в сквозной проект курса. Задача из Commerce OS: F-03: Add notes field to refund-request. Фича, не багфикс — и на ней видно, что current behavior нужен не только для ошибок.
Рабочий фрагмент TASK_SPEC.md draft, который уже можно давать Claude:
## Текущее поведение
Оператор создаёт refund-request из `admin/orders/{id}`.
Нет поля, чтобы приложить контекстную заметку, например:
«клиент позвонил, согласовали частичный возврат».
Сейчас заметка хранится в отдельном комментарии к саппорт-тикету
и не связана с записью возврата.
В итоге финансовые ревьюеры не видят логику оператора
при последующем аудите возвратов.
Гипотеза: колонка `notes` может уже существовать в таблице `refunds`
от старой миграции. Сначала проверь текущую схему, прежде чем редактировать.
Язык фактов: не «сервис плохо спроектирован», а наблюдаемое — поля нет, заметка уезжает в комментарий, связь теряется. Гипотеза про колонку помечена и не выдаётся за факт.
Целевое состояние:
## Желаемое поведение
- форма refund-request в `admin/orders/{id}` содержит необязательное поле `notes`
(textarea, до 1000 символов);
- при отправке формы `notes` сохраняется вместе с записью возврата;
- в карточке возврата заметка отображается в отдельной секции;
- payload события `refund.created` содержит поле `notes`;
- существующие возвраты без заметки рендерятся корректно, без ошибок.
Не размытое «добавить заметки», а пять проверяемых утверждений — каждое закрывает свой кусок: ввод, сохранение, отображение, событие для интеграций, обратную совместимость.
После этих двух блоков Claude видит весь разрыв, а не одну строчку на фронтенде, и не фантазирует про причину без проверки схемы. Пример сам подводит к нужным вопросам: где живёт форма, как сохраняется запись, есть ли колонка в БД, кто формирует refund.created, как рендерятся старые записи. Не «угадать фикс», а понять систему по фактам.
6. Сначала проверка, потом правки
Блоки описаны — не просите Claude «сразу сделать фичу». Пусть сначала прочитает их как инженерный вход. Не зададите ритм — он кинется править код раньше, чем подтвердит версии.
Работает короткая инструкция «сначала разберись с фактами»:
Прочитай блоки `Current behavior`, `Desired behavior` и `Hypothesis`.
Сначала перечисли:
1. какие утверждения уже подтверждены фактами;
2. какие нужно проверить в коде или схеме;
3. какие файлы и сущности, вероятно, связаны с задачей.
Код пока не меняй.
Чтобы аккуратнее отделить факты от догадок, держите в черновике TASK_SPEC.md шаблон:
## Текущее поведение
...
## Желаемое поведение
...
## Гипотезы для проверки
- ...
- ...
## Известные доказательства
- ...
- ...
Не перепутайте уровни. Current behavior и Desired behavior — устойчивые части spec. Hypotheses to verify и Known evidence — временные заметки: держите до правок, после проверки сожмите или уберите. Даже короткий Known evidence приучает спрашивать: «это я наблюдал или красиво догадываюсь?»
В итоге Claude получает не туманную просьбу, а инженерный вход: что есть, что должно стать, что предполагаем, но не доказали. С этого места он меньше гадалка с клавиатурой и больше помощник, который сначала читает факты, потом трогает код.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ