Andrey Epifancev c8b92fae01 docs(dsh): пробный прогон SDD — режимы, дефект и fix-loop (#41)
Три задачи в temp-репозитории: implementer'ы deepseek-flash, все ревью
deepseek-v4-pro. Ревьюер Task 2 независимо нашёл T2.1 (медиана чётной длины
противоречит спеке) и T2.2 (нет теста), fix-раунд 1 → 186575c, скоуп-ре-ревью
APPROVED, финальное ревью ветки APPROVED. Режим 2 (фоновый контроллер, глубина
2) проверен отдельной пробой: вызов subagent из контроллера прошёл.

Артефакты прогона — openspec/changes/dsh-sdd/trial/ (план, спека, брифы,
отчёты, ledger), результаты — design.md. По урокам прогона skill sdd уточнён:
DONE_WITH_CONCERNS при замеченном расхождении, число тестов в плане — ориентир,
повтор при ошибке валидации provider/model.

Co-Authored-By: DeepSeek Harness <noreply@deepseek.com>
2026-10-24 17:49:38 +04:00

151 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
name: sdd
description: Use when executing an implementation plan in DeepSeek Harness (DSH) with subagents — async dispatch, controller modes, ledger, task review, fix loop, final branch review. Not for Claude Code, where subagent-driven-development applies.
---
# SDD в DeepSeek Harness
Исполнение плана субагентами в DSH. Заменяет `subagent-driven-development`
только в DSH-сессиях: у Claude Code синхронный `Task`, у DSH — асинхронный
`subagent`. Это **не паритет** с Claude-SDD и не имитация: протокол построен
на том, что DSH умеет (уведомление о завершении, `send_message`, ledger), а не
на том, чего у него нет (возврат результата из вызова инструмента).
## Когда применять
- Есть план в `docs/superpowers/plans/`, задачи независимы, сессия — DSH.
- Не применять: Claude Code (там исходный `subagent-driven-development`);
плана нет (сначала `brainstorming` → `writing-plans`); правка одна
(дешевле `executing-plans`).
## Режимы контроллера
| Условие | Контроллер | Глубина | Когда |
|---|---|---|---|
| Один план в сессии | главная сессия | 1 | по умолчанию; рулинги по конфликтам плана делает тот, у кого спека |
| Несколько задач, каждая по SDD, параллельно | фоновый субагент на план | 2 | когда главная сессия нужна другой задаче |
**Правило выбора:** режим зависит от числа параллельных планов, а не от
привычки. Один план — Режим 1; несколько — Режим 2 на каждый план.
**Проверка до первого диспатча.** В Режиме 2 поднята ли глубина:
`bash dsh/install.sh --check` должен сказать `ok: subagent maxDepth=2 (...)`,
или первый диспатч контроллера падает с `exceeds maxDepth`. Если глубины нет —
не диспатчить контроллера, зафиксировать рулинг `R-n` об **откате** в Режим 1 и
продолжить в нём. Проверка выбора модели: в схеме `subagent` есть
`provider`/`model` (overlay `dsh/subagent-models.yml`); нет — все диспатчи идут
на модели сессии, и это наблюдение `O-n`, а не выполненное требование. Без
overlay ребёнок наследует модель сессии.
## Протокол диспатча и отчёта
1. Первым делом — ledger (см. ниже) и скан плана на конфликты; рулинги до
Task 1.
2. Бриф implementer'а — **файлом** `<workspace>/briefs/task-<n>.md`: контекст,
требования задачи, точные имена и сигнатуры, тест, команда проверки,
формат коммита. Промпт короткий: «прочитай бриф, выполни, напиши отчёт,
первая строка отчёта — статус».
3. Отчёт — **файлом** `reports/task-<n>.md`. Контракт первой строки:
`DONE`, `DONE_WITH_CONCERNS`, `NEEDS_CONTEXT`, `BLOCKED`. Дальше: коммиты,
одна строка сводки тестов, concerns, что осталось.
4. В контекст контроллера возвращается только: статус, коммиты, одна строка
тестов и concerns. Полный отчёт читается с диска при ревью, а не тащится
в контекст.
5. `NEEDS_CONTEXT` — ответить в тот же `send_message`; `BLOCKED` — рулинг
контроллера, а не остановка сессии.
6. Замеченное расхождение с брифом или спекой — это `DONE_WITH_CONCERNS`, даже
если задача формально выполнена: ревью его проверит, контроллер — решит.
## Ожидание без блокировки
`subagent` возвращает id и сразу завершается; результата в значении
инструмента нет. Поэтому:
- вызвал `subagent` — **закончи ход**. Следующий ход начнётся с уведомления о
завершении ребёнка;
- пока ребёнок работает и есть локальная работа (ревью-пакет, ledger,
следующий бриф) — делай её, а не жди;
- перед каждым следующим диспатчем — `list_agents`: неактивный ребёнок без
отчёта означает, что уведомление потерялось; истина — файл отчёта и git, а
не перезапуск задачи;
- ребёнок висит дольше разумного — `interrupt_agent`, затем решение по
состоянию git;
- `job_output` — не ожидание сабагента, а стрим фонового job'а: здесь
неприменим.
## Ревью задачи и fix-loop
Каждая задача проходит ревью **свежим** субагентом: соответствие спеке и
качество кода. Self-review implementer'а ревью не заменяет.
1. Пакет ревью — файлом: дифф задачи, отчёт implementer'а, выдержка из спеки.
2. Ревьюер возвращает вердикт и находки `T<n>.<k>` со статусом.
3. Fix-loop — не более 5 раундов: раунды 1–3 — `send_message` тому же
implementer'у, раунды 4–5 — свежий implementer на более дорогом маршруте.
4. Ре-ревью — только исправление (скоуп), не вся задача.
5. После 5-го раунда — адъюдикация каждой открытой находки: рулинг
`R-n (design #n)` и статус `fixed`/`deferred`/`rejected <причина>`.
Находка без статуса в отчёте контроллера — ошибка контроллера.
Ожидаемое число тестов в плане — ориентир, а не контракт: fix-раунд добавляет
тесты, поэтому в отчёте фиксируется фактическое число, а расхождение вверх
объясняется, а не считается дефектом.
## Финальное ревью ветки
После всех задач — один ревьюер на весь дифф `main...HEAD`: находки `C-n`
(critical), `I-n` (important), `M-n` (minor). При находках — **один**
fix-диспатч и одно скоуп-ревью; остатки адъюдицируются и уходят в
`deferred`/follow-up.
## Ledger
`.superpowers/sdd/<plan>/progress.md` в рабочем каталоге плана; первая строка —
путь плана. Обязательные секции:
- таблица сканирования плана: конфликт, решение, рулинг `R-n (design #n)`;
- `Task <n>: pending | complete` с коммитом;
- `## Findings` — каждая находка: маркер, одна строка, статус
`fixed <commit>`, `deferred` или `rejected <причина>`;
- `## Rulings` — рулинги с ценой ошибки.
Ledger — единственная память между ходами: чат и контекст теряются, а
ledger лежит в git-ignored scratch (после `git clean -fdx` восстанавливается
по `git log`). Поэтому записи не сжимать.
## Маршруты моделей
| Роль в SDD | Маршрут | Почему |
|---|---|---|
| implementer по готовому коду из плана | `deepseek-official/deepseek-flash` | транскрипция и тесты |
| implementer по прозе, интеграция | `deepseek-official/deepseek-v4-pro` | решение в нескольких файлах |
| ревью задачи, ре-ревью | `deepseek-official/deepseek-v4-pro` | вердикт важнее цены |
| финальное ревью ветки | `deepseek-official/deepseek-v4-pro` | самый широкий дифф |
Маршрут указывается в каждом диспатче: `provider`, `model`,
`reasoning_effort`. Параметры действуют только при включённом overlay
(`dsh/subagent-models.yml`); без него всё идёт на модели сессии, и отчёт
фиксирует это наблюдением `O-n`. Если `subagent` вернул «child LLM provider
and model must be supplied together», хотя оба параметра переданы, — повтори
вызов один раз: валидация в 0.2.1-rc.3 нестабильна.
## Отличие от Claude-SDD
| Свойство | Claude Code `subagent-driven-development` | DSH `sdd` |
|---|---|---|
| Вызов исполнителя | синхронный `Task`, результат в том же ходе | асинхронный `subagent`, id + уведомление позже |
| Ожидание | возврат значения инструмента | закончи ход, продолжи по уведомлению |
| Продолжение ребёнка | новый `Task` | `send_message` в того же ребёнка |
| Глубина по умолчанию | не ограничена | `maxDepth: 2` только с overlay |
| Выбор модели | тиры sonnet/haiku/opus | два маршрута, только с overlay |
| Изоляция контекста | наследование не по умолчанию | `subagent_fork` наследует ходы — для implementer'а не годится |
## Запреты
- Не ждать сабагента через `job_output`, поллинг или повторные `list_agents`.
- Не делать merge и force-push; финиш — `finishing-a-development-branch` и PR.
- Не выдавать прогон без overlay за работу на разных моделях.
- `workflow` — расширение для веера независимых задач, в этой версии не
используется: решения по конфликтам и адъюдикация требуют суждения в моменте.