chore(openspec): архив change dsh-openspec (#42) #61

Merged
aep merged 1 commits from chore/archive-dsh-openspec into main 2026-10-24 19:00:40 +03:00
4 changed files with 109 additions and 0 deletions

View 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