claude-harness/docs/superpowers/plans/2026-10-25-dsh-prestep.md

8.8 KiB
Raw Blame History

dsh-prestep Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use the sdd skill (DSH). Steps use checkbox syntax.

Goal: Портировать SessionStart-хуки harness-check и role-hint в DSH как неблокирующие agent/pre-step инъекции + закрыть follow-ups #62 (T2.1, T3.4, O-2).

Architecture: dsh/bundle/lib/prestep.js — чистые функции (detectAdoption с upward-walk, detectRole по ключевым словам первого пользовательского сообщения, тексты инъекций); общий хелпер видимости isInjectionVisible (рефакторинг из isBootstrapVisible); wiring в index.js (конфиг harnessCheck/roleHint, гейт — typeof ctx.on === 'function').

Tech Stack: Node builtins; тесты node:test; bash для install.sh-правки.

Spec: openspec/changes/dsh-prestep/ (proposal.md + design.md, D-1…D-10).

Models: Task 1, 3, 4 — deepseek-flash; Task 2 — deepseek-v4-pro; ревью — v4-pro.

Global Constraints

  • Node builtins only; package.test.mjs enforcement обновляется для новых файлов.
  • Инъекции неблокирующие; reject/abort — пропуск; сабагенты — пропуск (как bootstrap).
  • Маркер <!-- DSH-HARNESS-PRESTEP:<hash> -->; общая видимость через isInjectionVisible.
  • Роль-ключевики ровно из AGENTS.md (admin: jira, гант, спринт; qa: стенд, прогон, скриншот, макет; analyst: тз, oq, спека, методика; dev: срез, issue, pr, тест, миграция); pr — отдельным словом.
  • Вопрос с четырьмя вариантами — текст из design.md D-7.
  • Префикс инъекций [dsh-harness] (D-10; фильтр знает и [claude-harness]).
  • CC-сторона (hooks/) не трогается.

Review Focus

  1. Инъекции бандла не принимаются за первое пользовательское сообщение (фильтр маркеров).
  2. Автономный раунд без нового сообщения — role-hint не стреляет.
  3. cwd вне git-репозитория — harness-check молчит.
  4. Подкаталог репозитория (cwd = /dsh) — upward-walk находит корень, ложной подсказки нет.
  5. bootstrap:false — инъекции живут (гейт на ctx.on, не на bootstrapOk).

Task 1: prestep.js — чистые функции

Files: Create dsh/bundle/lib/prestep.js, dsh/tests/prestep.test.mjs.

Interfaces:

  • detectAdoption(cwd) -> {adopted:boolean, root:string|null, missing:string[]} — upward-walk: ближайший каталог с .git (или root ФС); сигналы: openspec/, .codegraph/, ## OpenSpec и superpowers в CLAUDE.md (без .claude/code-paths, D-9); вне git → {adopted:true, missing:[]} (молчим).
  • buildHarnessCheckText(root, missing) -> string — DSH-нативный текст (D-9): [dsh-harness] Проект <root> не подключён к обвязке: нет: … . Предложи владельцу настройку: openspec init --tools agents, codegraph init и секцию «OpenSpec и superpowers» в CLAUDE.md..
  • detectRole(firstUserText) -> 'dev'|'admin'|'analyst'|'qa'|null.
  • buildRoleHintText(role|null) -> string — [dsh-harness] Роль сессии: <r>. Вызови skill role. Если не так — скажи. или вопрос с четырьмя вариантами (D-7).
  • isHarnessMessage(text) -> boolean — текст начинается с <!-- DSH-HARNESS- или содержит [dsh-harness]/[claude-harness] (оба префикса до обновления AGENTS.md, D-10).
  • makePrestepMarker(text) -> {marker, body}.

Tests (TDD): detectAdoption в temp-дереве (adopted repo, missing-openspec repo, subdir cwd, non-repo cwd); detectRole по каждому слову + pr как слово/не слово; buildRoleHintText оба варианта; isHarnessMessage на bootstrap-тексте; маркер уникален.

  • Step 1: падающие тесты → Step 2: FAIL → Step 3: реализация → Step 4: PASS + bash dsh/tests/run.sh (161/0) → Step 5: коммит feat(dsh): prestep — detectAdoption/detectRole/тексты инъекций (#43).

Task 2: wiring + isInjectionVisible рефакторинг

Files: Modify dsh/bundle/lib/bootstrap.js (переименование экспорта + совместимый алиас), dsh/bundle/index.js, dsh/tests/bootstrap.test.mjs (imports), dsh/tests/prestep.test.mjs (apply-тесты).

Interfaces:

  • isInjectionVisible(agent, messages, marker) — та же логика, что isBootstrapVisible; старый экспорт остаётся алиасом (обратная совместимость).
  • index.js: DEFAULTS += {harnessCheck:true, roleHint:true}; в pre-step после bootstrap-блока: const onOk = typeof ctx.on === 'function'; harnessCheck && onOk → detectAdoption(sessionCwd) → не adopted → инъекция (маркер, isInjectionVisible); roleHint && onOk → первое user-сообщение текущего шага (source.kind user, не isHarnessMessage) → detectRole → инъекция.

Tests: apply с fake ctx: инъекция harness-check при missing-сигналах; молчание при adopted/non-repo; role-hint при user-сообщении с ключевиком; вопрос без ключевика; без нового user-сообщения — тишина; маркерные сообщения не считаются первыми; bootstrap:false + harnessCheck:true — инъекции работают (onOk прямой).

  • Steps TDD → коммит feat(dsh): wiring harness-check/role-hint в pre-step, isInjectionVisible (#43).

Task 3: follow-ups #62

Files: Modify dsh/tests/openspec.test.mjs (T2.1), dsh/install.sh (O-2 WARN), dsh/tests/install.test.mjs, dsh/skills/sdd/SKILL.md (T3.4 + пин в install.test.mjs).

Interfaces:

  • T2.1: негативный тест --check без openspec: вместо фиксированного PATH — временный каталог-сторож с symlink-ами на нужные бинарники без openspec (или skip-if-present; выбрать первое).

  • O-2: install.sh WARN «DSH_HOME указывает на существующий каталог при нестандартном HOME» в начале install_skills/install_roles; тест с temp HOME + реальный DSH_HOME → WARN.

  • T3.4: в sdd SKILL.md добавить предложение в протокол диспатча: «шаг „прогони тест и убедись, что он падает“ обязателен ДО кода»; пин текста в install.test.mjs (или sdd-skill.test.mjs — файл в списке брифа).

  • Steps TDD → коммит fix(dsh): #62 — PATH-изоляция теста, WARN DSH_HOME, TDD-порядок в sdd (#62).

Task 4: спека-дельта session-prestep + доки

Files: Create openspec/changes/dsh-prestep/specs/session-prestep/spec.md; Modify dsh/README.md, dsh/PORT.md, dsh/bundle/dsh-tools.md (упомянуть request_approval — T1.3 из #77), openspec/changes/dsh-prestep/design.md (статусы), openspec/specs/approval-gates/spec.md (T1.5 из #77 — формулировка ошибки диалога).

Requirements: ADDED — harness-check инъекция (сигналы, upward-walk, вне-git молчание, неблокируемость, конфиг), role-hint инъекция (триггер/фильтр/ключевики/тексты, раз за сессию), общая видимость инъекций, #62-фиксы (T2.1 PATH, O-2 WARN, T3.4 текст); строка про request_approval в dsh-tools.md (T1.3); формулировка «ошибка диалога» в approval-gates (T1.5).

  • Steps: openspec validate dsh-prestep --strict → valid; bash dsh/tests/run.sh; коммит docs(openspec): спека session-prestep, доки (#43, #62).

Предусловия

  • Ветка: feat/43-dsh-prestep (require-plan сопоставляет ветку по строке в плане; строка добавляется ДО plan-аппрува — A4).
  • baseline bash dsh/tests/run.sh = 161/0 на ветке; python3/git/node в PATH; сеть не нужна.
  • Гейты активны: план исполняется после /approve dsh-prestep plan (это и есть приёмка #59).