From 9d0298c6aa745d76e86e1ca9bd6b7cdbfa03e704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Thu, 14 May 2026 12:59:25 +0300 Subject: [PATCH] =?UTF-8?q?feat(graph):=203-color=20conflicts=20data=20(CO?= =?UTF-8?q?NFLICT=5FTYPES=20+=202=20new=20=E2=9A=AB=20edges=20+=20reclassi?= =?UTF-8?q?fy=206)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CONFLICT_TYPES enum (RED/BLACK/GREEN с color/bg/emoji/label/rank), CONFLICT() helper расширен опциональным `type` (default RED). 6 существующих рёбер реклассифицированы: 2 🔴 (sk_rls↔ag_rls, hookify↔hk_pre_claude), 4 🟢 (psr_v1↔claude_md, upm↔fd, 21st↔fd, economy↔superpowers). 2 новых ⚫ ребра: mcp_pw↔sk_parallel (browser-in-use, квирк #2), ag_pest↔mcp_redis (Redis race в Pest --parallel, квирк 72). NODE_DETAILS conflicts items получили field `type` для всех 12 existing + 4 new items. Iter2 spec §4.1, §4.2, §4.4. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/automation-graph.html | 68 ++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/docs/automation-graph.html b/docs/automation-graph.html index c8d85b23..60430f57 100644 --- a/docs/automation-graph.html +++ b/docs/automation-graph.html @@ -213,6 +213,11 @@ const NODES = [ // ════════════════════════════════════════════════════ // SECTION 2: EDGES // ════════════════════════════════════════════════════ +const CONFLICT_TYPES = { + RED: { color: '#ff5f57', bg: '#2d0000', emoji: '🔴', label: 'Не закрыт правилом', rank: 1 }, + BLACK: { color: '#888888', bg: '#1a1a1a', emoji: '⚫', label: 'Возник на практике', rank: 2 }, + GREEN: { color: '#859900', bg: '#0e1a00', emoji: '🟢', label: 'Закрыт правилом', rank: 3 }, +}; const E = (from, to, label) => ({ from, to, title: label, @@ -220,15 +225,15 @@ const E = (from, to, label) => ({ arrows: { to: { enabled: true, scaleFactor: 0.6 } }, smooth: { type: 'continuous', roundness: 0.5 } }); -const CONFLICT = (from, to, label) => ({ +const CONFLICT = (from, to, label, type = 'RED') => ({ from, to, title: label, - label: '⚡', + label: CONFLICT_TYPES[type].emoji, dashes: true, width: 2, - color: { color: '#ff5f57', highlight: '#ff8880', hover: '#ff8880' }, + color: { color: CONFLICT_TYPES[type].color, highlight: '#ff8880', hover: '#ff8880' }, arrows: { to: { enabled: true, scaleFactor: 0.7 }, from: { enabled: true, scaleFactor: 0.7 } }, - font: { color: '#ff5f57', size: 14, align: 'middle', strokeWidth: 3, strokeColor: '#1e1e2e' }, + font: { color: CONFLICT_TYPES[type].color, size: 14, align: 'middle', strokeWidth: 3, strokeColor: '#1e1e2e' }, smooth: { type: 'curvedCW', roundness: 0.35 } }); @@ -326,14 +331,17 @@ const EDGES = [ E('mcp_boost', 'ag_rls', 'схема БД\nдля RLS-review'), // ══════════════════════════════════════════════════ - // КОНФЛИКТЫ (красные пунктирные рёбра) + // КОНФЛИКТЫ — 3-color classification (iter2 §4) + // 🔴 не закрыт правилом / ⚫ возник на практике / 🟢 закрыт правилом // ══════════════════════════════════════════════════ - CONFLICT('psr_v1', 'claude_md', '⚡ T2.2'), - CONFLICT('upm', 'fd_plugin', '⚡ R14.5'), - CONFLICT('mcp_21st', 'fd_plugin', '⚡ R14.5'), - CONFLICT('sk_rls', 'ag_rls', '⚡ перекрытие RLS'), - CONFLICT('hookify_plugin','hk_pre_claude', '⚡ может затенить'), - CONFLICT('hk_economy', 'superpowers', '⚡ §12 vs Economy'), + CONFLICT('sk_rls', 'ag_rls', 'RLS compliance: оба покрывают, нет регламента', 'RED'), + CONFLICT('hookify_plugin', 'hk_pre_claude', 'hookify может перезаписать существующий хук', 'RED'), + CONFLICT('mcp_pw', 'sk_parallel', 'Browser is already in use (квирк #2)', 'BLACK'), + CONFLICT('ag_pest', 'mcp_redis', 'Redis race в Pest --parallel subdir-only (квирк 72)', 'BLACK'), + CONFLICT('psr_v1', 'claude_md', 'Закрыто §5п.10 CLAUDE.md + хук CLAUDE.md-warn', 'GREEN'), + CONFLICT('upm', 'fd_plugin', 'PSR_v1 R14.5: не параллельно', 'GREEN'), + CONFLICT('mcp_21st', 'fd_plugin', 'PSR_v1 R14.5: не параллельно', 'GREEN'), + CONFLICT('hk_economy', 'superpowers', 'Pravila §12.4: §12 неотменяем', 'GREEN'), ]; // ════════════════════════════════════════════════════ @@ -390,7 +398,7 @@ const NODE_DETAILS = { { name: 'Pravila', cond: 'оба читаются при старте сессии' }, { name: 'Tooling', cond: 'оба — оперативные карты уровня 2' } ], - [{ name: 'PSR_v1', desc: 'Правило §5 п.10 запрещает прямые правки, но PSR_v1 это явно не повторяет — есть риск Edit без скила' }] + [{ name: 'PSR_v1', desc: 'Правило §5 п.10 запрещает прямые правки, но PSR_v1 это явно не повторяет — есть риск Edit без скила', type: 'GREEN' }] ), psr_v1: nd( 'Правила совместной работы плагинов — кто с кем работает, какая процедура обязательна.', @@ -403,7 +411,7 @@ const NODE_DETAILS = { { name: '21st Magic MCP', cond: 'R14.4: включается только через процедуру' } ], [{ name: 'CLAUDE.md', cond: 'обе — оперативные карты, правятся согласованно' }], - [{ name: 'CLAUDE.md', desc: 'CLAUDE.md §5 п.10 требует править только через скил claude-md-mgmt, а PSR_v1 это ограничение не повторяет — риск прямых Edit' }] + [{ name: 'CLAUDE.md', desc: 'CLAUDE.md §5 п.10 требует править только через скил claude-md-mgmt, а PSR_v1 это ограничение не повторяет — риск прямых Edit', type: 'GREEN' }] ), tooling: nd( 'Реестр 35 инструментов — когда что использовать, команды установки, конфликты.', @@ -428,7 +436,7 @@ const NODE_DETAILS = { ], [{ name: 'Все 14 Superpowers-скилов', cond: 'содержит' }], [{ name: 'Frontend Design', cond: 'пара — работают вместе при UI-задачах' }], - [{ name: 'economy-mode хук', desc: 'Режим экономии 100% теоретически может «сэкономить» запуск скила и нарушить обязательное правило §12 (§12 нельзя отменить)' }] + [{ name: 'economy-mode хук', desc: 'Режим экономии 100% теоретически может «сэкономить» запуск скила и нарушить обязательное правило §12 (§12 нельзя отменить)', type: 'GREEN' }] ), fd_plugin: nd( 'Плагин знаний о UI — Vue, Vuetify, доступность, паттерны компонентов для Лидерры.', @@ -438,8 +446,8 @@ const NODE_DETAILS = { [], [{ name: 'Superpowers', cond: 'пара — FD даёт UI-знания, Superpowers даёт процесс' }], [ - { name: 'UI UX Pro Max', desc: 'Правило PSR_v1 R14.5: нельзя одновременно — оба включены в настройках, но должны чередоваться' }, - { name: '21st Magic MCP', desc: 'Правило PSR_v1 R14.5: нельзя одновременно с FD — оба потенциально доступны' } + { name: 'UI UX Pro Max', desc: 'Правило PSR_v1 R14.5: нельзя одновременно — оба включены в настройках, но должны чередоваться', type: 'GREEN' }, + { name: '21st Magic MCP', desc: 'Правило PSR_v1 R14.5: нельзя одновременно с FD — оба потенциально доступны', type: 'GREEN' } ] ), upm: nd( @@ -449,7 +457,7 @@ const NODE_DETAILS = { [{ name: 'PSR_v1', cond: 'R14.3: включается только через процедуру, не сам по себе' }], [], [], - [{ name: 'Frontend Design', desc: 'Правило PSR_v1 R14.5: нельзя одновременно — UPM как материал, FD как решатель; риск смешать роли' }] + [{ name: 'Frontend Design', desc: 'Правило PSR_v1 R14.5: нельзя одновременно — UPM как материал, FD как решатель; риск смешать роли', type: 'GREEN' }] ), claude_md_mgmt: nd( 'Единственный разрешённый способ править CLAUDE.md — через скил claude-md-improver или revise-claude-md.', @@ -467,8 +475,8 @@ const NODE_DETAILS = { [{ name: 'hookify:conversation-analyzer агент', cond: 'запускает анализ разговоров' }], [{ name: 'hookify:conversation-analyzer', cond: 'плагин и агент работают в паре' }], [ - { name: 'PreToolUse:CLAUDE.md-warn', desc: 'hookify создаёт новые PreToolUse-хуки на лету — может перезаписать или конкурировать с этим хуком' }, - { name: 'economy-mode хук', desc: 'новые хуки от hookify могут конфликтовать с логикой парсера режима экономии' } + { name: 'PreToolUse:CLAUDE.md-warn', desc: 'hookify создаёт новые PreToolUse-хуки на лету — может перезаписать или конкурировать с этим хуком', type: 'RED' }, + { name: 'economy-mode хук', desc: 'новые хуки от hookify могут конфликтовать с логикой парсера режима экономии', type: 'BLACK' } ] ), @@ -527,7 +535,8 @@ const NODE_DETAILS = { 'Изоляция через worktree обязательна — никакого «работаю в одной директории на 3 ветках сразу». Иначе риск конфликта файлов и веток.', [{ name: 'Superpowers', cond: 'содержит' }], [], - [{ name: 'worktree скил', cond: 'parallel-work использует worktree для изоляции' }] + [{ name: 'worktree скил', cond: 'parallel-work использует worktree для изоляции' }], + [{ name: 'MCP: playwright', desc: 'Browser is already in use при одновременном запуске нескольких сессий через worktrees', type: 'BLACK' }] ), sk_worktree: nd( 'Создаёт изолированную копию репозитория (worktree) для рискованной или параллельной работы.', @@ -598,7 +607,7 @@ const NODE_DETAILS = { [{ name: 'Tooling §3.2', cond: 'использует squawk (#15) и команды grep' }], [], [{ name: 'MCP: laravel-boost', cond: 'SQL запросы к schema.sql для проверки' }], - [{ name: 'rls-reviewer агент', desc: 'оба проверяют соответствие политик RLS — скил для ручной проверки таблицы, агент для разбора PR/diff; нет чёткой границы когда какой' }] + [{ name: 'rls-reviewer агент', desc: 'оба проверяют соответствие политик RLS — скил для ручной проверки таблицы, агент для разбора PR/diff; нет чёткой границы когда какой', type: 'RED' }] ), sk_qitem: nd( 'Добавляет новый открытый вопрос в реестр Открытые_вопросы_v8_3.md с обновлением счётчиков §0 и версии.', @@ -617,7 +626,7 @@ const NODE_DETAILS = { [{ name: '.claude/settings.json', cond: 'описан как хук PreToolUse' }], [], [], - [{ name: 'hookify (плагин)', desc: 'hookify динамически создаёт новые хуки PreToolUse — может перезаписать или конкурировать с этим хуком' }] + [{ name: 'hookify (плагин)', desc: 'hookify динамически создаёт новые хуки PreToolUse — может перезаписать или конкурировать с этим хуком', type: 'RED' }] ), hk_post_md: nd( 'После каждого Edit .md-файла запускает markdownlint --fix автоматически.', @@ -656,7 +665,7 @@ const NODE_DETAILS = { [{ name: '.claude/settings.json', cond: 'описан как хук UserPromptSubmit' }], [], [], - [{ name: 'Superpowers (§12)', desc: 'Экономия=100% теоретически может «сэкономить» вызов скила, нарушая обязательное правило (см. §12) — §12 неотменяем, экономия его не отменяет' }] + [{ name: 'Superpowers (§12)', desc: 'Экономия=100% теоретически может «сэкономить» вызов скила, нарушая обязательное правило (см. §12) — §12 неотменяем, экономия его не отменяет', type: 'GREEN' }] ), // ── АГЕНТЫ ─────────────────────────────────────── @@ -666,7 +675,8 @@ const NODE_DETAILS = { 'READ-ONLY (только читает код, ничего не правит). Каждую гипотезу подтверждает реальным запуском, а не «похоже на квирк».', [{ name: 'CLAUDE.md §6', cond: 'описывает когда вызывать' }], [], - [{ name: 'MCP: redis', cond: 'читает Redis для дебага квирка 72 (supplier:session race)' }] + [{ name: 'MCP: redis', cond: 'читает Redis для дебага квирка 72 (supplier:session race)' }], + [{ name: 'MCP: redis', desc: 'Pest --parallel subdir-only race с Redis-кэшем (квирк 72)', type: 'BLACK' }] ), ag_rls: nd( 'Проверяет миграции на соответствие RLS (защите строк по тенанту) — 7 пунктов чеклиста с реальными командами, только чтение.', @@ -675,7 +685,7 @@ const NODE_DETAILS = { [{ name: 'CLAUDE.md', cond: 'описывает в §6 и в директории агентов' }], [], [{ name: 'MCP: laravel-boost', cond: 'SQL запросы к db/schema.sql' }], - [{ name: 'rls-check скил', desc: 'оба покрывают соответствие RLS, чёткой границы нет: агент — для PR и диффов, скил — для ручной проверки таблицы' }] + [{ name: 'rls-check скил', desc: 'оба покрывают соответствие RLS, чёткой границы нет: агент — для PR и диффов, скил — для ручной проверки таблицы', type: 'RED' }] ), ag_statusline: nd( 'Настраивает строку состояния Claude Code через правку файла настроек.', @@ -757,7 +767,8 @@ const NODE_DETAILS = { 'Не для боевых пользователей. На сессию один общий браузер — при parallel-work возможны столкновения (см. квирк #2 в memory).', [{ name: 'CLAUDE.md §3.1 #2', cond: 'активен с фазы 0' }], [], - [{ name: 'SessionStart хук', cond: 'используется для визуальной проверки прототипов' }] + [{ name: 'SessionStart хук', cond: 'используется для визуальной проверки прототипов' }], + [{ name: 'parallel-work скил', desc: 'Один shared browser на сессию — конкуренция при параллельной работе через worktrees (memory квирк #2)', type: 'BLACK' }] ), mcp_gh: nd( 'GitHub API — читает/создаёт PR, issues, коммиты, ветки в репозитории CoralMinister/lidpotok.', @@ -797,7 +808,8 @@ const NODE_DETAILS = { '**СТРОГО READ-ONLY** — никаких DEL/FLUSHDB/SET/LPUSH из Claude (только GET/KEYS/LIST). Источник Anthropic устарел — миграция post-MVP.', [{ name: 'CLAUDE.md §3.3 #35', cond: 'off-phase debug-runtime; PSR_v1 R10.1 блок 3' }], [], - [{ name: 'pest-parallel-debugger агент', cond: 'агент использует для квирка 72 (гонка в Redis)' }] + [{ name: 'pest-parallel-debugger агент', cond: 'агент использует для квирка 72 (гонка в Redis)' }], + [{ name: 'pest-parallel-debugger агент', desc: 'Redis race condition в Pest --parallel subdir-only runs (квирк 72)', type: 'BLACK' }] ), mcp_21st: nd( 'Генератор стартовых шаблонов UI-компонентов через LLM. Активация только через процедуру R14.4.', @@ -806,7 +818,7 @@ const NODE_DETAILS = { [{ name: 'PSR_v1 R14.4', cond: 'строгая предпроверка: 9 условий перед активацией' }], [], [], - [{ name: 'Frontend Design', desc: 'PSR_v1 R14.5: нельзя параллельно — 21st как генератор материала, FD как решатель; риск смешать роли и нарушить R6 (фильтр стека)' }] + [{ name: 'Frontend Design', desc: 'PSR_v1 R14.5: нельзя параллельно — 21st как генератор материала, FD как решатель; риск смешать роли и нарушить R6 (фильтр стека)', type: 'GREEN' }] ), // ── LEFTHOOK JOBS ─────────────────────────────────