Skip to content

spec-driven ​

Артефакты рабочего процесса по умолчанию: их порядок, их форматы и папка изменений, которую они создают.

spec-driven — встроенная схема OpenSpec по умолчанию. schema.yaml определяет поля, которые она задаёт.

Артефакты ​

Рабочий процесс создаёт четыре артефакта:

АртефактФайлНазначение
proposalproposal.mdЗачем нужно изменение
specsspecs/<capability-path>/spec.md, один на каждую возможностьКакое поведение изменяется
designdesign.mdКак это построить
taskstasks.mdКонтрольный список реализации

Порядок разработки ​

text
             ┌─ specs ──┐
proposal ────┤          ├── tasks ── apply
             └─ design ─┘

Сначала создаётся предложение (proposal). Спецификации (specs) и дизайн (design) следуют в любом порядке, а для задач (tasks) нужны оба. Реализация (apply) начинается, как только на месте tasks.md.

Два артефакта можно пропустить:

  • design: если ни одно из его условий не выполняется, агент пропускает его и всё равно составляет tasks.
  • specs: установите skip_specs: true в файле .openspec.yaml изменения.

Пример папки изменения ​

Изменение с именем add-user-auth, со всеми созданными артефактами:

text
openspec/changes/add-user-auth/
├── .openspec.yaml      метаданные изменения, записываются при его создании
├── proposal.md
├── specs/
│   └── user-auth/
│       └── spec.md     один дельта-спек на каждую возможность
├── design.md
└── tasks.md

proposal.md ​

Определяет, зачем нужно изменение.

Структура ​

Шаблон, который агент получает как формат вывода (templates/proposal.md):

md
# Proposal

## Why

<!-- Объясните мотивацию этого изменения. Какую проблему оно решает? Почему сейчас? -->

## What Changes

<!-- Опишите, что изменится. Укажите конкретно новые возможности, изменения или удаления. -->

## Capabilities

### New Capabilities
<!-- Вводимые возможности. Называйте каждую возможность для целостного поведения системы,
     которая может владеть связанными требованиями по мере развития системы. Не называйте
     задачи реализации или разделы предложения. Избегайте широких обобщающих названий. Используйте
     kebab-case для вводимых сегментов пути (например, user-auth или identity/user-auth),
     которые следуют существующей организации спеков проекта. Каждая создаёт
     specs/<capability-path>/spec.md. -->
- `<capability-path>`: <краткое описание того, что охватывает эта возможность>

### Modified Capabilities
<!-- Существующие возможности, чьи ТРЕБОВАНИЯ изменяются (не только реализация).
     Указывайте здесь только при изменении поведения на уровне спеков. Для каждой нужен дельта-файл.
     Используйте точный существующий путь в openspec/specs/. Оставьте пустым, если требования
     не меняются. Изменение без возможностей вообще (чистый рефакторинг, инструменты, документация)
     должно установить skip_specs: true в своём .openspec.yaml - openspec validate отклоняет
     изменение с нулевой дельтой без этого маркера. Не выдумывайте требование только для
     прохождения валидации. -->
- `<existing-capability-path>`: <какое требование изменяется>

## Impact

<!-- Затронутый код, API, зависимости, системы -->

Инструкции ​

Инструкция, отправляемая агенту при создании этого артефакта (из schema.yaml):

md
Создайте документ предложения, который устанавливает, ЗАЧЕМ нужно это изменение.

Разделы:
- **Why**: 1-2 предложения о проблеме или возможности. Какую проблему это решает? Почему сейчас?
- **What Changes**: Маркированный список изменений. Укажите конкретно новые возможности, изменения или удаления. Помечайте ломающие изменения как **BREAKING**.
- **Capabilities**: Определите, какие спеки будут созданы или изменены:
  - **New Capabilities**: Перечислите вводимые возможности. Каждая становится новым `specs/<capability-path>/spec.md`. Называйте каждую возможность для долговременного поведения системы (например, `user-auth`), а не для работы в этом изменении (например, `add-login-endpoint`). Выбирайте целостную границу, которая может владеть связанными требованиями по мере развития системы; избегайте широких обобщающих возможностей. Используйте kebab-case для вводимых сегментов пути (например, `user-auth` или `identity/user-auth`) и следуйте существующей организации спеков проекта.
  - **Modified Capabilities**: Перечислите существующие возможности, чьи ТРЕБОВАНИЯ изменяются. Включайте только при изменении поведения на уровне спеков (не только деталей реализации). Для каждой нужен дельта-файл. Используйте точный существующий путь в `openspec/specs/`. Оставьте пустым, если требования не меняются.
- **Impact**: Затронутый код, API, зависимости или системы.

ВАЖНО: Раздел Capabilities критически важен. Он создаёт контракт между
этапами предложения и спеков. Изучите существующие спеки перед заполнением:
выполните `openspec list --specs` для инвентаризации возможностей проекта, затем
`openspec show "<spec-id>" --type spec --json --no-scenarios` для любых
похожих - это вернёт назначение возможности и тексты требований
без загрузки целых файлов спеков в контекст. Добавляйте `--store "<id>"` к
обеим командам только для зарегистрированного автономного хранилища и сохраняйте `--type
spec`: изменение и спек с одинаковым именем иначе дают ошибку неоднозначного элемента.
`openspec list` без `--specs` перечисляет изменения в работе, а не
спеки - он никогда не показывает, что проект уже покрывает. Используйте точный путь
существующей возможности вместо введения почти дублирующего имени.
Отфильтрованное чтение - только обзор. Прежде чем решать, что уже покрыто
или что должно измениться, прочитайте каждый соответствующий спек полностью, включая
сценарии, командой `openspec show "<spec-id>" --type spec` (то же правило `--store`).
Каждая возможность, указанная здесь, потребует соответствующего файла спека.

Каждое изменение должно либо объявить хотя бы одну возможность (новую или
изменённую), либо явно отказаться от спеков: `openspec validate` отклоняет
изменение с нулевой дельтой, если в `.openspec.yaml` изменения не установлено
`skip_specs: true`. Используйте `skip_specs: true` только когда поведение на уровне спеков
не меняется (чистый рефакторинг, инструменты, документация) - спеки описывают
поведение, поэтому если поведение не меняется, спек тоже не должен меняться.
Не выдумывайте требование только для прохождения валидации.

Будьте лаконичны (1-2 страницы). Сосредоточьтесь на "почему", а не "как" -
детали реализации относятся к design.md.

Это основа - спеки, дизайн и задачи строятся на этом.

Дельта-спеки (spec.md) ​

Определяют, какое поведение меняется, по одному дельта-спеку на каждую возможность, указанную в предложении.

Каждый дельта-спек - это spec.md внутри папки возможности. openspec validate и openspec archive отклоняют дельта-разделы, записанные в любом другом файле внутри specs/, например specs/user-auth.md, потому что archive никогда их не объединяет.

Структура ​

Шаблон, который агент получает как формат вывода (templates/spec.md):

md
# Spec Delta

## Purpose
<!-- Только для новых возможностей: одно-два предложения (50+ символов) о том, для чего эта возможность. Удалите этот раздел для существующей возможности. -->

## ADDED Requirements

### Requirement: <!-- имя требования -->
<!-- текст требования -->

#### Scenario: <!-- имя сценария -->
- **WHEN** <!-- условие -->
- **THEN** <!-- ожидаемый результат -->

Инструкции ​

Инструкция, отправляемая агенту при создании этого артефакта (из schema.yaml):

md
Создайте файлы спецификаций, определяющие, ЧТО должна делать система.

Спек - это контракт поведения, а не план реализации.

Хорошее содержание спека:
- Наблюдаемое поведение, на которое полагаются пользователи или нижестоящие системы
- Входные данные, выходные данные и условия ошибок
- Внешние ограничения (безопасность, конфиденциальность, надёжность, совместимость)
- Сценарии, которые можно проверить или явно валидировать

Чего избегать в спеках:
- Внутренних имён классов/функций
- Выбора библиотек или фреймворков
- Пошаговых деталей реализации
- Подробных планов выполнения (они относятся к design.md или tasks.md)

Быстрый тест: если реализация может измениться без изменения внешне
наблюдаемого поведения, это, скорее всего, не относится к спеку.

Создайте один файл спека на каждую возможность, указанную в разделе Capabilities предложения.
`<capability-path>` - это каталог спека относительно `specs/` (например,
`user-auth` или `identity/user-auth`). Сохраняйте полный путь:
- Новые возможности: используйте точный путь из предложения в `specs/<capability-path>/spec.md`. Любой сегмент пути, впервые введённый в предложении, должен быть в kebab-case. Следуйте существующей организации проекта; не добавляйте новый уровень домена, если проект использует плоскую структуру.
- Изменённые возможности: используйте точный существующий путь из `openspec/specs/<capability-path>/` при создании дельты в `specs/<capability-path>/spec.md`. Выполните `openspec list --specs`, чтобы подтвердить этот путь перед записью дельты, добавляя `--store "<id>"` только для зарегистрированного автономного хранилища - ошибочно написанный или выдуманный путь указывает на несуществующую возможность, а не на ту, что вы имели в виду. Не перемещайте и не переименовывайте возможность.

Записывайте файлы спеков по одному, чтобы пользователь видел прогресс, а
прерванный запуск сохранял уже записанные файлы:
- Перед записью чего-либо сравните возможности, указанные в предложении,
  с уже существующими файлами `specs/<capability-path>/spec.md`
  и начните с первой возможности, у которой нет файла. Не переписывайте
  существующий файл, если пользователь не просит об этом.
- Перед каждым файлом сообщите в одну строку, какую возможность вы записываете.
- Записывайте каждый файл сразу после его составления. Не планируйте все файлы
  перед записью первого.
- Остановитесь, когда каждая возможность из предложения получит свой файл.

Должен быть хотя бы один файл спека, если в `.openspec.yaml` изменения
не установлено `skip_specs: true` (нет изменения поведения на уровне спеков) - `openspec validate`
отклоняет изменение с нулевой дельтой без этого маркера. Если в предложении нет
возможностей и `skip_specs` не установлен, сначала пересмотрите предложение.

Дельта-операции (используйте заголовки ##):
- **ADDED Requirements**: Новые возможности
- **MODIFIED Requirements**: Изменённое поведение - ОБЯЗАТЕЛЬНО включать полное обновлённое содержимое
- **REMOVED Requirements**: Устаревшие функции - ОБЯЗАТЕЛЬНО включать **Reason** и **Migration**
- **RENAMED Requirements**: Только изменения имён - используйте формат FROM:/TO:

Требования к формату:
- Каждое требование: `### Requirement: <имя>` с последующим описанием
- Используйте SHALL/MUST для нормативных требований (избегайте should/may)
- Каждый сценарий: `#### Scenario: <имя>` в формате WHEN/THEN
- **КРИТИЧНО**: Сценарии ДОЛЖНЫ использовать ровно 4 решётки (`####`). Использование 3 решёток или маркеров приведёт к тихому сбою.
- Каждое требование ДОЛЖНО иметь хотя бы один сценарий.
- Каждый сценарий ДОЛЖЕН иметь шаг WHEN/GIVEN (его триггер) и шаг THEN (его результат). Сценарий только с строками AND или обычным текстом всё равно считается сценарием, но `openspec validate` помечает его как предупреждение: обычная валидация всё равно проходит, но `openspec validate --strict` завершается ошибкой.
- Держите описание каждого требования (текст между `### Requirement:` и его первым сценарием) не длиннее 500 символов. `openspec validate` помечает более длинные описания в ADDED требованиях и в основном спеке. Это предупреждение: обычная валидация всё равно проходит, но `openspec validate --strict` завершается ошибкой. При написании нового требования указывайте одно поведение на требование: переносите примеры и граничные случаи в сценарии и разделяйте требование, охватывающее несколько поведений, на отдельные блоки `### Requirement:`, каждый со своими сценариями. В MODIFIED сохраняйте существующий блок требования целиком; никогда не разделяйте, не сокращайте и не переписывайте существующий текст только для соблюдения длины. Разделяйте существующее длинное требование только по просьбе пользователя, в изменении, сделанном для этой цели: в MODIFIED сохраняйте его заголовок и каждый сценарий и сокращайте описание до одного поведения без изменения смысла, затем добавляйте каждое удалённое поведение как отдельное ADDED требование со своими сценариями.

Только для новых возможностей: первый раздел дельта-спека - `## Purpose` -
одно-два предложения (50+ символов, иначе `openspec validate --strict`
сообщит о слишком кратком) с описанием назначения возможности. Archive
копирует его в основной спек, который создаёт; без него новый основной спек
остаётся с плейсхолдером `TBD ... Update Purpose after archive` для ручного
заполнения. НЕ добавляйте `## Purpose` в дельту для существующей возможности -
у неё уже есть Purpose, и дельта-версия игнорируется. Чтобы изменить
Purpose существующей возможности - включая оставшийся плейсхолдер `TBD` -
редактируйте `<planningHome.root>/openspec/specs/<capability-path>/spec.md`
напрямую. `planningHome.root` берётся из ответа `openspec instructions ...
--json`. Всегда используйте его вместо пути относительно репозитория: он
разрешается в хранилище, когда изменение находится в нём - независимо от того,
получено ли это из `--store`, указателя `store:` проекта или глобального
хранилища по умолчанию - и в текущий репозиторий в противном случае. Не пытайтесь
выяснить, какой случай применим; поле уже содержит ответ.

Рабочий процесс для MODIFIED требований:
1. Найдите существующее требование в `<planningHome.root>/openspec/specs/<capability-path>/spec.md` (тот же корень с учётом хранилища, что и выше)
2. Скопируйте ВЕСЬ блок требования (от `### Requirement:` до всех сценариев)
3. Вставьте под `## MODIFIED Requirements` и отредактируйте под новое поведение
4. Убедитесь, что текст заголовка совпадает точно (без учёта пробелов)

Частая ошибка: использование MODIFIED с частичным содержимым теряет детали при архивации.
Если добавляете новые аспекты без изменения существующего поведения, используйте ADDED.

Пример (новая возможность, поэтому первый раздел - `## Purpose`):
```
# Spec Delta
```

## Назначение

Позволяет пользователям извлекать свои данные из продукта в переносимом формате.

## ДОБАВЛЕННЫЕ требования

### Требование: Пользователь может экспортировать данные
Система ДОЛЖНА предоставлять пользователям возможность экспортировать свои данные в формате CSV.

#### Сценарий: Успешный экспорт
- **КОГДА** пользователь нажимает кнопку "Export"
- **ТОГДА** система загружает CSV-файл со всеми данными пользователя

## УДАЛЁННЫЕ требования

### Требование: Устаревший экспорт
**Причина**: Заменён новой системой экспорта
**Миграция**: Используйте новую конечную точку экспорта по адресу /api/v2/export
```

Спецификации должны быть проверяемыми — каждый сценарий является потенциальным тест-кейсом.

design.md ​

Объясняет, как реализовать изменение. Составляется только тогда, когда изменению это необходимо.

Структура ​

Шаблон, который агент получает в качестве формата выходных данных (templates/design.md):

md
# Design

## Context

<!-- Current state and constraints that shape the approach. See proposal.md for motivation - don't restate it -->

## Goals / Non-Goals

**Goals:**
<!-- What this design aims to achieve -->

**Non-Goals:**
<!-- What is explicitly out of scope -->

## Decisions

<!-- Key design decisions with rationale and alternatives considered -->

## Risks / Trade-offs

<!-- Known risks and trade-offs -->

Инструкции ​

Инструкция, отправляемая агенту при составлении этого артефакта (из schema.yaml):

md
Create the design document that explains HOW to implement the change.

When to include design.md (create only if any apply):
- Cross-cutting change (multiple services/modules) or new architectural pattern
- New external dependency or significant data model changes
- Security, performance, or migration complexity
- Ambiguity that benefits from technical decisions before coding

Sections:
- **Context**: Only the current state and constraints needed to explain the approach. Reference the proposal for motivation instead of restating it (e.g., "See proposal.md - Why").
- **Goals / Non-Goals**: What this design achieves and explicitly excludes. Don't restate the proposal's scope - add only design-level boundaries.
- **Decisions**: Key technical choices with rationale (why X over Y?). Include alternatives considered for each decision.
- **Risks / Trade-offs**: Known limitations, things that could go wrong. Format: [Risk] → Mitigation
- **Migration Plan**: Steps to deploy, rollback strategy (if applicable)
- **Open Questions**: Unknowns that can safely be answered later without
  changing the specs, the approach, or the task breakdown. Omit if none.

Open questions are for genuinely deferrable unknowns, not decisions you
skipped. If a question would change the specs, the chosen approach, or
the task breakdown, resolve it now - ask the user instead of guessing.

Focus on architecture and approach, not line-by-line implementation.
The proposal covers why and what; design covers how. Reference the
proposal for motivation and, once written, the specs for requirements -
if a section would only restate them, point to them instead.

Good design docs explain the "why" behind technical decisions.

tasks.md ​

Разбивает реализацию на проверяемые задачи. apply отслеживает прогресс здесь.

Структура ​

Шаблон, который агент получает в качестве формата выходных данных (templates/tasks.md):

md
# Tasks

## 1. <!-- Task Group Name -->

- [ ] 1.1 <!-- Task description -->
- [ ] 1.2 <!-- Task description -->

## 2. <!-- Task Group Name -->

- [ ] 2.1 <!-- Task description -->
- [ ] 2.2 <!-- Task description -->

Инструкции ​

Инструкция, отправляемая агенту при составлении этого артефакта (из schema.yaml):

md
Create the task list that breaks down the implementation work.

Before writing tasks, check design.md for Open Questions. If any of them
would change what gets built, resolve them with the user first - do not
bake an unstated assumption into the task list.

**IMPORTANT: Follow the template below for tracked tasks.** The apply phase parses
checkbox format to track progress. A box holding only `x` counts as done,
upper or lower case and with any spacing, so `- [ x]` is done too. Every
other marker, including `- [~]`, `- [-]` and an empty `- []`, reads as
unfinished. A line with no checkbox is not tracked at all.

Guidelines:
- Group related tracked tasks under ## numbered headings
- Each tracked task MUST be a checkbox: `- [ ] X.Y Task description`
- Tasks should be small enough to complete in one session
- Order tasks by dependency (what must be done first?)
- Track implementation and verification work that can be completed before
  archive. If the requested workflow includes archive or work that requires
  this change to be archived, preserve those steps as plain bullets in an
  optional `## Workflow follow-up` section at the end of tasks.md. These
  bullets are reference information outside tracked task progress.
- Each task MUST state how to verify completion (a test, command,
  observable behavior, or delivered artifact). Put the verification in
  that task's checkbox description. Use a separate verification task only
  when it checks broader integration or system behavior that spans
  multiple implementation tasks.
- Each task group MUST land the tests and documentation its own work
  calls for. Do NOT collect testing or documentation into a final group -
  when a late group first exercises work from an early one, the failures
  cascade back through every group in between and force rework. A group
  whose work calls for neither, such as scaffolding or dependency setup,
  carries neither. A final group is for integration checks only, not for
  the tests and docs an earlier group owed.

Example:
```
# Tasks

## 1. Setup

- [ ] 1.1 Create new module structure and verify expected files are present
- [ ] 1.2 Add dependencies to package.json and verify package installation succeeds

## 2. Core Implementation

- [ ] 2.1 Implement data export function and verify the export test passes
- [ ] 2.2 Add CSV formatting utilities and verify unit tests cover quoting and delimiters
- [ ] 2.3 Document the export API in docs/export.md and verify the documented command runs as written
```

When applicable, append workflow follow-up as plain bullets, for example:
```
## Workflow follow-up

- Archive the change after the project's review requirements are satisfied.
- Verify the archived result.
```

Reference specs for what needs to be built, design for how to build it.

Apply ​

Переход от планирования к реализации. Apply — это фаза, которая работает с tasks.md, а не артефакт.

  • Начинается: как только tasks.md существует и содержит хотя бы одну задачу.
  • Отслеживает: флажки в tasks.md. Отметка их является записью о прогрессе.
  • Завершается: когда все флажки отмечены. Затем OpenSpec предлагает архивировать изменение.

Настройки ​

Настройки apply (из schema.yaml):

yaml
apply:
  requires: [tasks]
  tracks: tasks.md
  # instruction: shown below

Инструкции ​

Инструкция, отправляемая агенту при начале реализации (из schema.yaml):

md
Read context files, work through pending tasks, mark complete as you go.
Pause if you hit blockers or need clarification.

schema.yaml ​

Полный schema.yaml, с опущенными телами инструкций. Каждая из них показана полностью в своём разделе выше.

yaml
name: spec-driven
version: 1
description: Default OpenSpec workflow - proposal → specs → design → tasks
artifacts:
  - id: proposal
    generates: proposal.md
    description: Initial proposal document outlining the change
    template: proposal.md
    # instruction: shown in full under proposal.md above
    requires: []

  - id: specs
    generates: "specs/**/*.md"
    description: Detailed specifications for the change
    template: spec.md
    # instruction: shown in full under Delta specs above
    requires:
      - proposal

  - id: design
    generates: design.md
    description: Technical design document with implementation details
    template: design.md
    # instruction: shown in full under design.md above
    requires:
      - proposal

  - id: tasks
    generates: tasks.md
    description: Implementation checklist with trackable tasks
    template: tasks.md
    # instruction: shown in full under tasks.md above
    requires:
      - specs
      - design

apply:
  requires: [tasks]
  tracks: tasks.md
  # instruction: shown in full under Apply above