Перейти к содержимому
Программа SDDSDD.3 Инструменты SDD

OpenSpec

OpenSpec держит актуальные спецификации системы в одном месте, а каждую доработку оформляет как предложение изменения с дельтами требований, которые при архивировании сливаются в общую картину. Установка, команды, формат дельт, практика на листе ожидания в существующем проекте с настоящим выводом CLI, сравнение со Spec Kit.

УРОКsdd/sdd-3-tools/02-openspec.mdx2 чУрок 2 из 3
После урока вы сможете
  • Объяснить модель OpenSpec — источник истины в openspec/specs/ и папки изменений с предложением, дельтами, дизайном и задачами
  • Установить OpenSpec, подключить агента и провести изменение через propose, apply и archive в существующем проекте
  • Писать дельты требований (ADDED, MODIFIED, REMOVED, RENAMED) так, чтобы валидатор и архивирование их приняли и ничего не потерялось
  • Сравнить OpenSpec и Spec Kit и выбрать инструмент под новый проект или под развитие старого

Представьте онлайн-школу через полгода работы по Spec Kit. В specs/ лежат папки 001-enrollment, 004-waitlist, 009-cancel-email, 015-waitlist-offer-12h… Новый разработчик спрашивает: «Как сейчас работает отмена записи?» Чтобы ответить, нужно открыть четыре spec.md, понять, какой из них новее, и мысленно наложить их друг на друга. Тот же вопрос задаст и агент — и, скорее всего, прочитает не тот файл.

Большая часть настоящей работы — не новые проекты, а изменения в живых системах. Это называют развитием существующей системыразвитие существующей системы (brownfield)EN brownfield projectРабота в живом проекте с историей, пользователями и унаследованным кодом. Спецификации обычно пишут не на всю систему, а на то, что меняют сейчас; так устроен OpenSpec.. OpenSpecOpenSpecEN OpenSpecОткрытый инструмент SDD (Fission-AI/OpenSpec, MIT, CLI openspec на Node.js). Актуальные спецификации лежат в openspec/specs/, каждая доработка — папка в openspec/changes/ с предложением, дельтами требований, дизайном и задачами; при архивировании дельты сливаются в specs/. построен вокруг этой ситуации. Его идея похожа на git, только для требований: есть «основная ветка» — актуальные спецификации того, как система работает сейчас, и есть изменения — аналог pull request с диффом требований. Когда изменение сделано, его дифф вливается в основную ветку. Ответ на вопрос «как сейчас работает отмена» всегда в одном файле.

После openspec init и пары изменений проект выглядит так (схема из docs/getting-started.md):

openspec/
├── specs/ # источник истины: как система работает сейчас
│ └── <возможность>/
│ └── spec.md
├── changes/ # предлагаемые изменения, по папке на каждое
│ ├── <имя-изменения>/
│ │ ├── proposal.md # зачем и что меняем
│ │ ├── design.md # как (для простых изменений может отсутствовать)
│ │ ├── tasks.md # чек-лист реализации
│ │ └── specs/ # дельты: что меняется в требованиях
│ │ └── <возможность>/
│ │ └── spec.md
│ └── archive/ # завершённые изменения: ГГГГ-ММ-ДД-<имя>/
└── config.yaml # настройки проекта: схема, контекст, правила

Главные понятия:

  • Спецификация в openspec/specs/ описывает поведение одной возможностивозможность (capability) в OpenSpecEN capabilityУстойчивая область поведения системы, у которой своя спецификация openspec/specs/имя/spec.md, например enrollment. Называют по поведению, а не по задаче: enrollment, а не add-waitlist. Предложение изменения перечисляет новые и изменяемые возможности. (capability): например, enrollment — запись на потоки. Возможности называют по устойчивому поведению, а не по задаче: enrollment, а не add-waitlist. Удобно резать их по ограниченным контекстам — документация OpenSpec прямо предлагает такой вариант (ordering/, fulfillment/), и это прямая связь с программой DDD.
  • Предложение измененияпредложение измененияEN change proposal (OpenSpec change)В OpenSpec — одна доработка, оформленная папкой openspec/changes/имя/: proposal.md (зачем и что меняем), дельты спецификаций в specs/, design.md (как) и tasks.md (чек-лист). Сначала его согласуют, потом реализуют и архивируют. — папка openspec/changes/<имя>/. В CLI это называется change, а справка openspec --help описывает группу команд как «Manage OpenSpec change proposals».
  • Дельта спецификациидельта спецификацииEN delta specСпецификация внутри предложения изменения, которая описывает только разницу с текущей: разделы ADDED, MODIFIED, REMOVED и RENAMED Requirements. MODIFIED содержит требование целиком в новой редакции — при архивировании оно заменяет старое полностью. описывает только разницу с текущей спецификацией.
  • Архивированиеархивирование измененияEN archiving a changeЗавершение изменения в OpenSpec: дельты сливаются в openspec/specs/ (добавленные требования дописываются, изменённые заменяют старые, удалённые удаляются), а папка изменения переезжает в openspec/changes/archive/ГГГГ-ММ-ДД-имя/. Команда openspec archive делает это программно и детерминированно; /opsx:archive в чате сливает дельты силами агента. вливает дельты в specs/ и переносит папку изменения в archive/ для истории.
flowchart LR
E["/opsx:explore<br/>(по желанию)"] --> P["/opsx:propose<br/>proposal, дельты,<br/>design, tasks"]
P --> R["ревью человеком<br/>openspec validate, show --diff"]
R --> A["/opsx:apply<br/>код и тесты, отметки [x]"]
A --> AR["/opsx:archive"]
AR --> S["openspec/specs/<br/>обновлены"]
AR --> H["changes/archive/<br/>ГГГГ-ММ-ДД-имя"]
S -.->|"основа для следующего изменения"| P
Жизненный цикл изменения в OpenSpec

Артефакты изменения строятся по цепочке proposal → specs → design → tasks, но OpenSpec называет зависимости «enablers, not gates»: они показывают, что стало возможно, а не запрещают возвращаться. Любой артефакт можно поправить в любой момент — для этого есть /opsx:update.

Спецификация — обычный markdown, но со строгой разметкой, потому что её разбирает программа:

  • требование начинается с ### Requirement: <название>;
  • текст требования содержит SHALL или MUST — ключевые слова RFC 2119ключевые слова RFC 2119EN RFC 2119 keywords (MUST, SHALL, SHOULD, MAY)Слова из стандарта IETF RFC 2119 с закреплённой силой требования: MUST и SHALL — обязательно, SHOULD — желательно с исключениями, MAY — можно. Валидатор OpenSpec предупреждает, если в тексте требования нет SHALL или MUST, а в строгом режиме (--strict) не пропускает такое требование; поэтому эти слова оставляют английскими и в русских спецификациях.;
  • у каждого требования хотя бы один сценарий #### Scenario: <название> — ровно четыре решётки — с пунктами WHEN и THEN (сценарии «Дано / Когда / Тогда» из урока SDD.2.1);
  • у новой возможности первый раздел — ## Purpose, одно-два предложения о её назначении.

В отличие от формата курса (REQ-001, сценарии SC-001) и Spec Kit (FR-001), номеров у требований OpenSpec нет: требование опознаётся по заголовку. Поэтому опечатка в заголовке MODIFIED ломает архивирование — это мы увидим в практике. Пункт GIVEN в сценарии тоже допустим: так написаны примеры в docs/concepts.md. Сводная таблица соответствий трёх форматов — в уроке SDD.3.1.

Дельта раскладывает требования по четырём разделам. Вот правила из шаблона и инструкции схемы spec-driven:

РазделЧто в нёмЧто сделает архивирование
## ADDED Requirementsновые требованиядопишет их в основную спецификацию
## MODIFIED Requirementsизменённое требование целиком, в новой редакциизаменит требование с тем же заголовком
## REMOVED Requirementsудаляемое требование с пометками Reason и Migrationудалит его
## RENAMED Requirementsсмена названия в формате FROM: / TO:переименует

Фрагмент шаблона дельты из schemas/spec-driven/templates/spec.md (MIT, как есть):

## ADDED Requirements
### Requirement: <!-- requirement name -->
<!-- requirement text -->
#### Scenario: <!-- scenario name -->
- **WHEN** <!-- condition -->
- **THEN** <!-- expected outcome -->

OpenSpec умеет писать артефакты на другом языке. Флаг openspec init --language Russian записывает в openspec/config.yaml такой контекст (настоящий файл из нашего прогона):

schema: spec-driven
context: |
Language: Russian
All artifacts must be written in Russian.
Keep OpenSpec structural headings and SHALL/MUST keywords in English.

Заголовки разметки и слова SHALL/MUST остаются английскими: на них опирается валидатор. Мы проверили, что будет, если написать «Система должна добавлять…» вместо «Система SHALL добавлять…»: обычный openspec validate выдаёт предупреждение «should contain SHALL or MUST», а openspec validate --strict уже не пропускает изменение. Поле context: в config.yaml подмешивается в каждый запрос к агенту на создание артефакта — туда же стоит записать стек и правила проекта, которые агент не выведет из кода сам.

По README нужен Node.js 20.19.0 или новее. Установка и подключение к проекту:

Окно терминала
npm install -g @fission-ai/openspec@latest # или: brew install openspec
cd school
openspec init # интерактивно спросит, каких агентов настроить

Без глобальной установки можно запустить пакет разово через npx — так делали мы:

Окно терминала
npx -y @fission-ai/openspec@1.14.1 init --tools claude --language Russian

Ключ --tools настраивает агентов без вопросов. В справке openspec init --help версии 1.14.1 около пятидесяти идентификаторов, среди них claude, codex, cursor, github-copilot, gemini, kiro, qwen; README говорит о поддержке «30+ инструментов».

Как и в Spec Kit, у OpenSpec две половины. В терминале работает CLI openspec, в чате агента — слэш-команды:

ПрофильСлэш-командаЧто делает
core (по умолчанию)/opsx:explore«напарник для размышлений»: читает код, сравнивает варианты, код не пишет
core/opsx:proposeсоздаёт изменение и все артефакты до готовности к реализации
core/opsx:applyвыполняет задачи из tasks.md, отмечает [x]
core/opsx:updateправит артефакты изменения и согласует их между собой, код не трогает
core/opsx:syncвливает дельты в specs/, не архивируя изменение
core/opsx:archiveзавершает изменение: дельты в specs/, папку в archive/
expanded/opsx:new, /opsx:continue, /opsx:ffпошаговое создание артефактов по одному или «перемотка» всех сразу
expanded/opsx:verifyпроверяет полноту, правильность и согласованность реализации с артефактами
expanded/opsx:bulk-archive, /opsx:onboardархивировать несколько изменений; обучающий проход на вашем коде

Расширенный профиль включается командами openspec config profile и openspec update. Написание команды зависит от агента: в Claude Code — /opsx:propose, в Cursor и GitHub Copilot — /opsx-propose, в Amazon Q — @opsx-propose, в Codex — $openspec-propose. Подсказка в конце openspec init печатает правильную форму для выбранных агентов.

Полезные команды CLI: openspec list (активные изменения), openspec list --specs (возможности), openspec show <имя> --diff (дифф требований), openspec validate <имя> (проверка формата), openspec status --change <имя> (какие артефакты готовы), openspec archive <имя> --yes (архивирование без вопросов), openspec view (панель в терминале).

Практика: лист ожидания в существующем проекте

Заголовок раздела «Практика: лист ожидания в существующем проекте»

Та же фича, что в уроке про Spec Kit: если мест нет, студент встаёт в лист ожидания (FIFO), освободившееся место предлагается первому в очереди, у него 24 часа на подтверждение. Но теперь проект старый: модуль Набора src/school/enrollment.py уже работает, спецификаций нет.

Вывод терминала ниже настоящий. Тексты артефактов мы написали сами — так, как их написал бы агент по инструкциям схемы, — и прогнали через настоящие openspec validate, status, show и archive. У вас агент напишет другой текст, но структура и поведение CLI будут теми же.

Окно терминала
cd school # существующий репозиторий с кодом
openspec init --tools claude --language Russian
OpenSpec Setup Complete
Created: Claude Code
6 skills and 6 commands in .claude/
Config: openspec/config.yaml (schema: spec-driven)
Getting started:
Start your first change: /opsx:propose "your idea"
Note: 6 more workflows are available (new, continue, ff, bulk-archive, verify, onboard).
Add them with `openspec config profile`.

Что появится:

.claude/
├── commands/opsx/ # apply.md, archive.md, explore.md, propose.md, sync.md, update.md
└── skills/ # openspec-apply-change/, openspec-archive-change/, openspec-explore/,
# openspec-propose/, openspec-sync-specs/, openspec-update-change/ — по SKILL.md
openspec/
├── changes/archive/.gitkeep
├── specs/.gitkeep
└── config.yaml

CLAUDE.md OpenSpec не создаёт и не трогает: контекст проекта живёт в openspec/config.yaml.

Шаг 2. Описать только тот кусок, который будем менять

Заголовок раздела «Шаг 2. Описать только тот кусок, который будем менять»

Документация OpenSpec настаивает: не пишите спецификации на всю старую систему, начните с той части, которую сейчас трогаете. Лист ожидания изменит правило отмены записи, поэтому сначала зафиксируем, как запись работает сейчас. Это отдельное маленькое изменение без изменения поведения: спецификация плюс тесты-фиксаторы (приём из урока 11.1.2).

/opsx:propose describe-enrollment Опиши текущее поведение записи на поток по коду src/school/enrollment.py:
вместимость, повторная запись, отмена с возвратом. Поведение не меняем, задачи — тесты, которые его фиксируют.

После ревью, реализации (/opsx:apply) и архивирования в проекте появляется первая спецификация. Вывод архивирования из терминала (openspec archive describe-enrollment --yes):

Task status: ✓ Complete
Specs to update:
enrollment: create
Applying changes to openspec/specs/enrollment/spec.md:
+ 3 added
Totals: + 3, ~ 0, - 0, → 0
Specs updated successfully.
Change 'describe-enrollment' archived as '2026-10-06-describe-enrollment'.

Фрагмент получившейся openspec/specs/enrollment/spec.md — заголовок и требование, которое мы скоро изменим:

# enrollment Specification
## Purpose
Запись студентов на потоки онлайн-школы с соблюдением вместимости и правил отмены.
## Requirements
### Requirement: Отмена записи
Система SHALL отменять запись по запросу студента; при отмене за 7 и более суток до старта возврат полный,
позже — без возврата.
#### Scenario: Отмена за 10 дней до старта
- **WHEN** студент отменяет оплаченную запись за 10 суток до старта
- **THEN** запись получает статус «отменена» и запускается полный возврат

Закоммитьте результат: дальше каждое изменение спецификаций будет видно в git diff.

Если не уверены, как встроить очередь в существующий код, начните с /opsx:explore — он прочитает модуль и предложит варианты, ничего не меняя. Когда картина ясна:

/opsx:propose add-waitlist Если на потоке нет мест, студент встаёт в лист ожидания (FIFO). Освободившееся
место предлагается первому в очереди, у него 24 часа на подтверждение, потом — следующему. Отмена записи
должна освобождать место для листа ожидания.

Под капотом агент выполняет openspec new change add-waitlist; настоящий вывод:

Created change 'add-waitlist' at openspec/changes/add-waitlist/
Schema: spec-driven
Next: openspec status --change add-waitlist

Затем пишет артефакты по очереди. Промежуточное состояние, когда готовы предложение и дельты:

Change: add-waitlist
Schema: spec-driven
Progress: 2/4 artifacts complete
[x] proposal
[x] specs
[ ] design
[-] tasks (blocked by: design)

Что появится в конце (openspec status сообщает «Progress: 4/4 artifacts complete … All planning artifacts complete!»):

openspec/changes/add-waitlist/
├── .openspec.yaml # schema: spec-driven, created: 2026-10-06
├── proposal.md
├── design.md
├── tasks.md
└── specs/
└── enrollment/
└── spec.md # дельта

proposal.md — зачем и что. Раздел Capabilities — договор между предложением и дельтами: каждая перечисленная возможность должна получить файл дельты.

# Proposal
## Why
Популярные потоки заполняются за день, а потом часть студентов отменяет запись. Освободившиеся места
пропадают: менеджеры не знают, кому их предложить.
## What Changes
- Если мест нет, студент может встать в лист ожидания потока.
- Освободившееся место предлагается первому в листе ожидания (FIFO), у него 24 часа на подтверждение.
- Отмена записи теперь освобождает место для листа ожидания.
## Capabilities
### New Capabilities
### Modified Capabilities
- `enrollment`: добавляется лист ожидания; меняется требование «Отмена записи»

Дельта specs/enrollment/spec.md — главное, что нужно ревьюить. Обратите внимание: в MODIFIED требование «Отмена записи» скопировано целиком — со старым сценарием — и дополнено.

## ADDED Requirements
### Requirement: Лист ожидания
Система SHALL добавлять студента в конец листа ожидания потока, если свободных мест нет.
#### Scenario: Поток заполнен
- **WHEN** студент записывается на поток, где свободных мест нет
- **THEN** студент добавляется в конец листа ожидания и видит свой номер в очереди
### Requirement: Предложение места
Система SHALL предлагать освободившееся место первому студенту в листе ожидания; предложение действует 24 часа.
#### Scenario: Первый в очереди подтвердил
- **WHEN** место освободилось и первый в листе ожидания подтвердил предложение в течение 24 часов
- **THEN** для него создаётся запись со статусом «ожидает оплаты»
#### Scenario: Предложение истекло
- **WHEN** первый в листе ожидания не ответил за 24 часа
- **THEN** место предлагается следующему в листе ожидания
## MODIFIED Requirements
### Requirement: Отмена записи
Система SHALL отменять запись по запросу студента; при отмене за 7 и более суток до старта возврат полный,
позже — без возврата. Освободившееся место SHALL предлагаться листу ожидания.
#### Scenario: Отмена за 10 дней до старта
- **WHEN** студент отменяет оплаченную запись за 10 суток до старта
- **THEN** запись получает статус «отменена» и запускается полный возврат
#### Scenario: Отмена при непустом листе ожидания
- **WHEN** студент отменяет запись, а в листе ожидания есть студенты
- **THEN** освободившееся место предлагается первому в листе ожидания

tasks.md — плоский чек-лист с нумерацией групп; именно его разбирает /opsx:apply:

# Tasks
## 1. Модель
- [ ] 1.1 Добавить `Waitlist` в агрегат `Cohort` и проверить тестом порядок FIFO
- [ ] 1.2 Изменить `Cohort.cancel`: освобождённое место предлагать листу ожидания; проверить тестом
## 2. Предложение места
- [ ] 2.1 Добавить предложение места со сроком 24 часа и проверить тестом истечение срока
- [ ] 2.2 Отправлять письмо с предложением через Уведомления и проверить тестом с подменой отправителя

Это главный момент для человека: код ещё не написан, а изменение поведения видно целиком. Три команды терминала:

Окно терминала
openspec validate add-waitlist # формат
openspec show add-waitlist --diff # дифф требований
openspec list # что в работе

Настоящий вывод: Change 'add-waitlist' is valid, затем дифф (фрагмент про MODIFIED):

MODIFIED: Отмена записи
@@ -1,6 +1,10 @@
### Requirement: Отмена записи
-Система SHALL отменять запись по запросу студента; при отмене за 7 и более суток до старта возврат полный, позже — без возврата.
+Система SHALL отменять запись по запросу студента; при отмене за 7 и более суток до старта возврат полный, позже — без возврата. Освободившееся место SHALL предлагаться листу ожидания.
#### Scenario: Отмена за 10 дней до старта
...
+#### Scenario: Отмена при непустом листе ожидания

и список: add-waitlist 0/4 tasks just now.

Что валидатор ловит, а что нет, мы проверили, специально испортив копию изменения:

ОшибкаРеакция CLI
Требование без сценария✗ [ERROR] … ADDED "Лист ожидания" must include at least one scenario — изменение не проходит проверку
Опечатка в заголовке MODIFIED («Отмена записей»)validate говорит «valid», но добавляет [INFO] … Archive would refuse this delta … not found; archive отвечает «Aborted. No files were changed.»
Нет SHALL/MUST в тексте требованияпредупреждение; с --strict — ошибка

Вывод: читайте не только итог «valid», но и строки INFO и WARNING под ним.

/opsx:apply

Агент идёт по tasks.md, пишет код и тесты, отмечает задачи [x]. Если по ходу выяснилось, что дизайн нужно поменять, правят артефакт (/opsx:update) и продолжают. Когда все задачи отмечены, openspec list показывает add-waitlist ✓ Complete. Перед архивированием полезно включить расширенный профиль и запустить /opsx:verify — он ищет в коде подтверждения каждого требования и сценария.

Архивировать можно двумя способами, и они устроены по-разному:

  • /opsx:archive в чате. Агент проверяет готовность артефактов и задач, предлагает синхронизировать дельты и выполняет слияние сам — документация называет его «умным, а не копированием» (intelligent merge), — затем проверяет структуру получившейся спецификации и переносит папку изменения в архив.
  • openspec archive add-waitlist --yes в терминале. То же самое делает программа: валидирует изменение, детерминированно сливает дельты и переносит папку. Если что-то не сходится, она останавливается, ничего не поменяв.

Мы запускали второй вариант — вот его настоящий вывод:

Task status: ✓ Complete
Specs to update:
enrollment: update
Applying changes to openspec/specs/enrollment/spec.md:
+ 2 added
~ 1 modified
Totals: + 2, ~ 1, - 0, → 0
Specs updated successfully.
Change 'add-waitlist' archived as '2026-10-06-add-waitlist'.

Что изменится: openspec list --specs показывает enrollment requirements 5, а git status — ровно две вещи:

M openspec/specs/enrollment/spec.md
?? openspec/changes/archive/2026-10-06-add-waitlist/

Основная спецификация снова описывает систему целиком и актуально: пять требований, в «Отмене записи» — обновлённый текст и два сценария. Папка изменения с предложением, дизайном и задачами ушла в архив — это история решений. Если архивировать с невыполненными задачами, CLI предупредит («Warning: 4 incomplete task(s) found»), но с --yes продолжит — проверка задач остаётся на вас.

ШагГдеЧто появляется или меняется
openspec init --tools claudeтерминал.claude/commands/opsx/, .claude/skills/openspec-*/, openspec/
/opsx:propose add-waitlistчатopenspec/changes/add-waitlist/ с .openspec.yaml, proposal, дельтами, design, tasks
openspec validate, show --diffтерминалничего, только проверка
/opsx:applyчаткод и тесты, отметки [x] в tasks.md
/opsx:archive или openspec archive add-waitlist --yesчат или терминалopenspec/specs/enrollment/spec.md обновлена, папка изменения — в changes/archive/
  1. Напишите дельту для изменения allow-leave-waitlist: студент может сам выйти из листа ожидания, и тогда все, кто стоял за ним, продвигаются на одну позицию.
Разбор

Это новое поведение той же возможности, поэтому файл — openspec/changes/allow-leave-waitlist/specs/enrollment/spec.md с разделом ADDED, без ## Purpose (у возможности он уже есть):

## ADDED Requirements
### Requirement: Выход из листа ожидания
Система SHALL удалять студента из листа ожидания по его запросу; студенты за ним сдвигаются на одну позицию.
#### Scenario: Выход из середины очереди
- **WHEN** в листе ожидания три студента и второй выходит из очереди
- **THEN** третий становится вторым, а первый остаётся первым

Отдельный вопрос для ревью: что если вышедшему уже предложено место? Это крайний случай, его стоит или описать вторым сценарием, или явно вынести в «не делаем» в proposal.md.

  1. Найдите четыре ошибки в дельте:
## MODIFIED Requirements
### Requirement: Отмена записи
Освободившееся место should предлагаться листу ожидания.
### Scenario: Отмена при непустом листе ожидания
- **WHEN** студент отменяет запись
- **THEN** место предлагается первому в листе ожидания
## REMOVED Requirements
### Requirement: Повторная запись
Разбор
  1. В MODIFIED только новая фраза: старый текст про возврат и старый сценарий потерялись бы — MODIFIED заменяет блок целиком. Валидатор заметит пропавший сценарий «Отмена за 10 дней до старта» и не пропустит архивирование, но пропавший текст про возврат он не ловит. 2) ### Scenario с тремя решётками: сценарий не распознается, у требования формально не будет сценариев. 3) «should» вместо SHALL/MUST: для OpenSpec это необязательное пожелание, валидатор предупредит. 4) В REMOVED нет Reason и Migration: зачем удаляем и что делать тем, кто на это полагался.
  1. Два разработчика параллельно сделали изменения: add-waitlist и add-cancel-email (после отмены студент получает письмо с итогом). Оба меняют требование «Отмена записи», оба написаны от одной и той же старой версии. Первое заархивировали. Что будет со вторым?
Разбор

Мы проверили это на настоящем CLI. Сначала второе изменение не проходит проверку: «MODIFIED “Отмена записи” omits scenario(s) the current spec still has: “Отмена при непустом листе ожидания”», и archive отвечает «Aborted. No files were changed.» — валидатор сравнивает MODIFIED с текущей спецификацией и не даёт потерять сценарий. Но когда мы скопировали пропавший сценарий, а текст требования оставили своим («…Студенту SHALL отправляться письмо с итогом отмены»), архивирование прошло, и фраза «Освободившееся место SHALL предлагаться листу ожидания» тихо исчезла из спецификации. Правило: после архивирования первого изменения перепишите MODIFIED второго от актуальной версии требования (это и есть «rebase» для требований) и посмотрите git diff openspec/specs/ после архивирования.

Spec KitOpenSpec
УстановкаPython 3.11+, uv; CLI specifyNode.js 20.19+, npm или Homebrew; CLI openspec
Единица работыфича: specs/001-waitlist/изменение: openspec/changes/add-waitlist/
Документыконституция, spec, plan, research, data-model, contracts, quickstart, tasks, чек-листыproposal, дельты, design (может не быть), tasks; контекст в config.yaml
После реализациипапка фичи остаётся; что с ней делать — решает команда (flow-forward, flow-back, living spec)дельты вливаются в specs/, изменение — в архив
Уровень по Бёккелерпо умолчанию spec-first; spec-anchored — при дисциплинеspec-anchored по устройству
Форматсвободный markdown по шаблонустрогая разметка, которую разбирает и проверяет программа
Проверкиclarify, checklist, analyze, converge — выполняет модельopenspec validate — программа; /opsx:verify — модель
Агенты42 интеграции30+ по README, около 50 идентификаторов в --tools
Сильнее всегоновый проект или крупная фича, где нужны план, модель данных, контракты, общие принципыразвитие существующей системы потоком небольших изменений

Граница не жёсткая. У Spec Kit есть руководство по внедрению в существующий проект, OpenSpec прекрасно работает и в новом. В каталоге сообщества Spec Kit с конца сентября 2026 года даже есть экспериментальное расширение openspec, которое добавляет в Spec Kit цикл «предложить → реализовать → проверить → заархивировать» (мейнтейнеры Spec Kit его не проверяли). Идеи инструментов сближаются.

Сильные стороны:

  • Одна актуальная картина. «Как сейчас работает отмена» — один файл, а не археология по папкам фич.
  • Дельты читаются как дифф. Ревьюер видит ровно то, что меняется, — в терминах поведения, до кода.
  • Детерминированные операции. Проверку формата, слияние и архивирование может делать программа, а не модель (openspec validate, openspec archive); ошибки формата ловятся до слияния.
  • Лёгкость. Четыре артефакта вместо девяти, design можно пропустить; удобно для частых небольших изменений.
  • Внедрение без «большого описания». Спецификации растут вместе с изменениями, история решений — в архиве.

Ограничения:

  • Строгая разметка. Четыре решётки у сценария, SHALL/MUST по-английски, MODIFIED целиком. Ошибка в заголовке — и архивирование откажет.
  • Параллельные изменения одного требования нужно согласовывать вручную; валидатор защищает сценарии, но не каждую фразу текста.
  • Только поведение в источнике истины. Архитектурные решения из design.md уходят в архив вместе с изменением. Если нужен живой документ архитектуры — ведите его отдельно (например, журнал ADR из урока SDD.2.2).
  • Сценарии — не тесты. Ничто не исполняет WHEN/THEN автоматически; тесты из сценариев — тема урока SDD.4.2.
  • Агент может отметить задачу, не сделав её, а archive --yes не остановится на невыполненных задачах. Ложное чувство контроля никуда не делось.
Проверь себя6 вопросов
1 Где в проекте с OpenSpec искать ответ на вопрос «как сейчас работает отмена записи»?
2 В дельте в разделе MODIFIED оставили только новый сценарий требования «Отмена записи», без старого. Что ответят openspec validate и openspec archive в терминале?
3 Вы запускаете в терминале openspec archive add-waitlist --yes. Что при этом делает сама программа, без участия модели? Выберите все верные.Можно выбрать несколько ответов
4 Как называется в Claude Code команда, с которой обычно начинают новое изменение в профиле по умолчанию?
5 Команда ведёт CRM, которой пять лет, и каждую неделю вносит три-четыре небольших изменения правил. Что разумнее взять за основу?
6 Какой уровень SDD по классификации Бёккелер ближе всего к устройству OpenSpec?
  • OpenSpec делит мир на две папки: openspec/specs/ — как система работает сейчас, openspec/changes/ — предложения изменений с proposal, дельтами, design и tasks.
  • Дельта описывает только разницу: ADDED, MODIFIED (требование целиком), REMOVED (с Reason и Migration), RENAMED. При архивировании она вливается в спецификацию — программой (openspec archive) или агентом (/opsx:archive), — а изменение уходит в архив.
  • Цикл в чате агента: /opsx:explore по желанию, /opsx:propose, ревью, /opsx:apply, /opsx:archive. В терминале — openspec validate, show --diff, list, status.
  • Строгая разметка — цена детерминированной проверки и слияния. Читайте не только «valid», но и INFO и WARNING, а после архивирования смотрите git diff openspec/specs/.
  • Spec Kit сильнее в больших фичах с нуля, OpenSpec — в развитии старых систем; граница размыта, и выбор зависит от потока работы, а не от моды.

Дальше: урок SDD.3.3 — карта остальных инструментов SDD (Kiro, Tessl, BMAD-METHOD, cc-sdd, Agent OS), сравнительная таблица и свой минимальный процесс без специальных инструментов.