SDD-V1.CLEARN.RU

Spec-Driven Development · Qwen Code + OpenSpec

Где живут спецификации

Решение для команды: микросервисы, разные репозитории, свои NuGet-библиотеки. Варианты, подводные камни и рекомендация — чтобы выбрать осознанно.

01 · Проблема

Требования, которых нет

  • Каждый инженер работает с ИИ-агентом по-своему: промпты в заметках, переписки в чатах, контекст в головах.
  • Требования нигде не записаны так, чтобы их читал и человек, и агент.
  • Когда агент «уверенно строит не то» — виноват не агент: ему дали неявное знание и попросили явный результат.
Реальный инцидент Агент «починил» возврат платежа, разрешив рефанд в любом статусе заказа. Про статусы не было ни слова в промпте — а в чате три недели назад было.

02 · Идея

Промпт — пунктир, спецификация — сплошная линия

Промпт
  • существует один раз, в одном чате
  • нельзя отревьюить и переиспользовать
  • не отвечает через месяц на «почему так?»
Спецификация
  • лежит в git: история, автор, ревью
  • написана до кода — договариваемся, пока дёшево
  • источник истины для любого следующего изменения
SDD одной строкой Изменение системы начинается со спеки: что меняем, зачем, какие сценарии должны стать правдой. Код — производная от спеки, а не наоборот.

03 · Инструменты

Qwen Code + OpenSpec: цикл из четырёх команд

$ npm install -g @fission-ai/openspec@latest
$ cd payments-service && openspec init --tools qwen

qwen> /opsx-explore                       # обсудить идею (ничего не создаёт)
qwen> /opsx-propose limit-refund-window   # агент пишет спеку — вы ревьюите
      ✓ proposal.md   зачем и что меняем
      ✓ specs/        требования + сценарии GIVEN–WHEN–THEN
      ✓ design.md     техническое решение
      ✓ tasks.md      чек-лист реализации
qwen> /opsx-apply                         # реализация по чек-листу
qwen> /opsx-archive                       # дельта влилась в openspec/specs/
Чем не waterfall Спека размером с изменение, а не с проект. Возврат к артефактам — норма. После archive спека живёт как актуальное описание системы.

04 · Наш контекст

Что имеем на входе

Сервисы
7 микросервисов на .NET — у каждого свой репозиторий
Библиотеки
2 NuGet-пакета в отдельном репозитории, свой фид
Всего репозиториев
11: сервисы, фронтенды, библиотеки, инфраструктура
Команда
6 инженеров, все уже пользуются агентами — каждый по-своему
Главный вопрос openspec init в одном репо тривиален. Но где живёт спецификация, когда репозиториев одиннадцать?

05 · Развилка №1 — код

Монорепозиторий или мультирепо

МонорепозиторийМультирепо
Сквозное изменениеодин PR, ревьюер видит всёN PR, согласование руками
Атомарность контрактовкод и контракт меняются вместеверсии пакетов, окно рассинхрона
Права и владениесложнее разграничитьграница репо = граница команды
CIтяжелеет, нужна селективная сборкапростые независимые пайплайны
Контекст для агентавсё в одной рабочей копииагент видит один репо
Переезддорогой разовый проектмы уже здесь
Вывод Переезд в монорепо ради SDD — лечение головной боли трепанацией. Мультирепо — не ошибка, а контекст, в котором проектируем размещение спек.

06 · Развилка №2 — спеки

Три варианта размещения спецификаций

  • А. openspec/ в каждом репозитории — спека рядом с кодом.
  • Б. Центральный репозиторий спецификаций — OpenSpec Store: отдельный репо, чья единственная работа — планирование.
  • В. Гибрид: локальные спеки в сервисах + store для всего, что пересекает границы репозиториев.

Дальше — каждый вариант с плюсами, минусами и подводными камнями. Решение в конце.

07 · Вариант А

openspec/ в каждом репозитории

Плюсы
  • спека и код в одном PR — атомарно
  • агент видит спеки сервиса без настройки
  • владение очевидно: чей сервис, того и спека
  • минимальное внедрение: openspec init и всё
Минусы и камни
  • сквозная фича размазывается: общий контракт дублируется в 2–3 репо
  • копии контракта разъезжаются к концу квартала — молча
  • требования к NuGet-библиотекам живут в N местах
  • нет точки, где команда видит систему целиком
Когда ок Сервисы почти не общаются, общих библиотек нет. Не наш случай.

08 · Вариант Б

Центральный репозиторий спецификаций (Store)

            syn-specs  (store: планирование в своём репо)
            ├── .openspec-store/store.yaml
            └── openspec/
                ├── specs/      что истинно
                └── changes/    что в работе
                      ▲
        ┌─────────────┼─────────────┐
   payments-svc   orders-svc    syn-libs (NuGet)
Плюсы
  • один источник истины для всей системы
  • сквозные фичи планируются в одном месте
  • можно планировать до того, как код существует
Минусы и камни
  • спека и код — в разных PR: нужна дисциплина ссылок
  • два PR на любую мелочь — трение растёт
  • Stores — beta: форматы и флаги могут меняться
  • store никогда не синкается сам — устаревший клон врёт, пока не сделаешь git pull

09 · Вариант В

Гибрид: локальные спеки + store для контрактов

  • Спеки одного сервиса — в его репозитории (как в А).
  • Всё, что пересекает границу репо — контракты API, схемы событий, обещания библиотек, — в store (как в Б).
  • Связь — одна строка в конфиге; references — read-only контекст для агента.
# payments-service/openspec/config.yaml
references:
  - syn-specs
Плюсы / камни
  • локальное — дёшево и атомарно; общее — централизовано
  • граница «что в store» = настоящая архитектурная граница
  • камень: нужно одно командное соглашение, куда что кладём
  • та же beta-оговорка по Stores

10 · Сравнение

Одним взглядом

А: везде свояБ: всё в storeВ: гибрид
Локальная фичаодин PRдва репо на мелочьодин PR
Сквозная фичаразмазанаодно местоконтракт в store
NuGet-библиотекитребования в N репоцентрализованоспека в репо либы, контракт в store
Видимость системынетполнаяпо контрактам
Сложность внедренияминимальнаясредняясредняя
Зрелость инструментастабильноbetabeta (references)

11 · Особый случай

NuGet-библиотека: два вида требований — два адреса

ТребованиеПримерГде спека
Публичный контракт пакета «событие сериализуется как raw JSON без envelope» store — его читают все потребители
Реализация пакета «кеш резолвера не аллоцирует на горячем пути» openspec/ в репозитории библиотек
Правило Потребитель пакета не должен ходить в чужой репозиторий, чтобы узнать, что ему обещано. Обещания — в store; как обещание выполнено — приватное дело библиотеки.

12 · Рекомендация

Вариант В — гибрид

  • В каждом сервисном репо — свой openspec/.
  • Один store — для контрактов между сервисами и обещаний библиотек.
  • Сквозная фича: контракт ревьюится в store до первой строки кода, потом независимые implement-changes в каждом репо.
Практическое правило Спека живёт там, где живёт ревью её кода. Контракт живёт там, где его читают все.
Страховка от beta Store — это просто git-репозиторий со спеками. Если Stores изменятся — клонируем рядом и даём агенту путь; references лишь автоматизирует то же самое.

13 · Подводные камни

Типовые ошибки внедрения

ОшибкаСимптомЛечение
Спека после кода«допишу перед мержем»propose — вход в задачу, до первой строки кода
Спека-роман40 требований на изменениеодно изменение = одна связная дельта
Всё в storeдва PR на правку текстаstore — только для пересекающего границы
Мёртвый архивchanges/ пухнетarchive — часть закрытия задачи
Спека без ревьюагент написал, никто не прочёлу спеки тот же ревьюер, что у кода
Карго-культ сценариевGIVEN/WHEN/THEN пересказывают кодсценарий — поведение для потребителя

14 · План

Шесть недель до нормы

Недели 1–2 · Пилот
Один репозиторий, один волонтёр, 3–4 реальные задачи через полный цикл. Метрика: сколько ошибок поймало ревью спеки.
Недели 3–4 · Границы
Ставим store, фиксируем правило размещения — как первую спеку самого store. Подключаем references по мере надобности.
Недели 5–6 · Гейты
openspec validate --all в CI каждого репо со спеками. Конвенция ревью: сначала спека, потом код.
Понедельник
npm i -g @fission-ai/openspec, пилотный репо, openspec init --tools qwen, первая задача через /opsx-propose.

Решение за командой

Вопросы на обсуждение

  • Согласны ли с гибридом — или у нас есть довод в пользу А или Б?
  • Кто владеет store и ревьюит контракты?
  • Какой сервис берём в пилот и кто волонтёр?
→ / пробел — дальше · ← — назад · Home / End