Andrey Epifancev ca3814f62a docs(openspec): результаты приёмки DSH-цикла (#42)
Co-Authored-By: DeepSeek Harness <noreply@deepseek.com>
2026-10-24 19:43:30 +04:00

10 KiB
Raw Blame History

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-сессии проверяет контроллер отдельным сабагентом; результат дописывается сюда после прогона.