74 lines
5.5 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.

# Design: dsh-prestep — harness-check и role-hint через agent/pre-step
Issue: #43 (+#62). Статус: черновик до builder-check; утверждение —
`/approve dsh-prestep design`.
## Контекст
CC-хуки harness-check/role-hint — SessionStart; в DSH аналог — инъекции
`agent/pre-step` (уже используем для superpowers-bootstrap). Гейты #59
живые: этот change идёт первым по гейтованному циклу (acceptance #59).
## Механика
Обе инъекции — раз за сессию, с маркером `<-- DSH-HARNESS-PRESTEP:...>`
и тем же механизмом видимости, что у bootstrap (`isBootstrapVisible`
переименован в общий `isInjectionVisible(agent, messages, marker)`).
Порядок в pre-step: другие инъекции → harness-check → role-hint (обе
неблокирующие; reject/abort — пропуск; сабагенты — пропуск, как
bootstrap).
### harness-check
- Сигнал подключения: `CLAUDE.md` или `AGENTS.md` в корне cwd содержит
`OpenSpec и superpowers` ИЛИ существует `openspec/` ИЛИ
`.claude/code-paths` ИЛИ `CLAUDE.harness-section.md`. Нет — инъекция:
«[claude-harness] Проект не подключён к обвязке: предложи владельцу
`adopt-project.sh` или спроси, нужна ли обвязка». Не блокирует.
- cwd — `sessionCwd` (та же резолюция, что у гейтов: workingDirectory →
process.cwd()).
### role-hint
- Триггер: первое пользовательское сообщение сессии (в `decision.messages`
ищем message с `source.kind === 'user'` и текстом; до первого такого —
инъекции нет).
- Ключевые слова (порядок приоритета, как в AGENTS.md):
- admin: `jira`, `грант`, `гант`, `спринт`;
- qa: `стенд`, `прогон`, `скриншот`, `макет`;
- analyst: `тз`, `oq`, `спека`, `методика`;
- dev: `срез`, `issue`, `pr`, `тест`, `миграция`.
Совпадение — инъекция `[claude-harness] Роль сессии: <r>. Вызови
skill role. Если не так — скажи.` Нет — инъекция вопроса с четырьмя
вариантами (текст — как в AGENTS.md).
- Матчинг: нижний регистр, подстроки по границам слов (русские слова —
подстрока в нижнем регистре; `pr` — только как отдельное слово).
## Decisions made without discussion
| # | Решение | Обоснование | Цена ошибки |
|---|---|---|---|
| D-1 | Роль определяется по первому сообщению (не по заголовку — его в DSH нет) | Ровно то правило AGENTS.md, которое модель сейчас исполняет «по памяти»; переносим в технику | Ложная подсказка роли при неоднозначном сообщении — поправима (`/role`), не блокирует |
| D-2 | harness-check — только подсказка, без HARNESS_AUTO_ADOPT | YAGNI; авто-подключение — отдельная фича при запросе | Сессия в неподключённом проекте продолжает работу — как и сейчас |
| D-3 | Общий хелпер инъекций (рефакторинг bootstrap) без изменения поведения bootstrap | Два новых pre-step не должны дублировать маркер/дедуп | Регрессия bootstrap — страхуется существующими тестами bootstrap |
| D-4 | #62-пункты едут задачами этого change (не отдельными фичами) | Мелкие, один PR-цикл дешевле трёх | Смешивание тем в одном PR — компенсируется отдельными задачами плана |
| D-5 | Конфиг-ключи harnessCheck/roleHint — по умолчанию true, гейтятся bootstrapOk (нужен ctx.on) | Симметрия с bootstrap; без pre-step обе инъекции невозможны | Нет |
## Тесты (идеи для плана)
- pure: detectAdoption(files), detectRole(firstUserText) → role|null,
buildRoleHintText(role), buildHarnessCheckText(), маркер-дедуп;
- wiring: apply с fake ctx — инъекции появляются при наличии
пользовательского сообщения, один раз, пропускаются для сабагентов;
- T2.1: негативный тест openspec — PATH-изоляция (временный каталог без
openspec-бинарника);
- O-2: install.sh WARN при DSH_HOME→существующий каталог + нестандартный
HOME (тест в install.test.mjs);
- T3.4: пин текста в sdd-скилле («шаг „тест падает“ обязателен»).
## На потом (в план)
- Разбивка: Task 1 prestep.js (harness-check+role-hint pure) → Task 2
wiring+bootstrap-рефакторинг → Task 3 #62 (T2.1/O-2/T3.4) → Task 4
спека-дельта `session-prestep` + доки.