Улучшенный Spec-driven-dev. Это SDD + handoff’ы — передний край лучших мировых практик как для соло-разработки, так и для небольших команд. Это не история про рой агентов, которые в абстрактном цикле «план → код → ревью → тесты → деплой» самостоятельно везут продукт, синхронизируясь друг с другом через воркфлоу. У нас нет личного датацентра или полумиллиона долларов на токены.
В конце будет ссылка на репозиторий-шаблон, который можно скачать, или просто указать, и сказать Opus’у (Fable’у): «сделай мне такую же систему спецификаций» — дальше он справится сам.
Проблемы, которые решаем
1. Чистота контекста. В контексте модели с одной стороны должно быть необходимое для задачи — но с другой не должно быть лишнего. Лишнее повышает когнитивную нагрузку, снижает качество решения. Правильный контекст — это правильный ответ, правильный код, правильное решение. Контекст к тому же конечный и платный — вопрос «что НЕ загружать» не менее важен, чем «что загружать».
2. Переключение с задачи на задачу. Собрать контекст одной задачи можно и вручную, прямо в промпте. Но задач, как правило, несколько, и они параллельны: аудит и фиксы серверного кода, дизайн клиентского приложения, переезд на новый CI/CD, концептуальное планирование новой фичи. У каждой — свой набор нужных документов, своё состояние «сделано/осталось», свои принятые решения. К тому же сессия конечна: даже при одной задаче контекст, данный в начале сессии, при передаче его в другую сессию уже не актуален. При переключении между задачами и между сессиями мы платим временем, качеством и токенами.
Часть первая: SDD
Карты
Исходная позиция: Solution-монорепозиторий с разношёрстным набором проектов — приложения, микросервисы, общие пакеты, devops-манифесты.
У каждого такого подпроекта — своя папка specs/ со своей локальной спецификацией и своей локальной картой. А в корне лежит корневая карта спецификаций, которая ссылается на карты подпроектов. Получается иерархия, и она даёт главное: из корня можно писать промпт про любую часть solution — модель найдёт нужное сама, спустившись по картам за два-три перехода и не загрузив по дороге ничего лишнего.
Уровней иерархии два или три: корень → подпроект → пакет. Больше — сомнительно: каждый уровень — это переход, который читатель (LLM) должен совершить, прежде чем доберётся до содержания.
Инвариант достижимости: каждый файл спецификации достижим по цепочке markdown-ссылок хотя бы от одной карты (голый текстовый путь связью не считается — его не видит ни IDE, ни аудит). Недостижимый файл — сирота; документ, которого никто не найдёт, не существует. Сирот ловит специальный аудит-скрипт.
Жанры
Каждый файл спецификации принадлежит жанру. Жанровость — из Diátaxis, но таксономия своя.
as-built — описание существующего кода, включая архитектурные обзоры. Обязан следовать за кодом — или честно писать, что устарел (об этом ниже). Уровень детализации удобно думать по C4: корневая карта и корневые as-built-спеки — это System Context и Containers (solution целиком и его приложения-контейнеры); спеки подпроекта — Container (внутренности одного контейнера: домены, сервисы, сторы); третий уровень — Component. Уровень Code спекам не отдаём: код лучше всего описывает сам себя.
plan — план реализации конкретного трека или фичи. Сердце рабочей сессии: именно вокруг плана крутится реализация. Принципиально временный: выполненный план, который прикидывается актуальным документом, — это дезинформация. После реализации план умирает: по умолчанию — tombstone (ценность уже дистиллирована в as-built и бэклог; о tombstone ниже); superseded — если у плана есть преемник; archive — если он сохраняет справочную ценность как история решений.
reference — надкодовые справочники, исследования, обоснования, рабочие тетради. Как as-built, только не про код: следовать за реальностью не обязан, ценен как материал.
vision — надкодовое видение продукта или фичи. Кода ещё нет, или код не обязан соответствовать. Сюда же — бизнес-план, продуктовые гипотезы: всё, что «про что мы делаем», а не «как оно устроено». Примерно как plan, но не для кода.
log — журнал архитектурных решений, он же ADR (Architecture Decision Records). Append-only: каждая запись — «контекст → решение → последствия», записи имеют собственные статусы. Отвечает на вечный вопрос «почему здесь так странно сделано» — за абзац, а не за археологическую экспедицию по git-истории.
Статусы
Вторая ось, ортогональная жанру: где документ в жизненном цикле.
|
Статус |
Смысл |
|---|---|
|
|
Брейншторм/предложение, не принято |
|
|
Принято к реализации (для plan/vision) |
|
|
Актуально; для as-built — соответствует коду |
|
|
Известен дрейф от кода/реальности, ждёт сверки |
|
|
Заменён другим документом — обязательна ссылка на преемника |
|
|
Историческое, не поддерживается, ценность справочная |
Важно! Самый ценный статус в таблице — stale. Классическое требование «всегда обновляй документацию вместе с кодом» не всегда выполнимо. HDD правило честнее: код и его as-built-спека правятся в одной сессии; не можешь обновить спеку сейчас — поставь ей stale. Долг не погашен, но он явно помечен. Модель, увидев stale, знает: этому документу не верить, перепроверь по коду. Дезинформации не произошло — произошла информация о недостоверности.
Итого каждый файл спецификации несёт под заголовком одну строку:
Статус: as-built / current · сверено: 2026-07-03
Жанр, статус и дата сверки. Отметим: сверено: — это дата последней сверки содержимого с кодом, а не дата правки текста. Поправить опечатку — не значит сверить. «Current, сверено вчера» и «current, сверено полгода назад» читаются очень по-разному.
Tombstone
У документа есть жизненный цикл — значит должна быть смерть. Если документацию не удалять («вдруг пригодится»), она копится. И тогда кладбище прикидывается библиотекой — это прямой удар по чистоте контекста.
Протокол смерти — два шага. Документ удаляется физически — архив у вас уже есть, он называется git. В карте на его месте остаётся надгробие, одна строка: «spec-server-audit.md — удалена 2026-07-03, git-история».
Что решает надгробие: файл мёртвой спецификации не попадает случайно в живой контекст. С другой стороны, мы знаем, что этот файл удалён и когда удалён — об этом есть информация. И не думаем, что мы его просто потеряли. Если вдруг он зачем то нужен (на самом деле нет) — его можно достать из git, а не держать 150 килобайт в живом каталоге.
Бэклоги
Ещё одна эффективная фича: два файла, backlog.md и backlog-resolved.md. Инвариант: задача живёт ровно в одном из них. Открыл задачу — строка в бэклоге; закрыл — строка переезжает в resolved вместе с описанием решения.
Чем это хорошо для ИИ. Открытый бэклог — компактный, всегда актуальный ответ на «что у нас не сделано», который дёшево грузится в контекст целиком. Резолвнутый — база прецедентов: прежде чем чинить баг, модель может грепнуть resolved и обнаружить, что похожее уже чинили, вот таким-то способом, — и не переизобретать решение (и не перевносить старый баг). А инвариант единственного местоположения гарантирует, что задача не числится одновременно «открытой» в одном файле и «закрытой» в другом — модель тут уязвима больше, чем человек. Для модели такой трекер в git внезапно (на самом деле очевидно) удобнее MCP к Jira: файл грузится в контекст одним чтением и грепается офлайн, а Jira через MCP — это tool-call на каждое действие, пагинация и JSON-обёртки, это токены, латентность и шум — снижение качества контекста, снижение качества решения. Главное — атомарность: задача закрывается в том же коммите, что код и спека, — одна транзакция правды. Саму Jira ничто не мешает вести для нужд стейкхолдеров с дашбордами. Оговорка честности: синхронизация за рамками HDD.
Часть вторая: HANDOFF
Если SDD это про хранение и организацию спецификаций, то Handoff (буквально передача) — это про управление контекстом, про передачу контекста между сессиями и между задачами. Здесь LLM словно заступает на вахту. И для этого нам нужен вахтовый журнал.
Индекс: TRACKS.md
Трек — это некоторая задача, она эволюционирует, она суперсидируется следующими задачами, она расщепляется на подзадачи (на новые треки). Наконец, она просто выполняется. В корневом specs/ лежит TRACKS.md — индекс живых треков, одна строка на трек:
- **Фиксы аудита сервера** — [handoff](server/specs/handoff-server-audit-fixes.md) —
active, 2026-07-02, next: канал ошибок concept.service.ts
Суть одной фразой, ссылка на handoff, статус (active / paused — и почему / blocked — и на чём), дата последнего касания, следующий шаг. Никакого содержания — только указатели. Весь файл читается за доли секунды и отвечает на вопрос «что в работе и за что браться». Переключение между задачами — это выбор handoff’а.
Handoff
Сам handoff — файл handoff-<slug>.md, лежит рядом с зоной работ: у серверного трека — в спеках сервера, у продуктового — в корневых. Файл один на трек, правится по месту, версии хранит git. Внутри:
-
Что загрузить в начале сессии — нумерованный список с «зачем» на каждый пункт. И обязательно анти-список: что НЕ загружать целиком (тяжёлые артефакты — грепать, не читать). Handoff — это рецепт сборки контекста под задачу: решение проблемы 1 на уровне трека.
-
Задача и методология — выработанный протокол работы, дословно. Например: разведка перед правкой → доложить и предложить → дождаться одобрения → фикс с тестом, причём новый тест прогоняется на дофиксовой версии кода — доказать, что он вообще ловит баг.
-
Состояние — сделано / осталось / замечено попутно, но вне scope.
-
Уроки методические — повторяющиеся вновь и вновь проблемы, или требуемые от разработчика действия.
-
Не перерешивать — решения трека с однострочным обоснованием каждого. Пересмотр решения не стирает его молча, а помечает: ⚠, дата, улика.
-
Первый шаг новой сессии — конкретная точка входа: что прочитать, что разведать, что спросить у человека.
Ритм и закрытие
Рабочий день с этой конструкцией выглядит так. Начало сессии: модель читает TRACKS.md, загружает handoff нужного трека, из него — ровно указанный контекст. Конец сессии: обновить handoff (состояние, уроки, решения) и строку в индексе (дата, next). Всё.
Закрытие трека. Handoff удаляется — но через дистилляцию: решения «не перерешивать» и всё полезное переезжает в постоянные спеки; итог в одно-два предложения — в TRACKS-LOG.md, журнал закрытых треков; строка из индекса убирается. Новые Handoff клонируется из шаблона и дополняются задачей из промпта. Старые удаляются — операционная деятельность сильно загрязняет репозиторий.
Замыкает систему одна инструкция в конфиге агента (у Claude Code это CLAUDE.md): начинаешь работу по треку — загрузи его handoff; заканчиваешь сессию — обнови handoff и строку в TRACKS.md. Это работает — у Claude с дисциплиной всё лучше и лучше.
Чем это отличается от Spec Kit и Kiro
Spec-driven сейчас ассоциируется с GitHub Spec Kit и Amazon Kiro, чем же отличается HDD? Спецификация у Kit и Kiro — это вход генерации: specify → plan → tasks → код фичи. Спека смотрит вперёд и фактически умирает после мерджа. В HDD спеки смотрят на существующую систему и обязаны оставаться правдой, а handoff удерживает правду о незавершённой работе. Поток Kit и Kiro укладывается в HDD жанр plan — с той разницей, что после реализации план умирает (tombstone), а as-built продолжает жить.
Заимствования HDD: статусы жизненного цикла — из ADR/RFC-практики; жанровость — Diátaxis; уровни зума карт — C4; «документация в репо + механический аудит» — docs-as-code как он есть. Оригинальны здесь тройка «жанр × статус × сверено» на каждом файле, инвариант достижимости и handoff-слой целиком.
Ограничения
Ещё раз: это не история про рой агентов, это — про соло разработку или небольшую команду по соответствующе месячной подписке. Там, где MCP к Confluence и к Jira — излишни и контрпродуктивны. С другой стороны: соло-разработка в современную эпоху всё более распространена. Более того, LLM делают возможным для вести несколько проектов силами одного человека.
Репозиторий-шаблон
Всё описанное упаковано в репозиторий-шаблон: github.com/yetanothervan/handoff-driven-development
Внутри: spec-specs.md — правила системы одним документом; заготовка specs-map.md; handoff-template.md; TRACKS.md и TRACKS-LOG.md; аудит-скрипт specs-audit.py; готовый блок для CLAUDE.md.
Применять так: клонируйте — или просто дайте ссылку своему агенту с промптом дословно:
Посмотри репозиторий https://github.com/yetanothervan/handoff-driven-development Применим в моём проекте такую же систему спецификаций: разложи карты и правила по нашей структуре, заведи TRACKS.md и предложи первые треки.
Дальше он разложит сам.
Автор: oggr


