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

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** Влить ruflo-наслой в каноническую карту `docs/automation-graph.html` (iter4): +12 узлов, +22 ребра, 8→11 конфликтов, рефреш 4 узлов-правил и §12/sub-policy-формулировок под нормативку v2.0, удалить форк `automation-graph-ruflo.html`.

**Architecture:** Правка единственного self-contained HTML-файла (vis.js Network 9.1.9). Ruflo-наслой добавляется в 6 секций файла (`GROUPS`, `CATEGORY_LABELS`, `cat-legend` HTML, `NODES`, `EDGES`, `NODE_DETAILS`, `EDGE_DETAILS`). SECTION 4–8 (vis-init, легенда-панель, тулбар, resize, highlighting) НЕ трогаются — подсветка авто-выводит `NEIGHBOURS` из рёбер и `CONFLICT_ENDPOINTS` из dashed-рёбер, фильтр `group:ruflo` авто-работает через `data-filter-key`. 3 атомарных коммита: ruflo-наслой → рефреш v2.0 → удаление форка. Затем visual smoke и синхронизация memory.

**Tech Stack:** HTML5, vanilla JS, vis-network 9.1.9 (CDN, Solarized Dark). Без сборки, без unit-тестов — верификация через структурный grep-подсчёт + visual smoke (Playwright MCP).

**Спек:** `docs/superpowers/specs/2026-05-15-automation-graph-iter4-ruflo-design.md` (коммит `55696e5`).

---

## Структура файла

Единственный затрагиваемый файл реализации — `docs/automation-graph.html` (1609 строк). Затрагиваемые регионы:

| Регион | Что | Якорь для вставки |
|---|---|---|
| `cat-legend` (HTML) | +1 пункт фильтра ruflo | после `data-filter-key="group:memory"` строки, перед `conflict:RED` |
| SECTION 1 `NODES` | +12 узлов | перед закрывающей `];` массива `NODES` (после узла `mem_github`) |
| SECTION 2 `EDGES` | +22 ребра | перед закрывающей `];` массива `EDGES` (после `CONFLICT('hk_economy', ...)`) |
| SECTION 2 `CONFLICT` #8 | правка строки | строка `CONFLICT('hk_economy', 'superpowers', ...)` |
| SECTION 3 `CATEGORY_LABELS` | +1 ключ `ruflo` | объект `CATEGORY_LABELS` |
| SECTION 3 `NODE_DETAILS` | +12 записей + правка 7 записей | перед закрывающей `};` объекта `NODE_DETAILS` (после `mem_devindices`) |
| SECTION 3.5 `EDGE_DETAILS` | +21 запись + правка 2 записей | перед закрывающей `};` объекта `EDGE_DETAILS` (после `'hk_economy->superpowers'`) |
| SECTION 4 `GROUPS` | +1 группа `ruflo` | объект `GROUPS`, после `memory:` |

Прочие файлы: `docs/automation-graph-ruflo.html` (удаление), memory `project_automation_map.md` + `project_ruflo_integration.md` (синхронизация, вне git-репозитория).

---

## Task 1: Ruflo-наслой — группа, узлы, рёбра, легенды

**Files:**

- Modify: `docs/automation-graph.html` (секции `cat-legend`, `GROUPS`, `CATEGORY_LABELS`, `NODES`, `EDGES`, `NODE_DETAILS`, `EDGE_DETAILS`)

Один логический коммит — полный ruflo-наслой. После задачи карта когерентна: ruflo-узлы рендерятся, кликабельны, легенды заполнены.

- [ ] **Step 1: Добавить группу `ruflo` в `GROUPS`**

В объекте `const GROUPS = { ... }` (SECTION 4) после строки группы `memory:` добавить строку. Якорь — строка `memory:` (заканчивается на `font: { color: '#eee8d5', size: 10 } },`). После неё, перед `};`:

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

- [ ] **Step 2: Добавить ключ `ruflo` в `CATEGORY_LABELS`**

Объект `const CATEGORY_LABELS = { ... }` (начало SECTION 3). Заменить целиком:

```js
const CATEGORY_LABELS = {
  rules: 'Правило',  plugins: 'Плагин',    skills_sp: 'Скил Superpowers',
  skills_proj: 'Скил проекта', hooks: 'Хук .claude', agents: 'Агент',
  mcp: 'MCP-сервер', lefthook: 'Lefthook job', memory: 'Memory-файл',
  ruflo: 'ruflo (оркестратор)'
};
```

- [ ] **Step 3: Добавить пункт фильтра ruflo в `cat-legend`**

В блоке `<div id="cat-legend">` после строки `<div class="cat-item" data-filter-key="group:memory">...</div>` и перед строкой `data-filter-key="conflict:RED"` вставить:

```html
  <div class="cat-item" data-filter-key="group:ruflo"><div class="cat-dot" style="background:#ff8800"></div>🌊 ruflo (оркестратор)</div>
```

- [ ] **Step 4: Добавить 12 ruflo-узлов в `NODES`**

В массиве `const NODES = [ ... ]` (SECTION 1) перед закрывающей `];` (последний легаси-узел — `mem_github`) добавить:

```js

  // ── RUFLO ОРКЕСТРАТОР (11) — кластер вне радиального layout (верх-лево) ──
  { id: 'ruflo_queen',     label: 'ruflo Queen\n(Queen-led routing)', group: 'ruflo', size: 44, x: -1300, y: -700 },
  { id: 'ruflo_architect', label: 'Architect',                       group: 'ruflo', size: 24, x: -1150, y: -870 },
  { id: 'ruflo_coder',     label: 'Coder',                           group: 'ruflo', size: 24, x: -980,  y: -860 },
  { id: 'ruflo_security',  label: 'Security',                        group: 'ruflo', size: 24, x: -880,  y: -740 },
  { id: 'ruflo_rls',       label: 'RLS-reviewer',                    group: 'ruflo', size: 22, x: -880,  y: -580 },
  { id: 'ruflo_qa',        label: 'QA',                              group: 'ruflo', size: 22, x: -980,  y: -490 },
  { id: 'ruflo_tester',    label: 'Tester',                          group: 'ruflo', size: 22, x: -1150, y: -490 },
  { id: 'ruflo_reviewer',  label: 'Reviewer',                        group: 'ruflo', size: 22, x: -1300, y: -490 },
  { id: 'ruflo_memory',    label: 'Memory-keeper\n(HNSW + SONA)',     group: 'ruflo', size: 24, x: -1470, y: -580 },
  { id: 'ruflo_daemon',    label: 'Daemon-worker\n(PM2, 5 задач)',    group: 'ruflo', size: 22, x: -1470, y: -740 },
  { id: 'ruflo_mcp',       label: 'ruflo MCP\n(~210 инструментов)',   group: 'ruflo', size: 24, x: -1100, y: -340 },

  // ── MEMORY +1 (артефакт ruflo big-bang) ──
  { id: 'mem_ruflo',       label: 'memory:\nproject_ruflo_integration', group: 'memory', size: 14, x: -1700, y: -470 },
```

NB: ruflo-узлы без свойств `ring`/`...pos()` (они вне радиального layout) и без `fixed`/`subPolicy` (физика отключена глобально, `subPolicy` — мёртвое свойство из форка). Координаты — финальная подгонка по visual smoke в Task 4.

- [ ] **Step 5: Добавить 22 ruflo-ребра в `EDGES`**

В массиве `const EDGES = [ ... ]` (SECTION 2) перед закрывающей `];` (последняя строка массива — `CONFLICT('hk_economy', 'superpowers', ...)`) добавить:

```js

  // ══════════════════════════════════════════════════
  // RUFLO ОРКЕСТРАТОР — наслой ruflo big-bang (2026-05-15)
  // ══════════════════════════════════════════════════
  // Queen → 9 swarm-ролей
  E('ruflo_queen', 'ruflo_architect', 'подчиняет'),
  E('ruflo_queen', 'ruflo_coder',     'подчиняет'),
  E('ruflo_queen', 'ruflo_security',  'подчиняет'),
  E('ruflo_queen', 'ruflo_rls',       'подчиняет'),
  E('ruflo_queen', 'ruflo_qa',        'подчиняет'),
  E('ruflo_queen', 'ruflo_tester',    'подчиняет'),
  E('ruflo_queen', 'ruflo_reviewer',  'подчиняет'),
  E('ruflo_queen', 'ruflo_memory',    'подчиняет'),
  E('ruflo_queen', 'ruflo_daemon',    'подчиняет'),
  // Queen → MCP-сервер ruflo
  E('ruflo_queen', 'ruflo_mcp',       'экспонирует\n~210 инструментов'),
  // Queen → 4 узла-правила (нормативная декларация уровня −1)
  E('ruflo_queen', 'pravila',         'перенял\nsub-policy'),
  E('ruflo_queen', 'claude_md',       'перенял\nsub-policy'),
  E('ruflo_queen', 'psr_v1',          'перенял\nsub-policy'),
  E('ruflo_queen', 'tooling',         'перенял\nsub-policy'),
  // swarm → legacy execution-layer
  E('ruflo_coder',    'ag_pest',   'делегирует TDD'),
  E('ruflo_security', 'ag_rls',    'делегирует RLS'),
  E('ruflo_rls',      'sk_rls',    'делегирует\nRLS-скил'),
  E('ruflo_memory',   'mem_state', 'reindex HNSW'),
  // memory → ruflo
  E('mem_ruflo',      'ruflo_queen', 'документирует\nинтеграцию'),

  // 3 новых конфликта ruflo (3-color, iter2 §4)
  CONFLICT('ruflo_queen',  'pravila',   'Нормативка декларирует ruflo уровнем −1 (overlord) — фактически parallel subsystem', 'RED'),
  CONFLICT('ruflo_daemon', 'mem_state', 'Два хранилища памяти (.md и HNSW) рассинхронизированы; memory store не персистит', 'BLACK'),
  CONFLICT('ruflo_daemon', 'ag_pest',   'Daemon worker-jitter усиливает частоту Pest квирка 72', 'BLACK'),
```

NB: ребро `E('ruflo_queen', 'pravila', ...)` И `CONFLICT('ruflo_queen', 'pravila', ...)` — два ребра с одной парой from/to. Это допустимо (vis.js рисует параллельные рёбра); `EDGE_DETAILS` индексируется одним ключом `'ruflo_queen->pravila'` — под него кладётся запись конфликта (Step 7, diagnostic-priority — как 3 легаси-пары normal+conflict).

- [ ] **Step 6: Добавить 12 ruflo-записей в `NODE_DETAILS`**

В объекте `const NODE_DETAILS = { ... }` (SECTION 3) перед закрывающей `};` (последняя легаси-запись — `mem_devindices`) добавить:

```js

  // ── RUFLO ОРКЕСТРАТОР ────────────────────────────
  ruflo_queen: nd(
    'Оркестратор ruflo v3.7.0-alpha.38 — Queen-led routing: SONA нейро-классификация задач, swarm-топологии (Raft/Byzantine/Gossip), HNSW vector memory. По нормативке — entry-point уровня −1 для всех задач.',
    'По нормативке — первичная классификация любой задачи и маршрутизация в sub-policy paired-stack ИЛИ прямое исполнение через swarm.',
    'Фактически ruflo НЕ перехватывает Claude Code workflow — Claude работает напрямую (скилы/инструменты). Queen-led routing как entry-point — нормативная декларация, не runtime. Alpha-версия. LLM API-ключи отсутствуют → swarm-агенты idle, $-расход near-zero. Plugin discovery через IPFS нестабилен (Pinata/Cloudflare недоступны 15.05.2026, рабочий только ipfs.io).',
    [],
    [
      { name: '9 swarm-ролей', cond: 'hive-mind Queen + 9 worker-агентов (idle)' },
      { name: 'ruflo MCP', cond: 'экспонирует ~210 инструментов' },
      { name: '4 узла-правила', cond: 'нормативная декларация уровня −1 (без enforcement)' }
    ],
    [{ name: 'memory:project_ruflo_integration', cond: 'memory-файл документирует интеграцию' }],
    [{ name: 'Pravila', desc: 'Нормативка (Pravila §0/§12, CLAUDE.md §1, PSR_v1 R0) декларирует ruflo Queen-led routing уровнем −1 — overlord над всей иерархией. Фактически ruflo — параллельная подсистема: Claude работает напрямую, ruflo daemon/hive-mind крутятся рядом. Механизма enforcement нет — декларация ≠ runtime.', type: 'RED' }]
  ),
  ruflo_architect: nd(
    'Swarm-агент роли Architect в hive-mind ruflo — проектирование архитектуры.',
    'При routing-decision Queen на архитектурную задачу.',
    'idle — LLM API-ключи отсутствуют, реальная агентская работа (spawn --claude) не запускалась. Generic type. Alpha.',
    [{ name: 'ruflo Queen', cond: 'подчинён — Queen-led hierarchy' }],
    [],
    []
  ),
  ruflo_coder: nd(
    'Swarm-агент роли Coder в hive-mind ruflo — написание кода.',
    'При routing-decision Queen на задачу реализации кода.',
    'idle — LLM API-ключи отсутствуют, spawn --claude не запускался. Generic type. Alpha.',
    [{ name: 'ruflo Queen', cond: 'подчинён — Queen-led hierarchy' }],
    [],
    [{ name: 'агент pest-parallel-debugger', cond: 'делегирует TDD-задачи в legacy execution-layer' }]
  ),
  ruflo_security: nd(
    'Swarm-агент роли Security в hive-mind ruflo — аудит безопасности.',
    'При routing-decision Queen на задачу безопасности.',
    'idle — LLM API-ключи отсутствуют, spawn --claude не запускался. Generic type. Alpha.',
    [{ name: 'ruflo Queen', cond: 'подчинён — Queen-led hierarchy' }],
    [],
    [{ name: 'агент rls-reviewer', cond: 'делегирует RLS-задачи в legacy execution-layer' }]
  ),
  ruflo_rls: nd(
    'Swarm-агент роли RLS-reviewer в hive-mind ruflo — проверка RLS (защиты строк по тенанту).',
    'При routing-decision Queen на задачу RLS-аудита.',
    'idle — LLM API-ключи отсутствуют, spawn --claude не запускался. Generic type. Alpha.',
    [{ name: 'ruflo Queen', cond: 'подчинён — Queen-led hierarchy' }],
    [],
    [{ name: 'скил rls-check', cond: 'делегирует RLS-скил в legacy execution-layer' }]
  ),
  ruflo_qa: nd(
    'Swarm-агент роли QA в hive-mind ruflo — контроль качества.',
    'При routing-decision Queen на QA-задачу.',
    'idle — LLM API-ключи отсутствуют, spawn --claude не запускался. Generic type. Alpha.',
    [{ name: 'ruflo Queen', cond: 'подчинён — Queen-led hierarchy' }],
    [],
    []
  ),
  ruflo_tester: nd(
    'Swarm-агент роли Tester в hive-mind ruflo — прогон тестов.',
    'При routing-decision Queen на задачу тестирования.',
    'idle — LLM API-ключи отсутствуют, spawn --claude не запускался. Generic type. Alpha.',
    [{ name: 'ruflo Queen', cond: 'подчинён — Queen-led hierarchy' }],
    [],
    []
  ),
  ruflo_reviewer: nd(
    'Swarm-агент роли Reviewer в hive-mind ruflo — ревью кода.',
    'При routing-decision Queen на задачу ревью.',
    'idle — LLM API-ключи отсутствуют, spawn --claude не запускался. Generic type. Alpha.',
    [{ name: 'ruflo Queen', cond: 'подчинён — Queen-led hierarchy' }],
    [],
    []
  ),
  ruflo_memory: nd(
    'Swarm-агент роли Memory-keeper — HNSW vector index + SONA neural routing. Хранилище `.swarm/memory.db` (sql.js) + реальные embeddings Xenova/all-MiniLM-L6-v2 384-dim.',
    'При обращении к памяти ruflo — переиндексация memory-файлов в HNSW-базу.',
    '`ruflo memory store` CLI не персистит между запусками процесса (alpha-баг H7 — in-memory sql.js не флашится на диск).',
    [{ name: 'ruflo Queen', cond: 'подчинён — Queen-led hierarchy' }],
    [],
    [{ name: 'memory:project_state', cond: 'переиндексирует memory-файлы в HNSW' }]
  ),
  ruflo_daemon: nd(
    'Фоновый демон ruflo под PM2 (`ruflo-daemon`, 5 workers: map/audit/optimize/consolidate/testgaps). Reboot-survival через Windows Task Scheduler.',
    'Работает постоянно в фоне — 5 workers в local-fallback mode.',
    'Workers в local-fallback (file I/O по `.claude-flow/`, без платных LLM-вызовов). Worker-jitter усиливает частоту Pest --parallel квирка 72 — на baseline-регрессии нужно `pm2 stop ruflo-daemon`.',
    [{ name: 'ruflo Queen', cond: 'подчинён — Queen-led hierarchy' }],
    [],
    [],
    [
      { name: 'memory:project_state', desc: 'Два хранилища памяти — статичные memory/*.md и HNSW-база ruflo (.swarm/memory.db) — рассинхронизированы. `ruflo memory store` не персистит между запусками (alpha-баг H7). Дублирование без регламента синхронизации.', type: 'BLACK' },
      { name: 'агент pest-parallel-debugger', desc: 'Daemon worker-jitter усиливает частоту Pest --parallel квирка 72 (гонка в Redis). ruflo не трогает Redis :6379 — лишь timing-amplifier. На baseline-регрессии — `pm2 stop ruflo-daemon` (квирк #93).', type: 'BLACK' }
    ]
  ),
  ruflo_mcp: nd(
    'MCP-сервер ruflo — stdio mode, 7-й сервер в `.mcp.json`, экспонирует ~210 инструментов (agent/memory/swarm/hooks/neural и др.).',
    'Инструменты экспонированы постоянно — доступны Claude как MCP-tools.',
    'Claude НЕ обязан вызывать ruflo-инструменты — отсюда статус ruflo как parallel subsystem, а не overlord. Alpha-версия.',
    [{ name: 'ruflo Queen', cond: 'часть оркестратора ruflo' }],
    [],
    []
  ),
  mem_ruflo: nd(
    'Memory-файл `project_ruflo_integration` — история ruflo big-bang: Phase 1–7 + активация рантайма, alpha-баги, операционные ноты.',
    'При работе с ruflo — для контекста интеграции и известных alpha-багов.',
    'Снимок состояния на 15.05.2026. Описывает alpha-баги (memory-CLI H7, embeddings-fragility) — обновлять при изменении.',
    [],
    [],
    [{ name: 'ruflo Queen', cond: 'документирует ruflo-интеграцию' }]
  ),
```

- [ ] **Step 7: Добавить 21 ruflo-запись в `EDGE_DETAILS`**

В объекте `const EDGE_DETAILS = { ... }` (SECTION 3.5) перед закрывающей `};` (последняя легаси-запись — `'hk_economy->superpowers'`) добавить:

```js

  // ── RUFLO ОРКЕСТРАТОР (наслой ruflo big-bang 2026-05-15) ──
  'ruflo_queen->ruflo_architect':  { type: 'подчиняет',         when: 'hive-mind активен — Queen раздаёт задачи swarm-агентам',           transfers: 'контроль',              mandatory: 'опционально',           rule: 'Tooling §4.10 (orchestration layer)' },
  'ruflo_queen->ruflo_coder':      { type: 'подчиняет',         when: 'hive-mind активен — Queen раздаёт задачи swarm-агентам',           transfers: 'контроль',              mandatory: 'опционально',           rule: 'Tooling §4.10 (orchestration layer)' },
  'ruflo_queen->ruflo_security':   { type: 'подчиняет',         when: 'hive-mind активен — Queen раздаёт задачи swarm-агентам',           transfers: 'контроль',              mandatory: 'опционально',           rule: 'Tooling §4.10 (orchestration layer)' },
  'ruflo_queen->ruflo_rls':        { type: 'подчиняет',         when: 'hive-mind активен — Queen раздаёт задачи swarm-агентам',           transfers: 'контроль',              mandatory: 'опционально',           rule: 'Tooling §4.10 (orchestration layer)' },
  'ruflo_queen->ruflo_qa':         { type: 'подчиняет',         when: 'hive-mind активен — Queen раздаёт задачи swarm-агентам',           transfers: 'контроль',              mandatory: 'опционально',           rule: 'Tooling §4.10 (orchestration layer)' },
  'ruflo_queen->ruflo_tester':     { type: 'подчиняет',         when: 'hive-mind активен — Queen раздаёт задачи swarm-агентам',           transfers: 'контроль',              mandatory: 'опционально',           rule: 'Tooling §4.10 (orchestration layer)' },
  'ruflo_queen->ruflo_reviewer':   { type: 'подчиняет',         when: 'hive-mind активен — Queen раздаёт задачи swarm-агентам',           transfers: 'контроль',              mandatory: 'опционально',           rule: 'Tooling §4.10 (orchestration layer)' },
  'ruflo_queen->ruflo_memory':     { type: 'подчиняет',         when: 'hive-mind активен — Queen раздаёт задачи swarm-агентам',           transfers: 'контроль',              mandatory: 'опционально',           rule: 'Tooling §4.10 (orchestration layer)' },
  'ruflo_queen->ruflo_daemon':     { type: 'подчиняет',         when: 'hive-mind активен — Queen раздаёт задачи swarm-агентам',           transfers: 'контроль',              mandatory: 'опционально',           rule: 'Tooling §4.10 (orchestration layer)' },
  'ruflo_queen->ruflo_mcp':        { type: 'экспонирует',       when: 'MCP-сервер ruflo постоянно поднят (stdio, 7-й в .mcp.json)',       transfers: 'инструменты',           mandatory: 'опционально',           rule: 'Tooling §4.10' },
  'ruflo_queen->pravila':          { type: 'конфликт',          when: 'нормативка декларирует уровень −1, фактически parallel subsystem', transfers: 'контроль',              mandatory: 'декларативно',          rule: 'нет регламента enforcement (Pravila §0/§12, CLAUDE.md §1, PSR_v1 R0)' },
  'ruflo_queen->claude_md':        { type: 'перенял sub-policy', when: 'нормативная декларация уровня −1 (entry-point)',                  transfers: 'контроль (декларативно)', mandatory: 'декларативно — без enforcement', rule: 'CLAUDE.md §1 priority chain (уровень −1)' },
  'ruflo_queen->psr_v1':           { type: 'перенял sub-policy', when: 'нормативная декларация уровня −1',                                transfers: 'контроль (декларативно)', mandatory: 'декларативно — без enforcement', rule: 'PSR_v1 R0 (sub-policy delegation pattern)' },
  'ruflo_queen->tooling':          { type: 'перенял sub-policy', when: 'нормативная декларация уровня −1',                                transfers: 'контроль (декларативно)', mandatory: 'декларативно — без enforcement', rule: 'Tooling §4.10 (orchestration layer)' },
  'ruflo_coder->ag_pest':          { type: 'делегирует',        when: 'при routing-decision Queen (требует LLM API-ключи — сейчас idle)', transfers: 'триггер',               mandatory: 'опционально',           rule: 'Tooling §4.10' },
  'ruflo_security->ag_rls':        { type: 'делегирует',        when: 'при routing-decision Queen (требует LLM API-ключи — сейчас idle)', transfers: 'триггер',               mandatory: 'опционально',           rule: 'Tooling §4.10' },
  'ruflo_rls->sk_rls':             { type: 'делегирует',        when: 'при routing-decision Queen (требует LLM API-ключи — сейчас idle)', transfers: 'триггер',               mandatory: 'опционально',           rule: 'Tooling §4.10' },
  'ruflo_memory->mem_state':       { type: 'читает',            when: 'Memory-keeper переиндексирует memory-файлы в HNSW-базу',           transfers: 'данные',                mandatory: 'опционально',           rule: 'Tooling §4.10 (HNSW vector memory)' },
  'mem_ruflo->ruflo_queen':        { type: 'документирует',     when: 'memory-файл хранит историю ruflo-интеграции (Phase 1–7 + runtime)', transfers: 'данные',               mandatory: 'рекомендуется',         rule: 'memory/project_ruflo_integration.md' },
  'ruflo_daemon->mem_state':       { type: 'конфликт',          when: 'два хранилища памяти — статичные .md и HNSW-база ruflo',           transfers: 'coverage',              mandatory: 'опционально',           rule: 'нет регламента синхронизации (alpha-баг H7)' },
  'ruflo_daemon->ag_pest':         { type: 'конфликт',          when: 'daemon worker-jitter усиливает частоту Pest квирка 72',            transfers: 'coverage',              mandatory: 'опционально',           rule: 'memory feedback_environment квирк #93 (pm2 stop на baseline-регрессии)' },
```

- [ ] **Step 8: Структурная верификация**

Run:

```bash
cd "c:/моя/проекты/портал crm/Документация"
grep -c "^  { id: '" docs/automation-graph.html
grep -c "^  E('" docs/automation-graph.html
grep -c "^  CONFLICT('" docs/automation-graph.html
grep -c "^  ruflo_" docs/automation-graph.html
grep -c "'ruflo_queen->" docs/automation-graph.html
```

Expected: `{ id: '` → **85**; `E('` → **85**; `CONFLICT('` → **11**; `ruflo_` (NODE_DETAILS keys) → **10** (ruflo_queen + 9 swarm; `ruflo_mcp` ключ начинается так же — итого 11; если grep даёт 11, это ок — считает ruflo_mcp); `'ruflo_queen->` → **14** (9 swarm + mcp + 4 правила). Если числа не сходятся — найти пропущенную/лишнюю запись до коммита.

- [ ] **Step 9: Visual smoke — ruflo-узлы рендерятся и кликабельны**

Если Playwright MCP доступен:

```bash
cd "c:/моя/проекты/портал crm/Документация/docs" && python -m http.server 8765
```

(квирк #90 — Playwright отвергает `file://`). Открыть `http://localhost:8765/automation-graph.html`, проверить: (а) граф рендерится, ruflo-кластер виден в верхнем-левом углу оранжевым; (б) клик по `ruflo_queen` — панель легенды заполнена 7 секциями, конфликт 🔴 виден; (в) клик по ruflo-ребру — edge-легенда 5 полей (не «Регламент не задокументирован»); (г) клик «🌊 ruflo (оркестратор)» в нижней легенде подсвечивает 11 ruflo-узлов; (д) консоль браузера — 0 ошибок. Остановить сервер. Если Playwright MCP недоступен — пометить smoke как отложенный к Task 4.

- [ ] **Step 10: Commit A**

```bash
cd "c:/моя/проекты/портал crm/Документация"
git add docs/automation-graph.html
git commit -m "feat(graph): ruflo orchestrator overlay — +12 nodes / +22 edges / 3 conflicts (iter4)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"
```

---

## Task 2: Рефреш под нормативку v2.0 — узлы-правила, §12/sub-policy, конфликт #8

**Files:**

- Modify: `docs/automation-graph.html` (`NODES` метки 4 правил, `NODE_DETAILS` записи `pravila`/`claude_md`/`psr_v1`/`tooling`/`superpowers`/`hk_economy`/`mem_sp`, `EDGES` конфликт #8, `EDGE_DETAILS` записи `pravila->superpowers`/`hk_economy->superpowers`)

- [ ] **Step 1: Обновить метки 4 узлов-правил в `NODES`**

В массиве `NODES` заменить (4 точечные правки):

- `label: 'Pravila v1.13'` → `label: 'Pravila v1.14'`
- `label: 'CLAUDE.md v1.92'` → `label: 'CLAUDE.md v2.0'`
- `label: 'PSR_v1 v2.1'` → `label: 'PSR_v1 v3.0'`
- `label: 'Tooling v1.17'` → `label: 'Tooling v2.0'`

- [ ] **Step 2: Переписать `NODE_DETAILS.pravila`**

Заменить запись `pravila: nd( ... ),` целиком на:

```js
  pravila: nd(
    'Главный свод правил работы Клода — кто чем командует, что запрещено, какие обязательные действия.',
    'Действует всегда — Клод читает его при старте каждой сессии.',
    '§12 Superpowers стал sub-policy под ruflo Queen-led routing (уровень −1); в уровнях 0–6 цепочки приоритетов §12 остаётся hard-rule (скил инвокируется первым), economy-режим §12 не отменяет. Расходимость с другими документами — нарушение §7.',
    [{ name: 'ruflo Queen', cond: 'уровень −1 по нормативке — ruflo Queen-led routing над Pravila' }],
    [
      { name: 'CLAUDE.md', cond: 'подчинён, уровень 2a в цепочке приоритетов' },
      { name: 'PSR_v1', cond: 'подчинён, уровень 3 в цепочке приоритетов' },
      { name: 'плагин Superpowers', cond: '§12 обязывает запускать скил первым' },
      { name: 'Все компоненты', cond: 'через цепочку приоритетов §1' }
    ],
    [{ name: 'CLAUDE.md', cond: 'оба читаются при старте сессии' }],
    [{ name: 'ruflo Queen', desc: 'Нормативка декларирует ruflo Queen-led routing уровнем −1 над Pravila — overlord. Фактически ruflo — параллельная подсистема, Claude работает напрямую; механизма enforcement нет (декларация ≠ runtime).', type: 'RED' }]
  ),
```

- [ ] **Step 3: Переписать `NODE_DETAILS.claude_md`**

Заменить запись `claude_md: nd( ... ),` целиком на:

```js
  claude_md: nd(
    'Оперативная карта проекта — технологии, команды, фазы, 9-уровневая цепочка приоритетов (§1, уровень −1 — ruflo) и §3.5 orchestration layer, ссылки на документы.',
    'Читается при старте каждой сессии; обновляется при новом инструменте или новой фазе.',
    'Править можно только через скил `/claude-md-management:claude-md-improver` или `:revise-claude-md` (правило §5 п.10). Прямые Edit/Write блокируются хуком предупреждения.',
    [{ name: 'Pravila', cond: 'всегда подчинён (уровень 2a)' }],
    [
      { name: 'Tooling v2.0', cond: 'ссылается как на реестр инструментов' },
      { name: 'плагин claude-md-management', cond: 'правило §5 п.10 — единственный канал правок' }
    ],
    [
      { name: 'Pravila', cond: 'оба читаются при старте сессии' },
      { name: 'Tooling', cond: 'оба — оперативные карты уровня 2' }
    ],
    [{ name: 'PSR_v1', desc: 'Правило §5 п.10 запрещает прямые правки, но PSR_v1 это явно не повторяет — есть риск Edit без скила', type: 'GREEN' }]
  ),
```

- [ ] **Step 4: Переписать `NODE_DETAILS.psr_v1`**

Заменить запись `psr_v1: nd( ... ),` целиком на:

```js
  psr_v1: nd(
    'Правила совместной работы плагинов — кто с кем работает, какая процедура обязательна. R0 stack-gate переформулирован в sub-policy paired-stack delegation pattern под ruflo Queen-led routing.',
    'При выборе UI-инструмента (плагин Frontend Design против плагина UI UX Pro Max против MCP-сервера 21st Magic), при координации парных плагинов, при включении дополнительного MCP (внешнего сервиса-инструмента Claude) вне основных фаз.',
    'Обязательное правило R14.5: плагины UI UX Pro Max, 21st Magic, Frontend Design — нельзя использовать одновременно. Обязательное правило R6.0 (фильтр стека) и R6.1 (палитра Forest) — нужно соблюдать при UI-выводе плагинов.',
    [{ name: 'Pravila', cond: 'подчинён, уровень 3 в цепочке' }],
    [
      { name: 'плагин Superpowers + плагин Frontend Design', cond: 'координирует как пару плагинов' },
      { name: 'плагин UI UX Pro Max', cond: 'R14.3: включается только через процедуру' },
      { name: 'MCP-сервер 21st Magic', cond: 'R14.4: включается только через процедуру' }
    ],
    [{ name: 'CLAUDE.md', cond: 'обе — оперативные карты, правятся согласованно' }],
    [{ name: 'CLAUDE.md', desc: 'CLAUDE.md §5 п.10 требует править только через скил claude-md-management, а PSR_v1 это ограничение не повторяет — риск прямых Edit', type: 'GREEN' }]
  ),
```

- [ ] **Step 5: Переписать `NODE_DETAILS.tooling`**

Заменить запись `tooling: nd( ... ),` целиком на:

```js
  tooling: nd(
    'Реестр 55 позиций — 35 формализованных инструментов + 20 ruflo-плагинов; +§4.10 Orchestration layer. Когда что использовать, команды установки, конфликты.',
    'При выборе инструмента для фазы (нулевая документация / первая backend / вторая frontend / третья перед запуском в боевую среду), при добавлении нового инструмента, при обновлении версий.',
    'При прямом конфликте с CLAUDE.md побеждает CLAUDE.md (оперативная карта уровня 2a). Любая правка требует синхронизации с CLAUDE.md §3.',
    [
      { name: 'Pravila', cond: 'уровень 2b — оперативная карта рядом с CLAUDE.md' },
      { name: 'CLAUDE.md', cond: 'при прямом конфликте побеждает CLAUDE.md' }
    ],
    [],
    [{ name: 'CLAUDE.md', cond: 'обе — оперативные карты, правятся синхронно' }]
  ),
```

- [ ] **Step 6: Обновить `NODE_DETAILS.superpowers` — `limits` и `conflicts`**

В записи `superpowers: nd( ... )` заменить 3-й аргумент (`limits`):

Было: `'Обязательное правило §12: единственная отмена — явная просьба заказчика «не используй superpowers сейчас» на текущее действие. Раздел §9 «Отступления» к §12 не применяется.'`

Стало: `'§12 Superpowers — sub-policy под ruflo Queen-led routing (уровень −1); в уровнях 0–6 остаётся hard-rule (скил инвокируется первым). Единственная отмена — явная просьба заказчика «не используй superpowers сейчас» на текущее действие; §9 «Отступления» к §12 не применяется; economy-режим §12 не отменяет.'`

И в той же записи заменить `desc` единственного элемента 7-го аргумента (`conflicts`):

Было: `'Режим экономии 100% теоретически может «сэкономить» запуск скила и нарушить обязательное правило §12 (§12 нельзя отменить)'`

Стало: `'Режим экономии 100% теоретически может «сэкономить» запуск скила — §12 (sub-policy под ruflo Queen-led routing) economy-режим не отменяет.'`

- [ ] **Step 7: Обновить `NODE_DETAILS.hk_economy` — `limits` и `conflicts`**

В записи `hk_economy: nd( ... )` заменить 3-й аргумент (`limits`):

Было: `'Правило §12 **НЕ** отменяется этим режимом ни на каком уровне. Действует только на текущую задачу — следующий промпт разбирается заново.'`

Стало: `'§12 Superpowers — sub-policy под ruflo Queen-led routing, но economy-режим §12 НЕ отменяет ни на каком уровне. Действует только на текущую задачу — следующий промпт разбирается заново.'`

И заменить `desc` единственного элемента 7-го аргумента (`conflicts`):

Было: `'Экономия=100% теоретически может «сэкономить» вызов скила, нарушая обязательное правило (см. §12) — §12 неотменяем, экономия его не отменяет'`

Стало: `'Экономия=100% теоретически может «сэкономить» вызов скила — §12 (sub-policy под ruflo Queen-led routing) economy-режим не отменяет ни на каком уровне (Pravila §12.4).'`

- [ ] **Step 8: Обновить `NODE_DETAILS.mem_sp` — `desc`**

В записи `mem_sp: nd( ... )` заменить 1-й аргумент (`desc`):

Было: `'Обязательное правило §12 + архитектура хука economy из 6 компонентов — дисциплина вызова скилов.'`

Стало: `'Правило §12 (sub-policy под ruflo Queen-led routing) + архитектура хука economy из 6 компонентов — дисциплина вызова скилов.'`

- [ ] **Step 9: Обновить конфликт #8 в `EDGES`**

Заменить строку:

Было: `CONFLICT('hk_economy',     'superpowers',     'Pravila §12.4: §12 неотменяем',                 'GREEN'),`

Стало: `CONFLICT('hk_economy',     'superpowers',     '§12 — sub-policy под ruflo; economy-режим §12 не отменяет (Pravila §12.4)', 'GREEN'),`

- [ ] **Step 10: Обновить 2 записи в `EDGE_DETAILS`**

Заменить запись `'pravila->superpowers'`:

Было: `'pravila->superpowers':          { type: 'подчиняет',     when: 'задача попадает под карту §12.2 (14 типов)',                               transfers: 'контроль',     mandatory: 'hard-block',    rule: 'Pravila §12 (hard rule, §9 не применяется)' },`

Стало: `'pravila->superpowers':          { type: 'подчиняет',     when: 'задача попадает под карту §12.2 (14 типов)',                               transfers: 'контроль',     mandatory: 'hard-block',    rule: 'Pravila §12 (sub-policy под ruflo Queen-led routing; в уровнях 0–6 — hard rule, §9 не применяется)' },`

Заменить запись `'hk_economy->superpowers'`:

Было: `'hk_economy->superpowers':       { type: 'конфликт',      when: 'economy hook блокирует skill в обход Pravila §12',                         transfers: 'контроль',     mandatory: 'hard-block',    rule: 'Pravila §12.4 (только явный «не используй»)' },`

Стало: `'hk_economy->superpowers':       { type: 'конфликт',      when: 'economy-режим теоретически может «сэкономить» вызов скила — §12 (sub-policy под ruflo) economy не отменяет', transfers: 'контроль',     mandatory: 'hard-block',    rule: 'Pravila §12.4 (только явный «не используй»)' },`

- [ ] **Step 11: Верификация — устаревшие формулировки вычищены**

Run:

```bash
cd "c:/моя/проекты/портал crm/Документация"
grep -n "неотменяем" docs/automation-graph.html
grep -n "v1.13\|v1.92\|v2.1\|v1.17\|35 инструмент" docs/automation-graph.html
```

Expected: оба `grep` — **0 совпадений** (пустой вывод). Если что-то найдено — не закоммиченный остаток, исправить. `grep -c "^  ruflo_" docs/automation-graph.html` — без изменений (Task 2 не трогает ruflo-записи).

- [ ] **Step 12: Visual smoke — узлы-правила**

Если Playwright MCP доступен — открыть карту (как в Task 1 Step 9), кликнуть `pravila` / `claude_md` / `psr_v1` / `tooling`: метки показывают v1.14 / v2.0 / v3.0 / v2.0; легенда `pravila` показывает reportsTo «ruflo Queen» + конфликт 🔴; 0 ошибок в консоли. Иначе — отложить к Task 4.

- [ ] **Step 13: Commit B**

```bash
cd "c:/моя/проекты/портал crm/Документация"
git add docs/automation-graph.html
git commit -m "docs(graph): refresh rule nodes + §12/sub-policy to v2.0 normative (iter4)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"
```

---

## Task 3: Удаление форка

**Files:**

- Delete: `docs/automation-graph-ruflo.html`

- [ ] **Step 1: Удалить форк-файл**

```bash
cd "c:/моя/проекты/портал crm/Документация"
git rm docs/automation-graph-ruflo.html
```

Expected: `rm 'docs/automation-graph-ruflo.html'`.

- [ ] **Step 2: Подтвердить, что на форк нет ссылок в репозитории**

```bash
cd "c:/моя/проекты/портал crm/Документация"
grep -rn "automation-graph-ruflo" --include=*.md --include=*.html . || echo "ссылок нет"
```

Expected: `ссылок нет` ИЛИ только совпадения внутри `docs/superpowers/specs/2026-05-15-ruflo-integration-design.md` и `docs/superpowers/plans/2026-05-15-ruflo-big-bang-integration.md` (исторические упоминания форка в закрытых spec/plan — править НЕ нужно, это исторические артефакты). Если ссылка найдена в актуальной нормативке или активном `.md` — отметить для отдельной правки, не блокировать коммит.

- [ ] **Step 3: Commit C**

```bash
cd "c:/моя/проекты/портал crm/Документация"
git commit -m "chore(graph): remove automation-graph-ruflo.html fork — merged into main map (iter4)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"
```

---

## Task 4: Комплексный visual smoke + подгонка координат

**Files:**

- Modify (при необходимости): `docs/automation-graph.html` (только координаты `x`/`y` ruflo-узлов при перекрытии)

- [ ] **Step 1: Запустить локальный сервер**

```bash
cd "c:/моя/проекты/портал crm/Документация/docs" && python -m http.server 8765
```

(квирк #90 — Playwright отвергает `file://`; нужен HTTP-сервер.)

- [ ] **Step 2: Visual smoke через Playwright MCP**

Открыть `http://localhost:8765/automation-graph.html`. Проверить по спеку §8:

- (а) 85 узлов рендерятся; ruflo-кластер (11 оранжевых) виден в верхнем-левом углу, без перекрытий с легаси-узлами и между собой; `mem_ruflo` (серый) рядом с кластером;
- (б) клик по каждому из 11 ruflo-узлов + `mem_ruflo` — панель легенды заполнена (7 секций), без пустых панелей;
- (в) клик по ruflo-рёбрам — edge-легенда показывает 5 полей (не «Регламент не задокументирован»);
- (г) фильтр `🌊 ruflo (оркестратор)` в нижней легенде подсвечивает 11 ruflo-узлов; фильтры 🔴/⚫/🟢 подхватывают 3 новых конфликта;
- (д) клик по 4 узлам-правилам — метки v1.14/v2.0/v3.0/v2.0, легенды освежены;
- (е) консоль браузера — 0 ошибок (квирк-проверка: нет узлов-сирот от несуществующих id);
- (ж) кнопки тулбара (Зафиксировать/Расшевелить/Сбросить вид/Снять выделение) и поиск работают.

Если Playwright MCP недоступен — выполнить структурные grep-проверки (Task 1 Step 8 + Task 2 Step 11) и передать визуальную проверку заказчику (Edit в Edge). При клике по узким ruflo-рёбрам Playwright `browser_click` может быть flaky (квирк #91) — workaround `browser_evaluate('el.click()')`.

- [ ] **Step 3: Подгонка координат при перекрытии**

Если smoke выявил перекрытие `ruflo_mcp` / `mem_ruflo` / swarm-узлов — скорректировать `x`/`y` соответствующих узлов в `NODES`. Остановить сервер (Ctrl+C в фоновом процессе).

- [ ] **Step 4: Commit D (только если координаты менялись)**

```bash
cd "c:/моя/проекты/портал crm/Документация"
git add docs/automation-graph.html
git commit -m "fix(graph): tune ruflo node coordinates after visual smoke (iter4)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"
```

Если координаты не менялись — шаг пропустить.

---

## Task 5: Синхронизация memory

**Files:**

- Modify: `memory/project_automation_map.md` (вне git-репозитория — путь `C:\Users\Administrator\.claude\projects\c---------------------crm-------------\memory\`)
- Modify: `memory/project_ruflo_integration.md`

Memory-файлы вне git-репозитория проекта — правки через Edit, без коммита.

- [ ] **Step 1: Обновить `project_automation_map.md`**

Re-Read файл. Обновить секцию «Текущее состояние»: iter3 → **iter4**; метрики 73 узла / 74 ребра / 8 конфликтов → **85 узлов / 96 рёбер / 11 конфликтов (🔴3/⚫4/🟢4)**; 9 групп → **10 (+ruflo)**; добавить ruflo-кластер в «Структуру узлов» (Queen + 9 swarm + ruflo_mcp; +mem_ruflo в memory-группе); добавить ссылки на spec/plan iter4 (`docs/superpowers/specs/2026-05-15-automation-graph-iter4-ruflo-design.md`, `docs/superpowers/plans/2026-05-15-automation-graph-iter4-ruflo.md`) и коммиты iter4; убрать упоминание форка `automation-graph-ruflo.html` как существующего файла.

- [ ] **Step 2: Обновить `project_ruflo_integration.md`**

Re-Read файл. В секции «Что сделано в session» / «Spec/plan documents» — строку «Map fork: `docs/automation-graph-ruflo.html` commit `796d814` — TO-BE визуализация» отметить как **слитую в каноническую `docs/automation-graph.html` (iter4, 2026-05-15) и удалённую**; форк больше не существует.

---

## Self-Review (выполнено при написании плана)

**Spec coverage:** §5.1 узлы → Task 1 Step 4; §5.2 рёбра → Task 1 Step 5; §5.3 конфликты (3 новых) → Task 1 Step 5, конфликт #8 → Task 2 Step 9; §5.4 узлы-правила → Task 2 Steps 1–5; §5.5 §12/sub-policy → Task 2 Steps 6–10; §5.6 ruflo NODE_DETAILS → Task 1 Step 6; §5.7 ruflo EDGE_DETAILS → Task 1 Step 7; группа+CATEGORY_LABELS+cat-legend → Task 1 Steps 1–3; §6 границы scope — SECTION 4–8 не трогаются (отражено в Architecture); §7 файлы → Task 3 (удаление форка) + Task 5 (memory); §8 верификация → Task 4; §10 метрики → Task 5 Step 1. Покрытие полное.

**Placeholder scan:** заглушек нет — весь JS-код приведён литералом, все Edit-правки даны парами «Было/Стало».

**Type consistency:** `nd(desc, when, limits, reportsTo, manages, together, conflicts)` — 7-арг сигнатура; ruflo-узлы без конфликтов вызываются с 6 арг (`conflicts` опционален — `nd` подставляет `[]`), `ruflo_queen`/`ruflo_daemon` — с 7 арг. `E(from,to,label)` и `CONFLICT(from,to,label,type)` — сигнатуры из SECTION 2. `EDGE_DETAILS` ключи `'from->to'` совпадают с `edgeKey()`. Узловые id (`ruflo_queen`, `ruflo_*`, `ruflo_mcp`, `mem_ruflo`) консистентны между `NODES`, `EDGES`, `NODE_DETAILS`, `EDGE_DETAILS`.

**Коллизия ключа `ruflo_queen->pravila`:** ребро существует дважды (`E` «перенял sub-policy» + `CONFLICT`); `EDGE_DETAILS['ruflo_queen->pravila']` — одна запись типа «конфликт» (diagnostic-priority, как 3 легаси-пары normal+conflict). Учтено в Task 1 Step 5 NB + Step 7.
