Files
brain/docs/superpowers/session-protocol-2026-06-13.md
T

136 lines
14 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.
# Протокол сессии — 2026-06-13 (роутер-наставник)
> Записи в раздел «Решения» делает Claude ТОЛЬКО по команде владельца «фиксируй …».
> Самовольные записи Claude запрещены (строгий запрет).
## Решения
### Р1 (2026-06-13) — способ сборки L1→L2
Выбран **способ B**: наставник — первый хук (выносит вердикт), судья — хук ПОСЛЕ наставника
(судит вслепую, печатает). Судья делается **fail-safe**: нет вердикта наставника для этого
плана → судья молчит, не дедлочит. Поведение: наставник → судья → печать судьи; счётчики 3+3;
карточка владельцу при тупике.
### Р2 (2026-06-13) — канал доставки замечаний контроллеру (обязательно, принцип №1)
На КАЖДЫЙ NO-GO (наставника или судьи) хук обязан отдать контроллеру ПОЛНЫЙ текст замечания
через канал обратной связи, который Claude реально получает (feedback хука / exit-2 stderr) —
НЕ `console.error` в пустоту и НЕ только в рантайм-файл. Проверяемо: после NO-GO контроллер
буквально видит текст замечания в своём контексте. Спека §2 П1 это требует, но в коде НЕ
реализовано — это и есть корень мучений. Не зависит от A/B.
### Р3 (2026-06-13) — канонический поток L1→L2 (эталон, словами владельца)
**Круг L1 — контроллер ↔ наставник (до 3 раз):**
1. Контроллер пишет план → его смотрит ТОЛЬКО наставник. Судья ещё не в курсе.
2. Наставник: «пункт 2 плохой, переделай». Счётчик L1 = 1.
3. Контроллер переписал → наставник смотрит снова: «теперь ок». Счётчик L1 → сброс.
(если за 3 круга не сошлись → карточка владельцу: «я и наставник спорим, реши».)
4. Наставник доволен → САМ несёт план судье. Судья видит план ВПЕРВЫЕ.
**Круг L2 — наставник передал → судья (до 3 раз):**
5. Судья судит ВСЛЕПУЮ (не зная мнения наставника):
- Судья GO → судья ПОДПИСЫВАЕТ печать. План запечатан. Контроллеру приходит «GO, делай». ✅
- Судья NO-GO → его замечание возвращается контроллеру. Счётчик L2 = 1. Контроллер переписал
→ снова к наставнику (L1 заново) → наставник одобрил → снова судье (L2 = 2)…
- (3 NO-GO судьи подряд → карточка владельцу.)
1. Контроллер НИ РАЗУ не общается с судьёй напрямую. Печатает ТОЛЬКО судья.
### Р4 (2026-06-13) — чистое завершение плана (выход в разговорный)
По коду: после выполнения плана контроллер ЗАСТРЕВАЕТ в режиме реализации — следующее действие
блокируется «план исчерпан» (`enforce-supreme-gate.mjs:217`); выйти можно только ручным удалением
`frozen-plan` или новой сессией (стена сама печать не снимает — грепом подтверждено).
**Решение:** добавить ЧИСТОЕ завершение — когда последний шаг плана выполнен ИЛИ владелец сказал
«готово», стена САМА снимает печать (удаляет `frozen-plan`) и возвращается в разговорный. Ручное
удаление файла больше не нужно.
### Р5 (2026-06-13) — состояние сессии для передачи в новую
**Пивот:** O9 (исходная задача — лимит доли INFERRED) **ПАРКНУТА** — судья-ИИ через aitunnel
таймаутил (500/timeout), печать спеки/плана не вставала. Код `context-verity.mjs`/`.test.mjs`
**НЕ тронут** (изменений O9 на диске нет). Orphan-файлы `specs/2026-06-13-o9-*.md` +
`plans/2026-06-13-o9-*.md` (v1+r2) — мусор, удалить.
**Сделано:** через `brainstorming``writing-plans` собран redesign согласования L1→L2:
- спека `specs/2026-06-13-l1-l2-negotiation-redesign-design.md` (простым языком, с примерами);
- план `plans/2026-06-13-l1-l2-negotiation-redesign-plan.md` (6 фаз, TDD);
- решения Р1-Р4 (выше).
**СТЕНА СНЯТА** (maintenance: `.claude/settings.json` = `{"hooks":{}}`, бэкап
`.claude/settings.json.bak-before-maintenance-2026-06-13`). Edit/Write/Bash свободны, цикла печати нет.
**Остаток:** исполнить план, начать с **Фазы 0 (smoke канала замечаний — ГЕЙТ)**, inline TDD.
**Риски:** судья-транспорт aitunnel нестабилен; канал доставки замечаний контроллеру — критичная
неизвестность (Фаза 0 её снимает). Коммиты — владелец; settings.json — владелец.
### Р6 (2026-06-13) — наставник видит контекст, судья судит вслепую (уточнение Р3, Фаза 3 спека)
Наставник судит спеку (и план) и даёт замечания, и **ОБЯЗАН видеть контекст** (verified-context,
переговоры — наставник работает рядом с контроллером, как старший коллега). Судья судит
**ВСЛЕПУЮ** — контекст НЕ видит, на суд идёт только сам артефакт (спека/план), чтобы оценка была
честной и независимой. Действует одинаково для спеки (gate1) и плана (gate2).
### Р7 (2026-06-13) — наставник заворачивает на содержательном несогласии (фикс круга L1)
Сквозной смоук способа B (Фаза 6.3) вскрыл: наставник доносил замечание контроллеру ТОЛЬКО при
сломанном/degraded вердикте; содержательное «пункт 2 плохой, переделай» оформлялось как валидный
вердикт → проходило как **GO** → молча, до контроллера не доходило, счётчик L1 не рос. То есть
круг L1 из Р3 НЕ работал — несогласие наставника тонуло. **Решение — Подход А:** в вердикт
наставника добавить явное поле `decision: "GO" | "NO-GO"` (как у судьи). Логика: `blocked =
wired && (decision==='NO-GO' ИЛИ вердикт сломан)`; на NO-GO контроллеру приходит СУТЬ
(`recommendation` + `reasoning` + `plan_points_addressed`, не «есть замечание»); `mentor-GO`
пишется только при `wired && ok && decision==='GO'`; счётчик L1 растёт на NO-GO (3 → карточка).
**Видимость вердикта — ТОЛЬКО на NO-GO** (на GO тихо, минимум шума). Судья (уже имеет decision +
objections), печать, счётчик-механика, finish-грант, стена — БЕЗ изменений. Реализация — через
живой цикл способа B (спека→наставник→судья→печать→план→печать→правки) + TDD, план со скил-цепочкой.
### Р8 (2026-06-13) — мерж роутера в наставника (Подход 1): роутер СОХРАНЯЕТ мозг
**Решение владельца:** наставник — ЕДИНЫЙ рецензент: судит спеку + план + **выбор скилов в плане**,
заворачивает NO-GO на любом несогласии. Роутер сливается с наставником по **Подходу 1**: наставник
на ревью плана зовёт классификатор **как функцию**.
**ГАРАНТИЯ (страх владельца снят): «становится функцией» НЕ значит «теряет мозг».** Мозг роутера
сохраняется ЦЕЛИКОМ: `classify()` — 3 слоя (prefilter → LLM → regex-fallback) + **граф скилов/узлов**
(`docs/registry/nodes.yaml` через `registry-load.mjs`, с per-node атрибут-**карточками**) +
эмбеддинги/PAMYATKA. Меняется ТОЛЬКО проводка: `classify()` зовёт **наставник** (а не дохлый
`router-prehook`), результат идёт в **вердикт наставника** (а не в файл-в-стол). На пенсию — лишь
обёртки-хуки `router-prehook` / `chain-recommendation` / `graph-first` (пустые посредники), НЕ мозг.
**Предпосылка:** план ОБЪЯВЛЯЕТ выбранные скилы структурно (иначе судить нечего). Этот мерж
ПОГЛОЩАЕТ фикс наставник-NO-GO (Р7) — он фундамент (наставник обязан уметь NO-GO).
### Р9 (2026-06-13) — состояние сессии для передачи в новую (handoff)
**СДЕЛАНО этой сессией (на диске, НЕ закоммичено — коммиты за владельцем):**
1. **Redesign согласования L1→L2, Фазы 0–6** (план `2026-06-13-l1-l2-negotiation-redesign-plan.md`):
Ф0 smoke-гейт канала (PostToolUse exit-2 ДОХОДИТ до контроллера, подтверждено фактом, хуки без
рестарта); Ф1 канал замечаний (`objection-delivery.mjs` `buildObjectionFeedback`/`buildDegradedFeedback`;
наставник+судья отдают дословный текст на NO-GO; degraded «не дозвонился» §9; root-cause:
`formatJudgeObjection` читал `verdict.blocking`, не `.objections`); Ф2 способ B
(`mentor-go-store.mjs` домен `MENTOR_GO`; наставник пишет mentor-GO/не печатает; судья fail-safe
сам печатает; дедлок-фикс снят); Ф3 спека тем же сценарием (`runMentorSpecVerdict`+`onSpecWrite`,
binding к хешу артефакта; судья gate1 под mentor-GO; `bindingHashForJudge`); Ф4 счётчики per
task-id (mentor+judge); Ф5 чистое завершение (`removeFrozenPlan`, авто после последнего шага +
finish-грант `PLAN_FINISH_ACTION='plan-done'`, Вариант А). **Полная регрессия 3877 passed + 2 skip,
0 регрессий.**
2. **способ B settings.json** отдан владельцу (наставник→судья оба PostToolUse, судья снят из Pre).
Владелец активировал → **сквозной смоук Ф6.3 вскрыл ДВА бага:** (A) наставник доносит замечание
только при СЛОМАННОМ вердикте — содержательное «переделай» тонет (Р7); (B) **роутер работает в
пустоту**: `classify()` зовёт только `router-prehook`, который пишет в файл и отдаёт контроллеру
`{}`; хуки `chain-recommendation`/`graph-first` в способ-B вообще не зарегистрированы.
3. **Дизайн мержа** (Р7/Р8 + спека `2026-06-13-router-mentor-merge-design.md` + план
`2026-06-13-router-mentor-merge-plan.md`, 9 задач TDD): наставник — единый рецензент
(спека+план+скилы), зовёт `classify()` как функцию (мозг роутера цел: 3 слоя + граф `nodes.yaml`
- карточки), заворачивает NO-GO. Поглощает Р7.
**СОСТОЯНИЕ СРЕДЫ:** **СТЕНА СНЯТА** (maintenance, `.claude/settings.json` = `{"hooks":{}}`; способ-B
бэкап у владельца + `settings - Copy.json`). Edit/Write/Bash свободны.
**ОСТАЛОСЬ:** исполнить план мержа (9 задач, inline TDD), затем владелец вернёт способ-B стену +
повторит смоук. Реализация НЕ начата.
**ПРОТОКОЛ:** записи только по команде владельца «фиксируй». Цепочка скилов исполнения: executing-plans
ИЛИ test-driven-development (inline RED→GREEN); systematic-debugging на баг; brainstorming перед
новым дизайном; /graphify или Grep/Read перед вопросом по коду. Регрессия — ТОЛЬКО
`npx vitest run --root app --config vitest.config.tools.mjs` (баре, без cd/&&/пайпа).