13 KiB
Design: установка DSH без зависимости от ~/.claude
Issue: #49. Спека: openspec/changes/dsh-install-source/specs/dsh-install/spec.md.
Исходные факты: dsh/PORT.md §3/§5/§7, issue #37/#38 (runtime-отвязка уже
сделана), ответ владельца 24.10.2026 («нормально так» — без вендоринга).
1. Что уже сделано и чего не хватает
| Слой | Источник в runtime | Зависимость от ~/.claude |
|---|---|---|
bootstrap using-superpowers |
~/.dsh/skills → ~/.agents/skills → кэш CC → ~/.claude/skills |
только fallback |
роли /role, skill role |
~/.dsh/roles → ~/.claude/roles → repo roles/ |
только fallback |
установка --skills |
кэш плагина CC | жёсткая |
установка --roles |
repo roles/ |
нет |
| установленные инструкции | global/CLAUDE.md + adapter-шапка |
текст путей ролей |
То есть #37 снял зависимость в том, что исполняется, и оставил её в том, что
устанавливается. Первая же команда --skills на чистой машине не находит
источник, печатает WARN и оставляет bootstrap без скилла — при этом установка
формально успешна.
2. Решения
D-1 (решение владельца). Без вендоринга superpowers
Копию апстрима в репозиторий не кладём. Обоснование: superpowers живёт своей версией (в кэше уже 6.4.1 и 7.0.0), репозиторий обвязки не должен превращаться в зеркало; обновление вендорной копии — ручная синхронизация, которая стареет молча. Цена: install-time источник нужно получить один раз (клон), это лишний шаг в quick start.
D-2. Три уровня источника, один формат
Порядок: --superpowers-from → DSH_SUPERPOWERS_SOURCE →
$DSH_HOME/superpowers/skills → legacy-кэш CC → legacy ~/.claude/skills.
- Флаг и переменная принимают оба каталога: корень superpowers (с
skills/) и самskills/. Клонgit clone … ~/.dsh/superpowersдаёт первый вид, кэш CC — второй; пользователь не должен помнить, какой именно. $DSH_HOME/superpowers— рекомендуемое место пиннинга: один клон на машину, дальше--skillsвоспроизводим без флага и без~/.claude.- Явно заданный невалидный источник —
FAIL, а не fallback: иначе опечатка в пути тихо даёт установку из legacy-кэша, и на чистой машине это снова «установка прошла, bootstrap пуст».
D-3. FAIL только когда ставить нечего
--skills без источника:
$DSH_HOME/skills/using-superpowers/SKILL.mdесть →WARN+ код 0 (идемпотентный повтор, старые копии не трогаем);- нет →
FAIL+ код 1 + готовая команда клона.
Локальные скиллы (role, sdd) ставятся в обоих случаях: они из репозитория и
от superpowers не зависят. Из-за этого --skills может вернуть 1, уже записав
часть файлов — это сказано в FAIL-сообщении.
D-4. Legacy-пути остаются, но говорят о себе
~/.claude поддерживается как fallback: машины, где --skills --roles ещё не
перезапускали, не должны сломаться на этом change. Предупреждения:
--skillsиз legacy-источника →WARN: legacy superpowers source;--check→WARNдля legacy и для «источника нет»;- bootstrap/
resolveRolesDirпри выборе~/.claude→ одно предупреждение за процесс (module-levelSet), не на каждыйagent/pre-step.
Удаление fallback'ов — отдельная задача: сначала все машины должны переехать на
~/.dsh (и это видно по WARN), потом код можно чистить. Цена: путь
~/.claude остаётся в bundle, и code review видит его ещё один цикл.
D-5. Инструкции переписываются при установке, не в источнике
global/CLAUDE.md — общий с Claude Code, его правит только CC-контур. Поэтому
install_global пишет AGENTS.md в два шага: adapter-шапка (как сейчас, плюс
явная строка про формат инструкций) и тело global/CLAUDE.md, прогнанное через
замену ~/.claude/roles → ~/.dsh/roles.
Замена точечная и проверяемая тестом: после --global в AGENTS.md есть
~/.dsh/roles/dev.md и нет ~/.claude/roles; сам global/CLAUDE.md не меняется
(тест сравнивает содержимое до/после). Цена: расхождение между источником и
установленной копией теперь intentional, и его надо помнить при правках CC-текста.
D-6. --check не падает без источника
--check — диагностика, а не установка: отсутствие superpowers-источника
остаётся WARN, код возврата меняют только жёсткие FAIL (python3, git, node,
хуки, бандл). Так же уже сделано для openspec (#42, R-4). Исключение —
невалидный явный источник (--superpowers-from/DSH_SUPERPOWERS_SOURCE):
это ошибка конфигурации пользователя, --check даёт FAIL, иначе опечатка
выглядит как «источника нет».
3. Формулировки, которые попадут в установленный AGENTS.md
DSH adapter: role files are ~/.dsh/roles (installed by --roles); legacy ~/.claude/roles is a migration fallback.DSH adapter: superpowers skills are ~/.dsh/skills (installed by --skills from --superpowers-from, DSH_SUPERPOWERS_SOURCE, or ~/.dsh/superpowers); the ~/.claude cache is a legacy fallback.DSH adapter: a project CLAUDE.md/AGENTS.md is the instruction-file format of this harness; it does not imply a Claude Code runtime.- Тело
global/CLAUDE.md— с заменой~/.claude/roles→~/.dsh/roles; строка проrole-hintостаётся, adapter-шапка говорит, что хука в DSH нет и роль выводится из первого сообщения.
4. Решения, принятые без обсуждения
- 2026-10-24. Клон для пиннинга —
git clone --depth 1 https://github.com/obra/superpowers ~/.dsh/superpowers. Это апстрим superpowers (public repo).install.shего не запускает: сеть в установке запрещена (D-1/спека). Цена ошибки: неверный URL — баг документации, ловится первой же установкой на чистой машине; лечится одной строкой в README/PORT. - 2026-10-24.
--superpowers-fromпринимает и корень, иskills/. Обоснование: два реальных источника дают разные формы (клон и кэш CC). Цена: две ветки разбора и два теста; ошибка разбора видна сразу поFAIL. - 2026-10-24. Предупреждение о legacy в runtime — один раз за процесс.
agent/pre-stepвызывается на каждом шаге; предупреждение на каждый шаг утопило бы лог. Цена: после перезапуска процесса предупреждение повторится — это ожидаемо; диагностика —--check. - 2026-10-24.
--checkпроверяет у пиннинга только наличиеusing-superpowers. Полная инвентаризация набора — работа--skills(он копирует всё, что есть). Цена: неполный клон пройдёт--checkи даст частичный набор скиллов; признак — отсутствие ожидаемого имени в каталоге скиллов сессии. - 2026-10-24.
tasks.mdOpenSpec не заполняется. Задачи живут в плане superpowers, как требуетCLAUDE.mdрепозитория. Цена:openspec statusпоказывает незаполненныйtasks.md;archiveэто не блокирует (уже так вdsh-openspec).
5. Риски
set -euo pipefailпротив «частичного успеха».install_skillsприFAILвозвращает 1; в--skillsон вызывается через|| status=1, иначеinstall_local_skillsне выполнится. Тест на «первую установку без источника» проверяет оба файла и код возврата.- Legacy-fallback маскирует неправильную настройку. Лечится
WARNв установке,--checkи runtime-предупреждением; полное удаление — D-4. - Замена
~/.claude/roles→~/.dsh/rolesв тексте. Заменяем только этот префикс, а не~/.claudeцеликом: в тексте есть упоминания хуков/CC, которые DSH-версии не касаются. Тест проверяет и наличие нового пути, и отсутствие старого. - Проверка «чистый HOME» — юнит-уровень. Реальный fresh-session smoke в DSH
делает владелец: сессия должна подняться без
~/.claudeи показать superpowers-скиллы. В PR это отмечено как единственный ручной шаг приёмки. - Апстрим superpowers может переехать. Явный источник проверяется по
using-superpowers/SKILL.md; если апстрим переименует каталог,FAILскажет, что искать.
6. Приёмка
openspec validate dsh-install-source --strict— change валиден.bash dsh/tests/run.sh— зелёный, включая новые тесты источника,AGENTS.mdи legacy-предупреждений.bash tests/run.sh— регрессий в CC-контуре нет.- Temp
HOMEбез~/.claude:--global --skills --rolesс--superpowers-from;--check;prepareBootstrap({home})— маркер на месте. - Живой fresh-session smoke без
~/.claude— за владельцем (в PR отмечено).
Приёмка: прогон 24.10.2026
openspec validate dsh-install-source --strict→Change 'dsh-install-source' is valid.bash dsh/tests/run.sh→ 61/61 pass (до изменения — 57).- Temp
HOMEбез~/.claude: копия реальных superpowers 7.0.0 в<tmp>/superpowers,--global --skills --roles --superpowers-from→ 15 superpowers-скиллов, 2 локальных (role,sdd), 4 роли;$HOME/.claudeне создан;prepareBootstrap({ home })выбрал~/.dsh/skills/using-superpowers/SKILL.md, маркер<!-- DSH-HARNESS-BOOTSTRAP:412d797495fc8765 -->;--check—ok: dsh skills,ok: role skill,ok: roles,WARN: no superpowers source(источник был временным каталогом, копии на месте). - Машина владельца:
--check—WARN: legacy superpowers source (~/.claude/plugins/cache/.../7.0.0/skills),ok: dsh skills,ok: roles. В установленном~/.dsh/AGENTS.mdещё три пути~/.claude/roles— нужен повторный--global(ручной шаг, отмечен в PR). - Fresh-session smoke без
~/.claude— за владельцем: юнит-уровень (prepareBootstrapс temp HOME) пройден, реальную сессию DSH поднимает владелец.