Три задачи в 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>
23 KiB
DSH-native SDD — Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Дать DSH-сессии инструкцию исполнения плана субагентами (асинхронный subagent, ledger, ревью, fix-loop) и opt-in overlay профиля с глубиной 2 и двумя маршрутами моделей; доказать семантику пробным прогоном из 3 задач.
Architecture: Три слоя. (1) dsh/subagent-models.yml — overlay, который владелец копирует в cordis.patch.yml профиля: включает subagent-model-selection-settings (маршруты deepseek-flash / deepseek-v4-pro) и subagent.maxDepth: 2; в бандл не входит, иначе падает headless. (2) dsh/skills/sdd/SKILL.md — DSH-семантика исполнения плана: два режима контроллера, протокол ожидания через завершение хода и уведомление, ревью задачи, fix-loop, ledger ## Findings. (3) Пробный прогон в temp-репозитории: контроллер — главная сессия, implementer (flash) → reviewer (v4-pro) → fix через send_message → финальное ревью (v4-pro); отдельной пробой проверяется режим 2 (фоновый контроллер, глубина 2).
Tech Stack: bash, python3 stdlib, Node test runner (node --test), markdown, DSH 0.2.1-rc.3 (Cordis bundle, subagent, send_message, list_agents), Gitea CLI tea.
Spec: openspec/changes/dsh-sdd/ — proposal.md, design.md (источник решений), specs/dsh-sdd/spec.md (требования и сценарии).
Ветка: feat/41-dsh-sdd-spike, issue #41, worktree .claude/worktrees/sdd-spike.
Global Constraints
- DSH 0.2.1-rc.3; версия плагинного API не заморожена, после апгрейда тесты прогоняются заново.
- Бандл импортирует только Node builtins и локальные файлы (
dsh/tests/package.test.mjsэто проверяет): никаких@deepseek-ai/*импортов. subagent-model-selection-settingsнельзя ставить вdsh/bundle/cordis.patch.yml: строки нет в headless-профиле, включённый флаг роняет загрузку. Только overlay профиля.- Skill
sddставится только в~/.dsh/skillsчерезbash dsh/install.sh --skills. Claude Code его не получает:roles/,hooks/,global/,install.sh(корневой),agents/не меняются. - Тесты идут без DSH runtime:
bash dsh/tests/run.shиbash tests/run.sh(630/630 на момент дизайна) — зелёными должны быть оба набора. - Документация и тексты — по-русски, формат планов/ledger — как в этом репозитории.
- Коммиты — с trailer
Co-Authored-By: DeepSeek Harness <noreply@deepseek.com>, force-push запрещён. - Маркировка: находки ревью
T<n>.<k>/C-n/I-n/M-n, рулингиR-n (design #n), наблюденияO-n, замечания человекаH-n; у каждой находки статусfixed <commit>/deferred/rejected <причина>.
Review Focus
- Overlay копируют в headless-профиль → загрузка падает на «requires … in the Host scope»; overlay и PORT.md обязаны это сказать явно, а не только в design.md.
- Skill прочитан в сессии без model selection → диспатч с
provider/modelмолча игнорируется или падает; skill обязан деградировать на модель сессии и записать это наблюдением, а не выдавать за выполненное требование. - Ожидание описано как
job_output/поллинг или как возврат значенияsubagent→ инструкция врёт о платформе; ожидание — только конец хода + уведомление +list_agents. - Фоновый контроллер при
maxDepth: 1→subagent depth 2 exceeds maxDepth 1; skill обязан проверить глубину до диспатча и откатиться в режим 1 с рулингом. - Ledger без
## Findings/статусов или находка без маркера → отчёт контроллера считается ошибочным; тест skill обязан требовать разделы, а пробный прогон — показать заполненный ledger. install.sh --skillsс новым skill ломает счётчик «copied 1 local skills» вdsh/tests/install.test.mjs→ счётчик и проверка наличияsddобновляются в той же задаче.
Task 1: Overlay профиля и статическая проверка глубины
Files:
- Create:
dsh/subagent-models.yml - Create:
dsh/tests/subagent-models.test.mjs - Modify:
dsh/install.sh(check(), после проверки hook bridge) - Modify:
dsh/PORT.md(§5 Configuration — подраздел про overlay и глубину; §7 — риск «Model tiers»; §8 — п. 4)
Interfaces:
-
Produces: файл
dsh/subagent-models.yml— YAML-массив из двух записей:- id: subagent-model-selection-settingsсconfig.enabled: trueиconfig.allowedModelsиз двух пар (deepseek-official/deepseek-flash,deepseek-official/deepseek-v4-pro), затем- id: subagentсconfig.maxDepth: 2. -
Produces: строки вывода
check():ok: subagent overlay (<путь>)илиWARN: subagent overlay missing …;ok: subagent maxDepth=2 (<файл>)илиWARN: subagent maxDepth is not 2 in any profile patch; SDD mode 2 is unavailable. -
Consumes: ничего из других задач.
-
Step 1: Написать падающий тест
dsh/tests/subagent-models.test.mjs
import assert from 'node:assert/strict'
import { spawnSync } from 'node:child_process'
import { existsSync, readFileSync } from 'node:fs'
import { dirname, join } from 'node:path'
import test from 'node:test'
import { fileURLToPath } from 'node:url'
import { cleanup, tempDir, write } from './helpers.mjs'
const here = dirname(fileURLToPath(import.meta.url))
const overlay = join(here, '..', 'subagent-models.yml')
const script = join(here, '..', 'install.sh')
test('overlay enables model selection for both routes and depth 2', () => {
assert.ok(existsSync(overlay), 'dsh/subagent-models.yml is missing')
const text = readFileSync(overlay, 'utf8')
assert.match(text, /id: subagent-model-selection-settings/)
assert.match(text, /model: deepseek-flash/)
assert.match(text, /model: deepseek-v4-pro/)
assert.match(text, /id: subagent\n\s+config:\n\s+maxDepth: 2/)
assert.match(text, /headless/)
})
test('install.sh --check reports the overlay and the profile depth', () => {
const home = tempDir()
try {
const dshHome = join(home, '.dsh')
const env = { ...process.env, HOME: home, DSH_HOME: dshHome }
const missing = spawnSync('bash', [script, '--check'], { env, encoding: 'utf8' })
assert.match(missing.stderr, /subagent maxDepth is not 2/)
write(join(dshHome, 'profiles', 'desktop', 'cordis.patch.yml'), '- id: subagent\n config:\n maxDepth: 2\n')
const present = spawnSync('bash', [script, '--check'], { env, encoding: 'utf8' })
assert.match(present.stdout, /ok: subagent overlay/)
assert.match(present.stdout, /ok: subagent maxDepth=2/)
} finally {
cleanup(home)
}
})
- Step 2: Прогнать тест и убедиться, что он падает
Run: node --test dsh/tests/subagent-models.test.mjs
Expected: FAIL — dsh/subagent-models.yml is missing.
- Step 3: Создать
dsh/subagent-models.yml
YAML-массив с комментарием-шапкой: overlay для DSH-native SDD (#41); копировать в $DSH_HOME/profiles/desktop/cordis.patch.yml, не в бандл, потому что строки subagent-model-selection-settings нет в headless; после копирования — рестарт DSH; проверка — bash dsh/install.sh --check. Две записи из блока Interfaces, значения — дословно.
- Step 4: Добавить проверки в
dsh/install.sh
В check() после блока hook bridge: проверить наличие $ROOT/dsh/subagent-models.yml; отдельно — grep -qs 'maxDepth: 2' "$DSH_HOME"/profiles/*/cordis.patch.yml (glob не раскрылся — предупреждение, не ошибка; failed не поднимать: overlay опционален).
- Step 5: Обновить
dsh/PORT.md
§5: подраздел «Model routes and delegation depth» — как включить (скопировать dsh/subagent-models.yml в профиль, рестарт), что даёт (provider/model у subagent и subagent_fork, глубина 2), чего не делает (не в бандле; без overlay всё идёт на модели сессии).
§7: в пункте «Model tiers» — два маршрута и ссылка на overlay.
§8: п. 4 (SDD spike) получает статус «в работе, change dsh-sdd».
- Step 6: Прогнать тесты
Run: node --test dsh/tests/subagent-models.test.mjs
Expected: PASS (2 tests).
- Step 7: Прогнать оба набора
Run: bash dsh/tests/run.sh && bash tests/run.sh
Expected: все зелёные (если в worktree падает guard на 5 тестах — проверить ls -ld dsh/bundle/hooks, должен быть симлинк ../../hooks, O-1).
- Step 8: Коммит
git add dsh/subagent-models.yml dsh/tests/subagent-models.test.mjs dsh/install.sh dsh/PORT.md
git commit -m "feat(dsh): overlay профиля — model selection и maxDepth 2 (#41)"
Task 2: Skill sdd — DSH-семантика исполнения плана
Files:
- Create:
dsh/skills/sdd/SKILL.md - Create:
dsh/tests/sdd-skill.test.mjs - Modify:
dsh/tests/install.test.mjs(ожидание «copied 2 local skills», проверкаskills/sdd/SKILL.md) - Modify:
dsh/README.md(What works / Not yet / Layout / Known limits)
Interfaces:
-
Produces: skill с frontmatter
name: sddиdescription: Use when executing an implementation plan in DeepSeek Harness …; текст содержит: оба режима,maxDepth, инструментыsubagent/send_message/list_agents/interrupt_agent, статусыDONE/DONE_WITH_CONCERNS/NEEDS_CONTEXT/BLOCKED, маршрутыdeepseek-official/deepseek-flashиdeepseek-official/deepseek-v4-pro, ledger с## Findings, таблицу отличий от Claude-SDD. -
Consumes:
dsh/subagent-models.ymlиз Task 1 (ссылка в разделе про глубину и модели). -
Step 1: Написать падающий тест
dsh/tests/sdd-skill.test.mjs
Проверки (каждая — отдельный test):
- frontmatter:
/^---\nname: sdd\n/,description: .+; - режимы:
/Режим 1/,/Режим 2/,/maxDepth: 2/и/глубин/; - инструменты:
subagent,send_message,list_agents,interrupt_agent; - статусы:
DONE_WITH_CONCERNS,NEEDS_CONTEXT,BLOCKED; - маршруты:
deepseek-official/deepseek-flash,deepseek-official/deepseek-v4-pro; - ledger:
## Findings,fixed <commit>,T<n>.<k>; - ожидание:
/закончи ход/и/уведомлен/; НЕ содержитjob_output; - отличие:
синхронныйиасинхронный,subagent-driven-development; - деградация:
/модель сессии/,/не паритет/— заголовок таблицы отличий с запретом выдавать за паритет; - размер:
Buffer.byteLength(text) < 12288.
Run: node --test dsh/tests/sdd-skill.test.mjs → FAIL (файла нет).
- Step 2: Написать
dsh/skills/sdd/SKILL.md
Разделы: When to use / when not (DSH-сессии; в Claude Code — исходный subagent-driven-development); два режима и правило выбора (один план — главная сессия, глубина 1; несколько параллельных планов — фоновый контроллер на план, глубина 2) + проверка глубины до первого диспатча и рулинг об откате; протокол диспатча (бриф файлом, отчёт файлом, контракт статусов, в контекст — только статус, коммиты, одна строка тестов); ожидание (конец хода, уведомление, list_agents перед каждым диспатчем, interrupt_agent для зависших, запрет job_output); ревью задачи (спека + качество) и fix-loop 5 раундов (1–3 — тот же implementer через send_message, 4–5 — свежий на тир выше, потом адъюдикация); финальное ревью ветки C-n/I-n/M-n; ledger (первая строка — путь плана, таблица конфликтов, рулинги R-n (design #n), ## Findings со статусами); маршруты моделей и деградация; таблица отличий от subagent-driven-development (синхронный Task vs асинхронный subagent, send_message, глубина по умолчанию, выбор модели, ожидание); запреты (не заявлять паритет, workflow — расширение, в первой версии не включать).
- Step 3: Прогнать тест
Run: node --test dsh/tests/sdd-skill.test.mjs → PASS.
- Step 4: Обновить
dsh/tests/install.test.mjs
copied 1 local skills → copied 2 local skills; после проверки role проверить join(dshHome, 'skills', 'sdd', 'SKILL.md') — существует и содержит name: sdd.
- Step 5: Обновить
dsh/README.md
What works: SDD-инструкция и overlay. Not yet: убрать SDD, оставить briefing, harness-check, role-hint, harness-doctor, auto-memory, caveman. Layout: skills/sdd/SKILL.md, subagent-models.yml. Known limits: заменить строку про sonnet/haiku/opus ссылкой на overlay.
- Step 6: Прогнать всё
Run: bash dsh/tests/run.sh && bash tests/run.sh → зелёные.
- Step 7: Коммит
git add dsh/skills/sdd/SKILL.md dsh/tests/sdd-skill.test.mjs dsh/tests/install.test.mjs dsh/README.md
git commit -m "feat(dsh): skill sdd — асинхронный протокол исполнения плана (#41)"
Task 3: Пробный прогон 3 задач и запись результатов
Files:
- Create:
/tmp/dsh-sdd-trial*— temp-репозиторий (не входит в PR) - Modify:
openspec/changes/dsh-sdd/design.md— раздел «Результаты пробного прогона» - Modify:
dsh/PORT.md§8 — п. 4 закрыт ссылкой на прогон - Modify: этот план — отметить шаги
- Comment: issue #41, затем PR (
tea pulls create)
Interfaces:
-
Consumes: skill
sddиз Task 2, overlay из Task 1 (в профиле уже включён владельцем). -
Produces: транскрипт прогона (диспатчи, статусы, отчёты, ledger) в
design.md; вывод о режимах 1 и 2. -
Step 1: Создать temp-репозиторий и план
TRIAL="$(mktemp -d)/trial"; git init -b main, коммит README.md; git checkout -b feat/trial; файл docs/superpowers/plans/2026-10-24-trial.md — один план (require-plan разрешает правки), проект: Python-модуль src/stats.py. Три задачи: (1) mean(values) — float, ValueError на пустом списке, готовый код и тест в плане; (2) median(values) — по требованиям для чётной длины среднее двух средних; в плане намеренно оставлен дефект: return xs[len(xs) // 2], а тест в плане покрывает только нечётную длину (дефект должен найти ревьюер, не тесты); (3) describe(values) — dict {count, mean, median} через две функции. Тесты — python3 -m unittest discover -s tests. Спека прогона — SPEC.md в temp-репо: требования к mean/median/describe, включая «чётная длина — среднее двух средних».
- Step 2: Ledger прогона
.superpowers/sdd/trial-plan/progress.md: первая строка — путь плана; таблица сканирования плана (конфликт: план Task 2 противоречит SPEC.md — рулинг R-1: следовать SPEC.md, дефект фиксировать находкой T2.1 при ревью, а не править план до диспатча); пустой ## Findings; три строки Task N: pending.
- Step 3: Диспатч implementer'а Task 1 (режим 1)
subagent c description «trial task 1», cwd = temp-репо, provider: deepseek-official, model: deepseek-flash; промпт — brief файлом briefs/task-1.md (контекст, требования, точный код, тест, коммит), отчёт — reports/task-1.md с первой строкой-статусом; требование: python3 -m unittest discover -s tests зелёный, коммит. После вызова — закончить ход; продолжить по уведомлению.
- Step 4: Собрать отчёт Task 1 и отправить на ревью
Прочитать reports/task-1.md, сверить коммит (git -C "$TRIAL" log --oneline) и прогон тестов; list_agents — сверка состояния; в ledger Task 1: complete. Диффпакет — review/pkg-task-1.txt (git diff main...HEAD); subagent с model: deepseek-v4-pro: ревью по SPEC.md и по качеству, находки T1.<k>, вердикт в reports/review-1.md.
- Step 5: Task 2 — диспатч, ревью, fix-loop
Так же диспатчить Task 2 (flash, brief с кодом из плана и дефектом). Ревью (v4-pro) должно вернуть T2.1 — чётная длина медианы. Fix-раунд 1: send_message тому же implementer'у с находкой; по уведомлению — тест на чётную длину, фикс, коммит; ре-ревью скопом — новый subagent (v4-pro) с пакетом review/pkg-fix-1.txt; в ledger T2.1: fixed <commit>. Если ревьюер дефект не нашёл — зафиксировать O-1 (протокол пройден, но приёмка #41 «ревьюер находит дефект» не доказана) и повторить ревью с явным указанием проверять требование «чётная длина».
- Step 6: Task 3 и финальное ревью ветки
Task 3 — flash, по плану; ревью — v4-pro; финальное ревью всей ветки — subagent v4-pro по полному диффу main...HEAD, находки C-n/I-n/M-n; один fix-диспатч при находках, одно скоуп-ревью.
- Step 7: Проба режима 2 (глубина 2)
Отдельный temp-репозиторий или новая ветка в том же: subagent (flash) с промптом «ты контроллер, задиспатчь implementer'а на задачу X, дождись уведомления, верни отчёт»; контроллер обязан сам вызвать subagent и завершиться. Записать: работает / падает exceeds maxDepth / уведомление не пришло. При падении — находка O-n и вывод, что режим 2 требует поднятой глубины (overlay уже в профиле).
- Step 8: Записать результаты
openspec/changes/dsh-sdd/design.md — раздел «Результаты пробного прогона 24.10.2026»: таблица приёмки #41 (пункт → чем доказан → статус), реальные диспатчи с моделями, найденный дефект T2.1 с коммитом фикса, ledger дословно, вывод по режимам, наблюдения O-n со статусами. dsh/PORT.md §8 п. 4 — закрыт.
- Step 9: Проверки, коммит, PR
Run: bash dsh/tests/run.sh && bash tests/run.sh; openspec validate dsh-sdd --strict (если поддерживается).
Коммит docs(dsh): пробный прогон SDD — режимы, дефект и fix-loop (#41), push, tea pulls create --base main --head feat/41-dsh-sdd-spike --title "DSH: SDD — skill, overlay, пробный прогон (#41)". Комментарий в #41 — состояние фазы и ссылка на PR.
Acceptance
Из #41: три задачи не теряются (ledger Task 1..3: complete + три коммита в temp-репо), отчёты собираются (файлы отчётов + строки ledger), ревьюер находит и проверяет хотя бы один дефект (T2.1 fixed <commit>), fix-loop завершается (ре-ревью чистое), ledger содержит ## Findings со статусами, прогон тестов зелёный, отличие от Claude-SDD указано таблицей в skill.