Симптом
LLM в кодовой базе ускоряет одного разработчика. Команда от этого не ускоряется — наоборот, на ревью обрушивается поток сгенерированного кода, который никто не успевает понять. Спека, написанная на старте задачи, через неделю уже не описывает то, что в master. Кто-то правит код, кто-то правит .md, через месяц расхождение замолчано.
Это не про дисциплину команды. Это про архитектуру процесса, в которой “спека” и “код” не имеют формальной связи.
Диагноз от Thoughtworks
28 апреля 2026 на сайте Мартина Фаулера вышла статья Structured Prompt-Driven Development от Wei Zhang и Jessie Xia. Они формулируют проблему точнее, чем я: “Local speed improves. But that doesn’t automatically translate into system-level throughput.”
Их предложение в трёх пунктах:
- Промпт — это first-class артефакт. Версионируется, ревьюется, переиспользуется как код. Не реплика в чате.
- REASONS Canvas — 7-частная структура промпта: Requirements, Entities, Approach, Structure, Operations, Norms, Safeguards. Первые четыре — абстракция, пятый — исполнение, последние два — governance.
- Замкнутая петля между промптом и кодом с правилом, что обновлять первым:
- изменение поведения -> сначала промпт, потом код
- рефакторинг -> сначала код, потом sync обратно в промпт
Третий пункт — главное. Он превращает вечный спор “что source of truth” в процедуру.
Где это совпало с моей практикой
У меня уже был свой spec-driven workflow:
~/my/archlint/templates/specifications/spec-template.md— шаблон спеки с разделами Architecture, Requirements, Acceptance Criteria, Implementation Steps. Размерные градации XS/S/M/L/XL.- Правило в
~/.claude/rules/spec-workflow.md: “задача >30 минут или >3 шагов — обязательно спека до старта”. - Команда
/ms-add-specв Claude Code, которая генерирует спеку под задачу. archlint— статический анализатор, который валидирует архитектурные правила (200+) на графе из AST.
REASONS Canvas почти один в один ложится на мой шаблон:
| REASONS | Мой шаблон |
|---|---|
| R Requirements | ## Requirements (FR1, FR2, …) |
| E Entities | ## Architecture / Data Model (UML Class) |
| A Approach | ## Overview / Solution Summary |
| S Structure | ## Architecture / Component Overview (C4) |
| O Operations | ## Implementation Steps |
| N Norms | (не было отдельного раздела) |
| S Safeguards | (не было отдельного раздела) |
Совпадение на 70-80%. Архитектурный governance у меня вообще сильнее — archlint проверяет автоматически то, что в SPDD держится на ревьюере-человеке.
Где SPDD добавил то, чего не было
Два пункта, которые у меня отсутствовали или были сформулированы неверно.
1. Спека “неизменна в процессе”
В моём spec-workflow.md буквально стояла формулировка:
Спека = ЧТО делать (неизменна в процессе)
Это противоположно идее живого артефакта. Спека написана, согласована, перенесена в inprogress/ — и потом никем не трогается, пока задача не закроется. На практике это значит, что любая правка реализации, отличающаяся от плана, проваливается между спекой и кодом.
2. Norms и Safeguards неявные
Стандарты команды (как именно мы оборачиваем ошибки, какой logger, какие naming-конвенции) у меня живут в куче .md файлов: ~/.claude/rules/architecture.md, проектные CLAUDE.md, в чате. На уровне отдельной спеки их явно никто не выносит. Авторы SPDD выделяют:
- Norms — стандарты как принято писать. Часть автоматизирована (golangci-lint, archlint), часть нет.
- Safeguards — неприкосновенные инварианты. Нарушение — стоп, не warning. Обратная совместимость, perf budgets, security boundaries.
Когда они в одной странице со спекой, тихий рефактор поперёк стандарта становится заметным на ревью.
Что я в итоге сделал
Два патча, оба сегодня.
Патч 1: ~/.claude/rules/spec-workflow.md
Удалил “Спека неизменна”. Заменил на “Спека — живой контракт, синхронизирован с кодом всегда”. Добавил раздел “Двусторонняя синхронизация” с явным правилом prompt-first vs code-first:
| |
И отдельный раздел “Norms и Safeguards: governance внутри спеки” с примерами и привязкой к archlint/golangci-lint.
Патч 2: ~/my/archlint/templates/specifications/spec-template.md
Добавил две секции после Acceptance Criteria:
| |
Размерные градации те же: для XS Safeguards обычно не нужны, для M/L/XL — обязательны.
Что я НЕ взял
Не взял CLI openspdd и команду /spdd-prompt-update. Слишком много церемонии для одиночной работы и для команды без отдельного workflow-инженера. У меня та же дисциплина держится на:
/ms-add-spec— создать спеку/ms-checkpoint— зафиксировать прогресс на длинной задачеarchlint— валидация Norms+Safeguards автоматически где можно- Code review через GitLab — двусторонний sync проверяется на ревью
Не взял правило “никогда не редактировать промпт руками”. У них это compensation за CLI-managed lifecycle. У меня его нет, и руками править .md спеку — нормальная операция.
Не взял заявление про “~99% intent alignment”. Это маркетинг, кейс N=1.
Двойная оптика
Технический слой статьи: дисциплина для AI-кодинга в команде.
Архитектура мышления за этим: проблема, которую решают авторы — не “AI пишет неправильный код”, а “bandwidth ревьюера не растёт со скоростью генератора”. Когда LLM выдаёт результат быстрее, чем человек успевает его понять, узкое место — когнитивная пропускная способность того, кто принимает изменения. SPDD сжимает то, на чём держится ревью, до одного артефакта (Canvas), чтобы он влезал в bandwidth.
Это та же задача, про которую я говорил на Стачке — контроль сложности через граф. Только на уровне процесса, а не статического анализа.
archlint = governance внутри кода (граф, правила, инварианты).
SPDD/спека = governance над изменениями (контракт между намерением и реализацией).
Эти две вещи комплементарны, не конкурируют. Если у тебя есть один без другого, ты получаешь либо красивые архитектурные правила без контракта на изменения, либо пухлые спеки без автоматической проверки.
Когда есть оба — каждый коммит проходит и через “не сломал ли архитектуру” (archlint), и через “соответствует ли намерению” (спека). На ревьюера падает только то, что обе автоматизации пропустили.
Ссылки
- Оригинал статьи: Structured Prompt-Driven Development
openspdd(Thoughtworks-affiliated CLI): https://github.com/gszhangwei/open-spdd- archlint: https://github.com/mshogin/archlint