Зачем это нужно
В предыдущих уроках мы разобрали, что specification описывает observable behavior, а user story нужно разворачивать в requirements и acceptance criteria. Теперь нужен практический формат: файл, который можно положить в репозиторий и дать coding agent как source of truth.
Шаблон spec.md нужен, чтобы каждый раз не изобретать структуру заново. Он помогает не забыть goal, non-goals, actors, current behavior, desired behavior, functional requirements, constraints, edge cases, security requirements, acceptance criteria и open questions.
Хороший шаблон не должен быть тяжелой бюрократией. Его задача - сделать важные решения явными до того, как агент начнет писать код.
Основная идея
Feature specification отвечает на вопрос:
Как должна вести себя конкретная фича?
Минимальный spec.md должен быть достаточно подробным, чтобы:
- агент понимал expected behavior;
- человек видел open questions;
- acceptance criteria можно было связать с тестами;
- task decomposition опиралась на утвержденный source of truth;
- review мог проверить соответствие результата требованиям.
Но spec.md не должен превращаться в implementation plan. Он описывает "что", а не детальное "как".
Ключевые термины
| Термин | Значение |
|---|---|
| Feature Spec | Specification для одной фичи или изменения поведения. |
| Goal | Краткое описание результата, который нужно получить. |
| Non-goals | Что явно не входит в задачу. |
| Actors | Пользователи, системы или роли, участвующие в сценарии. |
| Current Behavior | Как система ведет себя сейчас. |
| Desired Behavior | Как система должна вести себя после изменения. |
| Functional Requirements | Проверяемые требования к функциям системы. |
| Constraints | Ограничения на реализацию и scope. |
| Edge Cases | Пограничные сценарии. |
| Security Requirements | Требования безопасности, privacy, abuse prevention. |
| Acceptance Criteria | Условия приемки результата. |
| Open Questions | Нерешенные вопросы, которые блокируют или ограничивают реализацию. |
Минимальный шаблон
Базовый feature spec:
# Feature: <name>
## Goal
## Non-goals
## Actors
## Current behavior
## Desired behavior
## Functional requirements
REQ-001:
REQ-002:
REQ-003:
## Constraints
## Edge cases
## Security requirements
## Acceptance criteria
AC-001:
AC-002:
AC-003:
## Out of scope
## Open questions
Можно добавлять разделы, если они нужны проекту:
Data requirements;API contract;UX notes;Telemetry;Migration notes;Compatibility;Manual acceptance.
Но для курса важно сначала освоить минимальный стабильный формат.
Как заполнять разделы
Goal
Goal должен быть коротким и проверяемым на уровне фичи.
Плохо:
Улучшить authentication.
Лучше:
Пользователь может восстановить доступ к аккаунту,
запросив reset link по email и установив новый пароль по одноразовому token.
Non-goals
Non-goals защищают scope.
Пример:
- Не меняем login flow.
- Не добавляем social login.
- Не меняем email provider.
- Не реализуем passwordless login.
Для coding agent это особенно важно: если non-goals не написаны, агент может "улучшить" соседнюю область.
Actors
Actors помогают понять, кто взаимодействует с системой.
Пример:
- Anonymous user
- Existing registered user
- Auth service
- Email service
Current behavior
Current behavior нужен, чтобы агент не проектировал в вакууме.
Пример:
Сейчас пользователь не может восстановить пароль самостоятельно.
При потере пароля требуется обращение в поддержку.
Desired behavior
Desired behavior описывает целевое состояние без деталей реализации.
Пример:
Пользователь вводит email, получает reset link,
переходит по нему и устанавливает новый пароль.
Token нельзя использовать повторно.
Expired token не меняет пароль.
Functional requirements
Каждый requirement должен иметь идентификатор.
Пример:
REQ-001:
Пользователь может запросить password reset по email.
REQ-002:
API не раскрывает, существует ли email в системе.
REQ-003:
Reset token действует 15 минут.
REQ-004:
Reset token может быть использован только один раз.
Идентификаторы нужны для traceability:
REQ -> AC -> Test -> Task -> Review
Constraints
Constraints говорят агенту, какие решения запрещены или ограничены.
Пример:
- Не менять существующий `/api/login`.
- Использовать existing EmailService.
- Не добавлять новые external dependencies без отдельного approval.
- Не менять database schema вне auth module.
Edge cases
Edge cases делают поведение предсказуемым.
Пример:
- Unknown email.
- Expired token.
- Consumed token.
- Password не проходит policy.
- Повторный reset request до использования старого token.
Security requirements
Security requirements нельзя оставлять "на усмотрение агента".
Пример:
- Reset token должен храниться в hashed form.
- Unknown email response не должен раскрывать existence account.
- Endpoint request reset password должен иметь rate limit.
- Successful reset должен писать audit event.
Acceptance criteria
Acceptance criteria лучше писать в стиле Given/When/Then.
Пример:
AC-001:
Given email принадлежит существующему пользователю
When POST /password-reset/request
Then API возвращает HTTP 202
And reset email queued
AC-002:
Given token истек
When POST /password-reset/confirm
Then API возвращает HTTP 400
And error.code = "TOKEN_EXPIRED"
And password не меняется
Open questions
Open questions должны оставаться видимыми.
Пример:
- Нужно ли инвалидировать все старые sessions после reset?
- Какой лимит запросов reset на email/IP?
- Нужно ли отправлять notification после успешной смены пароля?
Если вопрос влияет на product/security behavior, агент не должен молча решать его сам.
Схема traceability
Эта схема показывает, почему spec.md - не отдельный документ "для порядка". Он связывает намерение, работу агента и проверку результата.
Пример фрагмента Password Reset spec
# Feature: Password Reset
## Goal
Пользователь может восстановить доступ к аккаунту через email reset link
и установить новый пароль по одноразовому token.
## Non-goals
- Не меняем login flow.
- Не добавляем social login.
- Не меняем email provider.
## Actors
- Anonymous user
- Existing registered user
- Auth service
- Email service
## Current behavior
Пользователь не может восстановить пароль самостоятельно.
## Desired behavior
Пользователь отправляет email, получает reset link,
переходит по нему и задает новый пароль.
## Functional requirements
REQ-001:
Пользователь может запросить password reset по email.
REQ-002:
API не раскрывает, существует ли email в системе.
REQ-003:
Reset token действует 15 минут.
REQ-004:
Reset token может быть использован только один раз.
## Constraints
- Использовать existing EmailService.
- Не менять существующий login endpoint.
- Не добавлять external dependencies без approval.
## Edge cases
- Unknown email.
- Expired token.
- Consumed token.
- Weak new password.
- Повторный reset request.
## Security requirements
- Reset token хранится в hashed form.
- Request endpoint имеет rate limit.
- Successful reset пишет audit event.
## Acceptance criteria
AC-001:
Given email принадлежит существующему пользователю
When POST /password-reset/request
Then API возвращает HTTP 202
And reset email queued
AC-002:
Given email не принадлежит пользователю
When POST /password-reset/request
Then API возвращает HTTP 202
And response не раскрывает, что аккаунта нет
AC-003:
Given token уже использован
When POST /password-reset/confirm
Then API возвращает HTTP 400
And error.code = "TOKEN_USED"
And password не меняется
## Open questions
- Нужно ли инвалидировать старые sessions после успешного reset?
- Какой точный rate limit использовать?
Это не финальная спецификация для production, но хороший учебный baseline.
Практика: написать spec.md
Создайте черновик:
specs/password-reset/spec.md
Заполните разделы:
Goal
Non-goals
Actors
Current behavior
Desired behavior
Functional requirements
Constraints
Edge cases
Security requirements
Acceptance criteria
Out of scope
Open questions
Минимальные требования к практике:
- минимум 5
REQ; - минимум 5
AC; - минимум 5 edge cases;
- минимум 3 security requirements;
- минимум 2 open questions;
- ни один open question не должен быть скрыт как assumption.
Типичные ошибки
Ошибка 1. Делать spec слишком общим
Если requirement нельзя проверить, он слишком общий.
Ошибка 2. Писать implementation вместо behavior
Specification может упоминать constraints, но не должна преждевременно диктовать каждую техническую деталь.
Ошибка 3. Не писать non-goals
Без non-goals агент часто расширяет scope.
Ошибка 4. Прятать нерешенные вопросы
Open questions должны быть видны. Если они исчезли из spec без решения, агент начнет угадывать.
Ошибка 5. Не использовать identifiers
Без REQ-001 и AC-001 трудно связать requirements с tasks, tests и review.
Критерии готовности
После урока студент должен уметь:
- объяснить назначение каждого раздела
spec.md; - написать goal и non-goals для feature spec;
- оформить requirements и acceptance criteria с идентификаторами;
- отделить constraints от desired behavior;
- явно записать edge cases, security requirements и open questions;
- подготовить черновик
specs/password-reset/spec.md.
Краткое резюме
Feature spec - это рабочий контракт между человеком, агентом и проверкой результата.
Минимальный spec.md фиксирует:
- что строим;
- что не строим;
- кто участвует;
- как система ведет себя сейчас;
- как должна вести себя после изменения;
- какие requirements и constraints обязательны;
- какие edge cases и security вопросы важны;
- какие acceptance criteria доказывают готовность;
- какие вопросы еще открыты.
Следующий шаг - не сразу писать code, а проверить specification на неопределенности.
Вопросы для самопроверки
- Зачем нужны non-goals?
- Почему requirements и acceptance criteria должны иметь identifiers?
- Чем constraints отличаются от desired behavior?
- Какие open questions нельзя оставлять агенту на самостоятельное решение?
- Почему
spec.mdне должен превращаться в implementation plan?
Что дальше
В следующем уроке мы разберем Clarification Phase. Даже хороший шаблон не гарантирует, что spec полный и непротиворечивый. Перед design и code агент должен найти ambiguity, conflicts, missing edge cases и implicit assumptions.