# Карта узлов iter9 — подсистема brain governance — design

**Версия:** 1.0
**Дата:** 2026-05-20
**Статус:** design (approved by user «рк» 2026-05-20) → awaiting written-spec review → writing-plans
**Автор:** Дмитрий (заказчик) + Claude (Opus 4.7) via superpowers:brainstorming
**Связано:** `docs/automation-graph.html`, `docs/automation-graph-data.js`, `docs/brain-dashboard.html`,
ADR-011, spec `2026-05-19-brain-governance-design.md`, spec `2026-05-19-observer-factor-analysis-design.md`,
`lefthook.yml`, memory `project_automation_map.md`

---

## 1. Контекст и разрыв

«Карта» (`docs/automation-graph.html` + общий `docs/automation-graph-data.js`) застыла на iter8
(снимок 18.05.2026). 19.05.2026 приехала подсистема **brain governance (ADR-011)** + observer
factor-analysis — её на карте нет. data.js — общий: его правка автоматически кормит и
`docs/brain-dashboard.html` (показывает ту же карту; сам себя узлом не рисует).

Разрыв (подтверждён data.js + спеками 19.05 + `lefthook.yml` + git-логом):

1. **Устаревшие версии в 4 узлах-правилах:** `pravila v1.29→v1.33`, `claude_md v2.16→v2.20`,
   `psr_v1 v3.14→v3.17`, `tooling v2.15→v2.17`.
2. **Подсистема brain governance отсутствует:** `router-procedure.md` v1.0; Stop-хук
   `observer-stop-hook.mjs` (пишет эпизоды + routing-gate `decision:block`); скил `/brain-retro`;
   5 контролёров lefthook jobs 11–15 (C1 l1-watcher, C2 cross-ref-checker, C3 observer-of-observer,
   C4 status-md post-commit, C5 observer-coverage-checker); observer-инфраструктура `docs/observer/`
   (episodes JSONL, STATUS.md, .read-counter, notes); внутренние `.mjs` (transcript-parser,
   routing-detector, choice-detector, brain-retro-analyzer).
3. **NODE_META** — снимок iter8; новых узлов нет.

## 2. Решения (согласованы с заказчиком)

- **Объём:** полный iter9 (а не light-sync).
- **Подход:** A — subsystem-level: +9 узлов в их **естественных функциональных группах**
  (контролёры — с lefthook, Stop-хук — с hooks, скил — с skills_proj), как iter A6/D3/C9.
  Внутренние `.mjs` и `brain-dashboard.html` — в паспортах, не отдельными узлами
  (отвергнуты: B fine-grained ~13 узлов; C — отдельный кластер, как ruflo).

## 3. 9 новых узлов

| id | label | group | ring·angle | size |
|---|---|---|---|---|
| `router_procedure` | router-procedure v1.0 | rules | 1·210 | 24 |
| `observer_stophook` | Stop: observer-stop-hook | hooks | 4·205 | 22 |
| `sk_brain_retro` | /brain-retro (skill) | skills_proj | 3·210 | 18 |
| `observer_evidence` | docs/observer/ episodes+STATUS | memory | 6·204 | 16 |
| `lh_l1watcher` | lefthook: l1-watcher (C1) | lefthook | 5·150 | 16 |
| `lh_crossref` | lefthook: cross-ref-checker (C2) | lefthook | 5·157 | 16 |
| `lh_obs_obs` | lefthook: observer-of-observer (C3) | lefthook | 5·164 | 16 |
| `lh_status_md` | lefthook: status-md (C4) | lefthook | 5·171 | 16 |
| `lh_obs_cov` | lefthook: observer-coverage (C5) | lefthook | 5·178 | 16 |

Углы выбраны в свободных слотах (≥7° от соседей того же кольца); не-перекрытие проверяется
рендером (см. §8). Новых групп/цветов нет — все 9 в существующих `GROUPS`.

## 4. Версии-метки + NODE_META (iter9)

- 4 узла-правила: версии-метки → v1.33 / v2.20 / v3.17 / v2.17; их `changed` → `19.05.2026`.
- `META_SNAPSHOT '18.05.2026'→'20.05.2026'`; `META_WINDOW '09–18.05.2026'→'09–20.05.2026'`.
- **Методология (как iter8, честная):** числа использования **старых** узлов НЕ перемеряются —
  транскрипты Claude Code недоступны как источник в репо (задокументированный предел iter8);
  только bump окна/снимка. Новым узлам `since='19.05.2026'`, `changed='—'`, `uses`:
  - `lh_l1watcher`/`lh_crossref`/`lh_obs_obs`/`lh_status_md`/`lh_obs_cov` — git-commit-count,
    затрагивающий их триггер-glob в окне (`usesSrc:'коммиты'`), подсчитывается при реализации.
  - `observer_stophook` — число строк-эпизодов в `docs/observer/episodes-2026-05.jsonl`
    (`usesSrc:'хук (эпизоды)'`), подсчитывается при реализации.
  - `observer_evidence` — значение из `.read-counter.json`, иначе baseline 1 (`usesSrc:'observer counter'`).
  - `sk_brain_retro` — baseline 1 (`usesSrc:'интеграция'`).
  - `router_procedure` — `uses:null` (rule-like, напрямую не вызывается; `usesSrc:'—'`).

## 5. 12 новых рёбер (EDGES)

- `claude_md→router_procedure` (§3.6 SoT), `tooling→router_procedure` (§4.X реестр → шаг 3),
  `pravila→router_procedure` (§12/§14/§15 hard-floor).
- `pravila→observer_stophook` (§16: observer + routing-тег),
  `observer_stophook→observer_evidence` (пишет эпизоды + routing-gate).
- `pravila→sk_brain_retro` (§16: факторный анализ раз в спринт),
  `sk_brain_retro→observer_evidence` (читает эпизоды).
- `lh_l1watcher→tooling` (C1 STRICT: settings.json↔Tooling drift),
  `lh_crossref→claude_md` (C2 STRICT: version drift §0 cross-refs; репрезентирует 5-файловую проверку),
  `lh_obs_obs→observer_evidence` (C3 warn: счётчик +54w),
  `lh_status_md→observer_evidence` (C4: генерит STATUS.md),
  `lh_obs_cov→observer_evidence` (C5 warn: покрытие + регистрация).

## 6. 1 новый конфликт (3-color)

🟢 GREEN `observer_stophook ↔ hk_verifier`: оба на Stop-event; HK1 §5.3 — коллизии нет
(append-chain), оба способны `decision:block`, Claude Code прогоняет все Stop-хуки, любой
block ⇒ продолжение хода. Новых 🔴/⚫ нет (подсистема спроектирована бесконфликтно).

## 7. Секции (NODE_SECTION) + счётчики

`router_procedure→E1`, `observer_stophook→E2`, `sk_brain_retro→E8`, `observer_evidence→E4`,
`lh_l1watcher→E1`, `lh_crossref→E1`, `lh_obs_obs→E2`, `lh_status_md→E2`, `lh_obs_cov→E2`.

Count-комментарии: узлы 125→134; rules 4→5; hooks 11→12; skills_proj 12→13; memory 24→25;
lefthook 10→15; «Покрывает все N узлов» 125→134.

## 8. Паспорта/детали + верификация

- Каждому из 9 узлов — полный паспорт `nd()` (desc/when/limits/reportsTo/manages/together/conflicts);
  каждому из 13 рёбер — полный `EDGE_DETAILS` (type/when/transfers/mandatory/rule).
  Источник фактов — спеки 19.05 + **как-built `lefthook.yml`**: C1/C2 STRICT (блокируют коммит);
  C3/C5 warn-only (скрипт всегда exit 0); C4 post-commit `|| true`. Внутренние `.mjs` —
  в desc/limits родителя; `brain-dashboard.html` — в паспорте `observer_evidence`.
- **Верификация:** рендер `automation-graph.html` через Playwright MCP (0 JS-ошибок; 9 узлов видны;
  без перекрытий; паспорта открываются; рёбра + GREEN-конфликт рисуются); `brain-dashboard.html`
  грузится с теми же данными (его Карта-view показывает новые узлы); sanity `node --check` на data.js;
  сверка count-комментариев с фактической длиной массивов; обновить smoke-PNG.

## 9. Вне scope

- Нормативка (Pravila/PSR_v1/Tooling/CLAUDE.md) — НЕ правится (это задача о карте, не о нормативке).
- **Наблюдение (фиксирую, не правлю):** CLAUDE.md v2.18 / memory утверждают «C1+C2 WARN-only via
  `|| true` jobs 11-14» — расходится с как-built `lefthook.yml` (C1/C2 STRICT). Карта отрисует факт;
  правка нормативки — отдельная задача через `claude-md-management`.
- `brain-dashboard.html` не редактируется (кормится из общего data.js).

## 10. Файлы

- `docs/automation-graph-data.js` — NODES (+9, версии-метки ×4), EDGES (+12), CONFLICT (+1 GREEN),
  NODE_SECTION (+9), count-комментарии.
- `docs/automation-graph.html` — NODE_DETAILS (+9), EDGE_DETAILS (+13), NODE_META (+9 + bump
  снимка/окна + `changed` на 4 узлах-правилах).

Коммиты: 1–2 атомарных (data.js структура + html паспорта/мета), сообщение
`feat(map): iter9 — brain governance subsystem`.
