9.6 KiB
Raw Blame History

Design: DSH port v2 — вариант C

Issue: #69. Статус: черновик, ждёт builder-check и утверждения владельца.

Контекст

Ревью 24.10.2026: RV-1 (своя доставка superpowers без пина и адаптации), RV-6 (legacy-фолбэки как техдолг), RV-11 (нет compat-чека против DSH SDK). Владелец выбрал вариант C: машинерию готового порта LayneChai/superpowers-dsh взять как форк/вендор, sync гонять самим. Чистка трекера подтверждена и выполнена 24.10.2026 (см. комментарий в #69; сводная — #70).

Что вендорим

Из LayneChai/superpowers-dsh (MIT):

  • scripts/sync-from-upstream.mjs — ассертные transform-ы (якорь не совпал ровно один раз → FAIL), skip-список чужих harness-референсов, staging-swap (назначение меняется только при всех пройденных ассертах), проверка «невзорвавшихся» transform-ов, сверка набора скиллов;
  • scripts/verify-skills.mjs — provider видит все скиллы, frontmatter валиден, нет висячих ссылок;
  • scripts/check-dsh-compat.mjs — не вендорим как есть: он написан под SkillProvider LayneChai (у нас его нет — скиллы читает встроенный skill-filesystem) и требует SDK вне app.asar (терминал всегда SKIPPED); его идея — сверка контракта с установленным DSH — переезжает в самопроверку бандла (D-6).

Адаптация под нас:

  • наши transform-ы, где их текст расходится с нашим (главное: их using-superpowers-rewrite остаётся, но reference указывает на наш dsh-tools.md из dsh/bundle/, а не на их port/overrides/);
  • пути — dsh/sync/; скиллы кладутся не в пакет, а в $DSH_HOME/skills (источник текста для bootstrap-инъекции бандла остаётся единым — как сейчас).

Decisions made without discussion

# Решение Обоснование Цена ошибки
D-1 Вендор в dsh/sync/, не зависимость от npm-пакета LayneChai MIT разрешает; их каденс не наш (уже на патч позади: v7.0.0 при свежем v7.0.1); форк-стоимость мала (~3 скрипта) Содержим sync-скрипты сами; escape-люк на их пакет остаётся
D-2 Пин на тег (v7.0.1) через DSH_SUPERPOWERS_REF; #67 — rejected Воспроизводимость; unpinned HEAD = случайная семантика Каждый релиз upstream — свой issue+PR; пропустили релиз = молча старый текст (митигируется --check)
D-3 Результат sync — в $DSH_HOME/skills; bootstrap бандла не меняется Один источник текста; install.sh остаётся инсталлятором, а не публикуемым пакетом Нет
D-4 Legacy-фолбэки ~/.claude/* живут до #66, удаляются им #49 уже ввёл их с WARN; рубить сейчас = сломать машины без переустановки Техдолг висит дольше; контракт удаления — в #66
D-5 dsh/ уже в .claude/code-paths (проверено 24.10.2026 — файл содержит dsh/); require-plan защищает весь dsh/, включая dsh/sync/ Вендоримый код обязан быть под хук Без проверки правки sync-скриптов не гейтятся планом — в план добавлен тест-assert на строку dsh/ в code-paths
D-6 Compat-чек (решение владельца 24.10.2026): самопроверка бандла внутри DSH — при активации и по команде проверяет контракт, на который бандл опирается (ctx.tools.guard, agent/pre-step, session.surface.nodes, ctx.commands, workingDirectory); терминальный --check гоняет только verify synced-скиллов (frontmatter, префиксы, висячие ссылки) и окружение SDK DSH лежит в app.asar, терминал до него не дотягивается — проверка контракта возможна только изнутри DSH; это закрывает RV-11 по-настоящему Бандл тронут аддитивно (активационный assert + команда) — «не трогаем бандл» смягчено до «без изменения существующего поведения»
D-7 Каденс: issue на каждый релиз obra/superpowers; compat — после апгрейда DSH Ритм без напоминаний; влезает в обычный цикл фичи Пропущенный релиз не виден между ретро — добавить строку в --check/doctor (#44)
D-8 Болевые точки эксплуатации заранее не фиксируются: ответ владельца 24.10.2026 — «пока трудно сказать, идёт разработка только самого харнеса». План сосредоточен на машинерии порта; первые реальные затыки DSH-сессий копятся в #69 и двигают приоритеты Не выдумывать боли за владельца, пока нет сигнала Задачи плана упорядочены без пользовательского приоритета — по зависимостям и P-классам находок
D-9 Модели исполнителей (указание владельца 24.10.2026 «простые задачи — дешёвой модели»): механика и простые правки — deepseek-official/deepseek-flash, интеграция и ревью — deepseek-official/deepseek-v4-pro; фиксируется в брифах плана Экономия на рутине без потери качества ревью Сложность недооценена → flash не справился, fix-loop дороже; страхуется ревьюером на v4-pro
D-10 #63 (ложный блок worktree-цепочки, O-4) — bounded-задача до старта плана (решение владельца 24.10.2026); CC-сторона хуков входит в скоуп только этим исключением Блок бьёт по каждому чеклисту закрытия; фикс маленький и независим от dsh/ Два параллельных потока правок в claude-harness (#63 и дизайн #69) — не пересекаются по файлам: #63 — hooks/ + тесты, #69 — dsh/

Статус решений (25.10.2026, ветка feat/69-dsh-port-v2)

  • D-5 — выполнено в этой ветке. .claude/code-paths содержит строку dsh/ (проверено 24.10.2026), вендоренный dsh/sync/ попадает под require-plan; строку держит assert в dsh/tests/install.test.mjs (code-paths lists dsh/), чтобы каталог не выпал из хука молча.
  • D-6 — выполнено в этой ветке. Самопроверка живёт в dsh/bundle/lib/selfcheck.js (чистый collectSelfCheck(ctxLike)) и dsh/bundle/command-check.js (команда dsh-harness-check), подключается аддитивно в dsh/bundle/index.js; ключи конфига selfCheck/checkCommand (default true); тесты — dsh/tests/selfcheck.test.mjs; риск и чем закрыт — PORT.md §7. Терминальный --check остался офлайн-проверкой файлов и окружения: SDK внутри app.asar ему недоступен, поэтому контракт проверяется только изнутри DSH (требование selfcheck в спеке-дельте).

Открытые вопросы (к владельцу) — решены 24.10.2026

  1. Момент в DSH-сессии, когда обвязка споткнула — ответ «пока трудно сказать» → D-8.
  2. Подтверждение схемы чистки трекера — подтверждено и выполнено (#70, закрытия, парковки).
  3. #63 bounded-задачей до плана — да → D-10, выполняется отдельным PR до плана.

На потом (в план, не в дизайн)

  • Разбивка задач: sync-вендор и пин → install.sh переделка → verify скиллов в --check → самопроверка бандла → сводная follow-ups (#70) → #59 → #43–#46 → удаление legacy (#66).