Merge pull request 'chore(openspec): архив change dsh-openspec (#42)' (#61) from chore/archive-dsh-openspec into main
This commit is contained in:
commit
de58eff8c0
109
openspec/specs/dsh-openspec/spec.md
Normal file
109
openspec/specs/dsh-openspec/spec.md
Normal file
@ -0,0 +1,109 @@
|
||||
# dsh-openspec Specification
|
||||
|
||||
## Purpose
|
||||
Слой OpenSpec в DeepSeek Harness: скиллы воркфлоу (propose → apply → archive →
|
||||
sync) и их установка в проект. В Claude Code эти скиллы генерирует
|
||||
`openspec init --tools claude` в `.claude/skills`; в DSH тот же генератор с
|
||||
адаптером `agents` кладёт их в `.agents/skills`, который DSH читает как
|
||||
проектный корень скиллов. Обвязка не переписывает воркфлоу: она ставит
|
||||
адаптер, проверяет его и описывает цикл.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: Скиллы OpenSpec живут в проекте
|
||||
Воркфлоу OpenSpec SHALL поставляться проектными скиллами в `.agents/skills`,
|
||||
созданными генератором `openspec init --tools agents`, и MUST NOT копироваться
|
||||
в глобальный `~/.dsh/skills`.
|
||||
|
||||
- Набор: `openspec-propose`, `openspec-apply-change`, `openspec-archive-change`,
|
||||
`openspec-explore`, `openspec-sync-specs`, `openspec-update-change`.
|
||||
- Каждый `SKILL.md` MUST иметь frontmatter с `name`, совпадающим с именем
|
||||
каталога, и `description`, по которому модель отличает propose от archive.
|
||||
- Источник истины — CLI `openspec` проекта: `openspec update` обновляет скиллы,
|
||||
ручные правки в них не переживают обновление.
|
||||
|
||||
#### Scenario: Проект с agents-адаптером
|
||||
- **WHEN** в проекте выполнено `openspec init --tools agents`
|
||||
- **THEN** в `.agents/skills/` лежат шесть каталогов `openspec-*` с `SKILL.md`,
|
||||
а `openspec list --json` возвращает ненулевой `root`
|
||||
|
||||
#### Scenario: DSH видит проектные скиллы
|
||||
- **WHEN** DSH-сессия стартует с cwd в проекте, где есть `.agents/skills/openspec-*`
|
||||
- **THEN** каталог скиллов сессии содержит эти шесть имён, и их можно вызвать
|
||||
инструментом `skill`
|
||||
|
||||
#### Scenario: Глобальная копия не создаётся
|
||||
- **WHEN** выполнено `bash dsh/install.sh --skills`
|
||||
- **THEN** в `~/.dsh/skills` нет каталогов `openspec-*`: они остаются проектными
|
||||
|
||||
#### Scenario: Два адаптера в одном проекте
|
||||
- **WHEN** проект инициализирован с `--tools claude`, затем с `--tools agents`
|
||||
- **THEN** `.claude/skills` и `.claude/commands` остаются без изменений, а
|
||||
`.agents/skills` добавляется рядом
|
||||
|
||||
### Requirement: Цикл change без Claude Code
|
||||
В DSH-сессии MUST проходиться полный цикл OpenSpec без Claude Code: создание
|
||||
change, артефакты по инструкциям CLI, строгая валидация и архив.
|
||||
|
||||
- Создание: `openspec new change <имя>`.
|
||||
- Артефакты: `openspec status --change <имя> --json` и
|
||||
`openspec instructions <artifact> --change <имя> --json`; агент пишет
|
||||
`proposal.md`, `specs/<capability>/spec.md`, `design.md`, `tasks.md`.
|
||||
- Проверка: `openspec validate <имя> --strict`.
|
||||
- Архив: `openspec archive <имя> -y` (без интерактивных подтверждений), спеки
|
||||
обновляются в `openspec/specs/`.
|
||||
|
||||
#### Scenario: Архив неинтерактивен
|
||||
- **WHEN** change валиден и все задачи `tasks.md` отмечены выполненными
|
||||
- **THEN** `openspec archive <имя> -y` завершается кодом 0, создаёт
|
||||
`openspec/changes/archive/<дата>-<имя>/` и обновляет основную спеку
|
||||
|
||||
#### Scenario: Невалидный change останавливает архив
|
||||
- **WHEN** в change нет ни одной дельты и в `.openspec.yaml` не стоит
|
||||
`skip_specs: true`
|
||||
- **THEN** `openspec validate --strict` завершается ненулевым кодом, и архив не
|
||||
выполняется
|
||||
|
||||
### Requirement: Проверка установки
|
||||
`dsh/install.sh --check` SHALL сообщать состояние слоя OpenSpec: наличие CLI,
|
||||
версию и наличие agents-скиллов в репозитории обвязки; отсутствие CLI MUST быть
|
||||
предупреждением, а не отказом, потому что остальная обвязка от OpenSpec не
|
||||
зависит.
|
||||
|
||||
#### Scenario: CLI установлен, скиллы на месте
|
||||
- **WHEN** `openspec` есть в `PATH` и `.agents/skills/openspec-propose/SKILL.md`
|
||||
существует
|
||||
- **THEN** `--check` печатает `ok: openspec <версия>` и `ok: openspec agents skills`
|
||||
|
||||
#### Scenario: CLI отсутствует
|
||||
- **WHEN** `openspec` нет в `PATH`
|
||||
- **THEN** `--check` печатает `WARN` с подсказкой установить CLI и продолжает
|
||||
проверку остальных пунктов; код возврата не меняется из-за одного OpenSpec
|
||||
|
||||
### Requirement: Установка в проект
|
||||
`bash dsh/install.sh --openspec` SHALL добавлять agents-адаптер в текущий проект
|
||||
вызовом `openspec init --tools agents`, MUST быть идемпотентной и MUST NOT
|
||||
создавать OpenSpec-корень там, где его нет.
|
||||
|
||||
#### Scenario: Проект уже использует OpenSpec
|
||||
- **WHEN** cwd — проект с каталогом `openspec/`, вызван `--openspec`
|
||||
- **THEN** скиллы появляются в `.agents/skills`, повторный вызов не дублирует и
|
||||
не ломает существующие файлы
|
||||
|
||||
#### Scenario: Проект без OpenSpec
|
||||
- **WHEN** cwd — проект без `openspec/`, вызван `--openspec`
|
||||
- **THEN** скрипт отказывается с сообщением `openspec init --tools agents`,
|
||||
ничего не создаёт и завершается ненулевым кодом
|
||||
|
||||
### Requirement: Вход в DSH — скиллы, не команды
|
||||
Слой OpenSpec MUST NOT добавлять слэш-команды в бандл: единственная команда
|
||||
обвязки остаётся `/role`. Модель вызывает воркфлоу скиллом по `description`
|
||||
(«openspec propose», «openspec archive»).
|
||||
|
||||
#### Scenario: Команды бандла не изменились
|
||||
- **WHEN** установлен бандл этой версии
|
||||
- **THEN** список команд содержит `/role` и не содержит `/openspec` и `/opsx`
|
||||
|
||||
#### Scenario: Роль и bootstrap работают как раньше
|
||||
- **WHEN** в проекте с `.agents/skills` загружается роль `dev`
|
||||
- **THEN** `skill role` и bootstrap-маркер ведут себя так же, как без OpenSpec
|
||||
Loading…
x
Reference in New Issue
Block a user