DSH: OpenSpec — проектные скиллы, --openspec, проверка (#42) #60
137
openspec/changes/dsh-openspec/design.md
Normal file
137
openspec/changes/dsh-openspec/design.md
Normal file
@ -0,0 +1,137 @@
|
||||
# Design: OpenSpec в DSH
|
||||
|
||||
Issue: #42. Спека: `openspec/changes/dsh-openspec/specs/dsh-openspec/spec.md`.
|
||||
Спайк: 24.10.2026, temp-проект `/tmp/openspec-spike-dPkz`, openspec 1.13.1.
|
||||
|
||||
## 1. Что показал спайк
|
||||
|
||||
| Проверка | Результат |
|
||||
|---|---|
|
||||
| `openspec init --tools agents` в пустом git-проекте | 6 скиллов в `.agents/skills/`, `openspec/config.yaml`, `openspec/{specs,changes/archive}`; AGENTS.md не создаётся |
|
||||
| Команды | `Commands skipped for: agents (no adapter)` — слэш-команд адаптер не ставит |
|
||||
| `--tools claude`, затем `--tools agents` | `.claude/skills` и `.claude/commands/opsx` остаются нетронутыми, `.agents/skills` добавляется рядом |
|
||||
| Отличие agents-скиллов от claude-скиллов | одна строка подсказки (`/opsx:apply` → `/openspec-apply-change`) и `allowed-tools: Bash(openspec:*)` в frontmatter |
|
||||
| `openspec new change` → `instructions` → `validate --strict` → `archive -y` | весь цикл без интерактивных вопросов; спека `probe` создалась, change ушёл в `openspec/changes/archive/2026-10-24-spike-test/` |
|
||||
| `openspec change new` | команды нет; группа `new` скрыта из верхнего `--help`, но `openspec new change <name>` работает |
|
||||
| DSH видит `.agents/skills` | да: сабагент, запущенный с cwd в worktree после `openspec init --tools agents`, получил в каталоге скиллов все шесть `openspec-*` |
|
||||
|
||||
Последняя строка — главная: проектный корень скиллов DSH действительно читает
|
||||
`.agents/skills`, поэтому отдельный слой совместимости не нужен.
|
||||
|
||||
## 2. Решения
|
||||
|
||||
### R-1 (решение владельца). Скиллы живут в проекте, не глобально
|
||||
|
||||
`openspec init --tools agents` пишет `.agents/skills` в проект; в `~/.dsh/skills`
|
||||
копии нет. Обоснование:
|
||||
|
||||
- версия скиллов совпадает с версией CLI проекта, `openspec update` их обновляет;
|
||||
- глобальная копия стареет молча и не знает про `--store` и профили конкретного
|
||||
проекта;
|
||||
- если проект сделал init сам, глобальная копия даёт два скилла с одним именем;
|
||||
поведение DSH при дублях не проверено, и проверять его незачем.
|
||||
|
||||
Цена: новый проект нужно один раз подключить (`--openspec` или `openspec init`).
|
||||
Это осознанно: OpenSpec — свойство проекта, а не машины.
|
||||
|
||||
### R-2 (решение владельца). Слэш-команды нет
|
||||
|
||||
Вход — model-invocable скиллы: их `description` содержит «openspec propose»,
|
||||
«openspec archive» и т.п., поэтому фраза владельца запускает воркфлоу без
|
||||
команды. `/role` остаётся единственной командой бандла. Цена: в DSH нет
|
||||
аналога `/opsx:*`, набирать команды вручную нельзя — только просить модель.
|
||||
Это укладывается в то, как DSH уже работает с ролями.
|
||||
|
||||
### R-3. `--openspec` не создаёт OpenSpec-корень
|
||||
|
||||
Флаг добавляет agents-адаптер к проекту, который уже использует OpenSpec: если
|
||||
`openspec/` нет, скрипт отказывается и печатает готовую команду. Иначе
|
||||
`--openspec` в чужом каталоге молча завёл бы `openspec/`, `config.yaml` и
|
||||
changes-каталог — побочный эффект, который не читается из названия флага.
|
||||
|
||||
### R-4. `--check` предупреждает, а не падает
|
||||
|
||||
Отсутствие `openspec` в PATH — `WARN`: guard, bootstrap, роли и SDD от него не
|
||||
зависят. Код возврата `--check` меняют только `FAIL`-пункты (python3, git,
|
||||
node, хуки, бандл).
|
||||
|
||||
### R-5. Проверка «DSH видит скиллы» — живая, не в тестах
|
||||
|
||||
Юнит-тест может проверить наличие и frontmatter файлов, но не то, что DSH
|
||||
подхватил каталог. Поэтому в тестах — файлы и поведение `install.sh`, а
|
||||
видимость проверяется один раз живой сессией (сабагент с cwd в проекте) и
|
||||
фиксируется здесь.
|
||||
|
||||
## 3. Отличия от Claude Code
|
||||
|
||||
| Что | Claude Code | DSH |
|
||||
|---|---|---|
|
||||
| Куда ставит `openspec init` | `.claude/skills` + `.claude/commands/opsx/*` | `.agents/skills`, без команд |
|
||||
| Вход | `/opsx:propose`, `/opsx:apply`, … | скиллы по имени/фразе; команды нет |
|
||||
| Обновление | `openspec update` | `openspec update`, тот же генератор |
|
||||
| Глобальная копия | нет | нет (R-1) |
|
||||
|
||||
Обе копии в одном репозитории — не дублирование ради дублирования: это два
|
||||
клиента одного генератора. Расхождение ловится повторным `openspec init` /
|
||||
`openspec update`, а не ручной синхронизацией.
|
||||
|
||||
## 4. Решения, принятые без обсуждения
|
||||
|
||||
- **2026-10-24. Скиллы `.agents/skills` коммитятся в репозиторий обвязки.**
|
||||
Обвязка сама ведёт спеки через OpenSpec, а dogfooding — единственный способ
|
||||
держать слой проверенным. Обоснование: если скиллы не закоммичены, первый же
|
||||
DSH-прогон в этом репозитории их не увидит. Цена ошибки: лишние 6 каталогов
|
||||
в диффе при обновлении openspec; лечится `openspec update` и отдельным
|
||||
коммитом.
|
||||
- **2026-10-24. `.openspec-target` (`agents`) коммитится вместе со скиллами.**
|
||||
Это маркер адаптера, который пишет генератор; без него `openspec update` не
|
||||
знает, какой адаптер обновлять. Цена ошибки: одна строка в диффе.
|
||||
- **2026-10-24. Тест `--openspec` подставляет фейковый бинарь `openspec` в PATH.**
|
||||
Тесты DSH-порта идут без внешних CLI (см. `dsh/tests/run.sh`); живой openspec
|
||||
в тесте сделал бы набор зависимым от машины. Цена ошибки: тест не проверяет
|
||||
настоящий генератор — это делает живая приёмка.
|
||||
- **2026-10-24. Проверка скиллов в `--check` смотрит репозиторий обвязки
|
||||
(`$ROOT`), а не cwd.** `install.sh` — скрипт установки обвязки, его `--check`
|
||||
отвечает за состояние обвязки; проект проверяется флагом `--openspec`.
|
||||
Цена ошибки: из чужого проекта `--check` покажет `WARN` о скиллах обвязки —
|
||||
сообщение говорит, что делать.
|
||||
|
||||
## 5. Риски
|
||||
|
||||
- **Версия скиллов против CLI.** Скиллы генерирует CLI; если проект обновит
|
||||
`openspec` и не выполнит `openspec update`, скиллы отстанут от CLI. `--check`
|
||||
сравнивать версии не будет: он не знает, какой CLI у проекта. Признак —
|
||||
`metadata.generatedBy` во frontmatter.
|
||||
- **`.claude/commands/opsx` в DSH не работают** и остаются в репозитории для
|
||||
Claude Code. Это не мёртвый груз, а второй клиент; в PORT.md написано явно.
|
||||
- **DSH при дублях скиллов.** Не проверено и не проверяется, потому что
|
||||
глобальной копии нет (R-1). Если кто-то поставит `openspec init --tools agents`
|
||||
при уже скопированных вручную скиллах, поведение определит DSH.
|
||||
- **`openspec init` пишет в проект.** Флаг `--openspec` запускается только по
|
||||
явной команде и только при существующем `openspec/`; `adopt-project.sh` и
|
||||
`new-project.sh` его не вызывают.
|
||||
|
||||
## 6. Приёмка
|
||||
|
||||
- `openspec validate dsh-openspec --strict` — change валиден.
|
||||
- `bash dsh/tests/run.sh` — зелёный, включая новый `openspec.test.mjs`.
|
||||
- Живая проверка DSH: сессия/сабагент с cwd в проекте после `openspec init
|
||||
--tools agents` видит шесть `openspec-*` в каталоге скиллов; полный цикл
|
||||
`new change → validate --strict → archive -y` проходит без Claude Code
|
||||
(спайк 24.10.2026, транскрипт — в отчёте задачи).
|
||||
- `/role` и bootstrap не изменились: тесты `role-skill.test.mjs`,
|
||||
`bootstrap.test.mjs` и `sdd-skill.test.mjs` зелёные.
|
||||
|
||||
### Приёмка: прогон 24.10.2026
|
||||
|
||||
- CLI: openspec 1.13.1, temp-проект `/tmp/dsh-openspec-accept`, ветка `feat/probe`.
|
||||
- `openspec init --tools agents`: шесть скиллов в `.agents/skills`; повторный
|
||||
прогон идемпотентен, файлы не задвоились.
|
||||
- `openspec new change probe` → `status` → `instructions proposal` → написаны
|
||||
`proposal.md` и дельта `specs/probe/spec.md`.
|
||||
- `openspec validate probe --strict` → `Change 'probe' is valid`.
|
||||
- `openspec archive probe -y` → `Specs updated successfully.` / `Change 'probe'
|
||||
archived as '2026-10-24-probe'.`, основная спека
|
||||
`openspec/specs/probe/spec.md` создана.
|
||||
- Видимость скиллов в DSH-сессии проверяет контроллер отдельным сабагентом;
|
||||
результат дописывается сюда после прогона.
|
||||
Loading…
x
Reference in New Issue
Block a user