После закрытия M6 FIX-5 и верификации тест-гейта §9.2:
- 2026-06-10-phase8-state-snapshot.md: HEAD f2aa3fb7→33894a62; M6 FIX-5 из
«отложено» → закрыто (key-gated); D-3 доска live → закрыта (c9f823df);
регрессия 3449→3478; §9.2 верифицирован зелёным (предусловие C закрыто).
- 2026-06-09-phase8-deployment-runbook.md: Prerequisites регрессия →3478 +
§9.2 verified; +строка History 2026-06-10.
- 2026-06-10-phase8-settings-paste-block.md (новый): paste-ready записи для
settings.json — 13 хуков защитного контура (PreToolUse 10 / PostToolUse 2 /
Stop 1) + companion + список снятия зоопарка (~20). Merge-not-replace, атомарно,
пол #1 ДО снятия router-gate. Референс для владельца (Claude settings.json не пишет).
Только docs. Активация Фазы 8 (settings.json/keychain/ENV) — шаги владельца.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
19 KiB
Runbook: М7 Фаза 8 — переезд на оборону «роутер-наставник» (активация М1–М6)
Owner: владелец репозитория (шаги settings.json / keychain / ENV — только он; Claude'у закрыты) Frequency: один раз (большое переключение) + откат при необходимости Last Updated: 2026-06-09 · Last Run: — Кодовая фраза эпика: «роутер-наставник»
Что это. Пошаговая инструкция владельцу: как включить новую цельную оборону из 6 «машин» (М1–М6) + две новые двери (G1 verify, Level B criterion) + поглощённую дисциплину, и уволить старый «зоопарк» мелких сторожей — атомарно, с тест-гейтом до и откатом после. Код всех машин уже построен (commit-not-push на
worktree-brainrepo). Эта Фаза 8 — активация, не разработка.Источники истины: spec
docs/superpowers/specs/2026-06-08-router-mentor-machine-7-design.md§8 (ИИ-проводка судьи) / §9 (план переезда) / §10 (список увольнений) + аудитdocs/superpowers/audits/2026-06-09-phase8-readiness-audit.md(A-блок, GO/NO-GO). При расхождении этого runbook со spec — приоритет у spec.
Purpose
Перевести защиту контроллера со «старого зоопарка» (≈20 разрозненных хуков router-gate/verify-before-push/llm-judge-* и т.д.) на цельный контур М1–М6, где:
- необратимое рубит пол М5 (вне зависимости от плана);
- вне плана рубит стена М2;
- приёмку ТЗ/плана/результата ведёт судья М4;
- законную дверь (аварийный выход + правка ЗАКОНА) держит escape М6;
- видимость даёт доска «кто на посту» (§7).
Применять один раз, когда тест-гейт §9.2 зелёный по каждому пункту. Не применять частично (кроме осознанного поэтапного включения судьи через shadow — см. Шаг 5).
Prerequisites
- Весь код М7 (G1 + Level B + G2) смержен в
main(Вариант 3 «пуш» выполнен) — Фаза 8 включает то, что вmain. - Регрессия tools-only зелёная: 3478 passed / 2 skipped / 0 failed (обновлено 2026-06-10 после M6 FIX-5 +13; планка §9.2 ≥3350+2skip; исходная spec ≥2843 перекрыта). Тест-гейт §9.2 верифицирован зелёным 2026-06-10 — per-machine М1–М6 + интеграционные smokes (31 файл / 328 GREEN), все пункты §9.2 покрыты автоматными тестами с fail-CLOSE-ассертами.
- Доступ к
.claude/settings.json(правка хуков — только владелец, Claude'у закрыт). - Доступ к OS keychain (Windows Credential Manager через
keytar) для провижининга двух ключей. - Доступ к пользовательским ENV (Windows:
rundll32 sysdm.cpl,EditEnvironmentVariables) для трёх флагов. - Ключ модели судьи (
ROUTER_LLM_KEY) — тот же механизм, что у классификатора/L4 (уже есть в user env по прецеденту L4). - Снят актуальный бэкап
.claude/settings.json(для отката Шаг 7).
Procedure
Шаг 0: Бэкап settings.json (точка отката)
Copy-Item .claude\settings.json .claude\settings.json.bak-phase8-<дата>
Expected result: копия создана. If it fails: не продолжать — без бэкапа откат §9.4 невозможен.
Шаг 1: Провижининг двух ключей в keychain (НЕ в ENV)
Ключи только в keychain (env-fallback вырезан, Δ4 — анти-утечка через логи). Сервисы:
| Назначение | keychain service | account | питает |
|---|---|---|---|
| Ключ подписи расписок | router-mentor-receipts |
default |
verify-gate (G1) + criterion-gate (Level B) + М5 подписанный GREEN |
| Ключ судьи (подпись под-прогонов) | router-mentor-judge |
default |
судья М4 (дисциплина #1: вердикт без валидного под-прогона не принимается) |
Провижининг (пример через node+keytar — владелец генерит длинный случайный секрет per service):
node -e "require('keytar').setPassword('router-mentor-receipts','default', <СЕКРЕТ1>)"
node -e "require('keytar').setPassword('router-mentor-judge','default', <СЕКРЕТ2>)"
Expected result: оба ключа читаются (getPasswordSync возвращает значение).
If it fails: без ключа подписи verify/criterion-gate уйдут в keyMissing → fail-CLOSE (заблокируют commit/push); без ключа судьи — дисциплина #1 судьи fail-closed. Проверить, что keytar установлен и доступен.
Примечание про node -e: на этой машине
node -eрубит content-floor у Claude (отмычка). Это команда владельца в его терминале, не Claude.
Шаг 2: ИИ-проводка судьи М4 (§8 — последняя проводка владельца)
Обёртка enforce-judge-gate гейтит расход рубильником, но реальный llmCall-транспорт и извлечение «продукта на суд» в runJudgeGate владелец подключает на этом шаге (до подключения судья = нейтральный GO даже при mode=block — сессию не кирпичит).
- Подключить реальный транспорт модели в
runJudgeGate(паттернcallAnthropicAPIизrouter-classifier, модельCLASSIFIER_MODEL/Sonnet, ключROUTER_LLM_KEYв user env). - Убедиться, что журнал под-прогонов судьи пишется в неподделываемый канал (М4 §9.1 F1).
Expected result: при включённом флаге судья делает реальный вызов (не мок).
If it fails: оставить судью в inert/shadow — оборона М1/М2/М3/М5/М6 работает и без думающего слоя судьи (механический пол М4 + громкий крик).
Архитектурный нюанс (урок L4): регистрировать в settings.json нужно обёртку
enforce-judge-gate, НЕ движок (judge-orchestrator/judge-engine) — у движка нет рубильника $0.
Шаг 3: Большое переключение — атомарно зарегистрировать 13 хуков (§9.3)
В .claude/settings.json добавить разом все 13 хуков защитного контура. Форма команды: node tools/<имя>.mjs. Матчеры — по заголовку каждого хука (сверка с фикстурой tools/floor-manifest-check.test.mjs).
| # | Событие | Хук | Matcher | Роль |
|---|---|---|---|---|
| 1 | PreToolUse | enforce-floor.mjs |
* |
М5 пол: вето-до-плана на необратимое + content-floor (Bash/PowerShell) |
| 2 | PreToolUse | enforce-supreme-gate.mjs |
* |
М2 стена: default-deny вне запечатанного плана |
| 3 | PreToolUse | enforce-normative-content-rules.mjs |
Edit|Write|MultiEdit|NotebookEdit |
М1/М5 защита нормативки/памяти (КАРТА/ЗАКОН) |
| 4 | PreToolUse | enforce-read-path-deny.mjs |
Read |
М5 read-exfil (transcript/runtime/secrets) |
| 5 | PreToolUse | enforce-mcp-classification.mjs |
mcp__* |
М5 egress-exfil (исходящий MCP-payload) |
| 6 | PreToolUse | enforce-snapshot.mjs |
* |
М6 снимок: точка отката перед разрушительным (после пола) |
| 7 | PreToolUse | enforce-judge-gate.mjs |
* (Гейт-2: Write плана + per-tool надзор) |
М4 судья (рубильник + режим) |
| 8 | PreToolUse | enforce-verify-gate.mjs |
Bash |
G1: подписанный verify-receipt перед commit/push |
| 9 | PreToolUse | enforce-criterion-gate.mjs |
Bash |
Level B: по-критерийный mutation-proven GREEN |
| 10 | PreToolUse | enforce-todowrite-skill-verifier.mjs |
TodoWrite |
поглощённая дисциплина (журнал-K2) |
| 11 | PostToolUse | enforce-skill-journaler.mjs |
Skill |
М1 журналер навыков (неподделываемый канал K2) |
| 12 | PostToolUse | enforce-floor-escape-consume.mjs |
* |
М6 escape: one-shot погашение гранта |
| 13 | Stop | enforce-coverage-verify.mjs |
— | поглощённая дисциплина coverage (журнал-K2) |
Companion-хуки (оставить/добавить, не входят в 13 «required», но нужны контуру):
- SessionStart:
floor-manifest-check.mjs— самопроверка регистрации (доска кричит «ПОСТ ПУСТОЙ», если кто-то из 13 не зарегистрирован). - доска «кто на посту»: генератор
STATUS.md(расширен §7) — read-only. - наблюдение:
observer-stop-hook.mjs,cost-stop-hook.mjs,askuser-cosmetic-detector— остаются (§10 «Остаются»).
Expected result: все 13 в settings.json; на следующем SessionStart floor-manifest-check не кричит (mode: protected).
If it fails (кричит «ПОСТ ПУСТОЙ»): в WARN перечислены отсутствующие — дописать их. Это сигнал, не блок (Δ8).
Шаг 4: Снять весь зоопарк (§10) — в той же атомарной правке settings.json
⚠️ Порядок критичен (V1/V1-PS, DOC-1):
router-gate/powershell-gateснимать ТОЛЬКО после того, как пол М5 (хук #1) зарегистрирован — иначе ≈20 Bash-классов + весь PowerShell открываются. Регистрация (Шаг 3) и снятие (Шаг 4) — одна атомарная правка, не два захода.
Удалить из .claude/settings.json регистрации:
- Старая защита (растворена в пол/стену §5):
router-gate,powershell-gate,runtime-write-deny,verify-before-push,verify-record,branch-switch. - Старый судья (L4):
llm-judge-per-tool,llm-judge-response-scan. - Старый роутер-классификатор:
router-prehook,router-tool-gate,router-stop-gate,router-embedding-warmup(заменён М3). - Поглощённая дисциплина (теперь в М4/М5 журнал-K2):
memory-coverage,coverage-verify(старая версия),tdd-gate,tdd-real-test-verifier,self-debrief-detector,rationalization-audit,todowrite-skill-verifier(старая версия),prompt-injection(reminder). - Мёртвый груз (no-op):
decomposition-detector,safe-baseline-metering,parallel-session-lock. - Бессмысленные (субагенты запрещены):
subagent-return-scanner,subagent-prompt-prefix.
NB: новые журнал-K2 версии
enforce-coverage-verify.mjs(#13) иenforce-todowrite-skill-verifier.mjs(#10) — это НЕ старые одноимённые хуки. Старые снять, новые (из таблицы Шага 3) оставить. Различить по тому, что новые вDEFAULT_REQUIRED_HOOKS(G2, манифест 11→13).
Expected result: в settings.json остались только 13 + companion-хуки; зоопарка нет. If it fails: см. Откат (Шаг 7).
Шаг 5: Три ENV-флага (рубильники)
Через rundll32 sysdm.cpl,EditEnvironmentVariables (user scope), затем перезапуск Claude Code:
| ENV | Значение | Эффект |
|---|---|---|
ROUTER_MENTOR_VERIFY_ENABLED |
1 |
включает verify-gate (G1) + criterion-gate (Level B). Без флага — inert ($0). |
ROUTER_MENTOR_JUDGE_ENABLED |
1 |
включает судью М4. Без флага — inert ($0). |
ROUTER_MENTOR_JUDGE_MODE |
shadow → позже block |
shadow: судья логирует, НЕ блокирует (D28 «сперва тихо»); block: блокирует на NO-GO. |
Рекомендация дизайнера (§11, не обязательна): судью сперва в
shadowна короткий период обкатки, затемblock. Урок L4: живой судья в первый день может пере-блокировать рабочий цикл. verify/criterion-gate можно сразу включать (они механические, не ИИ).
Expected result: после перезапуска — floor-manifest-check зелёный; verify/criterion-gate активны; судья в выбранном режиме.
If it fails: снять флаг (вернуть в inert) — оборона М1/М2/М3/М5/М6 не зависит от этих флагов.
Шаг 6: shadow → block для судьи (отдельным шагом, после обкатки)
- Понаблюдать доску §7: режим судьи
shadow, есть ли ложные NO-GO в логе. - Нет ложных блоков → сменить
ROUTER_MENTOR_JUDGE_MODE=block+ перезапуск.
Expected result: судья в live-block; на доске режим = live-block.
If it fails (судья кирпичит цикл): вернуть shadow (или снять ROUTER_MENTOR_JUDGE_ENABLED); пол М5 продолжает рубить необратимое.
Шаг 7 (Откат, §9.4): если переключение глючит
Copy-Item .claude\settings.json.bak-phase8-<дата> .claude\settings.json -Force
- при необходимости снять три ENV-флага (вернуть всё в inert) + перезапуск.
Expected result: возврат к до-переездному состоянию (зоопарк назад).
If it fails: escape/снимок М6 — точки возврата
refs/floor-snapshots/<id>(создаютсяenforce-snapshotперед разрушительным).
Verification
- SessionStart
floor-manifest-check→mode: protected(не кричит «ПОСТ ПУСТОЙ»). - Доска
STATUS.md§7: все М1–М6 зарегистрированы + режим судьи показан корректно (inert/shadow/live-block). - Per-machine smokes (§9.2): каждая М1–М6 блокирует свой класс, fail-CLOSE, громко.
- Интеграционные smokes (§9.2): escape сквозной (стена+пол+egress чтут клик владельца); манифест кричит при снятом страже; ЗАКОН требует ключ, КАРТА — нет; дисциплина fail-CLOSE+громко на спровоцированной ошибке; журнал-факт не обходится текстом контроллера (Класс 1 закрыт).
- Зоопарка в settings.json нет; verify/criterion-gate реально блокируют commit без подписанного GREEN.
Troubleshooting
| Symptom | Likely Cause | Fix |
|---|---|---|
commit/push заблокирован [verify-gate]/[criterion-gate] сразу после включения |
флаг ON, но ключ router-mentor-receipts не в keychain → keyMissing fail-CLOSE |
провижинить ключ (Шаг 1) или снять ROUTER_MENTOR_VERIFY_ENABLED |
| Судья блокирует даже безобидное | живой block без обкатки (урок L4) |
ROUTER_MENTOR_JUDGE_MODE=shadow или снять ROUTER_MENTOR_JUDGE_ENABLED |
| Доска «ПОСТ ПУСТОЙ» | один из 13 не зарегистрирован | дописать отсутствующий (WARN перечисляет имена) |
Реальный force-push/запись в .env проходит несмотря на escape |
зоопарк ещё не снят (escape чтут только М2/М5/egress) — DOC-1 | завершить Шаг 4 (снять зоопарк) |
Bash-команда вида cp X ~/.claude/runtime/... не блокируется |
пол М5 (хук #1) не зарегистрирован, а router-gate уже снят |
срочно вернуть порядок: пол ON до снятия router-gate (Шаг 3 до Шага 4) |
Rollback
Полный откат — Шаг 7: восстановить .claude/settings.json из бэкапа .bak-phase8-<дата> + снять три ENV-флага + перезапуск. Зоопарк возвращается, новые хуки уходят в inert. Снимки М6 (refs/floor-snapshots/<id>) — резерв для отката разрушительных действий, исполненных в окно переключения.
Escalation
| Situation | Contact | Method |
|---|---|---|
| Тест-гейт §9.2 красный по любому пункту | — | НЕ переключать; вернуть в подготовку §9.1 |
| Судья кирпичит цикл и shadow не помогает | владелец | снять ROUTER_MENTOR_JUDGE_ENABLED, эскалировать в новую сессию «роутер-наставник» |
| Пол/стена блокируют легитимную работу без escape | владелец | escape М6 (AskUser-грант) на конкретное действие; разбор причины отдельно |
History
| Date | Run By | Notes |
|---|---|---|
| 2026-06-09 | Claude (подготовка runbook) | docs-only; код G1+Level B+G2 построен (commit-not-push); активация — шаги владельца |
| 2026-06-10 | Claude (refresh + §9.2) | M6 FIX-5 закрыт (key-gated, commits 7faef3c9..ae3f841c); D-3 доска live закрыта (84231a14); регрессия 3449→3478; тест-гейт §9.2 верифицирован зелёным (31 файл / 328 GREEN, предусловие C закрыто). Снимок+runbook освежены. |