- PVSM.RU - https://www.pvsm.ru -
Недавно мне нужно было внести изменение в проект, где не было никакого SDD-фреймворка. Вообще никакого, Карл! Ни proposal, ни design, ни дельт спек, ни даже скромного tasks.md в уголке. Я морально приготовился к долгому онбордингу агента: сейчас он будет час ходить по коду, путаться в модулях и спрашивать, где тут вход. А модель просто разобралась в коде, нашла места будущего вмешательства, сделала изменение, и оно спокойно прошло человеческое ревью у кодовнера. Без единой спеки. «А что, так можно было?»
После этого я посмотрел на свой рабочий проект с OpenSpec, на папку openspec/ с её двумя сотнями файлов, и задал себе резонный вопрос: зачем мы генерируем, храним и заносим под git кучу артефактов, которые современной модели не нужны? Кому мы пишем эти бумаги, если главный читатель прекрасно обходится без них?
Из этого вопроса вырос SlimSpec [1], плагин для Claude Code. Он берёт из SDD то, что работает, и выкидывает остальное. На реальном проекте сопоставимое изменение обошлось ему в 29,7M токенов против 45,7M у OpenSpec, а в git не попало ни строчки процессных файлов. Дальше расскажу, откуда взялась идея, как устроен флоу, покажу цифры и то, чем пришлось заплатить. Спойлер: заплатить пришлось, бесплатных обедов не бывает даже в мире LLM.
Ещё недавно модели были слабее, контекст маленьким, сабагентов не было. Работали так: в одной сессии составляешь подробный план, в следующей его реализуешь. Модель постоянно теряла контекст, как золотая рыбка, которая на третьем круге аквариума снова знакомится с замком. И память о проекте приходилось куда-то складывать, иначе каждая сессия начиналась с «привет, я новый джун, расскажите мне всё с начала».
Spec-driven development закрывал ровно эти боли: маленький контекст, отсутствие сабагентов, нужда в подробном плане. Записал всё на бумажку, бумажку положил в репозиторий, следующая сессия бумажку прочитала. Надёжно, как швейцарские часы. Так он и стал стандартом.
Тогда же появились два главных, на мой взгляд, фреймворка: OpenSpec [2] и Superpowers [3]. Я поработал с обоими, основным у меня стал OpenSpec. За что я их ценил:
режим explore (в Superpowers он называется brainstorming), где дизайн складывается раньше плана. Это вообще лучшее, что случилось с AI-разработкой: сначала думаем, потом пишем код, а не наоборот;
сам план и спецификации;
у OpenSpec ещё и мерж спек: в живой спеке остаётся только важное. Superpowers этого лишён напрочь и просто копит design-файлы, как бабушка пакеты под раковиной. Выкинуть жалко, а найти нужный уже нельзя.
В SDD-флоу, каким его видело сообщество, всё это ложилось идеально.
В пет-проектах я долго сидел на OpenSpec с «китайскими» моделями и проблем не видел. Скорее наоборот: код стало легче писать и поддерживать, пропали семантические дубли (ну вы знаете, когда в проекте вдруг находятся три функции форматирования даты), агент чаще делал то, что нужно, и делал правильнее.
На коммерческом проекте мы командой тоже выбрали OpenSpec, и поначалу я был в этом уверен на сто процентов. Через пару месяцев стало понятно, что флоу очень медленный. Особенно когда мы ушли от ручного ревью. Подписка корпоративная, лимиты жалеть незачем, мы шпарили в несколько окон терминала над разными фичами, а процесс всё равно тянулся, как очередь в МФЦ за справкой о том, что у тебя есть справка.
Что тормозило:
После proposal идут ещё четыре артефакта: design, tasks, дельты спек и прочее. Мы их практически не читали. Но они честно писались, коммитились и уезжали в архив. Без бумажки ты букашка, а с бумажкой… ну, тоже букашка, только с бумажкой.
Любая правка в незаархивированном change выливается в ещё один change. Передумал по ходу? Будьте добры, заполните заявление по форме.
Перед архивацией обязателен ребейз. И ещё надо попросить агента «ручками» проверить мерж спек, потому что кто-то другой мог залезть и «испортить» секцию, в которую вписывается MODIFIED-блок.
Мой личный рекорд бюрократии выглядит так. Нужно было выпилить фичу: ненужный кусочек экрана. Задача на удаление, что может быть проще? Удалить код, удалить тесты, закрыть тикет. Итоговый дифф:

Почти 5,5 тысячи строк ушло, и почти столько же пришло. Пришли, конечно, спеки: proposal о том, зачем удаляем, design о том, как удаляем, tasks о том, в каком порядке удаляем, и дельты REMOVED о том, что именно удалили. Чтобы выкинуть 5 тысяч строк, пришлось написать 5 тысяч строк. Это как сдать старый диван на свалку, но сначала заполнить на него техпаспорт, акт приёма-передачи и опись царапин.
А потом случился тот самый проект без фреймворка. И пазл сложился.
Всю механику я давно отдаю сабагентам. Основная сессия у меня превратилась в разговор: брейнштормлю фичу с агентом, и тут же рождаются дизайн и план. Отступления от плана фиксируются там же, новых changes не нужно. Если доработка разрастается, агент сам предлагает вынести её за скоуп, в non-goals. Никаких заявлений, никаких форм. Сказал «давай иначе», и стало иначе.
Выходит, источник знаний о фиче у меня уже есть, это сама сессия. Файлы нужны только на случай, если сессия потеряется или её пережуёт компакшн. Как запасной парашют: хорошо, что он есть, но прыгать с ним каждый день необязательно. Отсюда и «SDD наоборот»: не спека ведёт работу, а работа в конце оставляет после себя спеку.
Вокруг этой идеи я и решил собрать свой фреймворк. Взять лучшее у предшественников и сделать легче, быстрее и дешевле. Классическое «я его слепила из того, что было», только с TDD.
Внутри только скиллы и описания агентов для Claude Code. Скриптов, хуков и CLI нет, ломаться там особо нечему. Ставится и запускается так:
/plugin marketplace add yushman/slimspec
/plugin install slimspec@slimspec
/slimspec <идея>
Весь цикл на одной картинке:
Начинается всё с explore. Сабагент-сканер читает спеки модулей, потом код, и приносит короткую сводку: что тут есть, где что лежит, что может сломаться. Дальше основная сессия меня грилит: один вопрос на одно решение, независимые вопросы приходят пачкой. Ощущение как на собеседовании, только собеседуют твою же идею, и это полезно: половина «очевидных» решений на втором вопросе оказывается не такой уж очевидной. Итог ложится в explore.md: цель, non-goals, решения с отвергнутыми альтернативами, риски. Отдельных proposal и design нет, explore и есть спека изменения. К плану сессия сама не переходит, это решаю я.
В plan планировщик раскладывает работу в tasks.md по волнам. Волна делится на дорожки (lanes) из связанных задач. Дорожки одной волны трогают непересекающиеся файлы, поэтому идут параллельно. Слона едят по частям, но если частей несколько и тарелки разные, их можно есть одновременно. У каждой задачи сразу записан первый падающий тест.
apply короче всех: на дорожку по implementer’у, он идёт по задачам по порядку и на каждую приносит red и green. После волны основная сессия гоняет весь набор тестов, чтобы две параллельные дорожки не подрались где-нибудь на стыке.
С verify интереснее. Ревьюер сверяет результат с планом и дизайном и смотрит, что red упал по делу, а не из-за опечатки или забытого импорта. Тест, который падает с ModuleNotFoundError, это не red, это просто красный. Код-ревью он отдаёт встроенному /code-review. Баги в коде автоматически уходят обратно в apply. Вопросы к дизайну приходят ко мне через refine: он правит explore.md и возвращает в apply только инвалидированные задачи. Галя, у нас отмена, но только трёх позиций, остальные пробиваем. Если два автоматических круга исправлений не помогли, сессия зовёт меня.
Про ground ниже отдельно, там самое главное.
Остановок две: после explore и после plan. На каждой сессия показывает подробный разбор. После explore это дизайн с диаграммами «было/стало» и ссылками на path:line, после plan все волны, дорожки и тест на каждую задачу. Остальное едет само и дёргает меня только вопросами. Можно спокойно пойти за кофе. Можно даже за вторым.
Решения принимает основная сессия. Сабагенты работают по принципу «каждый сверчок знай свой шесток»: сделал свою часть и отчитался. Отчёт короткий и структурированный, без логов и диффов:
status: DONE | BLOCKED | FAILED
task: T3
files: [src/auth/token.ts, src/auth/token.test.ts]
decisions: ["used existing clock abstraction"]
deviations: ["renamed validate → verifyToken"]
tdd:
red: "token.test.ts: rejects expired token — FAIL (expected 401, got 200)"
green: "12 passed"
questions: []
Упёрся в открытый вопрос: останавливается со статусом BLOCKED. Самостоятельно ничего не додумывает и «как-нибудь сам» не решает. Основная сессия спрашивает меня и перезапускает агента с ответом. Контекст основной сессии остаётся чистым, без простыней тестовых логов, но в нём лежит каждое решение и каждый итог.
По-моему, TDD и код-ревью уже стали стандартом, так пусть лучше живут во фреймворке, чем в чьей-то дисциплине. Дисциплина, как известно, заканчивается в пятницу вечером. TDD проверяется не хуком, а по свидетельствам: задачу без red-прогона verify не примет. Ты не пройдёшь! (с) Гэндальф, ревьюер на полставки. Где TDD неприменим (конфиг, стили, миграции), задача помечается test: none — <причина> с альтернативной проверкой, и все такие исключения видны на гейте плана. Спрятать «ой, тут тесты не нужны» в середину списка не получится.
Изменение живёт в .slimspec/changes/<slug>/, там лежат explore.md и tasks.md. Папку SlimSpec сам добавляет в .gitignore, а после ground удаляет. Отряд не заметил потери бойца, и правильно сделал: всё полезное из бойца к этому моменту уже переехало в спеки. Историю хранят коммиты и обновлённые спеки. Потерялась сессия? /slimspec <slug> продолжит с того места, где остановились.
Последний этап, ground, наверное, единственное, что роднит SlimSpec с классическим SDD.
Из изменения дистиллируются долговременные знания: поведение, инварианты, контракты, решения. План и процесс выбрасываются. Кому через полгода интересно, что задача T3 шла во второй волне? Правильно, никому. Дальше это вливается в спеку модуля, и здесь главное отличие от OpenSpec. Мерж идёт не по ADDED/MODIFIED/REMOVED-блокам. Его делает агент, которому понятны причины, структура и дизайн изменения. Противоречащее утверждение он переписывает, а не дописывает рядом. Иначе спека быстро превращается в «было так, но потом стало вот так, хотя смотри пункт 7». Потом агент проверяет, что обновлённая спека покрывает цель изменения и не спорит с принятыми решениями.
Результат ложится во вложенный CLAUDE.md нужного модуля. Claude Code сам подгружает такие файлы, когда работает в этой директории, так что спека попадает в контекст без лишних движений и ровно там, где нужна. Одна спека на модуль вместо россыпи файлов по capability. Не надо помнить, какую спеку подсунуть агенту: он зашёл в модуль, и спека уже там.
Хватит теории, давайте мерить. На SlimSpec я перевёл два своих проекта. Замеры делал на одном из них, looqlog [4]. Это просмотрщик логов на Rust с веб-интерфейсом, раньше он жил на OpenSpec и переехал командой /slimspec:migrate-openspec.
У нас было 23 файла спек, 23 изменения в архиве, 200 файлов в openspec/ и 733 килобайта истории. Не то чтобы всё это было нужно агенту, но раз уж начал собирать артефакты, становится трудно остановиться.
|
|
OpenSpec |
SlimSpec |
|---|---|---|
|
Спеки поведения |
23 файла, 2 941 строка, ~155 КБ |
3 файла, 484 строки, ~34 КБ |
|
Архив изменений |
23 изменения, 12 394 строки, ~733 КБ |
0 |
|
Корневой |
130 строк |
121 строка |
|
Файлов в |
200 |
0 |
Сценарии WHEN/THEN влились в требования, которые они и описывали. Пустые разделы Purpose и шаблонные SHALL ушли (SHALL, SHALL NOT, SHALL ALWAYS… спека звучала как устав караульной службы). Агент читает только спеку модуля, в котором работает: правка в web/ подтягивает ~11 КБ, а не капабилити-файлы со всего дерева. Через четыре изменения на SlimSpec спеки модулей подросли до 4 файлов и 641 строки. Это всё ещё на 78% меньше, чем было у OpenSpec. Спеки растут, но растут как надо: вместе с кодом, а не вместе с бюрократией.
Считал по транскриптам Claude Code. Токены здесь означают весь вход, который обработала модель (input + чтение кэша + запись в кэш), основная сессия и сабагенты вместе. Самая близкая по размеру пара:
|
|
OpenSpec ( |
SlimSpec full ( |
|---|---|---|
|
Изменено кода |
409 строк, 4 файла, 1 модуль |
435 строк, 15 файлов, 3 модуля |
|
Обработано токенов |
45,7M |
29,7M (−35%) |
|
Токенов на строку кода |
~110k |
~68k (−38%) |
|
Ревью |
нет |
2 раунда verify на глубине high, один реальный блокер исправлен |
|
Закоммичено процессных файлов |
~530 строк |
0 |
|
Время с гейтами |
91 мин |
56 мин |
И это при том, что SlimSpec успел больше: 5 вопросов по решениям, 3 гейта, 9 задач в 3 волнах, ground в 4 спеки, ADR и оба README. Блокер, найденный ревьюером, был паникой на крайних датах. Та самая ошибка, которая в проде вылезает ровно 31 декабря в 23:59. В прогоне OpenSpec ревью не было вовсе.
На мелких изменениях то же самое. Два изменения на OpenSpec обработали 31,5M и 45,7M токенов, два на SlimSpec (fast и medium) 6,8M и 12,5M. Один implementer в OpenSpec в одиночку съедал 13–16M токенов, сабагент SlimSpec 0–1M: каждому достаётся одна узкая дорожка, и ему не нужно читать весь мир, чтобы поменять одну функцию.
Теперь оговорки, их лучше назвать самому, пока это не сделали в комментариях. n = 1–2 на подход, проект один. Статистики тут как в анекдоте про среднюю температуру по больнице. Мелкие изменения на SlimSpec были в 5–10 раз меньше по коду, так что часть разницы объясняется просто размером. Часть агентов SlimSpec работала на Sonnet или Haiku. А основная сессия full-прогона тащила посторонний контекст из более ранней работы, и это, наоборот, завышает её счёт. Так что цифры не бенчмарк, а наблюдение. Но наблюдение довольно громкое.
Гладко было на бумаге. Кое-что я сначала сделал иначе и потом переделывал.
Implementer на каждую задачу. Выглядело красиво: свежий агент, узкий контекст, чистота и порядок. На деле каждый холодный старт заново читал explore.md, спеки и код. Сколько задач, столько раз «здравствуйте, а что у вас тут за проект?». Теперь один implementer ведёт дорожку из связанных задач.
Worktree для изоляции в режиме full. Не взлетело, потому что worktree сабагента ответвляется от закоммиченного состояния и не видит незакоммиченных результатов прошлых волн. Вторая волна честно строила дом без первого этажа. Пришлось бы коммитить каждую волну. Оставил параллелизм по непересекающимся файлам в одном рабочем дереве.
Хотел хук, который не даёт править код без падающего теста. Звучит строго и надёжно. Но промпт-хук не может проверить, что red-прогон действительно был, а хуки плагина включены всегда, независимо от режима. Охранник, который не умеет проверять пропуска, но стоит у каждой двери. Проверка переехала в verify.
С настройкой вышла смешная история: сначала написал bash-визард. С менюшками, с вопросами, всё как у людей. Потом выяснилось, что скилл не умеет вести интерактивный скрипт, а ! в сессии работает без TTY. Визард получился красивый, но запустить его было нельзя. Сейчас /slimspec:init просто задаёт вопросы прямо в сессии.
И мелочь, которая раздражала каждый день: в explore вопросы шли строго по одному. Ждёшь круг на каждое решение, даже когда все вопросы известны заранее. Ощущение как в техподдержке: «ваш вопрос очень важен для нас, оставайтесь на линии». Теперь независимые идут пачкой, до четырёх за раз.
Ложки нашлись, но осадочек остался. Вот что ушло вместе с лишними артефактами:
Сценариев как готового списка тест-кейсов больше нет.
Обоснования отдельных изменений частично пропали. Что-то осталось в ADR, остальное только в git-истории. Если вы любите археологию по git log, вам понравится.
Самая большая спека модуля (~14 КБ) грузится целиком при любой работе в этом модуле.
Работает только с Claude Code. OpenSpec поддерживает 30+ AI-инструментов, Superpowers тоже работает со многими агентами и умеет кучу всего помимо спек: отладку, worktree, ревью. SlimSpec закрывает только spec-driven цикл и не притворяется швейцарским ножом.
Конфиг необязателен, у каждого ключа есть дефолт. Не хотите ничего настраивать? Не настраивайте, всё заведётся и так. /slimspec:init спросит всё в сессии и запишет .slimspec/config.yaml:
mode: medium # fast | medium | full
spec:
format: claude-md # claude-md | readme | central | native | none
unit: auto # auto (по билд-файлам) | glob директорий, напр. "src/*/"
adr: false # дополнительно вести решения в docs/adr/NNNN-*.md
test: auto # или явная команда
commit: none # none | lane | wave
apply:
agents: 3 # максимум параллельных implementer
review:
depth: auto # auto (по режиму) | low | medium | high
models: {} # модели по ролям: scanner, planner, implementer, reviewer, grounder
Пара слов о том, что тут не очевидно.
mode задаёт вес цикла. В fast explore и plan живут в одном файле, вопросов не больше трёх, implementer один, ревью на low. Это для «поменять текст кнопки и не сойти с ума». medium добавляет сканер, грилинг, планировщик и параллельные дорожки, ревью на medium. full сверху ставит явный гейт на explore.md и ревью на high, для изменений, после которых хочется спать спокойно. Можно вообще не выбирать: после скана /slimspec сам предложит режим по размеру изменения.
spec.format решает, где живут спеки. По умолчанию это вложенные CLAUDE.md. Можно README.md рядом с кодом, общую папку specs/ для фич поперёк модулей, нативные доки языка (Go doc.go, Rust //!, Python docstring, KDoc) или none, тогда ground пропускается. Для тех, кто живёт по принципу «код и есть документация».
spec.unit говорит, что считать модулем; auto находит границы по package.json, go.mod, Cargo.toml, build.gradle(.kts), pyproject.toml.
commit включает коммит после каждой дорожки или волны. Коммитит только основная сессия, агенты никогда. Пушить SlimSpec не умеет в принципе, и это фича: никаких сюрпризов в main в три часа ночи.
models раздаёт модели по ролям. По умолчанию сканер и implementer на Sonnet, а планировщик, ревьюер и grounder на Opus. Думать дорого, делать дешевле, вот и вся экономика.
Если проект уже сидит на OpenSpec или Superpowers, есть /slimspec:migrate-openspec и /slimspec:migrate-superpowers. Переносятся только спеки: каждая привязывается к модулям, сжимается и сверяется с кодом. Где код расходится со спекой, решаете вы, потому что иногда врёт спека, а иногда код, и угадывать тут нельзя. Старые файлы удаляются только после вашего подтверждения.
Сильным моделям не нужны тяжёлые спеки. Им достаточно подсказать, что делать и где искать, остальное они восстановят из кода быстрее, чем дочитают четыре артефакта. Токены, которые уходят на proposal, который никто не откроет, лучше потратить на следующую фичу. А ещё лучше на новый проект. Миллион токенов туда, миллион сюда, а в итоге набегает на ещё один пет-проект, который давно лежит в списке «когда-нибудь».
Если вы тоже упирались в медленный SDD-флоу, попробуйте SlimSpec на одном изменении и сравните со своим текущим процессом. Особенно интересно, как он поведёт себя в команде и на проектах крупнее моих. Пишите в комментариях или в issues, ругать тоже можно, только с цифрами.
SlimSpec на GitHub [1] · Сайт [5]
Автор: yushman
Источник [6]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/tdd/460704
Ссылки в тексте:
[1] SlimSpec: https://github.com/yushman/slimspec/blob/main/README.ru.md
[2] OpenSpec: https://github.com/Fission-AI/OpenSpec
[3] Superpowers: https://github.com/obra/superpowers
[4] looqlog: https://github.com/yushman/looqlog
[5] Сайт: https://yushman.github.io/slimspec/ru/
[6] Источник: https://habr.com/ru/articles/1098516/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1098516
Нажмите здесь для печати.