name: spec-driven
description: "Success-Oriented Software Architecture & Logic Spec Driven. Produces a spec document that defines what success looks like (observable, measurable), then the architecture and per-component logic contracts that guarantee it, then a verification plan that checks each success criterion. Use before implementing any non-trivial system: fuzzy requirements, multi-component features, behavior others must build/verify against, risky design with real failure modes. Turns 'build X' into a verifiable contract before a line of code is written."
spec-driven — методология, а не бинарник. Твоя роль: собрать контекст, провести reasoning по схеме ниже и записать результат в spec-файл. Не начинай реализацию, пока spec не сформулирован и не подтверждён пользователем (если он участвует).
Core idea
Обычный подход: «опиши фичи → построй → почини». Success-oriented подход идёт с обратного конца:
- Что значит «работает»? — наблюдаемые, проверяемые критерии успеха. Не список фич, а контракт с внешним миром.
- При каких ограничениях? — реальные пределы: latency, бюджет, совместимость, operational constraints.
- Какая архитектура гарантирует успех в этих границах? — компоненты, границы, потоки данных. Решения с rationale и отвергнутыми альтернативами.
- Какая логика у каждого компонента? — контракты, инварианты, состояния, ошибки. Достаточно точно, чтобы реализация стала механической.
- Как мы проверим каждый критерий успеха? — verification plan, привязанный к п.1, а не «напишем тесты».
Spec — это контракт. Реализация — это заполнение контракта. Если реализация расходится со spec'ом, чинят spec (если он был неправ) или реализацию (если она не дотянула). Без spec'а непонятно, кто неправ.
When to use
- Требования размыты. Пользователь сказал «сделай X», но X имеет 5 разумных трактовок. Spec фиксирует трактовку ДО реализации.
- Много компонентов / несколько исполнителей. Нужен общий контракт, иначе компоненты не состыкуются.
- Реальные failure modes. Система может упасть 10 способами — success criteria определяют, какие из них допустимы, какие нет.
- Дизайн с риском. Архитектурное решение, которое дорого менять потом. Spec заставляет подумать о границах и rationale сейчас.
- Кто-то будет верифицировать. Spec даёт проверяющему checklist, привязанный к успеху, а не к «как написано».
When NOT to use
- Однофайловая утилита, поведение очевидно из задачи — spec будет длиннее кода.
- Чистый рефакторинг без изменения контракта — контракт уже есть, меняется реализация.
- Спайк / прототип, который выкинут — успех = «узнали ответ», spec не нужен.
- Задача сводится к одной bash-команде или одной функции.
How to run
1. Собери контекст
Прежде чем писать spec, найди:
- Реальные требования. Что пользователь сказал дословно — сохрани как секцию
## Исходный запрос(как в deep-analyze). Тон и контекст важны, не только формальная формулировка. - Ограничения. Что уже зафиксировано: стек, бюджет, совместимость, deadlines, существующий код. Читай файлы проекта, не додумывай.
- Существующие решения. Если в проекте уже есть похожий код / архитектура — spec должен с ней стыковаться, а не изобретать параллельную вселенную.
Если контекста мало — задай конкретные вопросы пользователю. Не выдумывай требования. Лучше 3 вопроса, чем spec на основе галлюцинации.
2. Reasoning по схеме (внутренний шаг)
Пройди сверху вниз. На каждом уровне проверяй совместимость с предыдущим:
- Успех должен быть наблюдаемым («p99 latency < 50ms под 1k RPS на reference-железе»), а не свойством («быстрый»).
- Архитектура должна выводиться из успеха + ограничений, а не из «модно». Для каждого ключевого решения — rationale и хотя бы одна отвергнутая альтернатива с причиной отказа.
- Логика должна быть достаточно точной, чтобы второй человек (или свежий подагент) реализовал её без дополнительных вопросов. Контракты, инварианты, состояния, ошибки — явно.
- Verification должен проверять критерии успеха из п.1, а не «код работает». Каждый критерий → конкретная проверка.
3. Запиши spec
Пиши в markdown-файл. Структура ниже — canonical, отклоняйся только если задача явно требует иного.
4. Самопроверка перед передачей
Прочти spec и ответь на 4 вопроса. Если хоть один провален — доработай:
- Каждый ли критерий успеха наблюдаем и имеет порог? «Надёжный» — нет. «99.9% сообщений доставляются за < 1s» — да.
- Выводится ли архитектура из успеха + ограничений? Если решение обосновано «так принято» — это не rationale.
- Может ли свежий исполнитель реализовать логику без вопросов? Найди двусмысленности: «обрабатывает ошибку» — как именно? Допиши.
- Покрывает ли verification каждый критерий успеха? Найди criterion без проверки — это дыра.
5. Подтверждение и итерация
Если пользователь участвует — покажи spec и запроси подтверждение до реализации. Spec дешевле менять, чем код.
Если нашли пробелы в ходе реализации — вернись к spec, обнови, потом чини реализацию. Spec — источник правды, не реализация.
Output expectations
Один spec-файл. Не код, не прототип. Документ, из которого реализация становится механической, а верификация — checklist'ом по критериям успеха.
Размер: пропорционален сложности. Простая фича — полстраницы. Распределённая система — несколько страниц. Не раздувай ради объёма, не сжимай ради краткости в ущерб точности.
Язык: следуй языку задачи. Русский запрос — русский spec, английский — английский. Термины оставляй в оригинале.
Good invocations
«Сделай очередь задач для воркеров: 10k задач/день, p99 < 5s, переживает рестарт воркера» → spec фиксирует success criteria (throughput, latency, durability), архитектуру (queue, workers, ack/nack), логику (state transitions задачи, семантика retry/dlq), verification (нагрузочный тест, kill-test воркера).
«Добавь кэш в API» → слишком размыто для spec'а? Нет — spec заставит определить: кэш чего, какой hit rate считается успехом, invalidation стратегия, что при cache stampede. Без spec'а «кэш» = 5 разных реализаций у 5 исполнителей.
«Перепиши импорт CSV на стриминг» → success: memory < 200MB на файл любого размера, throughput > 50k строк/с. Архитектура: streaming pipeline, backpressure. Логика: обработка ошибочной строки, частичный коммит. Verification: тест на 10GB файл, тест на malformed rows.
Bad invocations
«Напиши spec для hello world» — задача тривиальна, spec длиннее кода.
«Сделай рефакторинг этой функции» — контракт не меняется, spec не нужен. Если меняется — тогда да.
«Опиши архитектуру нашего проекта» — это аудит/обзор, а не success-oriented spec. Используй deep-analyze.
Common pitfalls
- Success criteria как фичи. «Поддержка retry» — это фича, не критерий успеха. Критерий: «99% временно-недоступных зависимостей автоматически восстанавливается за < 30s без потери данных».
- Architecture без rationale. «Используем Redis» — почему? Какая альтернатива (Memcached, in-process, Postgres LISTEN) и почему нет? Без этого решение не обосновано, а продиктовано привычкой.
- Логика без ошибок. Описан только happy path. Реальные системы живут в failure modes. Специфицируй ошибки явно: какие, когда, семантика, что делает вызывающий.
- Verification не привязан к успеху. «Напишем unit-тесты» — не план. План: «SC1 → интеграционный тест с 1k RPS на reference-железе, порог p99 50ms, запускать в CI на nightly».
- Spec после кода. Если код уже есть и расходится со spec'ом — это не spec, это апология. Spec пишется до, либо честно фиксирует существующее как baseline.