# Карта автоматизации — iter4: слияние ruflo big-bang

**Дата:** 2026-05-15
**Статус:** дизайн утверждён заказчиком (brainstorming Q1/Q2/Q3 + дизайн)
**Артефакт:** `docs/automation-graph.html` — интерактивный граф системы автоматизации Лидерры (vis.js Network 9.1.9)
**Предыдущая итерация:** iter3 «interactive highlighting» (`docs/superpowers/specs/2026-05-15-graph-interactive-highlighting-design.md`, коммиты `ef88435..f0d3d49` + closure `8a22cc4`, на origin/main `aa39763`)

---

## 1. Контекст и проблема

«Карта» (`docs/automation-graph.html`) в речи заказчика — единственный канонический артефакт визуализации системы автоматизации. На момент iter3 карта содержит 73 узла / 74 ребра (66 обычных + 8 конфликтов 3-color: 🔴2 / ⚫2 / 🟢4) в радиально-секторном layout.

15.05.2026 проведён **ruflo big-bang** — перестройка системы автоматизации (3 сессии, `aa39763..5ac2961`):

- **Phase 1-2** (Session 1): установка ruflo v3.7.0-alpha.38, scaffold, MCP-сервер 7-м в `.mcp.json`.
- **Phase 3-4** (Session 2, коммиты `9c3057b`/`d30cbeb`/`5df88a1`/`f65a8d7`/`6287561`): переписаны 4 нормативных файла под sub-policy paradigm — Pravila v1.13→**v1.14**, PSR_v1 v2.1→**v3.0**, CLAUDE.md v1.92→**v2.0**, Tooling v1.17→**v2.0**. Цепочка приоритетов 8-уровневая → **9-уровневая** (добавлен уровень −1 ruflo Queen-led routing).
- **Runtime activation** (Session 3, коммит `5ac2961`): daemon под PM2 + reboot-survival, hive-mind Queen + 9 worker-агентов, memory `.swarm/memory.db` + реальные embeddings `Xenova/all-MiniLM-L6-v2` 384-dim.

**Две устаревшие карты на текущий момент:**

1. `docs/automation-graph.html` — ruflo отсутствует полностью; 4 узла-правила застряли на версиях v1.13/v1.92/v2.1/v1.17; содержание легенд («§12 неотменяем», «реестр 35 инструментов», 8-уровневая цепочка) разошлось с нормативкой v2.0.
2. `docs/automation-graph-ruflo.html` — форк iter3 (коммит `796d814`), создан как «бумажный TO-BE-предпросмотр» ДО активации рантайма. Добавил ruflo-узлы/рёбра/группу/пункт легенды, **но**: (а) `NODE_DETAILS` и `EDGE_DETAILS` для ruflo отсутствуют целиком — ruflo-узлы кликабельны, но панель легенды пустая; (б) баг — ребро ссылается на несуществующий узел `lh_pre_push`; (в) `CATEGORY_LABELS` без записи `ruflo`; (г) 4 узла-правила в форке тоже не освежены.

**Критичная фактическая оговорка** (из `memory/project_ruflo_integration.md`): нормативка декларирует ruflo Queen-led routing уровнем −1 (entry-point для всех задач), но runtime **не перехватывает фактический Claude Code workflow** — Claude работает напрямую (skills, tools), ruflo daemon/hive-mind крутятся параллельно как отдельный процесс. «Queen-led routing» в смысле «ruflo решает что делает Claude» не реализовано. Архитектурно ruflo остаётся **parallel subsystem**, не overlord.

## 2. Цель

Одна актуальная карта `docs/automation-graph.html`, отражающая систему после ruflo big-bang: ruflo-наслой включён, 4 узла-правила и §12/sub-policy-формулировки освежены под нормативку v2.0, цепочка приоритетов 9-уровневая. Расхождение «нормативная декларация (overlord) ↔ фактический parallel subsystem» показано на карте явно. Форк `automation-graph-ruflo.html` удалён.

## 3. Решения brainstorming (утверждены заказчиком)

| # | Вопрос | Решение |
|---|---|---|
| Q1 | Сколько карт держим? | **Одна.** Влить ruflo в `automation-graph.html`; форк `automation-graph-ruflo.html` удалить. |
| Q2 | Как показываем роль ruflo? | **Честный гибрид.** Queen рисуем уровнем −1 (по нормативке), НО + явный конфликт-маркер «декларация overlord ↔ фактически parallel subsystem» + реальный runtime-статус в легендах ruflo-узлов. |
| Q3 | Глубина обновления? | **Полный рефреш.** Освежить всё, что разошлось с нормативкой v2.0: 4 узла-правила, упоминания §12/sub-policy в `superpowers`/`sk_*`/`hk_economy`/`mem_sp`, конфликт #8, цепочка 8→9. |

## 4. Подход

**Подход 1 — правка `automation-graph.html` на месте** (выбран). Основная карта — база (в ней iter3-подсветка, она каноничная). Дописываем ruflo-секции, освежаем легенды, удаляем форк. Линейная история файла; путь `automation-graph.html` сохраняется.

Отклонён **Подход 2** (продвинуть форк через `git mv` поверх основной): экономит ~30 строк структуры, но ruflo-легенды всё равно писать с нуля, а `git mv` поверх каноничного файла рвёт blame-историю «карты».

## 5. Детальный дизайн

### 5.1. Новые узлы — +12 (станет 85)

**Группа `ruflo`** — оранжевая, добавляется в `GROUPS` и `CATEGORY_LABELS`:

```js
ruflo: { color: { background: '#332100', border: '#ff8800',
         highlight: { border: '#ffaa33', background: '#4d3300' } },
         font: { color: '#fdf6e3', size: 12, bold: true } },
```

`CATEGORY_LABELS.ruflo = 'ruflo (оркестратор)'`.

**11 узлов группы `ruflo`** — кластер в верхнем-левом углу вне радиального layout (фиксированные координаты, не `pos()`):

| id | label | координаты (x, y) | size |
|---|---|---|---|
| `ruflo_queen` | `ruflo Queen\n(Queen-led routing)` | −1300, −700 | 44 |
| `ruflo_architect` | `Architect` | −1150, −870 | 24 |
| `ruflo_coder` | `Coder` | −980, −860 | 24 |
| `ruflo_security` | `Security` | −880, −740 | 24 |
| `ruflo_rls` | `RLS-reviewer` | −880, −580 | 22 |
| `ruflo_qa` | `QA` | −980, −490 | 22 |
| `ruflo_tester` | `Tester` | −1150, −490 | 22 |
| `ruflo_reviewer` | `Reviewer` | −1300, −490 | 22 |
| `ruflo_memory` | `Memory-keeper\n(HNSW + SONA)` | −1470, −580 | 24 |
| `ruflo_daemon` | `Daemon-worker\n(PM2, 5 задач)` | −1470, −740 | 22 |
| `ruflo_mcp` | `ruflo MCP\n(~210 инструментов)` | −1100, −340 | 24 |

Координаты Queen + 9 swarm-ролей — из форка `796d814` (проверены визуально). `ruflo_mcp` — новый узел, координаты −1100/−340 (мост между кластером и легаси-графом); финальная позиция корректируется по visual smoke при перекрытии.

**1 узел группы `memory`** — `mem_ruflo`, файл `memory:\nproject_ruflo_integration`, координаты ≈ −1700, −470 (отдельностоящий, рядом с ruflo-кластером, серый цвет memory-группы); финальная позиция — по visual smoke.

Итог по группам после: rules 4, plugins 5, skills_sp 14, skills_proj 2, hooks 5, agents 11, mcp 7, lefthook 10, **memory 16**, **ruflo 11** = **85 узлов**.

### 5.2. Новые рёбра — +22 (станет 96)

| Группа | Кол-во | Рёбра |
|---|---|---|
| Queen → swarm | 9 | `ruflo_queen` → каждый из `ruflo_architect/coder/security/rls/qa/tester/reviewer/memory/daemon`, label `подчиняет` |
| Queen → MCP | 1 | `ruflo_queen` → `ruflo_mcp`, label `экспонирует\n~210 инструментов` |
| Queen → правила | 4 | `ruflo_queen` → `pravila` / `claude_md` / `psr_v1` / `tooling`, label `перенял\nsub-policy` (нормативная декларация уровня −1) |
| swarm → legacy | 4 | `ruflo_coder`→`ag_pest` `делегирует TDD`; `ruflo_security`→`ag_rls` `делегирует RLS`; `ruflo_rls`→`sk_rls` `делегирует RLS-скил`; `ruflo_memory`→`mem_state` `reindex HNSW` |
| memory → ruflo | 1 | `mem_ruflo` → `ruflo_queen`, label `документирует\nинтеграцию` |
| конфликты | 3 | см. §5.3 |

Форковское ребро `ruflo_daemon → lh_pre_push` **не переносится** — `lh_pre_push` не существует, а honest-связи «daemon делегирует в legacy» нет (daemon — фоновый процесс в local-fallback, его реальное взаимодействие с легаси описано конфликтами §5.3). Daemon в графе связан рёбрами `ruflo_queen→ruflo_daemon` (подчиняет) + 2 конфликта.

Ребро `mem_ruflo→ruflo_queen` (тип «документирует») — по образцу легаси-рёбер `mem_archive→claude_md` / `mem_plugins→psr_v1` / `mem_env→ag_pest`. Узел `mem_ruflo` **не** получает ребро на `hk_session`: файл `project_ruflo_integration` не входит в фиксированный inject-список SessionStart-хука (в `hk_session.manages` — 5 конкретных файлов; прочие 10 memory-узлов карты тоже без ребра на хук).

Итог по рёбрам: 85 обычных (66 легаси + 1 Queen→mcp + 9 Queen→swarm + 4 Queen→правила + 4 swarm→legacy + 1 mem_ruflo→Queen) + 11 конфликтов = **96 рёбер**.

### 5.3. Конфликты — было 8, станет 11

**7 старых — без изменений:** sk_rls↔ag_rls (🔴), hookify_plugin↔hk_pre_claude (🔴), mcp_pw↔sk_parallel (⚫), ag_pest↔mcp_redis (⚫), psr_v1↔claude_md (🟢), upm↔fd_plugin (🟢), mcp_21st↔fd_plugin (🟢).

**1 старый — освежить формулировку (цвет 🟢 сохраняется):** `hk_economy↔superpowers`. Было: «Pravila §12.4: §12 неотменяем». Стало: «§12 Superpowers — sub-policy под ruflo Queen-led routing (уровень −1); economy-режим §12 не отменяет ни на каком уровне (Pravila §12.4)».

**+3 новых ruflo-конфликта:**

| Пара | Тип | Описание |
|---|---|---|
| `ruflo_queen` ↔ `pravila` | 🔴 | «Нормативка (Pravila §0/§12, CLAUDE.md §1, PSR_v1 R0) декларирует ruflo Queen-led routing уровнем −1 — overlord над всей иерархией. Фактически ruflo — параллельная подсистема: Claude работает напрямую (skills/tools), ruflo daemon/hive-mind крутятся рядом, workflow не перехватывают. Механизма enforcement нет — декларация ≠ runtime.» |
| `ruflo_daemon` ↔ `mem_state` | ⚫ | «Два хранилища памяти — статичные `memory/*.md` и HNSW-база ruflo (`.swarm/memory.db`) — рассинхронизированы. `ruflo memory store` не персистит между запусками (alpha-баг H7, in-memory sql.js). Дублирование без регламента синхронизации.» |
| `ruflo_daemon` ↔ `ag_pest` | ⚫ | «Daemon worker-jitter усиливает частоту Pest --parallel квирка 72 (гонка в Redis). ruflo не трогает Redis :6379 — лишь timing-amplifier. На baseline-регрессии — `pm2 stop ruflo-daemon` (квирк #93).» |

Тип конфликта `ruflo_queen↔pravila` = 🔴 «не закрыт правилом»: суть — нормативка декларирует, но регламента/механизма enforcement нет, расхождение открыто.

Форковский конфликт `ruflo_queen↔mcp_pw` («IPFS gateway flaky») **не переносится** — пара from/to произвольная (проблема IPFS-реестра плагинов не связана с playwright). IPFS-flakiness переносится в поле «Ограничения» (`limits`) узла `ruflo_queen`.

**3-color баланс после:** 🔴3 / ⚫4 / 🟢4 = 11 конфликтов. Сортировка в легендах и подсветке (rank 1/2/3) — без изменений, авто-подхватывается.

### 5.4. Рефреш 4 узлов-правил

| Узел | label было → стало | Изменения в desc/when/limits/reportsTo/manages |
|---|---|---|
| `pravila` | `Pravila v1.13` → `Pravila v1.14` | `limits`: «§12 нельзя отменить» → «§12 Superpowers стал sub-policy под ruflo Queen-led routing (уровень −1); в уровнях 0–6 цепочки остаётся hard-rule (скил инвокируется первым), economy-режим §12 не отменяет». `reportsTo`: +`{ name: 'ruflo Queen', cond: 'уровень −1 по нормативке — ruflo Queen-led routing над Pravila' }`. |
| `claude_md` | `CLAUDE.md v1.92` → `CLAUDE.md v2.0` | `desc`: упомянуть 9-уровневую цепочку приоритетов + §3.5 orchestration layer. `manages`: «Tooling v1.17» → «Tooling v2.0». |
| `psr_v1` | `PSR_v1 v2.1` → `PSR_v1 v3.0` | `desc`: R0 stack-gate → sub-policy paired-stack delegation pattern под ruflo Queen-led routing. |
| `tooling` | `Tooling v1.17` → `Tooling v2.0` | `desc`: «Реестр 35 инструментов» → «Реестр 55 позиций: 35 формализованных инструментов + 20 ruflo-плагинов; +§4.10 Orchestration layer». `when`/`limits` — синхронизировать формулировки. |

Ссылка `claude_md` (в `manages`) на «Tooling v1.17» обновляется на «Tooling v2.0».

### 5.5. Рефреш §12 / sub-policy в легендах прочих узлов

| Узел / запись | Изменение |
|---|---|
| `superpowers` (`limits`) | «§12: единственная отмена — явная просьба...» → дополнить: «§12 — sub-policy под ruflo Queen-led routing (уровень −1); в уровнях 0–6 остаётся hard-rule (скил первым); §9 “Отступления” не применяется; economy-режим не отменяет». |
| `hk_economy` (`limits`) | «Правило §12 НЕ отменяется этим режимом» → уточнить: «§12 — sub-policy под ruflo, но economy-режим его не отменяет ни на каком уровне». |
| `mem_sp` (`desc`) | Лёгкая правка: «Обязательное правило §12 (sub-policy под ruflo) + архитектура хука economy из 6 компонентов». |
| EDGE_DETAILS `pravila->superpowers` (`rule`) | «Pravila §12 (hard rule, §9 не применяется)» → «Pravila §12 (sub-policy под ruflo Queen-led routing; в уровнях 0–6 — hard rule, §9 не применяется)». |
| EDGE_DETAILS `hk_economy->superpowers` (`when`) | Синхронизировать с новой формулировкой конфликта #8 (§5.3). |

Узлы `sk_*` с `reportsTo` вида `{ name: 'Pravila §12', cond: 'обязательное правило...' }` — формулировка «скил инвокируется первым» по сути остаётся верной (§12 как sub-policy в уровнях 0–6 продолжает действовать); точечная правка не требуется, кроме мест с буквальным «неотменяем». В рамках полного рефреша (Q3) — пройтись по всем 14 `sk_*` и убедиться, что нет буквального «§12 неотменяем»; при наличии — заменить на sub-policy-формулировку.

### 5.6. Содержание ruflo NODE_DETAILS (12 узлов — пишутся с нуля)

Каждый узел получает полные 7 полей (`desc`, `when`, `limits`, `reportsTo`, `manages`, `together`, `conflicts`) по образцу легаси-узлов. Ключевое содержание (точные строки — в плане реализации):

- **`ruflo_queen`** — `desc`: оркестратор ruflo v3.7.0-alpha.38, SONA neural routing + Queen-led hierarchy (Raft/Byzantine/Gossip), HNSW vector memory. `when`: по нормативке — entry-point для всех задач (уровень −1). `limits`: **фактически parallel subsystem — не перехватывает Claude workflow**; alpha-версия; LLM API-ключи отсутствуют → агенты idle, $-расход near-zero; plugin discovery через IPFS нестабилен (Pinata/Cloudflare недоступны 15.05.2026, работает только ipfs.io). `reportsTo`: пусто (уровень −1, верх по нормативке). `manages`: 9 swarm-ролей + ruflo_mcp + 4 узла-правила (декларативно). `conflicts`: 🔴 с pravila.
- **9 swarm-ролей** — `desc`: специализированный hive-mind агент (по роли). `when`: при routing-decision Queen. `limits`: **idle — нет LLM API-ключей; реальная агентская работа (`spawn --claude`) не запускалась**; generic type. `reportsTo`: ruflo Queen. У `ruflo_coder`/`ruflo_security`/`ruflo_rls` — `together`/`manages` с соответствующими legacy-узлами (ag_pest/ag_rls/sk_rls).
- **`ruflo_memory`** — `desc`: HNSW-индекс + SONA, `.swarm/memory.db` (sql.js) + embeddings `Xenova/all-MiniLM-L6-v2` 384-dim. `limits`: `ruflo memory store` CLI не персистит между запусками (alpha-баг H7). `conflicts`: пусто (конфликт dual-system привязан к daemon).
- **`ruflo_daemon`** — `desc`: фоновый демон под PM2 (`ruflo-daemon`, 5 workers: map/audit/optimize/consolidate/testgaps), reboot-survival через Windows Task Scheduler. `limits`: workers в local-fallback mode (file I/O по `.claude-flow/`, нет платных вызовов); worker-jitter усиливает Pest квирк 72. `conflicts`: ⚫ с mem_state, ⚫ с ag_pest.
- **`ruflo_mcp`** — `desc`: MCP-сервер ruflo, stdio mode, 7-й в `.mcp.json`, ~210 инструментов. `when`: инструменты экспонированы постоянно. `limits`: **Claude не обязан вызывать ruflo-инструменты — отсюда статус parallel subsystem, а не overlord**. `reportsTo`: ruflo Queen.
- **`mem_ruflo`** — `desc`: memory-файл `project_ruflo_integration` — Phase 1–7 + runtime activation. `when`: при работе с ruflo. `together`: ruflo Queen (документирует интеграцию). `reportsTo`/`manages`: пусто.

### 5.7. Содержание ruflo EDGE_DETAILS (~22 рёбер — пишутся с нуля)

5 полей (`type`, `when`, `transfers`, `mandatory`, `rule`) на каждое ребро по образцу легаси. Опорные значения:

- **9 Queen→swarm**: type `подчиняет`, when `hive-mind активен — Queen раздаёт задачи swarm-агентам`, transfers `контроль`, mandatory `опционально` (агенты idle без API-ключей), rule `Tooling §4.10 (orchestration layer)`.
- **Queen→ruflo_mcp**: type `экспонирует`, when `MCP-сервер ruflo в .mcp.json (stdio)`, transfers `инструменты`, mandatory `опционально`, rule `Tooling §4.10`.
- **4 Queen→правила**: type `перенял sub-policy`, when `нормативная декларация уровня −1 (entry-point)`, transfers `контроль (декларативно)`, mandatory `декларативно — без enforcement`, rule `Pravila §0/§12 · CLAUDE.md §1 · PSR_v1 R0 · Tooling §4.10`.
- **4 swarm→legacy**: type `делегирует`, when `при routing-decision Queen (требует LLM API-ключи — сейчас idle)`, transfers `триггер`, mandatory `опционально`, rule `Tooling §4.10`.
- **mem_ruflo→ruflo_queen**: type `документирует`, when `при работе с ruflo-интеграцией`, transfers `данные`, mandatory `рекомендуется`, rule `memory/project_ruflo_integration.md` (по образцу легаси `mem_archive→claude_md`).
- **3 конфликта**: type `конфликт`, transfers `контроль`/`coverage`, mandatory по сути конфликта, rule — см. §5.3.

## 6. Что НЕ трогаем (границы scope)

- **SECTION 4–8** карты (vis-init, легенда-панель, тулбар, resize-handle, highlighting). Подсветка (SECTION 8) авто-выводит `NEIGHBOURS` из рёбер и `CONFLICT_ENDPOINTS` из dashed-рёбер по цвету; фильтр `group:ruflo` авто-работает через `data-filter-key`. Изменения в SECTION 8 не нужны.
- **Радиальный layout 73 legacy-узлов** — координаты `pos()` без изменений.
- **iter4-бэклог из памяти** (`project_automation_map.md`): мёртвая переменная `highlightedNode`, foot-gun `state.selectedNode !== null`, rAF-throttle для `applyHighlight` — **вне scope** (не связано с ruflo); отдельная итерация при желании.
- **Прочий дрейф memory-узлов** (sprint1, audit-2026-05-14, full-audit-2026-05-12 и др.) — вне scope; добавляется только `mem_ruflo` как прямой артефакт перестройки.
- **Нормативка** (CLAUDE.md / Pravila / PSR_v1 / Tooling) — не трогаем: карта — doc-артефакт, не входит в priority chain; правки нормативки не требуются и не разрешены этой задачей.

## 7. Затрагиваемые файлы

| Файл | Действие |
|---|---|
| `docs/automation-graph.html` | Правка: +12 узлов, +22 ребра, +группа `ruflo`, +`CATEGORY_LABELS.ruflo`, +12 `NODE_DETAILS`, +~22 `EDGE_DETAILS`, +пункт `cat-legend` `group:ruflo`, рефреш 4 узлов-правил + §12-формулировок + конфликта #8. |
| `docs/automation-graph-ruflo.html` | **Удаление** (`git rm`) — форк-предпросмотр больше не нужен. |
| `docs/superpowers/specs/2026-05-15-automation-graph-iter4-ruflo-design.md` | Этот документ. |
| `docs/superpowers/plans/2026-05-15-automation-graph-iter4-ruflo.md` | План реализации (создаётся через writing-plans). |
| `memory/project_automation_map.md` | После завершения — освежить (iter4, ruflo-наслой, новые метрики 85/96/11). |
| `memory/project_ruflo_integration.md` | После завершения — поправить ссылку на удалённый форк `automation-graph-ruflo.html` (был «Map fork ... TO-BE визуализация»). |

## 8. Верификация

- **Визуальный smoke через Playwright MCP** (если MCP доступен) — открыть обновлённую карту локально (`python -m http.server`, т.к. Playwright отвергает `file://` — квирк #90), проверить: (а) 85 узлов рендерятся, ruflo-кластер виден в верхнем-левом углу; (б) клик по каждому ruflo-узлу открывает заполненную панель легенды (7 полей); (в) клик по ruflo-рёбрам открывает edge-легенду (5 полей, не «не задокументирован»); (г) фильтр `group:ruflo` в нижней легенде подсвечивает 11 ruflo-узлов; (д) 3 новых конфликта видны (dashed), фильтры 🔴/⚫/🟢 их подхватывают; (е) нет JS-ошибок в консоли; (ж) нет узлов-сирот от несуществующих id (проверка фикса `lh_pre_push`).
- **Заказчик проверяет карту визуально в Edge сам** перед production-use (методология iter1–iter3).
- **lychee** (pre-push) — карта не `.md`, ссылок в ней lychee не проверяет; релевантно только если правится `.md` (spec/plan/memory).
- **gitleaks** (pre-commit + pre-push) — стандартно.
- Карта — единственный HTML без сборки; Pest/Vitest/vue-tsc не затрагиваются (карта вне `app/`).

## 9. Риски

| # | Риск | Митигация |
|---|---|---|
| 1 | Перекрытие `ruflo_mcp` / `mem_ruflo` с легаси-узлами или ruflo-кластером | Координаты корректируются по visual smoke; кластер и так вне радиального layout. |
| 2 | Подсветка некорректно классифицирует новый 🔴-конфликт `ruflo_queen↔pravila` | SECTION 8 авто-выводит тип по `edge.color.color`; `CONFLICT` helper уже красит по типу — риск низкий, проверяется в smoke (п. «д»). |
| 3 | `ruflo_queen↔pravila` — пара from/to совпадает с обычным ребром? | Обычного ребра `ruflo_queen→pravila` нет среди 4 Queen→правила? Есть (`перенял sub-policy`). Дублирование пары from/to конфликт+обычное ребро — карта это уже умеет (iter2 §5, «diagnostic-priority strategy» в EDGE_DETAILS); ключ `edgeKey` один — в `EDGE_DETAILS` под `ruflo_queen->pravila` кладётся запись конфликта (приоритет диагностики). |
| 4 | Заказчик не вычитал spec | User Review Gate перед writing-plans. |

**Уточнение по риску 3:** ребро `ruflo_queen→pravila` существует в двух формах — обычное «перенял sub-policy» (§5.2) и конфликт «декларация ≠ реальность» (§5.3). `EDGE_DETAILS` индексируется по `edgeKey(from,to)` = `'ruflo_queen->pravila'` — один ключ. Согласно стратегии iter2 (3 такие пары уже есть среди легаси-конфликтов), под общий ключ кладётся запись с диагностическим приоритетом — то есть `EDGE_DETAILS['ruflo_queen->pravila']` описывает конфликт. План реализации фиксирует это явно.

## 10. Метрики после обновления (для memory)

| Метрика | Было (iter3) | Станет (iter4) |
|---|---|---|
| Узлы | 73 | 85 (+11 ruflo + 1 memory) |
| Рёбра | 74 | 96 (+22) |
| Конфликты | 8 (🔴2/⚫2/🟢4) | 11 (🔴3/⚫4/🟢4) |
| Группы | 9 | 10 (+`ruflo`) |
| Карты в `docs/` | 2 | 1 (форк удалён) |
