Change dsh-sdd перенесён в openspec/changes/archive/2026-10-24-dsh-sdd, дельта dsh-sdd добавлена в openspec/specs/dsh-sdd/spec.md (7 требований). Co-Authored-By: DeepSeek Harness <noreply@deepseek.com>
18 KiB
Design: DSH-native SDD
Context
Claude-SDD (~/.dsh/skills/subagent-driven-development/SKILL.md) опирается на
синхронный Task: контроллер вызвал implementer'а и в том же ходе получил
отчёт. DSH так не умеет — и это не деталь, а другая форма исполнения.
Что измерено в DSH 0.2.1-rc.3 (@deepseek-ai/dsh-tool-subagent,
dsh-subagent, dsh-tool-workflow, dsh-workflow-ptc):
| Свойство | Значение в DSH | Следствие для SDD |
|---|---|---|
subagent возвращает |
started subagent <id> сразу, результат — уведомлением позже |
нет синхронного ожидания; ход контроллера заканчивается |
| Продолжение ребёнка | send_message (провайдер spawn continuable) |
раунды фикса идут в того же implementer'а |
subagent_fork |
наследует завершённые ходы родителя | для implementer'а не годится: нужен свежий контекст |
subagent.maxDepth |
по умолчанию 1 (настройка сервиса, volatile) | контроллер-сабагент не позовёт implementer'а, пока не поднято до 2 |
Выбор модели у subagent |
только при modelSelectionSettings: true на строке tool-subagent; иначе ребёнок наследует модель сессии |
«укажи модель в dispatch» невыполнимо без правки профиля |
workflow |
синхронный, один вызов инструмента; agent(prompt, {schema, provider, model, label, phase}) |
годится для детерминированного fan-out с выбором модели без настроек |
Кэпы workflow |
maxTotalAgents, maxConcurrentAgents, maxItemsPerCall |
backstop для веера; для 3 задач не упираемся |
| Наблюдение за детьми | list_agents, interrupt_agent, уведомления |
«дождаться» = закончить ход и проснуться от уведомления |
| Модели в окружении | deepseek-official/deepseek-flash, deepseek-official/deepseek-v4-pro |
три тира роли схлопываются в два |
Строка subagent-model-selection-settings есть в web/desktop-профиле и
отсутствует в headless. Поэтому флаг modelSelectionSettings нельзя ставить в
бандл: headless упадёт на загрузке с «requires … in the Host scope». Он живёт
в opt-in overlay профиля.
Goals / Non-Goals
Goals
- Инструкция, по которой DSH-сессия исполняет план без вранья о возможностях
платформы: два режима контроллера, протокол отчётов, ревью задачи, fix-loop,
ledger с
## Findings, финальное ревью. - Проверяемый прогон: план из 3 задач в temp-репозитории, дефект найден ревьюером и закрыт в fix-loop.
- Тесты, идущие без DSH runtime.
- Явная таблица отличий от Claude-SDD.
Non-Goals
- Паритет с
Task: его не будет, и это фиксируется, а не имитируется. - Переписывание
~/.dsh/skills/subagent-driven-development/— skill superpowers остаётся как есть; DSH-семантика живёт в отдельном skill. - Правка
roles/dev.mdв общем слое: роль для DSH — слой~/.dsh/roles. - Автоматическое включение выбора модели и глубины: это решение владельца.
Решения владельца (brainstorming 24.10.2026)
- Режим контроллера зависит от контекста, а не один на всех. Одна сложная задача — контроллер главная сессия. Несколько задач параллельно, каждая по SDD, — контроллер фоновый сабагент на задачу.
Design
Режим 1 — главная сессия контроллер
Главная сессия читает план, ведёт ledger, диспатчит subagent (depth 1,
укладывается в дефолтный maxDepth: 1), получает уведомление, диспатчит
ревьюера, при находках — send_message implementer'у. Плюс: рулинги по
конфликтам плана принимает тот, у кого есть спека и контекст. Минус: контекст
главной сессии растёт, поэтому отчёты — файлами, а в контекст возвращается
только статус, коммиты и одна строка тестов.
Режим 2 — фоновый контроллер
Один subagent на план, maxDepth: 2. Контроллер не блокируется: диспатч
implementer'а возвращает id, ход заканчивается, уведомление о завершении
начинает следующий ход. Пропущенное уведомление ловится list_agents перед
следующим диспатчем. Главная сессия в это время свободна для другой задачи.
Протокол (общий для обоих режимов)
- Setup: ledger
.superpowers/sdd/<plan>/progress.md, первая строка — путь плана; скан плана на конфликты (таблица в ledger, рулинги до Task 1). - Dispatch implementer'а: brief файлом, отчёт файлом, контракт —
DONE,DONE_WITH_CONCERNS,NEEDS_CONTEXT,BLOCKED. - Ревью задачи: пакет диффа файлом, вердикт по спеке и по качеству, находки
T<n>.<k>. - Fix-loop до 5 раундов: раунды 1–3 — тот же implementer через
send_message, 4–5 — свежий и на тир выше; затем адъюдикация. - Финальное ревью ветки:
C-n/I-n/M-n, один fix-диспатч, одно скоуп-ревью. - Ledger:
## Findingsс маркером и статусом; рулингиR-n (design #n).
Модели
Два маршрута вместо трёх тиров:
| Роль в SDD | Маршрут | Почему |
|---|---|---|
| implementer по готовому коду из плана | deepseek-official/deepseek-flash |
транскрипция + тесты |
| implementer по прозе, интеграция | deepseek-official/deepseek-v4-pro |
решение в нескольких файлах |
| ревью задачи, ре-ревью | deepseek-official/deepseek-v4-pro |
вердикт важнее цены |
| финальное ревью ветки | deepseek-official/deepseek-v4-pro |
самый широкий дифф |
Без overlay всё идёт на модели сессии (deepseek-flash); тиры становятся
недоступны, и инструкция это явно говорит, а не молча игнорирует.
Где живёт
dsh/skills/sdd/SKILL.md — в репозитории обвязки, ставится
dsh/install.sh --skills в ~/.dsh/skills. Claude Code его не получает:
DoD порта требует, чтобы CC-харнес не менялся.
Альтернативы
- Только workflow. Детерминированный fan-out силён для независимых задач, но решения по конфликтам плана, адъюдикация находок и «стоп, план врёт» требуют суждения в моменте. Скрипт может ветвиться по структурному ответу ревьюера, но не может решить, что находка неверна.
- Только фоновый контроллер. Дороже на одну задачу и требует поднятой глубины; для одиночной задачи лишний уровень.
- Гибрид.
workflow— для веера независимых задач внутри плана, контроллер — для последовательной петли. Держим как расширение, в первой версии не включаем: веер ещё не встречался в планах этого репозитория.
Риски
- Уведомление о завершении ребёнка не пришло (обрыв, компакция) — контроллер
обязан сверяться с
list_agentsи git, а не с памятью. maxDepth: 2не поднят, а режим 2 выбран — диспатч упадётsubagent depth 2 exceeds maxDepth 1; инструкция требует проверить до старта и откатиться в режим 1 с записью рулинга.- Ledger лежит в git-ignored scratch:
git clean -fdxего уничтожает; восстановление — поgit log. - Модели две: «haiku» из Claude-текста не существует, перенос формулировок тиров без таблицы превратится в фикцию.
Что должен доказать пробный прогон
| Пункт приёмки #41 | Чем доказывается |
|---|---|
| 3 задачи не теряются | ledger: три Task N: complete, три коммита |
| отчёты собираются | файлы отчётов implementer'ов + строки в ledger |
| ревьюер находит дефект | T1.1 с fixed <commit> |
| fix-loop завершается | раунд в ledger, ре-ревью чистое |
ledger содержит ## Findings со статусами |
сам файл |
| отличие от Claude-SDD указано | таблица выше + раздел в skill |
Результаты пробного прогона 24.10.2026
Площадка — /tmp/dsh-sdd-trial: отдельный git-репозиторий, ветка feat/trial,
база main; модуль src/stats.py из трёх задач. Контроллер — главная сессия
(Режим 1), overlay профиля включён (model selection + maxDepth: 2),
deepseek-flash — implementer'ы, deepseek-v4-pro — все ревью. Артефакты
скопированы в trial/: SPEC.md, plan.md, брифы, отчёты implementer'ов и
ревьюеров, ledger.md (первая строка — путь плана, ## Findings, ## Rulings).
Диспатчи
| Шаг | Агент | Маршрут | Результат |
|---|---|---|---|
| Task 1 implementer | 1c906f6f |
flash | DONE, dc1670f, 2 теста OK |
| Task 1 review | 68a1aeb4 |
v4-pro | APPROVED, находок нет |
| Task 2 implementer | 1ec8f7fc |
flash | DONE, 836a730, 4 теста OK, concern: план противоречит спеке на чётной длине |
| Task 2 review | e50c74d2 |
v4-pro | CHANGES_REQUESTED: T2.1, T2.2 (проверено независимо от concerns) |
| Task 2 fix, раунд 1 | 1ec8f7fc (send_message) |
flash | 186575c, 6 тестов OK |
| Task 2 re-review (скоуп) | 7912c16b |
v4-pro | APPROVED: T2.1 fixed 186575c, T2.2 fixed 186575c |
| Task 3 implementer | 6ca07edc |
flash | DONE, 7cb0383, 7 тестов OK |
| Task 3 review | f10e3165 |
v4-pro | APPROVED, находок нет |
| Final branch review | 0fec8102 |
v4-pro | APPROVED, находок нет |
Приёмка #41
| Пункт приёмки | Чем доказан | Статус |
|---|---|---|
| 3 задачи не теряются | ledger Task 1..3: complete, 4 коммита dc1670f/836a730/186575c/7cb0383 |
выполнен |
| отчёты собираются | 9 файлов в trial/reports/, статус первой строкой у каждого |
выполнен |
| ревьюер находит и проверяет дефект | T2.1 найден независимо (median([1,2]) == 2.0 вместо 1.5), T2.2 — отсутствие теста; оба fixed 186575c, ре-ревью APPROVED |
выполнен |
| fix-loop завершается | раунд 1 из 5, ре-ревью чистое | выполнен |
ledger содержит ## Findings со статусами |
trial/ledger.md |
выполнен |
| итоговый прогон зелёный | python3 -m unittest discover -s tests → 7 тестов OK; bash dsh/tests/run.sh и bash tests/run.sh зелёные |
выполнен |
| отличие от Claude-SDD указано | таблица в dsh/skills/sdd/SKILL.md |
выполнен |
Находки и наблюдения прогона
| Маркер | Что | Статус |
|---|---|---|
T2.1 |
median на чётной длине возвращал верхний средний элемент вместо среднего двух |
fixed 186575c |
T2.2 |
не было теста на чётную длину | fixed 186575c |
O-1 |
«Interfaces» плана обещают аннотации типов, «Exact code» их не содержит; SPEC аннотаций не требует | rejected (правка плана в прогоне не даёт результата) |
O-2, O-3 |
первый вызов subagent с переданными provider/model вернул «child LLM provider and model must be supplied together»; немедленный повтор тем же вызовом проходит (2 раза за прогон) |
deferred (наблюдение о стабильности валидации DSH; повтор в skill) |
O-4 |
ожидаемое число тестов в плане (5) устарело после fix-раунда Task 2 (фактически 7) |
fixed — в skill добавлено правило «число тестов в плане — ориентир» |
O-5 |
тест describe([1,2,3]) на симметричном входе не отличил бы перестановку mean/median |
deferred (реализация верна, слабость плана) |
Отдельно: implementer Task 2 заметил расхождение плана со спекой, но поставил
DONE, а не DONE_WITH_CONCERNS; ревью дефект всё равно поймало, потому что
ревьюер проверял по SPEC.md, а не по отчёту. Правило уточнено в skill:
замеченное расхождение с брифом — это DONE_WITH_CONCERNS.
Режим 2 (фоновый контроллер)
Отдельная площадка /tmp/dsh-sdd-mode2. Контроллер afe886e5 (flash) вызвал
subagent (flash) и получил id; ход закончился, уведомление о завершении пришло
отдельным сообщением, после чего контроллер проверил отчёт, коммит 0601d6e и
тесты независимо. Глубина 2 работает с overlay; синхронного ожидания нет.
Отличия от дизайна, обнаруженные прогоном
- Число тестов в плане — ориентир: fix-раунд добавляет тесты, и расхождение вверх не дефект (O-4).
- Ошибка валидации
provider/modelнестабильна; лечится повтором, а не пересмотром маршрутов (O-2/O-3). - Ревьюер, проверяющий по спеке, а не по отчёту implementer'а, ловит дефекты, даже если implementer промолчал бы.
Decisions made without discussion
- 24.10.2026 — overlay вместо флага в бандле. Обоснование: headless-профиль
не содержит строку
subagent-model-selection-settings, включённый флаг роняет загрузку. Цена ошибки: владельцу нужно скопировать три записи в профиль руками; забыл — работает на модели сессии. - 24.10.2026 — карта тиров.
flash— транскрипция и механика,v4-pro— интеграция и все ревью. Цена ошибки: дороже прогон или слабее ревью; правится одной таблицей в skill. - 24.10.2026 — skill ставится только в
~/.dsh. Обоснование: DoD порта запрещает менять CC-харнес. Цена ошибки: в Claude-сессиях инструкции про DSH-режимы нет — там работает исходныйsubagent-driven-development. - 24.10.2026 — гибрид отложен.
workflowописан как расширение, не реализуется в этом change. Цена ошибки: веер задач придётся ввести позже отдельной правкой skill.
Открытые вопросы
- Нужно ли после приёмки добавить в
~/.dsh/roles/dev.mdстроку «в DSH исполнение плана — skillsdd» (сейчас роль ссылается на superpowers-SDD).