Implementation plan для spec 2026-05-14-automation-graph-refactor-design.md. 10 tasks, каждый = 1 коммит, в порядке: 1. canvas rendering fix 2. edge labels → tooltips 3. HTML legend sections (когда + ограничения) 4. nd() helper signature + render 5a-5f. when+limits content для 73 узлов (rules+plugins / skills / hooks+agents / MCP / lefthook / memory) 6. radial-sector positioning (ring + sectorAngle на 73 NODES + pos() helper) 7. physics off + button handlers + smooth continuous 8. final smoke + data integrity check Self-review: spec coverage ✅, no placeholders ✅, type consistency ✅, backward-compat nd() handler в Task 4 (for intermediate state). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
85 KiB
Automation Graph Refactor — Implementation Plan
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: Apply 4 refactor fixes to docs/automation-graph.html from spec 2026-05-14-automation-graph-refactor-design.md: canvas rendering artifacts fix, edge labels→tooltips, radial-sector layout, two new legend sections (когда+ограничения).
Architecture: Same single-file HTML. All JS lives in one <script> tag. Tasks land independently as atomic commits — each commit leaves the file in a working state. Visual smoke (open in Edge/Chrome) is the test method; no automated tests for browser viz.
Tech Stack: vis.js Network 9.1.9 (CDN), vanilla JS, CSS3 Solarized Dark. No new dependencies.
Source spec: docs/superpowers/specs/2026-05-14-automation-graph-refactor-design.md
Base commit: 7ee78a9 (first iteration, 73 nodes / 6 conflicts).
File Map
| File | Action | Purpose |
|---|---|---|
docs/automation-graph.html |
Modify | The single deliverable; all changes here |
cspell-words.txt |
Maybe modify | Add new technical terms if cspell blocks commit |
Verification Method
For each task: open docs/automation-graph.html in Edge (or Chrome) and visually verify the criteria listed in "Expected" steps. Browser console (F12) must show no JS errors. The pre-commit hook (lefthook) runs gitleaks, stylelint (on .html), markdownlint (on .md); they must pass.
Task 1: Canvas rendering artifacts fix
Files:
- Modify:
docs/automation-graph.html— CSS block + vis.Network options
Spec ref: Section 1 (Rendering artifacts фона).
- Step 1: Add explicit canvas background CSS
In the <style> block, locate #network { flex: 1; background: #1e1e2e; } and add a new rule immediately after it:
#network { flex: 1; background: #1e1e2e; }
#network canvas { background: #1e1e2e; }
- Step 2: Remove hideEdgesOnDrag from vis.Network options
Find the interaction block inside new vis.Network(...):
interaction: {
hover: true,
tooltipDelay: 400,
hideEdgesOnDrag: true,
multiselect: false,
},
Remove the hideEdgesOnDrag: true, line:
interaction: {
hover: true,
tooltipDelay: 400,
multiselect: false,
},
- Step 3: Visual verification
Open docs/automation-graph.html in Edge. Refresh. Move mouse around canvas, hover/click random nodes, drag a node. Verify the canvas background is uniformly #1e1e2e — no rectangular shadow/region artifacts visible.
- Step 4: Commit
cd "c:/моя/проекты/портал crm/Документация"
git add docs/automation-graph.html
git commit -m "fix(graph): canvas rendering artifacts — explicit canvas bg + remove hideEdgesOnDrag"
Expected: pre-commit passes; commit hash printed.
Task 2: Remove edge labels, switch to tooltips
Files:
- Modify:
docs/automation-graph.html—E()andCONFLICT()factory functions
Spec ref: Section 2 (Подписи рёбер → в легенду).
- Step 1: Replace E() factory
Locate the E() factory:
const E = (from, to, label) => ({
from, to, label,
color: { color: '#586e75', highlight: '#93a1a1', hover: '#93a1a1' },
arrows: { to: { enabled: true, scaleFactor: 0.6 } },
font: { color: '#839496', size: 10, align: 'middle', strokeWidth: 2, strokeColor: '#1e1e2e' },
smooth: { type: 'dynamic' }
});
Replace with:
const E = (from, to, label) => ({
from, to,
title: label,
color: { color: '#586e75', highlight: '#93a1a1', hover: '#93a1a1' },
arrows: { to: { enabled: true, scaleFactor: 0.6 } },
smooth: { type: 'continuous', roundness: 0.5 }
});
Changes: removed label (was rendered on canvas) and font (no canvas text needed); changed to title (HTML tooltip on hover); changed smooth.type to continuous (better for radial layout in Task 6).
- Step 2: Replace CONFLICT() factory
Locate:
const CONFLICT = (from, to, label) => ({
from, to, label,
dashes: true,
width: 2,
color: { color: '#ff5f57', highlight: '#ff8880', hover: '#ff8880' },
arrows: { to: { enabled: true, scaleFactor: 0.7 }, from: { enabled: true, scaleFactor: 0.7 } },
font: { color: '#ff5f57', size: 10, align: 'middle', strokeWidth: 2, strokeColor: '#1e1e2e' },
smooth: { type: 'curvedCW', roundness: 0.35 }
});
Replace with:
const CONFLICT = (from, to, label) => ({
from, to,
title: label,
label: '⚡',
dashes: true,
width: 2,
color: { color: '#ff5f57', 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' },
smooth: { type: 'curvedCW', roundness: 0.35 }
});
Conflicts keep a short ⚡ marker on canvas (so the user immediately sees something is wrong); the full description still goes to title.
- Step 3: Visual verification
Open docs/automation-graph.html in Edge. Refresh.
-
No verbose Russian text appears on canvas next to edges.
-
Hover over a normal grey edge → small tooltip with the original label appears.
-
Six red dashed bidirectional edges still visible with a small
⚡marker. -
Hover over a
⚡edge → tooltip shows the original conflict label (e.g. «⚡ T2.2»). -
Step 4: Commit
cd "c:/моя/проекты/портал crm/Документация"
git add docs/automation-graph.html
git commit -m "fix(graph): remove edge labels from canvas, move to hover tooltips"
Task 3: Legend panel HTML — add «Когда» + «Ограничения» sections
Files:
- Modify:
docs/automation-graph.html—#legend-panelblock in HTML
Spec ref: Section 4 (Секции «Когда используется» и «Ограничения»).
- Step 1: Insert two new legend-section divs
Locate the legend panel in HTML:
<div id="legend-panel">
<button id="legend-close">×</button>
<div id="legend-title">—</div>
<div id="legend-category"></div>
<div class="legend-section"><h4>Что делает</h4><p id="ld-desc">—</p></div>
<div class="legend-section"><h4>Кому подчиняется</h4><ul id="ld-reports"></ul></div>
...
Insert two new <div class="legend-section"> blocks after the "Что делает" section and before "Кому подчиняется":
<div id="legend-panel">
<button id="legend-close">×</button>
<div id="legend-title">—</div>
<div id="legend-category"></div>
<div class="legend-section"><h4>Что делает</h4><p id="ld-desc">—</p></div>
<div class="legend-section"><h4>Когда используется</h4><p id="ld-when">—</p></div>
<div class="legend-section"><h4>Ограничения</h4><p id="ld-limits">—</p></div>
<div class="legend-section"><h4>Кому подчиняется</h4><ul id="ld-reports"></ul></div>
<div class="legend-section"><h4>Кто подчиняется ему</h4><ul id="ld-manages"></ul></div>
<div class="legend-section"><h4>С кем работает одновременно</h4><ul id="ld-together"></ul></div>
<div class="legend-section" id="conflicts-section">
<h4>⚡ Конфликты</h4>
<div id="ld-conflicts"></div>
</div>
</div>
- Step 2: Visual verification
Open docs/automation-graph.html in Edge. Refresh.
Click on any node (e.g. "Pravila v1.13").
Expected: legend panel opens; sections "Когда используется" and "Ограничения" appear with — placeholder text. Other sections render content as before. No JS errors in console.
- Step 3: Commit
cd "c:/моя/проекты/портал crm/Документация"
git add docs/automation-graph.html
git commit -m "feat(graph): legend panel — add «Когда используется» and «Ограничения» sections"
Task 4: nd() helper signature + showLegend rendering
Files:
- Modify:
docs/automation-graph.html—nd()function,NODE_DETAILSfirst few entries (sanity),showLegend()function
Spec ref: Section 4 (Структура данных + Рендеринг).
This task changes the nd() factory signature from 5 params to 7 params. Since NODE_DETAILS calls nd(desc, reportsTo, manages, together, conflicts) 73 times, we keep backward-compat by accepting optional positional args and sniffing arg types.
- Step 1: Replace nd() helper
Locate:
function nd(desc, reportsTo, manages, together, conflicts) {
return { desc, reportsTo, manages, together, conflicts: conflicts || [] };
}
Replace with:
function nd(desc, when, limits, reportsTo, manages, together, conflicts) {
// Backward-compat: old 5-arg signature was nd(desc, reportsTo, manages, together, conflicts).
// If 2nd arg is an array, treat as old-style call.
if (Array.isArray(when)) {
return {
desc,
when: '',
limits: '',
reportsTo: when, // shift
manages: limits, // shift
together: reportsTo, // shift
conflicts: (manages || []), // shift
};
}
return { desc, when: when || '', limits: limits || '', reportsTo, manages, together, conflicts: conflicts || [] };
}
This makes existing NODE_DETAILS entries work unchanged; new tasks (5a-5f) will rewrite calls to 7-arg form.
- Step 2: Update showLegend() to render when/limits
Locate inside showLegend(nodeId):
document.getElementById('ld-desc').textContent = details.desc;
const ldReports = document.getElementById('ld-reports');
Insert between them:
document.getElementById('ld-desc').textContent = details.desc;
document.getElementById('ld-when').textContent = details.when || '—';
document.getElementById('ld-limits').textContent = details.limits || 'без особых ограничений';
const ldReports = document.getElementById('ld-reports');
- Step 3: Visual verification
Open docs/automation-graph.html in Edge. Refresh. Click any node.
Expected:
-
"Когда используется" shows
—(because old-style calls havewhen: ''). -
"Ограничения" shows
без особых ограничений(default fallback). -
All other sections render correctly with original content.
-
No JS errors.
-
Step 4: Commit
cd "c:/моя/проекты/портал crm/Документация"
git add docs/automation-graph.html
git commit -m "feat(graph): nd() helper supports when+limits fields; showLegend renders them"
Task 5a: Fill when+limits for Rules + Plugins (9 nodes)
Files:
- Modify:
docs/automation-graph.html— 9 entries inNODE_DETAILS(pravila, claude_md, psr_v1, tooling, superpowers, fd_plugin, upm, claude_md_mgmt, hookify_plugin)
Spec ref: Section 4 (Контент from нормативка).
- Step 1: Replace 4 rules entries
Locate pravila: nd(...) and replace all 4 rules with 7-arg form:
pravila: nd(
'Главный свод правил работы Клода — приоритеты, запреты и обязательные скилы.',
'Действует постоянно — fundamental слой автоматизации; читается при старте каждой сессии через SessionStart хук.',
'§12 hard rule неотменяем; §9 «Отступления» не применяется к §12. Расходимость с CLAUDE.md/PSR_v1/Tooling — нарушение §7.',
[],
[
{ name: 'CLAUDE.md', cond: 'подчинён уровень 2a' },
{ name: 'PSR_v1', cond: 'подчинён уровень 3' },
{ name: 'Superpowers', cond: '§12 — обязывает инвокировать первым' },
{ name: 'Все компоненты', cond: 'через цепочку приоритетов §1' }
],
[{ name: 'CLAUDE.md', cond: 'оба читаются при старте сессии' }]
),
claude_md: nd(
'Оперативная карта проекта — список технологий, команд, фаз, ссылок на документы.',
'Читается при старте каждой сессии (SessionStart хук); upd при добавлении новых tooling/фазы.',
'Правки **только** через `/claude-md-management:claude-md-improver` или `:revise-claude-md` (§5 п.10). Прямые Edit/Write запрещены — блокируются PreToolUse:CLAUDE.md-warn хуком.',
[{ name: 'Pravila', cond: 'всегда (уровень 2a)' }],
[
{ name: 'Tooling v1.17', cond: 'ссылается как на реестр инструментов' },
{ name: 'claude-md-mgmt', cond: '§5п.10 — единственный канал правок' }
],
[
{ name: 'Pravila', cond: 'оба читаются SessionStart хуком' },
{ name: 'Tooling', cond: 'оба operational maps уровня 2' }
],
[{ name: 'PSR_v1', desc: 'T2.2: §5п.10 запрещает прямые правки, но PSR_v1 не дублирует это явно — риск Edit без skill\'а' }]
),
psr_v1: nd(
'Правила совместного использования плагинов — кто с кем работает, какой pipeline обязателен.',
'При выборе UI-инструмента (FD vs UPM vs 21st), при координации парного стека, при активации off-phase MCP.',
'R14.5: UPM, 21st, FD — не одновременно. R6.0 фильтр стека и R6.1 hard-override Forest обязательны для UI-вывода плагинов.',
[{ name: 'Pravila', cond: 'уровень 3 в цепочке' }],
[
{ name: 'Superpowers + Frontend Design', cond: 'координирует как парный стек' },
{ name: 'UI UX Pro Max', cond: 'R14.3: активирует только через pipeline' },
{ name: '21st Magic MCP', cond: 'R14.4: активирует только через pipeline' }
],
[{ name: 'CLAUDE.md', cond: 'оба operational maps — согласуются при правках' }],
[{ name: 'CLAUDE.md', desc: 'T2.2: CLAUDE.md §5п.10 требует claude-md-mgmt, PSR_v1 не дублирует это ограничение — риск прямых Edit' }]
),
tooling: nd(
'Реестр 35 инструментов — когда что использовать, команды установки, конфликты.',
'При выборе инструмента для фазы (0/1/2/3), при добавлении нового tooling, при актуализации после обновления версий.',
'При прямом конфликте с CLAUDE.md приоритетнее CLAUDE.md (operational map уровня 2a). Изменения требуют sync с CLAUDE.md §3.',
[
{ name: 'Pravila', cond: 'уровень 2b (operational map рядом с CLAUDE.md)' },
{ name: 'CLAUDE.md', cond: 'при прямом конфликте CLAUDE.md приоритетнее' }
],
[],
[{ name: 'CLAUDE.md', cond: 'оба operational maps — правятся синхронно' }]
),
- Step 2: Replace 5 plugins entries
Locate superpowers: nd(...) and replace all 5 plugin entries:
superpowers: nd(
'Плагин поведения Клода — 14 скилов для TDD, дебага, планирования, параллельной работы.',
'При creative / multi-step / debug / verify / TDD / brainstorm / parallel / worktree / finishing-PR / subagent / writing-skills задачах (карта §12.2 Pravila).',
'§12 hard rule — единственный override: явная просьба заказчика «не используй superpowers сейчас» на текущее действие. Pravila §9 «Отступления» к §12 не применяется.',
[
{ name: 'Pravila §12', cond: 'hard rule: инвокируется первым' },
{ name: 'PSR_v1', cond: 'координирует как парный стек с Frontend Design' }
],
[{ name: 'Все 14 Superpowers-скилов', cond: 'содержит' }],
[{ name: 'Frontend Design', cond: 'парный стек — работают вместе при UI-задачах' }],
[{ name: 'economy-mode хук', desc: 'Economy=100% теоретически может «сэкономить» инвокацию skill\'а, нарушая §12 hard rule (§12 неотменяем)' }]
),
fd_plugin: nd(
'Плагин знаний о UI — Vue, Vuetify, a11y, паттерны компонентов для Лидерры.',
'При UI/UX задачах — компоненты, экраны, паттерны взаимодействия; в паре с Superpowers (процесс).',
'R6.0 фильтр стека: срезать React/Tailwind/shadcn/JSX → Vue 3 + Vuetify 3. R6.1 hard-override Forest для палитры/шрифтов/иконок.',
[{ name: 'PSR_v1', cond: 'R5: подчинён как часть парного стека' }],
[],
[{ name: 'Superpowers', cond: 'парный стек — FD даёт UI-знания, Superpowers даёт процесс' }],
[
{ name: 'UI UX Pro Max', desc: 'PSR_v1 R14.5: нельзя параллельно — оба активны в settings.json, но должны чередоваться' },
{ name: '21st Magic MCP', desc: 'PSR_v1 R14.5: нельзя параллельно с FD — оба потенциально доступны одновременно' }
]
),
upm: nd(
'Резервная библиотека UI — 50+ стилей, 161 палитра, 99 UX-гайдлайнов. Только по pipeline.',
'PSR_v1 R14.3 pipeline: фаза 2 R2 fallback к FD ИЛИ фаза 1 R2 «третий вариант» в R12 архитектурном.',
'R14.5: не параллельно с FD/21st. R6.0 фильтр стека + R6.1 hard-override Forest обязательны. Pa11y a11y на deployable.',
[{ name: 'PSR_v1', cond: 'R14.3: активируется только через pipeline, не самостоятельно' }],
[],
[],
[{ name: 'Frontend Design', desc: 'PSR_v1 R14.5: нельзя параллельно — UPM как материал, FD как решатель; риск смешивания ролей' }]
),
claude_md_mgmt: nd(
'Единственный разрешённый способ редактировать CLAUDE.md — через skill claude-md-improver или revise-claude-md.',
'При любой правке CLAUDE.md (новая фаза, новый tooling, изменение версии, новые quirks — все через skill).',
'PSR_v1 R10.1 блок 1 (infrastructure). Внутри flow продолжают действовать §4 правил Claude (синхронизация Pravila + Tooling).',
[{ name: 'PSR_v1', cond: 'R10.1 Блок 1: инфраструктурная категория' }],
[{ name: 'CLAUDE.md', cond: '§5п.10: монопольный канал правок' }],
[{ name: 'q-item-add скил', cond: 'скил делегирует CLAUDE.md правки через этот плагин' }]
),
hookify_plugin: nd(
'Плагин создания хуков — анализирует разговоры и предлагает новые автоматизации через хуки.',
'При запросе «давай повесим хук на это поведение» или после серии повторяющихся ошибок — анализ через conversation-analyzer агента.',
'PSR_v1 R10.1. Новые хуки могут конфликтовать с существующими (см. конфликты ниже) — обязательная проверка settings.json до создания.',
[{ name: 'PSR_v1', cond: 'R10.1: формализован' }],
[{ name: 'hookify:conversation-analyzer агент', cond: 'запускает анализ разговоров' }],
[{ name: 'hookify:conversation-analyzer', cond: 'плагин и агент работают в паре' }],
[
{ name: 'PreToolUse:CLAUDE.md-warn', desc: 'hookify создаёт новые PreToolUse хуки динамически — может перезаписать или затенить существующий CLAUDE.md-warn' },
{ name: 'economy-mode хук', desc: 'новые хуки от hookify могут вступить в конфликт с логикой economy-mode парсера' }
]
),
- Step 3: Visual verification
Open in Edge. Refresh. Click on Pravila v1.13, CLAUDE.md, Superpowers, Frontend Design.
Expected: «Когда используется» and «Ограничения» sections now show real Russian text for these 9 nodes. Other nodes still show —/без особых ограничений defaults.
- Step 4: Commit
cd "c:/моя/проекты/портал crm/Документация"
git add docs/automation-graph.html
git commit -m "feat(graph): when+limits content for rules + plugins (9 nodes)"
Task 5b: Fill when+limits for Skills (16 nodes)
Files:
-
Modify:
docs/automation-graph.html— entriessk_brainstormthroughsk_elements(14) +sk_rls,sk_qitem(2) -
Step 1: Replace 14 superpowers skill entries
Locate sk_brainstorm: nd(...) and replace all 14 SP-skills + 2 project skills with 7-arg form:
sk_brainstorm: nd(
'Продумывает задачу вместе с заказчиком, формулирует варианты A/B/C и согласует дизайн до написания кода.',
'При creative задаче — новая фича, нетривиальный refactor, дизайн-решение; ПЕРЕД любым кодом или планом.',
'Обязательно «Approved» от заказчика до перехода к writing-plans. HARD-GATE: нельзя инвокировать implementation skill до утверждения дизайна.',
[{ name: 'Superpowers', cond: 'содержит' }, { name: 'Pravila §12', cond: 'обязателен для creative задач' }],
[],
[{ name: 'writing-plans', cond: 'вызывается сразу после brainstorming для создания плана' }]
),
sk_tdd: nd(
'Ведёт разработку через написание провального теста до кода — failing test first, потом GREEN.',
'При любом новом production коде — backend (Pest) и frontend (Vitest).',
'Failing test ДО написания implementation; код «должен работать» без verified теста — нарушение §12.',
[{ name: 'Superpowers', cond: 'содержит' }, { name: 'Pravila §12', cond: 'обязателен для любого нового кода' }],
[],
[{ name: 'executing-plans', cond: 'TDD встроен в каждый шаг плана выполнения' }]
),
sk_debug: nd(
'Системный дебаг: минимум 3 гипотезы, фальсификация каждой перед исправлением — никаких «должно работать».',
'При unexpected behavior, фейле теста, runtime ошибке, неожиданном выводе.',
'Минимум 3 гипотезы. Фальсификация через реальные команды/тесты, не «логика подсказывает». Никаких «попробую исправить» без проверки причины.',
[{ name: 'Superpowers', cond: 'содержит' }, { name: 'Pravila §12', cond: 'обязателен при unexpected behavior' }],
[],
[{ name: 'MCP: redis', cond: 'используется для дебага Redis-очередей' }]
),
sk_wplans: nd(
'Создаёт детальный план реализации с полным кодом, командами и шагами по 2-5 минут.',
'После brainstorming (creative задача) или сразу для multi-step (≥3 шага) технической задачи.',
'Никаких placeholder\'ов (TBD, TODO, «add validation»). Каждый шаг — реальный код или команда. Spec coverage обязателен.',
[{ name: 'Superpowers', cond: 'содержит' }, { name: 'Pravila §12', cond: 'обязателен для multi-step задач (≥3 шага)' }],
[],
[{ name: 'executing-plans или subagent-driven', cond: 'план передаётся в один из них для выполнения' }]
),
sk_eplans: nd(
'Выполняет готовый план шаг за шагом, отмечает чекбоксы, делает коммиты после каждого шага.',
'После writing-plans (если выбран inline execution); альтернатива — subagent-driven для same-session.',
'Каждый шаг отмечается checkbox\'ом, не batch\'ит коммиты — атомарно (Pravila §4.2).',
[{ name: 'Superpowers', cond: 'содержит' }],
[],
[{ name: 'writing-plans', cond: 'получает план от writing-plans' }, { name: 'subagent-driven', cond: 'альтернатива — зависит от выбора пользователя' }]
),
sk_verify: nd(
'Обязательная проверка перед «готово» — запускает тесты, видит реальный вывод, никаких предположений.',
'Перед любым claim «готово»/«passed»/«closed»/«merged» — обязательно (§12 + economy 0% hard requirement).',
'Реальный запуск, не «должно пройти». Output виден полностью. Cherry-picking запрещён («tests pass» = ровно столько, сколько прошло).',
[{ name: 'Superpowers', cond: 'содержит' }, { name: 'Pravila §12', cond: 'обязателен перед любым claim «готово»' }],
[],
[{ name: 'MCP: laravel-boost', cond: 'запросы к БД для проверки данных' }]
),
sk_parallel: nd(
'Разбивает независимые задачи на параллельные потоки с изоляцией через git worktrees.',
'При наличии нескольких независимых рабочих фронтов (CTO-task + Plan task + audit-fix) одновременно.',
'Изоляция через worktree обязательна — никакого «работаю в одной директории на 3 ветках сразу». Risk of contention.',
[{ name: 'Superpowers', cond: 'содержит' }],
[],
[{ name: 'worktree скил', cond: 'parallel-work использует worktree для изоляции' }]
),
sk_worktree: nd(
'Создаёт изолированную копию репозитория для рискованной или параллельной работы.',
'При parallel-work или при рискованной работе (refactor с возможностью abort, ветка экспериментов).',
'Cleanup через ExitWorktree обязателен. Не оставлять untracked worktree\'ы — захламляют файловую систему.',
[{ name: 'Superpowers', cond: 'содержит' }],
[],
[{ name: 'parallel-work', cond: 'worktree — инструмент для parallel-work' }]
),
sk_pr: nd(
'Чеклист финальной готовности PR — тесты, документация, чистота кода, pre-push хуки.',
'Перед `gh pr create` или `git push` на upstream — обязательная проверка готовности.',
'Pre-push хуки (gitleaks full-history + lychee) — не bypass\'ить через `--no-verify`. Pravila §4.2.',
[{ name: 'Superpowers', cond: 'содержит' }],
[],
[{ name: 'MCP: github', cond: 'создаёт PR через GitHub MCP' }, { name: 'lefthook pre-push', cond: 'запускает gitleaks + lychee' }]
),
sk_subagent: nd(
'Запускает суб-агентов для крупных задач — каждый в отдельном контексте без накопленного шума.',
'При plan-driven execution в same-session ИЛИ при делегировании поиска/анализа большого scope.',
'Subagent в режиме экономии 0%: запрашивать raw output, не summary — решения принимать самому.',
[{ name: 'Superpowers', cond: 'содержит' }],
[
{ name: 'Explore агент', cond: 'запускает для поиска по кодовой базе' },
{ name: 'general-purpose агент', cond: 'запускает для сложных задач' },
{ name: 'Plan агент', cond: 'запускает для архитектурного планирования' }
],
[{ name: 'writing-plans', cond: 'subagent-driven — основной способ выполнения планов' }]
),
sk_wskills: nd(
'Создаёт новые скилы по стандартному шаблону с SKILL.md, frontmatter, workflow.',
'При формализации повторяющегося workflow в reusable skill (после 2-3 примеров одинаковой работы).',
'Шаблон SKILL.md, frontmatter (name, description, when_to_use, allowed-tools), workflow с DOT-диаграммой.',
[{ name: 'Superpowers', cond: 'содержит' }],
[],
[{ name: 'plugin-dev:skill-reviewer', cond: 'агент проверяет созданный скил' }]
),
sk_spreview: nd(
'Проверяет spec-документ на полноту, противоречия, placeholder\'ы и scope.',
'После writing-plans на отдельном этапе ДО implementation — для крупных multi-task планов.',
'Inline self-review в режиме brainstorming достаточно для small spec; для крупных — выделенная инвокация.',
[{ name: 'Superpowers', cond: 'содержит' }],
[],
[{ name: 'brainstorming', cond: 'spec-review вызывается в конце brainstorming после записи спека' }]
),
sk_coderev: nd(
'Систематический code review — безопасность, тесты, архитектура, соответствие правилам.',
'Перед merge PR; после крупной серии коммитов; при подготовке к релизу; при подозрении на регрессию.',
'Не cherry-pick: review всех diff\'ов, не только tarred. SAST (Semgrep) включается обязательно.',
[{ name: 'Superpowers', cond: 'содержит' }],
[],
[{ name: 'MCP: semgrep', cond: 'SAST-проверка при code review' }]
),
sk_elements: nd(
'Улучшает написание текстов и документации — ясность, лаконичность, без воды.',
'При написании spec/plan/CHANGELOG/PR description — для коммуникации с командой.',
'Без воды. Без «легко», «просто», «всего лишь». Каждое утверждение — измеримое.',
[{ name: 'Superpowers', cond: 'содержит' }],
[],
[]
),
sk_rls: nd(
'7-шаговый чеклист RLS для новой таблицы: tenant_id, ENABLE RLS, политики, 5-role GRANTs, CHANGELOG, squawk, smoke test.',
'При создании новой таблицы в db/schema.sql ИЛИ при правках существующих RLS политик.',
'5-role GRANTs обязательны (crm_app_user / crm_app_admin / crm_supplier_worker BYPASSRLS / crm_readonly / crm_migrator). CHANGELOG_schema.md обязателен.',
[{ name: 'Tooling §3.2', cond: 'использует squawk (#15) и команды grep' }],
[],
[{ name: 'MCP: laravel-boost', cond: 'SQL запросы к schema.sql для проверки' }],
[{ name: 'rls-reviewer агент', desc: 'оба проверяют RLS compliance — скил для ручной проверки таблицы, агент для PR/diff review; нет чёткой границы когда какой' }]
),
sk_qitem: nd(
'Добавляет новый открытый вопрос в реестр Открытые_вопросы_v8_3.md с обновлением счётчиков §0 и версии.',
'При появлении нового открытого вопроса (Биз-/CTO-/Ю-/Диз-/DO-/OPEN-) — формальный input в реестр.',
'Категоризация (Биз-/CTO-/...) обязательна. Связанные документы (CLAUDE.md/Pravila/PSR_v1/Tooling) — синхронизируются.',
[],
[],
[{ name: 'claude-md-mgmt', cond: 'скил делегирует правку CLAUDE.md через плагин (§5п.10)' }]
),
- Step 2: Visual verification
Refresh in Edge. Click brainstorming, TDD, systematic-debugging, rls-check. Expected: новые секции «Когда» / «Ограничения» содержат конкретный русский текст для всех 16 skills.
- Step 3: Commit
git add docs/automation-graph.html
git commit -m "feat(graph): when+limits content for skills (14 SP + 2 проектных)"
Task 5c: Fill when+limits for Hooks + Agents (16 nodes)
Files:
-
Modify:
docs/automation-graph.html— entrieshk_pre_claudeчерезhk_economy(5) +ag_pestчерезag_skreview(11) -
Step 1: Replace 5 hooks + 11 agents entries
Locate hk_pre_claude: nd(...) and replace all 16:
hk_pre_claude: nd(
'Блокирует прямое редактирование CLAUDE.md — срабатывает на Edit/Write по этому файлу.',
'PreToolUse — перед каждым Edit/Write tool call, matcher на путь к CLAUDE.md.',
'Bypass запрещён. Единственный способ редактировать — claude-md-mgmt skill (§5п.10).',
[{ name: '.claude/settings.json', cond: 'описан как PreToolUse hook' }],
[],
[],
[{ name: 'hookify (плагин)', desc: 'hookify динамически создаёт новые PreToolUse хуки — может перезаписать или конкурировать с этим хуком' }]
),
hk_post_md: nd(
'После каждого Edit .md файла запускает markdownlint --fix автоматически.',
'PostToolUse — после Edit/Write на *.md (кроме корневого CLAUDE.md, чтобы не зациклить).',
'Не fix\'ит CLAUDE.md (исключён из matcher). При неисправимой ошибке (e.g. broken link) — warning, не block.',
[{ name: '.claude/settings.json', cond: 'описан как PostToolUse hook' }],
[],
[{ name: 'lefthook:markdownlint', cond: 'дублируют задачу: хук — в сессии, lefthook — при коммите' }]
),
hk_post_schema: nd(
'После правки db/schema.sql напоминает обновить db/CHANGELOG_schema.md.',
'PostToolUse — после Edit/Write на `db/schema.sql`.',
'Reminder, не block. Дисциплина CHANGELOG_schema на разработчике (§4.2 Pravila).',
[{ name: '.claude/settings.json', cond: 'описан как PostToolUse hook' }],
[],
[{ name: 'lefthook:squawk', cond: 'оба реагируют на изменения SQL' }]
),
hk_session: nd(
'При старте каждой сессии инжектирует CLAUDE.md, Pravila и ключевые memory-файлы в контекст.',
'SessionStart — единожды при инициализации сессии Claude Code.',
'Memory-список фиксированный — для расширения править hook config. Не читает 80+ квирков целиком — выборочно по relevance.',
[{ name: '.claude/settings.json', cond: 'описан как SessionStart hook' }],
[
{ name: 'memory:user_profile', cond: 'читает' },
{ name: 'memory:feedback_env', cond: 'читает' },
{ name: 'memory:project_state', cond: 'читает' },
{ name: 'memory:feedback_superpowers', cond: 'читает' },
{ name: 'memory:feedback_plugins', cond: 'читает' }
],
[]
),
hk_economy: nd(
'Перед каждым промптом парсит «экономия X%» и выставляет режим строгости (0%=полная качество, 100%=по умолчанию).',
'UserPromptSubmit — перед каждым промптом пользователя; парсит regex /экономия\\s*(\\d+)%/.',
'§12 hard rule **НЕ** override\'ится этим режимом — на всех уровнях. Действует только на текущую задачу — следующий промпт парсится заново.',
[{ name: '.claude/settings.json', cond: 'описан как UserPromptSubmit hook' }],
[],
[],
[{ name: 'Superpowers (§12)', desc: 'Economy=100% теоретически может «сэкономить» инвокацию skill\'а, нарушая §12 hard rule — §12 неотменяем, экономия его не override\'ит' }]
),
ag_pest: nd(
'Диагностирует падения Pest --parallel: классифицирует как реальный баг или один из 5 квирков (72-73-77...).',
'При падении Pest --parallel ИЛИ при subdir-only flake (как в audit Phase 3 SyncSupplierProjectsJobTest).',
'READ-ONLY на коде, не правит самостоятельно. Falsify каждую гипотезу через реальный запуск, не «вероятно квирк».',
[{ name: 'CLAUDE.md §6', cond: 'описывает когда вызывать' }],
[],
[{ name: 'MCP: redis', cond: 'читает Redis для дебага quirk 72 (supplier:session race)' }]
),
ag_rls: nd(
'Проверяет RLS compliance в миграциях — 7-item чеклист с реальными запусками команд, READ-ONLY.',
'При создании/правке миграции в db/migrations/ ИЛИ при правке db/schema.sql ИЛИ при PR review с DB-изменениями.',
'READ-ONLY (только Read/Grep/Glob/Bash) — не пишет код. Не альтернатива sk_rls skill, у них разные сценарии.',
[{ name: 'CLAUDE.md', cond: 'описывает в §6 и агенты/ директории' }],
[],
[{ name: 'MCP: laravel-boost', cond: 'SQL запросы к db/schema.sql' }],
[{ name: 'rls-check скил', desc: 'оба покрывают RLS compliance, нет чёткой границы: агент — для PR/diff, скил — для ручной таблицы' }]
),
ag_statusline: nd(
'Настраивает строку состояния Claude Code через редактирование файла конфига.',
'При запросе пользователя «настрой statusline» — редкая разовая задача.',
'Правит только settings.json statusline-секцию, не другие части конфига.',
[],
[],
[]
),
ag_guide: nd(
'Отвечает на вопросы об API Claude Code, SDK, MCP серверах, хуках, slash commands.',
'При вопросе про возможности Claude Code/SDK/API — «Can Claude...», «How do I...», «Does Claude...».',
'READ-ONLY: ищет в документации, не правит код. Не для дебага кода — только для вопросов о platform.',
[],
[],
[{ name: 'MCP: github', cond: 'ищет примеры в репозитории при необходимости' }]
),
ag_explore: nd(
'Быстрый поиск файлов по паттерну или символу — только чтение, без анализа.',
'При targeted lookup — найти файл по имени или grep по символу/keyword.',
'Не для open-ended exploration. Не для review/audit (читает excerpts, миссует content past read window).',
[{ name: 'subagent-driven скил', cond: 'запускается для задач поиска' }],
[],
[]
),
ag_general: nd(
'Универсальный агент для сложных multi-step исследований с полным доступом к инструментам.',
'При сложных multi-step research / coding задачах, когда Explore недостаточно (нужен анализ, не только поиск).',
'Полный доступ к инструментам — может писать код. Дороже Explore по токенам.',
[{ name: 'subagent-driven скил', cond: 'запускается для основных задач' }],
[],
[]
),
ag_plan: nd(
'Архитектор: разрабатывает планы реализации, выявляет критичные файлы, рассматривает trade-offs.',
'При архитектурном планировании multi-component задачи (не для small refactor).',
'READ-ONLY (no Edit/Write/NotebookEdit). Возвращает план, не реализует его.',
[{ name: 'subagent-driven скил', cond: 'запускается для архитектурных задач' }],
[],
[{ name: 'writing-plans скил', cond: 'Plan агент и writing-plans решают похожую задачу для разных контекстов' }]
),
ag_hookify: nd(
'Анализирует транскрипты разговоров для поиска поведений, которые стоит предотвратить хуком.',
'При триггере /hookify без аргументов ИЛИ при запросе «look back at this conversation, what mistakes to prevent».',
'READ-ONLY (Read+Grep only). Рекомендует хуки, не создаёт их сам — передаёт в hookify plugin.',
[],
[],
[{ name: 'hookify (плагин)', cond: 'агент передаёт рекомендации в плагин' }]
),
ag_pcreator: nd(
'Создаёт конфигурацию новых агентов по описанию пользователя.',
'При запросе «create an agent that...» — генерация agent.md по описанию функциональности.',
'Только Write/Read tools. Не валидирует созданного агента — передаёт в plugin-validator.',
[],
[],
[{ name: 'plugin-dev:plugin-validator', cond: 'validator проверяет созданного агента' }]
),
ag_pvalid: nd(
'Проверяет структуру плагина на корректность — plugin.json, tools, manifest.',
'После создания/изменения plugin.json или plugin component\'ов — proactive validation.',
'READ-ONLY (Read/Grep/Glob/Bash). Сам не правит — даёт список нарушений.',
[],
[],
[{ name: 'plugin-dev:agent-creator', cond: 'validator и creator работают в паре' }]
),
ag_skreview: nd(
'Оценивает качество написанного скила — описание, workflow, примеры, best practices.',
'После создания/изменения скила через writing-skills — proactive review.',
'READ-ONLY (Read/Grep/Glob). Не правит — выдаёт рекомендации.',
[],
[],
[{ name: 'writing-skills скил', cond: 'skill-reviewer проверяет то, что writing-skills создал' }]
),
- Step 2: Visual verification
Refresh in Edge. Click hooks (SessionStart, PreToolUse:CLAUDE.md-warn, UserPromptSubmit:economy-mode), agents (pest-parallel-debugger, rls-reviewer, Explore). Expected: 2 новых секции заполнены для всех 16 узлов.
- Step 3: Commit
git add docs/automation-graph.html
git commit -m "feat(graph): when+limits content for hooks (5) + agents (11)"
Task 5d: Fill when+limits for MCP servers (7 nodes)
Files:
-
Modify:
docs/automation-graph.html— entriesmcp_pwчерезmcp_21st -
Step 1: Replace 7 MCP entries
mcp_pw: nd(
'Управляет браузером — снимает скриншоты, кликает, заполняет формы для smoke и a11y тестов.',
'При визуальной проверке прототипов (фаза 0), при a11y smoke (axe-core), при UI integration smoke.',
'Не для production users. На каждой сессии один shared browser — конфликты при parallel-work (см. квирк #2 в memory).',
[{ name: 'CLAUDE.md §3.1 #2', cond: 'активен с фазы 0' }],
[],
[{ name: 'SessionStart хук', cond: 'используется для визуальной проверки прототипов' }]
),
mcp_gh: nd(
'GitHub API — читает/создаёт PR, issues, коммиты, branches в репозитории CoralMinister/lidpotok.',
'При работе с PR/issues, при поиске в репозитории, при создании PR через finishing-pr skill.',
'Не push на main без явного одобрения. Pravila §4: атомарные коммиты, не batch\'ить через MCP.',
[{ name: 'CLAUDE.md §3.1 #3', cond: 'активен с фазы 0' }],
[],
[{ name: 'finishing-pr скил', cond: 'создаёт PR через этот MCP' }]
),
mcp_boost: nd(
'Laravel Boost — SQL запросы к dev-БД, схема таблиц, логи ошибок, поиск в docs Laravel.',
'Фаза 1+: при SQL запросах, при поиске в Laravel docs, при работе с Eloquent моделями.',
'**READ-ONLY к prod** — `.env.production` не должен попадать в локальный конфиг. Не использовать Inertia/Livewire/Tailwind/Filament guidelines.',
[{ name: 'CLAUDE.md §3.2 #10', cond: 'активен с фазы 1, READ-ONLY к prod запрещено' }],
[],
[{ name: 'ag_rls агент', cond: 'rls-reviewer использует Boost для SQL' }, { name: 'sk_rls скил', cond: 'rls-check использует Boost' }]
),
mcp_semgrep: nd(
'SAST анализ кода — ищет уязвимости, XSS, SQLi, нарушения правил по паттернам.',
'Фаза 3 pre-production: при code review (sk_coderev), при CI перед релизом.',
'Конфигурация в .semgrep.yml. False-positive\'ы документируются inline.',
[{ name: 'CLAUDE.md §3.4 #25', cond: 'фаза 3 pre-production' }],
[],
[{ name: 'code-review скил', cond: 'Semgrep MCP используется при code review' }]
),
mcp_sentry: nd(
'Читает ошибки из self-hosted Sentry в Yandex Cloud — события, стектрейсы, метрики. READ-ONLY.',
'При расследовании production runtime ошибок (после deployment Б-1).',
'**READ-ONLY** scope (org:read/project:read/event:read). Pending Sentry instance deployment Б-1 (зависит от ООО registration).',
[{ name: 'CLAUDE.md §3.3 #34', cond: 'off-phase debug-runtime; pending Sentry deployment Б-1' }],
[],
[]
),
mcp_redis: nd(
'Читает Redis/Memurai — ключи, очереди, кэш для дебага race conditions. СТРОГО READ-ONLY.',
'При дебаге Redis-очередей (Pest --parallel quirk 72), при анализе кэш-инвалидации.',
'**СТРОГО READ-ONLY** — никаких DEL/FLUSHDB/SET/LPUSH из Claude (только GET/KEYS/LIST). Deprecated Anthropic source — миграция post-MVP.',
[{ name: 'CLAUDE.md §3.3 #35', cond: 'off-phase debug-runtime; PSR_v1 R10.1 блок 3' }],
[],
[{ name: 'pest-parallel-debugger агент', cond: 'агент использует для quirk 72 (Redis race)' }]
),
mcp_21st: nd(
'Генератор стартовых шаблонов UI-компонентов через LLM. Активация только через R14.4 pipeline.',
'Только через PSR_v1 R14.4 pipeline: pre-check 9 условий (брендовый App*? Vuetify-эквивалент? существующий компонент?).',
'R14.5: не параллельно с FD/UPM. JSX→Vue, Tailwind→utility, shadcn→Vuetify обязательны. Pa11y a11y на deployable.',
[{ name: 'PSR_v1 R14.4', cond: 'строгий pre-check: 9 условий перед активацией' }],
[],
[],
[{ name: 'Frontend Design', desc: 'PSR_v1 R14.5: нельзя параллельно — 21st как генератор материала, FD как решатель; риск смешивания ролей и нарушения R6 фильтра стека' }]
),
- Step 2: Visual verification
Refresh. Click MCP: laravel-boost, MCP: sentry, MCP: redis. Expected: when/limits секции заполнены с READ-ONLY политиками.
- Step 3: Commit
git add docs/automation-graph.html
git commit -m "feat(graph): when+limits content for MCP servers (7)"
Task 5e: Fill when+limits for Lefthook jobs (10 nodes)
Files:
-
Modify:
docs/automation-graph.html— entrieslh_gitleaksчерезlh_lychee -
Step 1: Replace 10 lefthook entries
lh_gitleaks: nd(
'pre-commit: ищет ПДн, токены и API-ключи в staged-файлах. Блокирует коммит при находке.',
'pre-commit stage: на каждый `git commit` — сканирует только staged файлы.',
'Bypass через `--no-verify` запрещён (Pravila §4.2). Находка = blocking error, не warning. Обновление словаря — `.gitleaksignore` для known-false-positives.',
[{ name: 'lefthook.yml', cond: 'job #1 в pre-commit, parallel:false' }],
[],
[{ name: 'lefthook:gitleaks pre-push', cond: 'pre-push версия сканирует всю историю' }]
),
lh_mdlint: nd(
'pre-commit: проверяет и авто-исправляет стиль Markdown файлов перед коммитом.',
'pre-commit stage: на каждый `git commit` со staged `.md` файлами.',
'Конфиг `.markdownlint-cli2.cjs`. Auto-fix включён (stage_fixed: true) — fixed файлы повторно staged.',
[{ name: 'lefthook.yml', cond: 'job #2 в pre-commit' }],
[],
[{ name: 'PostToolUse:markdownlint-fix хук', cond: 'оба делают одно — хук немедленно, lefthook при коммите' }]
),
lh_cspell: nd(
'pre-commit: проверяет орфографию в .md файлах по словарю cspell-words.txt.',
'pre-commit stage: на каждый `git commit` со staged `.md` файлами.',
'Словарь: `cspell-words.txt`. Кириллица в нижнем регистре. Не bypass\'ить — добавлять валидные слова в словарь.',
[{ name: 'lefthook.yml', cond: 'job #3 в pre-commit' }],
[],
[]
),
lh_stylelint: nd(
'pre-commit: линтует CSS в HTML-прототипах (web/v8/*.html).',
'pre-commit stage: на staged `.html`/`.css` файлах.',
'Stylelint конфиг в `.stylelintrc`. Deprecated keywords (`word-break: break-word`) блокируют commit.',
[{ name: 'lefthook.yml', cond: 'job #4 в pre-commit' }],
[],
[]
),
lh_pint: nd(
'pre-commit: авто-форматирует PHP код по PSR-стандарту, stage_fixed:true.',
'pre-commit stage: на каждый staged `.php` файл (root: app/).',
'Auto-fix включён — fixed файлы повторно staged. Конфиг `app/pint.json`.',
[{ name: 'lefthook.yml', cond: 'job #5 в pre-commit, root:app/' }],
[],
[]
),
lh_larastan: nd(
'pre-commit: статический анализ PHP — находит ошибки типов выше baseline (Larastan L9).',
'pre-commit stage: на staged `.php` файлах (root: app/).',
'Baseline `phpstan-baseline.neon` фиксирован — новые ошибки блокируют commit. Не bump\'ить baseline без обоснования.',
[{ name: 'lefthook.yml', cond: 'job #6 в pre-commit, root:app/' }],
[],
[{ name: 'MCP: laravel-boost', cond: 'Boost даёт контекст типов через IDE stubs' }]
),
lh_squawk: nd(
'pre-commit: линтует SQL миграции на безопасные паттерны (lock-safe, concurrent, etc.).',
'pre-commit stage: на staged `database/migrations/*.php` или `db/*.sql` файлах.',
'Конфиг squawk.toml. Не разрешать UNSAFE миграции (`ALTER TABLE ADD COLUMN NOT NULL DEFAULT`) без явного `-- squawk-ignore`.',
[{ name: 'lefthook.yml', cond: 'job #7 в pre-commit, glob:*.sql' }],
[],
[{ name: 'Tooling #15 squawk', cond: 'соответствует §3.2 entry' }]
),
lh_eslint: nd(
'pre-commit: линтует Vue/TypeScript файлы в app/resources/js/.',
'pre-commit stage: на staged `.vue`/`.ts`/`.tsx` файлах (root: app/).',
'Flat-config eslint 10 + plugin-vue 10. Не bypass\'ить через `--no-verify`. Errors blocking, warnings allowed.',
[{ name: 'lefthook.yml', cond: 'job #8 в pre-commit, root:app/' }],
[],
[]
),
lh_gitleaks2: nd(
'pre-push: полный скан всей истории коммитов на секреты (строже pre-commit job).',
'pre-push stage: перед `git push` к remote — сканирует всю history новых коммитов.',
'Bypass через `--no-verify` запрещён. На больших push (200+ commits) занимает 30+ сек.',
[{ name: 'lefthook.yml', cond: 'job в pre-push' }],
[],
[{ name: 'lefthook:gitleaks', cond: 'pre-push версия строже pre-commit: проверяет всю историю' }]
),
lh_lychee: nd(
'pre-push: проверяет все ссылки в .md файлах на битые (docs/**/*.md, db/**/*.md, *.md).',
'pre-push stage: перед `git push` — проверяет ссылки во всех `.md` файлах в монорепе.',
'Внешние ссылки проверяются с timeout 10s; offline — fail. Конфиг `lychee.toml`. Не bypass\'ить через `--no-verify`.',
[{ name: 'lefthook.yml', cond: 'job в pre-push' }],
[],
[{ name: 'CLAUDE.md', cond: 'проверяет ссылки в CLAUDE.md в том числе' }]
),
- Step 2: Visual verification
Refresh. Click lefthook:gitleaks, lefthook:lychee-links, lefthook:stylelint. Expected: 2 новых секции заполнены.
- Step 3: Commit
git add docs/automation-graph.html
git commit -m "feat(graph): when+limits content for lefthook jobs (10)"
Task 5f: Fill when+limits for Memory files (15 nodes)
Files:
-
Modify:
docs/automation-graph.html— entriesmem_userчерезmem_devindices -
Step 1: Replace 15 memory entries
mem_user: nd(
'Профиль заказчика: Дмитрий, Windows Server 2022, VSCode, русский язык, путь к проекту.',
'Читается при старте каждой сессии через SessionStart хук — для language/preferences.',
'Не содержит секретов. При смене заказчика — переписать полностью.',
[],
[],
[{ name: 'SessionStart хук', cond: 'читается при старте каждой сессии' }]
),
mem_comm: nd(
'Стиль общения: короткие команды («а», «б», «делай»), варианты A/B/C, фиксация переоткрытий.',
'Читается при работе с пользователем — для соответствия стилю общения.',
'Не путь к code, а meta-rules коммуникации. Корректировки через явное feedback от заказчика.',
[],
[],
[{ name: 'memory:user_profile', cond: 'дополняет профиль пользователя' }]
),
mem_env: nd(
'80+ квирков окружения: специфика Windows Server, баги инструментов, митигации.',
'При unexpected behavior — сначала проверка memory_env на известный квирк.',
'Не дубль — добавлять только новые квирки. Quirk count актуализируется в `project_state.md`.',
[],
[],
[
{ name: 'pest-parallel-debugger агент', cond: 'квирки 72/77 используются агентом' },
{ name: 'SessionStart хук', cond: 'читается при старте' }
]
),
mem_sp: nd(
'Hard rule §12 + economy hook architecture из 6 компонентов — дисциплина инвокации скилов.',
'При работе со скилами — для соответствия §12 hard rule.',
'Описывает архитектуру economy hook (6 компонентов) — менять только при изменении самого хука.',
[],
[],
[{ name: 'economy-mode хук', cond: 'связаны: memory описывает архитектуру хука' }]
),
mem_plugins: nd(
'Правила парного стека плагинов, debug-runtime MCP, tier-структура PSR_v1.',
'При работе с плагинами FD/UPM/21st/Sentry/Redis MCP — для tier-разделения.',
'Синхронизируется с PSR_v1 — изменения в memory только если изменился сам PSR_v1.',
[],
[],
[{ name: 'PSR_v1', cond: 'memory отражает актуальные версии PSR_v1' }]
),
mem_state: nd(
'Текущее состояние: ветка, тесты (Pest/Vitest), последние коммиты, активные задачи.',
'Читается при старте сессии — для быстрого контекста; обновляется после крупных вех.',
'Может становиться stale — re-Read при сомнении. Не доверять данным более 2-3 дней без verify.',
[],
[],
[{ name: 'SessionStart хук', cond: 'читается при старте для быстрого контекста' }]
),
mem_phase1: nd(
'Стратегия фазы 1: native Windows стек без Docker, pg_partman заменён Artisan cron.',
'При работе с infrastructure фазы 1 (PG/Redis/PHP-CLI на Windows native).',
'Стратегия фиксированная до закрытия Б-1 (Managed PG в YC) или 6 месяцев — переоценка указана в файле.',
[],
[],
[]
),
mem_archive: nd(
'Карта источников истины: версии всех 13+ ключевых документов проекта.',
'При вопросах «какая версия документа X» или «где источник истины для Y».',
'Синхронизируется с CLAUDE.md §0. Изменения в memory только если изменился CLAUDE.md §0.',
[],
[],
[{ name: 'CLAUDE.md', cond: 'memory синхронизирует версии с CLAUDE.md §0' }]
),
mem_github: nd(
'GitHub репозиторий CoralMinister/lidpotok: HEAD, hooks, правила push.',
'При работе с GitHub — push, PR, branch operations.',
'Не push --force на main (warning в Pravila). Pre-push hooks обязательны.',
[],
[],
[{ name: 'MCP: github', cond: 'MCP и memory дополняют друг друга для работы с GitHub' }]
),
mem_handoff: nd(
'Дизайн-handoff Платона: что из liderra_v8_handoff/ используем, что нет.',
'При UI/дизайн задачах — для разделения «брендбук используем» vs «состав фич — по ТЗ v8.5».',
'Handoff — только дизайн/токены/компоненты. Функционал, состав экранов — НЕ из handoff (берём из ТЗ).',
[],
[],
[]
),
mem_audit: nd(
'Полный аудит портала 13.05.2026: 38 находок, вердикт 🟡, 10 Q-items закрыты.',
'При вопросах про аудит или его последствия (Q.DEFER, P0/P1/P2 распределение).',
'Снимок состояния — не редактировать при последующих аудитах, создавать новые memory-файлы.',
[],
[],
[]
),
mem_supplier: nd(
'Прогресс интеграции поставщика Plans 1-5: Tasks, коммиты, блокеры.',
'При работе с supplier integration (Plans 1-5) — для текущего state и blockers.',
'Блокеры (Б-1, credentials) — внешние, не разрешаются Claude\'ом. Только трекинг.',
[],
[],
[]
),
mem_brain: nd(
'Claude Brain v1.0 — extracted brain repo, тег brain-v1.0, install.sh.',
'При работе с brain repository или install.sh для consumer sync.',
'GitHub push на brain repo blocked (8.2). Не пытаться push без разрешения.',
[],
[],
[]
),
mem_redesign: nd(
'Редизайн Quiet Luxury: 20 коммитов, foundation CSS + composables + AppSidebar rewrite.',
'При работе с portal redesign (frontend, AppSidebar, foundation CSS).',
'I2 backlog в spec §15 — 10 пунктов отложены до I2. Не реализовывать I2 пункты без явного запроса.',
[],
[],
[]
),
mem_devindices: nd(
'Dev Element Indices — временная feedback-фича для разработки; к удалению в продакшене.',
'При работе с dev feedback (e.g. «1030 измени цвет») — для понимания number → element mapping.',
'**TEMPORARY** — заказчик прямо сказал «уберём в конечном релизе». Не вкладываться в долгосрочную инфраструктуру.',
[],
[],
[]
),
- Step 2: Visual verification
Refresh. Click memory:project_state, memory:audit_2026-05-13, memory:dev_indices. Expected: 2 новых секции заполнены для всех 15 memory узлов. Все 73 узла теперь имеют when+limits контент.
- Step 3: Commit
git add docs/automation-graph.html
git commit -m "feat(graph): when+limits content for memory files (15) — all 73 nodes done"
Task 6: Radial-sector positioning
Files:
- Modify:
docs/automation-graph.html—NODES[]массив (73 декларации) + новыйpositionNode()helper + цикл applyRadial()
Spec ref: Section 3 (Радиально-секторная иерархия).
This task adds ring and sectorAngle fields to each of 73 nodes and creates an apply-position helper. Sector assignment follows the functional grouping table from spec.
- Step 1: Add positionNode() helper before NODES declaration
Locate the comment // SECTION 1: NODES. Before the const NODES = [ line, insert the helper:
// ════════════════════════════════════════════════════
// SECTION 1: NODES
// ════════════════════════════════════════════════════
// Радиально-секторная компоновка.
// Сектора (по 90°): N=workflow (0–90), E=UI (90–180), S=infra (180–270), W=data/RLS (270–360).
const RADII = [0, 220, 400, 600, 800, 1000, 1180];
function pos(ring, angleDeg) {
const r = RADII[ring];
const a = angleDeg * Math.PI / 180;
return { x: Math.round(r * Math.cos(a)), y: Math.round(r * Math.sin(a)) };
}
- Step 2: Rewrite NODES array with ring + sectorAngle + (x,y) on each node
Replace the entire const NODES = [...] array (4+5+14+2+5+11+7+10+15 = 73 entries) with the version below. Each entry receives ring (0–6) and sectorAngle (degrees). x/y computed by pos() and spread inline.
const NODES = [
// ── ПРАВИЛА (4) ── центр + первое кольцо ───────
{ id: 'pravila', label: 'Pravila v1.13', group: 'rules', size: 38, ring: 0, ...pos(0, 0) },
{ id: 'claude_md', label: 'CLAUDE.md v1.92', group: 'rules', size: 34, ring: 1, ...pos(1, 30) },
{ id: 'psr_v1', label: 'PSR_v1 v2.1', group: 'rules', size: 32, ring: 1, ...pos(1, 150) },
{ id: 'tooling', label: 'Tooling v1.17', group: 'rules', size: 30, ring: 1, ...pos(1, 270) },
// ── ПЛАГИНЫ (5) ── второе кольцо ───────────────
{ id: 'superpowers', label: 'Superpowers v5.1', group: 'plugins', size: 30, ring: 2, ...pos(2, 45) }, // N sector
{ id: 'fd_plugin', label: 'Frontend Design', group: 'plugins', size: 26, ring: 2, ...pos(2, 135) }, // E sector
{ id: 'upm', label: 'UI UX Pro Max', group: 'plugins', size: 22, ring: 2, ...pos(2, 165) }, // E sector
{ id: 'claude_md_mgmt', label: 'claude-md-mgmt', group: 'plugins', size: 22, ring: 2, ...pos(2, 225) }, // S sector
{ id: 'hookify_plugin', label: 'hookify (плагин)', group: 'plugins', size: 22, ring: 2, ...pos(2, 200) }, // S sector
// ── СКИЛЫ SUPERPOWERS (14) — N sector (0–90) ────
{ id: 'sk_brainstorm', label: 'brainstorming', group: 'skills_sp', size: 18, ring: 3, ...pos(3, 5) },
{ id: 'sk_wplans', label: 'writing-plans', group: 'skills_sp', size: 20, ring: 3, ...pos(3, 11) },
{ id: 'sk_eplans', label: 'executing-plans', group: 'skills_sp', size: 18, ring: 3, ...pos(3, 17) },
{ id: 'sk_subagent', label: 'subagent-driven', group: 'skills_sp', size: 20, ring: 3, ...pos(3, 23) },
{ id: 'sk_tdd', label: 'TDD', group: 'skills_sp', size: 18, ring: 3, ...pos(3, 29) },
{ id: 'sk_verify', label: 'verification-before-completion', group: 'skills_sp', size: 18, ring: 3, ...pos(3, 36) },
{ id: 'sk_debug', label: 'systematic-debugging', group: 'skills_sp', size: 18, ring: 3, ...pos(3, 43) },
{ id: 'sk_parallel', label: 'parallel-work', group: 'skills_sp', size: 18, ring: 3, ...pos(3, 50) },
{ id: 'sk_worktree', label: 'worktree', group: 'skills_sp', size: 18, ring: 3, ...pos(3, 57) },
{ id: 'sk_pr', label: 'finishing-pr', group: 'skills_sp', size: 18, ring: 3, ...pos(3, 64) },
{ id: 'sk_coderev', label: 'code-review', group: 'skills_sp', size: 16, ring: 3, ...pos(3, 71) },
{ id: 'sk_spreview', label: 'spec-review', group: 'skills_sp', size: 16, ring: 3, ...pos(3, 78) },
{ id: 'sk_wskills', label: 'writing-skills', group: 'skills_sp', size: 16, ring: 3, ...pos(3, 85) },
{ id: 'sk_elements', label: 'elements-of-style', group: 'skills_sp', size: 16, ring: 3, ...pos(3, 92) }, // crosses to E
// ── СКИЛЫ ПРОЕКТА (2) — W sector (RLS) ─────────
{ id: 'sk_rls', label: 'rls-check', group: 'skills_proj', size: 20, ring: 3, ...pos(3, 305) }, // W (RLS)
{ id: 'sk_qitem', label: 'q-item-add', group: 'skills_proj', size: 20, ring: 3, ...pos(3, 220) }, // S (infra-like)
// ── ХУКИ (5) — S+infra ────────────────────────
{ id: 'hk_session', label: 'SessionStart:\ncontext-inject', group: 'hooks', size: 24, ring: 4, ...pos(4, 100) }, // E (boundary with workflow)
{ id: 'hk_economy', label: 'UserPromptSubmit:\neconomy-mode', group: 'hooks', size: 22, ring: 4, ...pos(4, 95) },
{ id: 'hk_pre_claude', label: 'PreToolUse:\nCLAUDE.md-warn', group: 'hooks', size: 22, ring: 4, ...pos(4, 215) }, // S (infra)
{ id: 'hk_post_md', label: 'PostToolUse:\nmarkdownlint', group: 'hooks', size: 20, ring: 4, ...pos(4, 195) },
{ id: 'hk_post_schema', label: 'PostToolUse:\nschema-changelog',group: 'hooks', size: 20, ring: 4, ...pos(4, 300) }, // W (data)
// ── АГЕНТЫ (11) — N (workflow) + W (RLS) ──────
{ id: 'ag_explore', label: 'Explore', group: 'agents', size: 20, ring: 4, ...pos(4, 10) },
{ id: 'ag_general', label: 'general-purpose', group: 'agents', size: 20, ring: 4, ...pos(4, 25) },
{ id: 'ag_plan', label: 'Plan', group: 'agents', size: 20, ring: 4, ...pos(4, 40) },
{ id: 'ag_pest', label: 'pest-parallel-debugger', group: 'agents', size: 24, ring: 4, ...pos(4, 55) },
{ id: 'ag_guide', label: 'claude-code-guide', group: 'agents', size: 18, ring: 4, ...pos(4, 70) },
{ id: 'ag_statusline', label: 'statusline-setup', group: 'agents', size: 18, ring: 4, ...pos(4, 85) },
{ id: 'ag_hookify', label: 'hookify:\nconversation-analyzer', group: 'agents', size: 18, ring: 4, ...pos(4, 230) }, // S
{ id: 'ag_pcreator', label: 'plugin-dev:\nagent-creator', group: 'agents', size: 16, ring: 4, ...pos(4, 245) }, // S
{ id: 'ag_pvalid', label: 'plugin-dev:\nplugin-validator',group: 'agents', size: 16, ring: 4, ...pos(4, 260) }, // S
{ id: 'ag_skreview', label: 'plugin-dev:\nskill-reviewer', group: 'agents', size: 16, ring: 4, ...pos(4, 275) }, // W
{ id: 'ag_rls', label: 'rls-reviewer', group: 'agents', size: 22, ring: 4, ...pos(4, 315) }, // W (RLS)
// ── MCP-СЕРВЕРЫ (7) — E (UI) + W (data) ───────
{ id: 'mcp_21st', label: 'MCP: 21st.dev Magic', group: 'mcp', size: 20, ring: 5, ...pos(5, 130) }, // E
{ id: 'mcp_pw', label: 'MCP: playwright', group: 'mcp', size: 22, ring: 5, ...pos(5, 110) },
{ id: 'mcp_gh', label: 'MCP: github', group: 'mcp', size: 22, ring: 5, ...pos(5, 75) }, // N (workflow)
{ id: 'mcp_boost', label: 'MCP: laravel-boost', group: 'mcp', size: 24, ring: 5, ...pos(5, 290) }, // W
{ id: 'mcp_redis', label: 'MCP: redis', group: 'mcp', size: 22, ring: 5, ...pos(5, 310) }, // W
{ id: 'mcp_sentry', label: 'MCP: sentry', group: 'mcp', size: 22, ring: 5, ...pos(5, 330) }, // W
{ id: 'mcp_semgrep', label: 'MCP: semgrep', group: 'mcp', size: 20, ring: 5, ...pos(5, 350) }, // W
// ── LEFTHOOK JOBS (10) — S+W (infra/data) ─────
{ id: 'lh_mdlint', label: 'lefthook:\nmarkdownlint', group: 'lefthook', size: 18, ring: 5, ...pos(5, 185) }, // S
{ id: 'lh_cspell', label: 'lefthook:\ncspell', group: 'lefthook', size: 18, ring: 5, ...pos(5, 200) },
{ id: 'lh_stylelint', label: 'lefthook:\nstylelint', group: 'lefthook', size: 16, ring: 5, ...pos(5, 215) },
{ id: 'lh_eslint', label: 'lefthook:\neslint-vue', group: 'lefthook', size: 18, ring: 5, ...pos(5, 230) },
{ id: 'lh_lychee', label: 'lefthook:\nlychee-links', group: 'lefthook', size: 18, ring: 5, ...pos(5, 245) },
{ id: 'lh_gitleaks', label: 'lefthook:\ngitleaks', group: 'lefthook', size: 18, ring: 5, ...pos(5, 260) },
{ id: 'lh_gitleaks2', label: 'lefthook:\ngitleaks pre-push', group: 'lefthook', size: 18, ring: 5, ...pos(5, 275) }, // S/W boundary
{ id: 'lh_pint', label: 'lefthook:\npint', group: 'lefthook', size: 18, ring: 5, ...pos(5, 25) }, // N (workflow)
{ id: 'lh_larastan', label: 'lefthook:\nlarastan', group: 'lefthook', size: 18, ring: 5, ...pos(5, 50) }, // N
{ id: 'lh_squawk', label: 'lefthook:\nsquawk', group: 'lefthook', size: 18, ring: 5, ...pos(5, 320) }, // W (data)
// ── MEMORY FILES (15) — distributed на внешнем кольце
{ id: 'mem_user', label: 'memory:\nuser_profile', group: 'memory', size: 16, ring: 6, ...pos(6, 0) },
{ id: 'mem_comm', label: 'memory:\nfeedback_comm', group: 'memory', size: 14, ring: 6, ...pos(6, 24) },
{ id: 'mem_env', label: 'memory:\nfeedback_env', group: 'memory', size: 16, ring: 6, ...pos(6, 48) },
{ id: 'mem_sp', label: 'memory:\nfeedback_superpowers',group: 'memory', size: 16, ring: 6, ...pos(6, 72) },
{ id: 'mem_plugins', label: 'memory:\nfeedback_plugins', group: 'memory', size: 16, ring: 6, ...pos(6, 96) },
{ id: 'mem_handoff', label: 'memory:\nreference_handoff', group: 'memory', size: 14, ring: 6, ...pos(6, 120) },
{ id: 'mem_redesign', label: 'memory:\nportal_redesign', group: 'memory', size: 14, ring: 6, ...pos(6, 144) },
{ id: 'mem_devindices', label: 'memory:\ndev_indices', group: 'memory', size: 12, ring: 6, ...pos(6, 168) },
{ id: 'mem_phase1', label: 'memory:\nphase1_strategy', group: 'memory', size: 14, ring: 6, ...pos(6, 192) },
{ id: 'mem_state', label: 'memory:\nproject_state', group: 'memory', size: 16, ring: 6, ...pos(6, 216) },
{ id: 'mem_brain', label: 'memory:\nclaude_brain', group: 'memory', size: 14, ring: 6, ...pos(6, 240) },
{ id: 'mem_supplier', label: 'memory:\nsupplier_integration',group: 'memory', size: 14, ring: 6, ...pos(6, 264) },
{ id: 'mem_audit', label: 'memory:\naudit_2026-05-13', group: 'memory', size: 14, ring: 6, ...pos(6, 288) },
{ id: 'mem_archive', label: 'memory:\nreference_archive', group: 'memory', size: 14, ring: 6, ...pos(6, 312) },
{ id: 'mem_github', label: 'memory:\nreference_github', group: 'memory', size: 14, ring: 6, ...pos(6, 336) },
];
- Step 3: Visual verification
Refresh in Edge. Expected:
-
Pravila в центре.
-
3 узла на первом кольце вокруг Pravila.
-
5 плагинов на втором кольце.
-
14+2 skills на третьем (workflow в N-секторе).
-
Узлы группируются по секторам — RLS-related (
sk_rls,ag_rls,mcp_boost,mcp_redis,mcp_sentry,lh_squawk) в W-секторе (лево-верх). -
Граф больше не «free-floating» — иерархия от центра наружу видна.
-
Физика всё ещё включена (Task 7 это изменит) — узлы могут «дрейфовать», но начинают с radial позиций.
-
Step 4: Commit
git add docs/automation-graph.html
git commit -m "feat(graph): radial-sector layout — 6 колец × 4 сектора (workflow/UI/infra/data)"
Task 7: physics off + button handlers + smooth: continuous
Files:
- Modify:
docs/automation-graph.html— vis.Network options + Section 6 (TOOLBAR) кнопочные обработчики
Spec ref: Section 3 (vis.js options + Поведение кнопок).
- Step 1: Disable physics by default + simplify edges
Locate the physics block in new vis.Network(...):
physics: {
enabled: true,
solver: 'barnesHut',
barnesHut: { ... },
stabilization: { enabled: true, iterations: 300, fit: true },
},
Replace with:
physics: {
enabled: false,
},
Also update edges section (if not already done in Task 2):
edges: {
smooth: { type: 'continuous', roundness: 0.5 },
selectionWidth: 2,
},
- Step 2: Update stabilizationIterationsDone callback
Since physics is off by default, stabilization won't fire. Replace:
network.once('stabilizationIterationsDone', () => {
network.fit({ animation: { duration: 800, easingFunction: 'easeInOutQuad' } });
});
with immediate fit on afterDrawing:
network.once('afterDrawing', () => {
network.fit({ animation: { duration: 600, easingFunction: 'easeInOutQuad' } });
});
- Step 3: Update button handlers in SECTION 6
Locate the toolbar handlers. Replace:
document.getElementById('btn-freeze').addEventListener('click', () => {
network.setOptions({ physics: { enabled: false } });
});
document.getElementById('btn-unfreeze').addEventListener('click', () => {
network.setOptions({ physics: { enabled: true } });
});
document.getElementById('btn-reset').addEventListener('click', () => {
network.fit({ animation: { duration: 600, easingFunction: 'easeInOutQuad' } });
});
with:
document.getElementById('btn-freeze').addEventListener('click', () => {
network.setOptions({ physics: { enabled: false } });
});
document.getElementById('btn-unfreeze').addEventListener('click', () => {
network.setOptions({
physics: {
enabled: true,
solver: 'forceAtlas2Based',
forceAtlas2Based: {
gravitationalConstant: -50,
centralGravity: 0.0,
springLength: 100,
springConstant: 0.02,
damping: 0.6,
avoidOverlap: 0.4,
},
},
});
});
document.getElementById('btn-reset').addEventListener('click', () => {
// (a) Restore radial positions
nodesDS.update(NODES.map(n => ({ id: n.id, x: n.x, y: n.y })));
// (b) Refit camera
network.fit({ animation: { duration: 600, easingFunction: 'easeInOutQuad' } });
});
- Step 4: Visual verification
Refresh in Edge. Expected:
-
Граф появляется сразу в radial layout, без stabilization анимации.
-
Узлы стоят детерминированно по своим (x,y) позициям.
-
Нажми «Расшевелить» — узлы начинают слегка двигаться (мягкая физика).
-
Нажми «Зафиксировать» — узлы замирают.
-
Передвинь узел мышкой — он остаётся в новой позиции (физика off).
-
Нажми «Сбросить вид» — узлы возвращаются в radial позиции + камера центрируется.
-
Edges идут плавными дугами (smooth continuous), не пересекают узлы агрессивно.
-
Step 5: Commit
git add docs/automation-graph.html
git commit -m "feat(graph): physics off by default + buttons restore radial layout + smooth continuous"
Task 8: Final smoke test + summary commit
Files:
-
No new modifications (smoke test only)
-
Step 1: Full visual smoke
Open docs/automation-graph.html in Edge. F12 → Console. Verify:
- No JS errors in console — clean output.
- No canvas rendering artifacts — фон ровный (
#1e1e2e). - Радиальная компоновка — Pravila в центре, 3 правила вокруг, 5 плагинов на втором кольце, и т.д.
- Нет подписей на edges — только узлы + стрелки + 6 красных ⚡ маркеров.
- Hover на edge → tooltip с описанием связи.
- Click on node → правая панель: 7 секций (что делает / когда / ограничения / подчиняется / подчиняется ему / одновременно / конфликты).
- Все 73 узла имеют контент когда/ограничения — нет
—для основной секции (проверь 6 случайных узлов в разных группах). - Toolbar:
- Поиск
econ→ находит UserPromptSubmit:economy-mode, остальные dim'нуты. - «Зафиксировать» / «Расшевелить» работают.
- «Сбросить вид» возвращает radial + центрирует камеру.
- «Снять выделение» закрывает легенду + clears search.
- Поиск
- 6 красных конфликтов видны и кликабельны (для tooltip).
- Step 2: Data integrity check via node
Run validation script:
cd "c:/моя/проекты/портал crm/Документация" && node -e "
const fs = require('fs');
const html = fs.readFileSync('docs/automation-graph.html', 'utf8');
const start = html.indexOf('<script>') + 8;
const end = html.lastIndexOf('</script>');
let script = html.slice(start, end);
const cutAt = script.indexOf('// SECTION 4: VIS INIT');
script = script.slice(0, cutAt);
const wrapped = '(function(){\n' + script + '\nreturn {NODES,EDGES,NODE_DETAILS};\n})()';
fs.writeFileSync('docs/check_tmp.js', 'const r = ' + wrapped + ';\nconsole.log(\"NODES:\", r.NODES.length);\nconsole.log(\"EDGES:\", r.EDGES.length);\nconsole.log(\"NODE_DETAILS:\", Object.keys(r.NODE_DETAILS).length);\nconst missing = r.NODES.filter(n => !r.NODE_DETAILS[n.id]).map(n => n.id);\nconsole.log(\"Missing details:\", missing.length ? missing.join(\",\") : \"NONE\");\nconst noRing = r.NODES.filter(n => n.ring === undefined).map(n => n.id);\nconsole.log(\"No ring:\", noRing.length ? noRing.join(\",\") : \"NONE\");\nconst noWhen = r.NODES.filter(n => !(r.NODE_DETAILS[n.id] && r.NODE_DETAILS[n.id].when)).map(n => n.id);\nconsole.log(\"No when:\", noWhen.length ? noWhen.join(\",\") : \"NONE\");\nconst conflicts = r.EDGES.filter(e => e.dashes);\nconsole.log(\"Conflict edges:\", conflicts.length);\n');
" && node docs/check_tmp.js && rm docs/check_tmp.js
Expected output:
NODES: 73
EDGES: 72
NODE_DETAILS: 73
Missing details: NONE
No ring: NONE
No when: NONE
Conflict edges: 6
If any value differs — fix before proceeding.
- Step 3: No additional commit (all changes already committed in Tasks 1-7)
This task is verification-only. Если все 8 пунктов visual smoke + 6 строк data integrity check соответствуют ожиданиям — задача завершена.
Self-Review
1. Spec coverage check:
- ✅ Spec §1 (Rendering artifacts фона) → Task 1
- ✅ Spec §2 (Подписи рёбер → tooltips) → Task 2
- ✅ Spec §3 (Радиально-секторная иерархия) → Tasks 6 + 7
- ✅ Spec §4 (Когда + ограничения секции) → Tasks 3 + 4 (HTML/render) + Tasks 5a-5f (content)
- ✅ Spec «Финальная структура legend panel 7 секций» → Task 3 (HTML order)
- ✅ Spec «Поведение кнопок» → Task 7
2. Placeholder scan: Нет TBD/TODO. Все 73 узла имеют полный контент по when/limits (Tasks 5a-5f). Все 73 узла имеют ring + sectorAngle (Task 6).
3. Type consistency:
nd()signature: 7 args (desc, when, limits, reportsTo, manages, together, conflicts). Backward-compat handler в Task 4. Все 73 entries (Tasks 5a-5f) — в новой 7-arg форме.pos(ring, angleDeg)consistent в Task 6.physics.enabled = falseconsistent в Task 7 (initial state + после «Зафиксировать»).- IDs
pravila,claude_md, etc. — unchanged from base commit. - 73 NODES count preserved across all tasks.
4. Backward-compat в Task 4 nd(): до Tasks 5a-5f часть NODE_DETAILS будут 5-arg форме — handler ловит Array.isArray(when) и сдвигает аргументы. Это работающее промежуточное состояние.
Execution Handoff
Plan complete and saved to docs/superpowers/plans/2026-05-14-automation-graph-refactor.md. Two execution options:
1. Subagent-Driven (recommended) — fresh subagent per task + two-stage review между задачами.
2. Inline Execution — sequential execution в этой сессии через executing-plans.
Which approach?