Spec, PRD, and tests: a single source of truth
Separating three artifacts by role: the PRD answers "why", the spec answers "what", tests answer "is it proven" — plus tracing criteria into tests.
Lesson content is currently available in Russian.
What you will learn
- →Разводить PRD, спеку и тесты по ролям и не дублировать содержимое между ними.
- →Строить трассировку «критерий приёмки → тест» и мерить покрытие критериев.
- →Держать спеку в репозитории рядом с кодом и менять её тем же PR, что и код.
Три артефакта, три вопроса
PRD, спека и тесты часто путают, потому что все три «описывают фичу». Развести их проще всего по вопросу, на который отвечает каждый:
| Артефакт | Вопрос | Аудитория | Горизонт |
|----------|-------------|----------------------|-----------------|
| PRD | Зачем и для | бизнес, продакт, | до запуска |
| | кого | стейкхолдеры | |
| Спека | Что именно | инженеры, агенты, | вся жизнь фичи |
| | делает | ревьюеры | |
| Тесты | Доказано ли | CI, инженеры | каждый коммит |
PRD объясняет рынок, метрики успеха и почему фича важнее других в бэклоге. Ему позволено быть убеждающим и неполным технически: «сократить время выгрузки отчёта с 40 минут до одной» — отличная строчка PRD и никакая — спеки. Спека — поведенческий контракт: роли, сценарии, ограничения, критерии. Ей запрещена агитация и запрещена размытость. Тесты — механическое доказательство того, что контракт выполняется, перезапускаемое на каждом коммите.
Практический вывод: не пытайтесь сделать один документ всем сразу. PRD, в который дописали критерии приёмки и схему API, не читает ни бизнес, ни агент. Каждому артефакту — своя роль, а связывают их ссылки: спека ссылается на PRD, тесты — на критерии спеки.
Единый источник истины
Классическая болезнь зрелого проекта: PRD в Notion описывает поведение годичной давности, тесты проверяют прошлогодний контракт наполовину, а код делает нечто третье, потому что были хотфиксы. Когда новый инженер — или агент — спрашивает «как должен работать экспорт?», честный ответ: «прочитай код и угадай». Это и есть отсутствие источника истины.
SDD назначает источником истины спеку — по одной простой причине: из трёх артефактов только она одновременно читаема человеком, исполняема агентом и достаточно компактна, чтобы её реально поддерживать. Из этого следуют два правила. Первое: при расхождении артефактов выигрывает спека. Если код ведёт себя иначе — это баг кода или устаревшая спека, и оба случая требуют явного решения, а не молчания. Если PRD обещает другое — PRD обновляют или фиксируют осознанное отклонение. Второе: любое изменение поведения начинается с правки спеки. Не «сделаем и допишем потом» — потом не наступает никогда.
Важная оговорка: единый источник истины не значит единственный документ. PRD продолжает жить для бизнеса, тесты — для CI. «Единый» означает: когда они противоречат друг другу, есть заранее назначенный арбитр, и это спека. Команды без такого арбитра решают каждый конфликт заново — совещанием.
Трассировка: критерий → тест
Связь спеки с тестами делается механической через идентификаторы критериев. Каждый AC-N из спеки должен встречаться в названии или описании хотя бы одного теста:
describe('CSV export', () => {
it('AC-1: 10k rows export in under 5s', ...);
it('AC-2: viewer role gets 403', ...);
it('AC-5: aborted connection leaves no partial file', ...);
});
Такая разметка даёт три эффекта. Покрытие критериев считается тривиальным grep: какие AC не встречаются в тестах — те не доказаны; это куда полезнее процента покрытия строк, потому что мерит контракт, а не код. Ревьюер PR сверяет чек-лист критериев с тестами за минуты. А агент получает готовый шаблон: на шаге tasks задача «интеграционные тесты AC-1..AC-6» однозначна и проверяема.
Направление трассировки принципиально: тесты выводятся из спеки, а не спека из тестов. Тест — это одна конкретная проекция критерия: AC-1 говорит «не дольше 5 секунд на 10 000 строк», тест фиксирует конкретный датасет и конкретную границу. Критериев без тестов быть не должно; тесты без критериев допустимы — регрессионные, юнит-тесты внутренних инвариантов, — но интеграционный тест, проверяющий поведение, которого нет в спеке, это звонок: либо поведение случайно, либо спека отстала.
Где живёт спека
Место хранения спеки — не бытовой вопрос, а половина её выживания. Спека в Confluence или Notion гниёт по предсказуемому механизму: код меняется через PR, а вики — «когда руки дойдут»; через полгода документ противоречит коду, ему перестают верить, а документ, которому не верят, перестают обновлять. Петля замыкается.
Лекарство — спека живёт в репозитории, рядом с кодом, который она описывает: specs/001-csv-export/spec.md, как это делает Spec Kit. Это даёт три механических эффекта. Версионирование бесплатно: git log по файлу спеки — полная история контракта, git blame отвечает, когда и почему изменился критерий. Атомарность изменений: PR, меняющий поведение, меняет спеку и код одним коммитом — ревьюер физически видит diff контракта рядом с diff реализации, и «поменяли код, забыли спеку» превращается из нормы в заметное нарушение. Доступность агенту: спека в репо попадает в контекст без копипасты, и любой агент — генератор, аудитор, ревьюер — читает её тем же способом, что и код.
PRD может оставаться во внешней системе — у него другая аудитория и другой ритм жизни. Но тогда в спеке должна быть ссылка на него, а не пересказ: пересказ устаревает, ссылка — нет.
Practice
Аудит трассировки на реальном проекте
Возьмите фичу из своего проекта, у которой есть хоть какая-то документация и тесты. Составьте таблицу: критерии (явные или восстановленные из документации) → тесты, которые их проверяют. Найдите критерии без тестов и тесты, проверяющие поведение, которого нет ни в одном документе. Разметьте существующие тесты идентификаторами AC-N.
Deliverable
Таблица трассировки «критерий → тест» с колонкой статуса (доказан / не доказан / тест без критерия) и PR или патч с разметкой тестов идентификаторами.
Checkpoint
В проекте PRD обещает экспорт «за секунды», спека говорит «до 5 секунд на 10 000 строк», а тест проверяет 1 000 строк за 2 секунды. Код на 10 000 строк работает 9 секунд. Разберите конфликт.
- ✓ Назначен арбитр: спека — источник истины, код ей не соответствует, это дефект.
- ✓ Замечено, что тест не доказывает критерий: датасет в 10 раз меньше граничного.
- ✓ Предложен порядок действий: починить код и тест под критерий спеки, PRD сверить и при необходимости обновить.
Check yourself
Sources