# Машина 6 — ЗАКРЫТА. Handoff в новую сессию (что дальше)

Кодовая фраза эпика: **«роутер-наставник»**.

> Машина 6 (аварийный выход владельца + авто-снимок) **собрана под ключ, TDD, НЕ запушена**.
> Этот файл — состояние на момент переезда + готовый промт для новой сессии.

---

## === ПРОМТ ДЛЯ НОВОЙ СЕССИИ (скопировать целиком) ===

роутер-наставник. Машина 6 (аварийный выход владельца + авто-снимок) ЗАКРЫТА в прошлой
сессии: собрана под ключ по плану, TDD, проверена, закоммичена — но НЕ запушена и НЕ
активирована. Прежде чем что-либо делать — прочитай этот handoff и память
`project_router_mentor_machine_6_done.md` (кодовая фраза «роутер-наставник»).

1. ДЕРЕВО (вся работа здесь, НЕ в основном репо):
   путь:  c:\моя\проекты\портал crm\Документация\.claude\worktrees\brainrepo
   ветка: worktree-brainrepo
   ОПЕЧАТКА-ловушка: «Документация» — русские а/и.
   HEAD содержательный = `8bfef418` (М6 + пост-аудит 4 фикса; финал стройки M6 был `d0e0bd18`). Подтверди: `git -C "<wt>" log -3 --oneline`. Детали фиксов — раздел «Пост-аудит правки» ниже + память `project_router_mentor_machine_6_done.md`.
   Bash-git может быть залочен — git делай через PowerShell (см. квирки).

2. ГДЕ СТОИМ:
   - М1-М5 собраны (фундамент/стена/М3/судья/пол), М6 собрана. Всё на `worktree-brainrepo`,
     **commit-not-push** — НИЧЕГО из роутера-наставника не запушено.
   - М6: 10 атомарных TDD-коммитов `87d84a2e..d0e0bd18` поверх handoff `4f7b1fab`.
   - Регрессия baseline tools-only **2843 passed + 2 skip** — планка, ниже не опускать (после пост-аудит фиксов; было 2834+2 на финале стройки).
   - Висящее в дереве (НЕ трогать, не наша зона): observer-шум
     (`.pii-counters.json`/`episodes-*.jsonl`/STATUS.md) + чужие untracked
     (`patch-*.mjs`/`setup-nm.mjs`/`commit-msg.txt`/`.scratch/`).

3. ЧТО ЖДЁТ (выбор владельца — спроси, что делаем):
   а) **ПУШ М6 (и/или всего роутера-наставника М1-М6)** — по слову «пуш». Тогда
      `superpowers:finishing-a-development-branch`: push + PR ЛИБО локальный merge (как скажет владелец).
      NB: создание PR через MCP/`gh` может быть заблокировано гейтом — тогда PR владелец
      открывает вручную по ссылке из `git push` output.
   б) **АКТИВАЦИЯ М6 владельцем в `.claude/settings.json`** (Claude'у settings.json заблокирован —
      это шаг ВЛАДЕЛЬЦА; до неё новые хуки инертны, $0):
        - `enforce-snapshot`            → PreToolUse, регистрировать ПОСЛЕ `enforce-floor`;
        - `enforce-floor-escape-consume`→ PostToolUse;
        - `enforce-floor` / `enforce-askuser-answer-parser` / `enforce-mcp-classification` /
          `enforce-supreme-gate` уже зарегистрированы — их правки активны после рестарта.
        Сперва тихий режим, затем hard-block.
   в) **М7 — НОВАЯ ФАЗА ДИЗАЙНА** (за рамками М6): канал «мозга» + растворение зоопарка
      + доска. Это дизайн с нуля → `superpowers:brainstorming` → `superpowers:writing-plans`,
      НЕ реализация. spec М5 §5 (шов) / §6 (YAGNI) — отправная точка обсуждения.

4. ЧТО ТАКОЕ М6 (итог, детали — в памяти + спеке/плане):
   - **escape**: всплывающий вопрос владельцу → среда пишет одноразовый пропуск
     `kind:"floor_escape"` в `askuser-decisions-<sess>.jsonl` (токен `FLOOR-ESCAPE: <канон-строка>`);
     привязка = ТОЧНОЕ совпадение `canonicalAction` (`bash:<cmd>`/`write:<path>`/`mcp:<tool>:<args>`);
     окно ≤5 мин + one-shot погашение (PostToolUse ПОСЛЕ реального исполнения). Сквозной:
     чтят пол М5 (`floor-decide` Bash+Write), стена М2 (`enforce-supreme-gate`, G-1 α — allow
     БЕЗ продвижения указателя), egress (`enforce-mcp-classification`).
   - **авто-снимок**: перед Bash-floor `enforce-snapshot` (PreToolUse, после floor) делает
     git-точку возврата (`git stash create` → `refs/floor-snapshots/<id>` + `restore-points.jsonl`);
     чистое дерево → ref=HEAD; реальная ошибка git → fail-CLOSE; откат ручной.
   - Модули: `escape-grant` / `floor-escape-consume` / `enforce-floor-escape-consume` /
     `snapshot-decide` / `enforce-snapshot`. Патчи: `floor-decide`/`enforce-floor`/
     `askuser-answer-parser`/`enforce-askuser-answer-parser`/`enforce-mcp-classification`/`enforce-supreme-gate`.
   - Аудит-гейты закрыты: G-1 α / G-2 / G-5 / G-6 / G-8.

5. ПЛАН СКИЛОВ — HARD-RULE (если будет НОВАЯ работа). Исполнение ИНЛАЙН. Суб-агенты /
   Task / Workflow / ultracode ЗАПРЕЩЕНЫ (ограничение владельца). На каждую правку
   существующего модуля — `audit-context-building` ПЕРЕД (пропускать запрещено); TDD RED→GREEN;
   рисковая линза (`sharp-edges` для каналов / корректность для пола); inline review (суб-агент
   запрещён → самопроверка); `verification-before-completion`; `regression` ≥ 2834+2 skip.
   `superpowers:systematic-debugging` при ЛЮБОМ непредвиденном красном (НЕ угадывать).

6. ЖЁСТКИЕ ПРАВИЛА: commit-not-push (пуш ТОЛЬКО «пуш»); эпик в памяти + spec/план/handoff
   в worktree, НЕ в основном CLAUDE.md (worktree-эксцепшн); владельцу — простым языком,
   код/память — технически; дыр не делать; каждый ответ: 1-я строка «экономия:…», 2-я «coverage:…».

7. КВИРКИ (проверены сессией реализации М6):
   - vitest — через **Bash**-инструмент (node сужен под vitest-runner; PowerShell-гейт `node`
     режет default-deny). ОДНА абсолютная команда, без cd/&&:
       node "<wt>\app\node_modules\vitest\vitest.mjs" run --root "<wt>\app" --config "<wt>\app\vitest.config.tools.mjs" [фильтр] --reporter dot
   - git — через **PowerShell**, по одной команде, литеральные пути, БЕЗ переменных
     (PowerShell-гейт режет `$var=...`; Bash-гейт коммит не матчит):
       git -C "<wt>" add <files>  ;  git -C "<wt>" commit -F "<wt>\.scratch\msg.txt"
     («Can't find lefthook in PATH» — шум.) `git restore` НЕ в whitelist PowerShell-гейта →
     откат рабочей копии: `git -C "<wt>" show HEAD:<path>` → перезаписать Write-tool'ом.
   - Bash-гейт АКТИВЕН: цепочки (&&/;/|) с мутацией, `>`/`>>`, rm/mv/Remove-Item → блок;
     `tail`/`wc`/`cat` → default-deny (используй Read/Grep вместо них).
   - tdd-gate: правка prod `X.mjs` без RED-теста в `X.test.mjs` → блок (тест первым, в свой
     test-файл; новый файл через Write свободен).
   - tdd-real-test-verifier: Edit тест-файла → new_string обязан содержать `it(` + `expect(` +
     строковый литерал-basename правленого prod-модуля; `it.each(` НЕ распознаётся → плоский `it()`;
     при camelCase-describe basename давать комментарием (`// floor-decide.mjs ...`).
   - ЗАПИСЬ В ПАМЯТЬ = ДВА охранника (per-turn): (а) активный скил `claude-md-management`
     (`revise-claude-md`) В ЭТОМ ходе; (б) первая строка `coverage: direct:memory-sync`.
   - Baseline tools-only: **2834 passed + 2 skip**.

8. СТАРТ новой сессии: прочитай этот handoff + память М6 + (при нужде) спеку/план М6 →
   спроси владельца, что делаем (пуш / активация-handoff / М7-дизайн) → действуй по плану скилов.

Кодовая фраза эпика: «роутер-наставник».

## === КОНЕЦ ПРОМТА ===

---

## Артефакты М6 (всё закоммичено на `worktree-brainrepo`, НЕ запушено)

- Spec:  `docs/superpowers/specs/2026-06-07-router-mentor-machine-6-design.md` (§11 — журнал аудита)
- План:  `docs/superpowers/plans/2026-06-07-router-mentor-machine-6.md`
- Промт-реализации (исторический): `docs/superpowers/plans/2026-06-07-router-mentor-machine-6-build-handoff.md`
- Этот DONE-handoff.
- Память: `project_router_mentor_machine_6_done.md` + строка в `MEMORY.md` (🚪 Машина 6).

## Цепочка коммитов М6 (ветка `worktree-brainrepo`, без push)

```
87d84a2e feat(m6): escape-grant pure core — canonicalAction + escapeGrantOpen + readers
6b44e7af feat(m6): toFloorEscapeRecord — распознавание escape-одобрения
a9e85857 feat(m6): писать floor_escape-пропуск из AskUser-ответа
d2109ac1 feat(m6): пол — escape во всех ветках, замена approvalOpen
4a10932c feat(m6): G-1 сквозной escape в верховной стене М2 (allow без продвижения указателя)
b83cfc65 feat(m6): floor-escape-consume — одноразовое погашение пропуска (PostToolUse)
6e2d485f feat(m6): egress-escape — снятие egress-блока совпавшим floor_escape
a5b99eaa feat(m6): snapshot-decide — триггер снимка + чистое-дерево vs ошибка
28b92d90 feat(m6): enforce-snapshot — git-точка возврата перед разрушительным (fail-close)
d0e0bd18 test(m6): сквозные инварианты escape + snapshot; регрессия зелёная (2834+2)
```

---

## Пост-аудит правки (2026-06-07, отдельная сессия — аудит М6 + 4 фикса; commit-not-push)

Аудит М6 шестью осями (`audit-context-building` + `sharp-edges` + корректность логики; +комплекс М1–М6).
Вывод: архитектурно верно, швы М1–М5 целы. Внесены 4 практичных фикса (TDD RED→GREEN, регрессия
tools-only **2843 passed + 2 skip**, +9 тестов, 0 регрессий):

- **FIX-1 (G-5 egress):** `enforce-mcp-classification` печатает в блок-сообщении точную канон-строку
  `… ; FLOOR-ESCAPE: mcp:<tool>:<json>` (раньше токен выводил только пол Bash/Write; egress оставался
  без точной строки для AskUser → владелец не получал, что вставлять).
- **FIX-2 (единый предикат свежести):** в `escape-grant` вынесен `findOpenGrant`; `escapeGrantOpen` и
  `floor-escape-consume.consumeDecision` гасят ИМЕННО открывший грант. Раньше при дублях/future-ts
  consume мог пометить «не тот» грант → утечка one-shot (тест воспроизводил баг → закрыт).
- **FIX-3 (журнал escape):** `enforce-supreme-gate.runGate` пишет escape best-effort в журнал
  намерений (`escape:true`), указатель НЕ двигается; сбой/отсутствие журнала escape НЕ блокирует
  (escape санкционирован владельцем). Снимает будущий false-positive реконсилера «action-without-record
  (обход стены)» для легитимного escape.
- **FIX-4 (уникальный снимок):** `enforce-snapshot` дефолтный id = `ts-pid-счётчик` (раньше два
  разрушительных в одну ms клобберили один `refs/floor-snapshots/<id>`).

**FIX-5 (подпись гранта) сознательно НЕ делали:** в штатном «без ключа» режиме reader обязан принимать
неподписанное (иначе escape ломается у всех) → защиты нет; protected-path уже гарантирует целостность.
Спек §6 пометил её «не обязательно».

### ⚠️ DOC-1 — escape НЕ сквозной через старый «зоопарк» (важно ПЕРЕД активацией)
escape чтут **только** стена М2 / пол М5 / egress. Параллельные стражи живой среды —
`enforce-router-gate` (default-deny whitelist; блокирует мутирующий git/bash — он в этой сессии
заблокировал даже `git log`), `enforce-runtime-write-deny` (блок Write в `~/.claude/runtime`) и судья
М4 (когда активируют) — escape **не знают** и заблокируют то же действие. Значит после активации М6
реальный `git push --force` / запись в `.env` всё равно не пройдут, пока эти хуки зарегистрированы.
Полностью «дверь открывается» только когда М7 растворит/научит зоопарк (или владелец деригистрирует
router-gate/runtime-write-deny). Это **ожидаемо по §7 (YAGNI→М7)**, но держать в голове: М6 — дверь в
стене М2/М5/egress, не во всей обороне.

**Изменённые файлы (10, commit-not-push):** `tools/{escape-grant,floor-escape-consume,enforce-mcp-classification,enforce-snapshot,enforce-supreme-gate}.mjs` + их `.test.mjs`.
