Files
portal/docs/superpowers/runbooks/2026-06-09-phase8-deployment-runbook.md
T
Дмитрий 2aea040125 docs(phase8): refresh снимок+runbook + paste-ready settings.json блок
После закрытия 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>
2026-06-10 05:52:32 +03:00

19 KiB
Raw Blame History

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-checkmode: 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 освежены.