Что такое Spec-First Development: полное руководство

· 1 мин чтения
spec-driven specifications methodology planning acceptance-criteria
Что такое Spec-First Development: полное руководство

Spec-first — это не методология. Это принуждающая функция: вы записываете сложные решения до того, как код примет их за вас, и признаёте, что половина написанного окажется неверной. Это нормально. «Неправильно, но записано» всегда лучше, чем «правильно, но нигде не зафиксировано».

Что на самом деле означает spec-first

Уберите buzzword — и останется нечто некомфортное: вам приходится решать то, что вы предпочли бы не решать прямо сейчас. Что происходит, когда платёжный шлюз таймаутится? Каково точное поведение, когда два пользователя одновременно редактируют одну запись? Чья обязанность — утверждать откат? Большинство команд предпочитают обнаруживать эти решения во время реализации, потому что тогда проблема хотя бы ощущается конкретной. Spec-first говорит: нет — вынесите их наружу до того, как кто-то напишет первый тест.

Спецификация — это просто документ. Настоящий артефакт — это спор, который вы ведёте, пока его пишете.

Почему большинство попыток проваливается

Команды тратят три недели на 40-страничную спеку, которая не отвечает ни на один реальный вопрос. Документ существует. Он прошел ревью. Все согласны. На четвёртой неделе реализации кто-то спрашивает: «А что если пользователь отменит операцию посередине?» — и никто не знает. Это не спецификация. Это артефакт соответствия.

Паттерн провала почти всегда один и тот же: пишут о фиче вместо решений. Хорошая спека на 60% состоит из граничных случаев, режимов отказа и явно сформулированных не-целей. Если она читается как рекламный проспект фичи — она не выполняет свою задачу.

Три вопроса, на которые должна отвечать любая спека

Прежде чем отправить спецификацию на ревью, она должна отвечать на эти вопросы за десять секунд чтения:

  • Что рецензент может отклонить? Если нет конкретики, на которую можно указать и сказать «нет, не так» — рамки слишком размыты.
  • Что тестировщик может проверить? Если QA должен брать у вас интервью, чтобы написать тест-кейсы — это не критерии приёмки.
  • Что дежурный может остановить? Если on-call не может назвать сигнал, означающий «прервать релиз» — у вас нет плана развёртывания, у вас есть надежда.

Большинство первых драфтов проваливают хотя бы один. Мои обычно проваливают все три. Именно поэтому спеку пишут первой — чтобы пробелы проявились на странице, а не в продакшене.

Критерии приёмки, которые не являются декорацией

Вот какие критерии приёмки пишут большинство команд:

  • Пользователь может отправить форму
  • Форма валидирует обязательные поля
  • Появляется сообщение об успехе

Что здесь пропущено: что означает «валидирует» — на клиенте, на сервере, или на обоих уровнях? Что происходит, если сервер отклоняет то, что клиент пропустил? Что говорит сообщение об успехе, и как долго оно отображается? Что происходит при двойном клике на отправку?

Сравните с критериями, которые реально предотвращают придумывание решений во время реализации:

  • Given отправка с валидным email и заполненными обязательными полями
    When пользователь нажимает «Отправить»
    Then дублирующие запросы в течение 2 секунд дебаунсятся
    And запись появляется со статусом status="pending" не более чем за 500мс
    And UI переходит в состояние подтверждения

  • Given сервер возвращает 409 Conflict на дублирующий email
    When ответ приходит
    Then форма снова активируется
    And поле email показывает инлайн-ошибку конфликта
    And на клиенте не создаётся pending-запись

Вторая версия заставляет принять три решения, которые первая оставляет «на потом»: поведение дебаунсинга, контракт 409 и UX ошибок. В этом и состоит весь смысл.

Что спросить до того, как кто-то начнёт кодить

Проверьте свою спеку так, будто вы её не писали:

  • Какие решения здесь всё ещё неоднозначны для человека, не присутствовавшего на совещании?
  • Может ли QA составить свою тестовую матрицу, ничего у меня не спрашивая?
  • Если этот релиз упадёт в 2 часа ночи — знает ли дежурный инженер, что делать?

Если вы не можете ответить без запуска треда в Slack — спека несёт непрояснённый риск. Вы заплатите за него позже, обычно днём накануне демо.

Rollout — часть спеки, а не сноска

Спека, заканчивающаяся на «задеплоено», не закончена. Rollout — источник большинства продакшн-инцидентов, и именно здесь большинство спек замолкают.

  • План staging. Не «мы просто включим». Кто переключает тумблер, в каком порядке, и какие сигналы подтверждают корректность на каждом этапе?
  • Пороги stop-loss. Назовите число. «Откатить, если error rate превышает baseline в 3 раза на протяжении 10 минут» лучше, чем «откатить, если что-то пойдёт не так».
  • Механика отката. Revert кода, feature flag, приостановка джобы или reversal миграции? Некоторые из этих действий занимают секунды, другие — часы. Знайте, какой вариант ваш, до того, как начнёте деплой.

Повторяющиеся ошибки

  • Использование слов «разумный» или «корректный» для описания поведения. Эти слова означают разное для разных читателей и оспариваются при QA. Замените их на числа или явные правила.
  • Откладывание безопасности и прав доступа на «позже, отдельным тикетом». Эти решения формируют модель данных. Отложите — и вы либо переписываете миграции, либо релизите с дырами.
  • Отсутствие записи о том, что вы не делаете. Не-цели предотвращают scope creep при реализации. Пропустите их — и каждый сторонний разговор будет ощущаться как блокер.

Сколько спеки достаточно?

Пишете ровно столько, чтобы предотвратить придумывание решений во время реализации. Это всё правило.

Строите пятнадцатый внутренний дашборд? Двух страниц, вероятно, достаточно. Строите платёжную систему? Вероятно, нужно десять страниц. Объём должен соответствовать риску, а не процессу.

Одна проверка на адекватность: подсчитайте количество решений, которые принимает спека. Если ответ «ноль, она описывает фичу» — перепишите. Если ответ «сорок» — вы протащили реализацию в спеку, сокращайте.

Полевой пример: что изменилось после переписывания спеки

В одном биллинговом workflow, который я ревьюил, исходный тикет содержал только «поддержка частичных возвратов». Первая реализация позволила бы дублирующие возвраты, потому что поведение при ретраях было оставлено на усмотрение payment worker. Переписывание запроса как спецификации изменило саму архитектуру, а не только формулировку.

До:

  • Пользователь может вернуть заказ.

После:

  • Given запрос на возврат с idempotency_key=abc
    When платёжный провайдер таймаутится
    Then воркер записывает status="pending_provider_confirmation"
    And повторный запрос с тем же ключом возвращает тот же refund_id
    And поддержка не может создать второй возврат, пока первый в статусе pending

Ценность — не в документе. Ценность — в том, что команда была вынуждена решить поведение ретраев до первого продакшн-таймаута.

Как начать внедрять spec-first в команде

Используйте этот материал, когда команда впервые пробует spec-first. Привяжите обсуждение к одному реальному изменению — иначе статья останется красивой идеей, которая никогда не коснётся спеки.

  • Первая цель: выберите один класс задач, а не весь инженерный процесс целиком.
  • Артефакт: решите, где хранятся спеки и как они линкуются из тикетов и pull request'ов.
  • Правило ревью: зафиксируйте, когда спека может перейти к реализации и кто подтверждает это.
  • Цикл обучения: используйте инциденты и переделки для улучшения шаблона, а не для добавления церемоний.

Первый rollout должен ощущаться скучным и узким. Это фича, а не провал.

Пакет для delivery review

Используйте при планировании, ревью дизайна или проверке готовности к релизу. Этот пакет делает видимыми ответственность и условия остановки.

Поле Значение
Решение Что такое spec-first development становится яснее, когда команда делает скрытые решения видимыми до начала кодинга
Product owner ___
Engineering owner ___
QA / Operations reviewer ___
В скоупе ___
Вне скоупа ___
Допущение, требующее подтверждения ___
Доказательство приёмки (тест/фикстура) ___
Лог/метрика/скриншот ___
Шаг ручного ревью ___

Граница процесса: owner, лог решений, доказательства и порог stop-loss должны быть определены до начала реализации.

Итог

Spec-first работает, потому что перемещает споры на более ранний этап, где они дёшевы. Вы спорите на странице вместо code review, на доске — вместо постмортема. Сам документ — не главная ценность. Процесс его написания — вот что создаёт мышление, которое вам действительно нужно.

Большинство команд, которые утверждают, что spec-first им не подходит, на самом деле не пробовали его. Они пробовали писать длинные документы, которые никто не читал. Это другой паттерн провала. Начните с трёх вопросов, привыкните ошибаться на странице — остальное приложится.

Источник: https://spec-coding.dev/blog/what-is-spec-first-development-complete-guide