# Router-mentor — Handoff к сессии «Блок H: карточки узлов + конфликт-рёбра»

**Дата:** 2026-06-08 · **Кодовая фраза эпика:** «роутер-наставник».
**Цель следующей сессии:** закрыть **Блок H** реестра хвостов — наполнить граф скилов данными (карточки-контракты ~84 узлов + явные конфликт-рёбра), по согласованной цепочке скилов + graphify как вторичная сверка.

---

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

роутер-наставник. Начинаем **Блок H** (карточки узлов + конфликт-рёбра графа скилов) из реестра хвостов. НЕ приступай к коду сразу — сперва подними согласованную **цепочку скилов** (ниже), отработай brainstorming (есть открытый Q1), и действуй по ней. Всё инлайн, субагенты/Task/Workflow ЗАПРЕЩЕНЫ.

1. ДЕРЕВО (вся работа здесь): `c:\моя\проекты\портал crm\Документация\.claude\worktrees\brainrepo`, ветка `worktree-brainrepo`. Git — ТОЛЬКО через PowerShell. Сверь: `git -C "<wt>" log -5 --oneline` (ожидаемый верх — коммит реестра хвостов + H-handoff).

2. ЧТО ТАКОЕ H (из реестра `docs/superpowers/plans/2026-06-08-router-mentor-loose-ends-registry.md`, блок H):
   - **R-11** — карточки-контракты для ~84 узлов. Сейчас написаны **2 из ~86**: `docs/registry/contracts/writing-plans.contract.json` (own) + `operations-process-doc.contract.json` (external).
   - **R-12** — явные конфликт-рёбра `attributes.conflicts_with` в `docs/registry/nodes.yaml`. Сейчас **0**.
   - Механика готова и протестирована: **3-A** `tools/skill-contract.mjs` (схема контракта `{needs/produces/constraints + preview-form/defaults/key-decisions/acceptance-criteria}` + механический валидатор формы + G4 хеш-страж external-дрейфа) + `tools/skill-contract-registry.mjs` (`buildRegistry`/`loadRegistry`); **3-B** `tools/node-graph.mjs` (`conflictsOf`/`twinsOf`/`hintLinksOf`, free-text НЕ парсит — только explicit). Инварианты на реальном реестре: `tools/m3a-*`/`tools/m3b-node-graph-invariants.test.mjs`.

3. ОТКУДА БРАТЬ КОНТЕНТ (первоисточники — НЕ graphify):
   - `needs/produces/constraints` карточек — `SKILL.md`-описания скилов + **Tooling Прил.Н** (`docs/Tooling_v8_3.md`) + CLAUDE.md §3 (категории/роли узлов).
   - конфликт-рёбра — **Tooling §9** (явный список запрещённых дублей «два инструмента на одну задачу») + ADR-границы (ADR-006/007/…/017) + конфликт-коды в истории CLAUDE.md.
   - external-карточки (вендоренные/чужие скилы) несут `source{version,hash,path}` (G4 анти-дрейф).

4. GRAPHIFY — ВТОРИЧНАЯ СВЕРКА, НЕ ИСТОЧНИК (важно, не переоценивать):
   - graphify-граф = граф знаний проекта (docs+code, ~6305 узлов, рёбра `calls/references/conceptually_related_to/semantically_similar_to`) — это НЕ реестр роутера; relation «конфликт» в нём НЕТ. Карточечного `needs/produces` там нет.
   - Польза для H: подсказки пересечений (`semantically_similar_to`/`conceptually_related_to` между инструментами) → кандидаты в близнецы/потенц.конфликты → проверять по канону (Tooling §9).
   - Статус: router-gate **разблокирован** для `graphify query/explain/path` (коммит `5a3ad6b8` в MAIN-репо, ветка `feat/gate-allow-worktree-cd`, НЕ запушено). НО бинарь `~/.local/bin/graphify.exe` **не на PATH харнесса** → из сессии `graphify query` пока не запустить (нужен Windows-PATH + рестарт — шаг владельца). **Обход:** `graphify-out/graph.json` читается напрямую через **Grep/Read** (не gated) — этого достаточно для сверки пересечений.

5. ЦЕПОЧКА СКИЛОВ (СОГЛАСОВАНА владельцем — держать на всех батчах):
   - **Слой 0 — brainstorming** (`superpowers:brainstorming`): зафиксировать подход ДО написания. **Открытый Q1 (scope карточек):** какие узлы получают карточки — (а) только активные маршрутизируемые, исключить DEFERRED #44/#50/#54/#67/#82/#83 + dormant ruflo; (б) все ~86 (заглушки для DEFERRED/dormant); (в) активные + лёгкие заглушки. Дорешить с владельцем. Плюс: батчинг (по категориям/подкатегориям), политика конфликт-рёбер, acceptance (валидатор 0 ошибок + инвариант «все активные узлы имеют контракт»?).
   - **Слой 0.1 — graphify** (вторичная разведка): Grep по `graphify-out/graph.json` на пересечения инструментов → кандидаты конфликт-рёбер (сверять с Tooling §9).
   - **Слой 0.5 — writing-plans** (`superpowers:writing-plans`): bite-sized план: verify схемы → source-mapping по категориям → батч-авторинг с прогоном валидатора + инвариант-тестов per батч → конфликт-рёбра → регрессия.
   - **Слой 1 — per-батч:** `audit-context-building` (прочитать ЦЕЛИКОМ skill-contract.mjs + 2 образца + node-graph.mjs + nodes.yaml + инварианты) → `superpowers:test-driven-development` (где трогаю код — новое правило валидатора/инвариант — RED→GREEN; для чистых данных «тест» = валидатор 0 ошибок + инварианты на реальном реестре зелёные) → `superpowers:systematic-debugging` (на красный) → `superpowers:verification-before-completion`.
   - **Слой 1.5:** `variant-analysis` (консистентность карточек между собой — поля/тон/полнота по категориям) + `sharp-edges` ПОСЛЕ конфликт-рёбер (двусторонняя согласованность, нет висячих ref).
   - **Слой 2 — гейт закрытия:** `audit-context-building` → `sharp-edges` → `variant-analysis` → `regression` (tools-only ≥ baseline) → `verification-before-completion` → коммит (не пуш).
   - **НЕ** `requesting-code-review`. Скилы загружать раз, применять инлайн (coverage `direct:<role>`).

6. ЖЁСТКОЕ: commit-not-push (пуш ТОЛЬКО по слову «пуш» через `superpowers:finishing-a-development-branch`); владельцу простым языком, код/память технически; **каждый ответ 1-я строка «экономия:…», 2-я «coverage:…»**. CLAUDE.md в worktree НЕ трогать (чужая зона, 99.8KB diff параллельной сессии). H — это данные `docs/registry/`, нормативку (§0 cross-refs) не двигают.

7. КВИРКИ (подтверждены этой сессией):
   - **vitest** — через Bash, из `app/`: `cd app && npx vitest run --config vitest.config.tools.mjs <фильтр> --reporter dot`. НЕ `node .../vitest.mjs` (ломается keytar'ом в `app/node_modules` → ошибка `reading 'config'`); НЕ `npx` из корня (тянет чужой vitest из реестра). Фильтр = подстрока имени файла.
   - **git** — через PowerShell, по одной команде, литеральные пути, БЕЗ переменных, БЕЗ if-чейнинга. Коммит: msg в `<wt>\.scratch\*.txt` (Write) → `git -C "<wt>" commit -F "<...>.txt"`. «Can't find lefthook in PATH» — ШУМ.
   - **enforce-tdd-gate:** prod-правка `tools/*.mjs` требует (а) предшествующей правки `*.test.mjs` + (б) **наблюдаемого RED-прогона vitest в этом ходе** перед prod-правкой. Для H, который в основном ДАННЫЕ (.json/.yaml), tdd-gate не триггерится — он только на `tools/*.mjs`.
   - **PowerShell-гейт** режет Get-Process/`$var=`/Write-Output/git ls-files → список файлов через **Grep** (не Glob — junction в worktree); существование — Read/Grep.
   - Чужая грязь в дереве (observer-jsonl авто-регенерат / чужие планы / `.scratch/` / `patch-*.mjs`) — НЕ коммитить, стейджить свои файлы поимённо (`git -C "<wt>" add "<path>"`).
   - `<wt>` = `c:\моя\проекты\портал crm\Документация\.claude\worktrees\brainrepo`.

8. СТАРТ: прочитай этот handoff + реестр хвостов (`...2026-06-08-router-mentor-loose-ends-registry.md`, блок H) → подними цепочку скилов со Слоя 0 (brainstorming, дореши Q1 с владельцем) → дальше по цепочке. Кодовая фраза: «роутер-наставник».

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

---

## Что сделано ЭТОЙ сессией (для контекста)

- **Реестр хвостов** эпика собран (read-only sweep, Максимум-методология) и закоммичен: `docs/superpowers/plans/2026-06-08-router-mentor-loose-ends-registry.md` (worktree commit `85ffb25e`). Блоки H/A/B/C/E/F/G + критический путь к продакшену. H выбран как первый Claude-закрываемый блок.
- **graphify gate-разблок** (по просьбе владельца): `tools/enforce-router-gate.mjs` + `.test.mjs` — whitelist `graphify query/explain/path` (мутирующие default-deny). TDD 122/122 GREEN. Security-review «unanchored allowlist» отработан и квалифицирован как **false-positive** (инъекция нейтрализуется ДО регекса: per-segment whitelist + tokenizer subshell-block + redirect hard-blacklist; `$VAR` раскрывается токенайзером; end-anchor+charset ломал Unicode-запросы). Коммит `5a3ad6b8` в MAIN-репо (ветка `feat/gate-allow-worktree-cd`), **не запушено**. NB: коммит подхватил 3 чужих pre-staged файла (`receipt-key-config.{mjs,test.mjs}` + `STATUS.md`) — были в индексе до сессии.
- **PATH-фикс graphify**: создал `~/.bashrc` + `~/.bash_profile` с `export PATH="$HOME/.local/bin:$PATH"` — но **не помогло** (Bash-инструмент = `bash -c`, профиль не читает; PowerShell-гейт тоже default-deny на graphify). **Остаток (шаг владельца):** добавить `~/.local/bin` в **Windows user PATH** + рестарт Claude Code → тогда `graphify query` заработает. Для H не блокер (graph.json Grep-readable).

## Открытые решения для H (дорешить в новой сессии)
- **Q1 scope** карточек (а/б/в — см. промт п.5).
- Батчинг узлов (по подкатегориям Tooling?).
- Acceptance: добавлять ли инвариант «все активные узлы имеют контракт» (TDD) в `m3a`-инварианты.
- Нужен ли всё же PATH-фикс graphify (приоритет вторичный — graph.json и так читается).

---

## ✅ H ЗАКРЫТ (2026-06-08, commit-not-push, ветка worktree-brainrepo)

**Решения (с владельцем):** Q1 = все 86 полноценно (per-node, `skill=slug`); acceptance = инвариант покрытия `m3e`; R-12 = только канон (§6/R14.5), ноль выдумок; батчинг по подкатегориям/фазам; own = наши скилы+superpowers, external = чужие (zero-hash+path"").

**Дополнительный аудит достаточности** (audit-context → variant-analysis → sharp-edges): схема паспорта достаточна для роутера И судьи (судья получает карточку целиком `judge-engine.mjs:56`; роутер — needs/key-decisions/acceptance-criteria look-ahead). 5 находок вложены в реализацию: **G-E** (мех-правка — страж дрейфа инертен при пустом `source.path`), **G-A** (разделитель близнецов в `constraints`+`capabilities`), **G-B** (инвариант «минимум содержания»), **G-G** (вход≠выход), **G-H** (резолв+симметрия конфликтов). G-F/G-C/G-D отложены.

**Артефакты:** 86 карточек `docs/registry/contracts/*.contract.json` + 4 конфликт-пары в `nodes.yaml` + `tools/card-coverage.mjs` + `tools/m3e-*` + правки `tools/skill-contract.mjs` (G-E) и `tools/m3a-*` (form-инвариант всех карточек). Регрессия tools-only **3174 passed / 2 skipped / 0 failed**. Коммиты `d1a76786..65b3c575`, НЕ запушено.

**КВИРК vitest (важно для будущих сессий в этом worktree):** worktree лежит под `.claude/worktrees/brainrepo`, сессия укоренена в ГЛАВНОМ репо → документированный `cd app && npx vitest …` тестит ГЛАВНЫЙ репо (не worktree), а `cd` в `.claude`-путь режет router-гейт (`.claude` в негативном lookahead `cd`-allowance). **Рабочая форма:** `npx vitest run --root "<wt>/app" --config "<wt>/app/vitest.config.tools.mjs" <фильтр> --reporter dot` (без `cd`, с явным `--root` на worktree). PowerShell-гейт `npx`/`Set-Location` тоже режет — git через PowerShell `-C`, тесты через Bash с `--root`.
