2026-05-13 17:05:59 +03:00
<!DOCTYPE html>
< html lang = "ru" >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< title > Система автоматизации Лидерры< / title >
< script src = "https://unpkg.com/vis-network@9.1.9/standalone/umd/vis-network.min.js" > < / script >
2026-05-19 15:36:31 +03:00
< script src = "automation-graph-data.js" > < / script >
2026-05-13 17:05:59 +03:00
< style >
* { box-sizing : border-box ; margin : 0 ; padding : 0 ; }
body { background : #0d0d1a ; color : #fdf6e3 ; font-family : 'Segoe UI' , system-ui , sans-serif ; height : 100 vh ; display : flex ; flex-direction : column ; overflow : hidden ; }
/* ── Toolbar ── */
# toolbar { background : #073642 ; border-bottom : 1 px solid #586e75 ; padding : 8 px 12 px ; display : flex ; align-items : center ; gap : 10 px ; flex-shrink : 0 ; }
# toolbar h1 { font-size : 14 px ; color : #93a1a1 ; white-space : nowrap ; margin-right : 6 px ; }
# search { background : #002b36 ; border : 1 px solid #586e75 ; color : #fdf6e3 ; border-radius : 5 px ; padding : 5 px 10 px ; font-size : 13 px ; width : 220 px ; outline : none ; }
# search : focus { border-color : #268bd2 ; }
# search :: placeholder { color : #586e75 ; }
. btn { background : #073642 ; border : 1 px solid #586e75 ; color : #93a1a1 ; border-radius : 5 px ; padding : 5 px 12 px ; font-size : 12 px ; cursor : pointer ; transition : all 0.15 s ; }
. btn : hover { background : #0d4a5a ; color : #fdf6e3 ; border-color : #839496 ; }
# btn-clear { margin-left : auto ; }
/* ── Main area ── */
# main { flex : 1 ; display : flex ; overflow : hidden ; }
/* ── Graph canvas ── */
# network { flex : 1 ; background : #1e1e2e ; }
2026-05-14 09:09:01 +03:00
# network canvas { background : #1e1e2e ; }
2026-05-13 17:05:59 +03:00
/* ── Legend panel ── */
2026-05-14 12:17:08 +03:00
# legend-panel { width : 300 px ; min-width : 300 px ; background : #002b36 ; border-left : 1 px solid #586e75 ; overflow-y : auto ; padding : 16 px ; display : none ; flex-direction : column ; gap : 14 px ; position : relative ; }
# legend-handle {
position : absolute ; left : 0 ; top : 0 ;
width : 6 px ; height : 100 % ;
cursor : col-resize ;
background : transparent ;
transition : background 0.15 s ;
z-index : 10 ;
}
# legend-handle : hover , # legend-handle . dragging { background : #0d4a5a ; }
2026-05-13 17:05:59 +03:00
# legend-panel . visible { display : flex ; }
# legend-close { align-self : flex-end ; background : none ; border : none ; color : #586e75 ; font-size : 18 px ; cursor : pointer ; line-height : 1 ; padding : 0 ; }
# legend-close : hover { color : #fdf6e3 ; }
# legend-title { font-size : 15 px ; font-weight : 600 ; color : #fdf6e3 ; overflow-wrap : break-word ; }
2026-05-14 13:14:20 +03:00
# legend-edge-title { font-size : 15 px ; font-weight : 600 ; color : #fdf6e3 ; overflow-wrap : break-word ; line-height : 1.4 ; }
2026-05-13 17:05:59 +03:00
# legend-category { font-size : 11 px ; text-transform : uppercase ; letter-spacing : 0.08 em ; }
. legend-section { background : #073642 ; border-radius : 6 px ; padding : 10 px 12 px ; }
. legend-section h4 { font-size : 11 px ; text-transform : uppercase ; letter-spacing : 0.06 em ; color : #839496 ; margin-bottom : 6 px ; }
. legend-section p { font-size : 13 px ; color : #eee8d5 ; line-height : 1.5 ; }
. legend-section ul { list-style : none ; display : flex ; flex-direction : column ; gap : 4 px ; }
. legend-section li { font-size : 12 px ; color : #eee8d5 ; line-height : 1.4 ; }
. legend-section li span . cond { color : #839496 ; font-style : italic ; }
2026-05-14 13:16:56 +03:00
. conflict-item { border-radius : 4 px ; padding : 6 px 8 px ; margin-top : 4 px ; }
. conflict-item . cname { font-weight : 600 ; font-size : 12 px ; }
. conflict-item . cdesc { color : #eee8d5 ; font-size : 11 px ; margin-top : 2 px ; line-height : 1.4 ; }
2026-05-13 17:05:59 +03:00
# legend-no-conflicts { font-size : 12 px ; color : #586e75 ; }
/* ── Category legend footer ── */
# cat-legend { background : #073642 ; border-top : 1 px solid #586e75 ; padding : 7 px 14 px ; display : flex ; flex-wrap : wrap ; gap : 12 px ; flex-shrink : 0 ; }
. cat-item { display : flex ; align-items : center ; gap : 5 px ; font-size : 11 px ; color : #839496 ; }
. cat-dot { width : 10 px ; height : 10 px ; border-radius : 50 % ; flex-shrink : 0 ; }
2026-05-15 06:04:27 +03:00
/* .cat-item interactive states (Task 1) — separate from layout rule above to keep concerns split */
2026-05-15 06:00:14 +03:00
. cat-item {
cursor : pointer ;
padding : 2 px 6 px ;
border-radius : 4 px ;
transition : background 0.12 s , box-shadow 0.12 s ;
user-select : none ;
}
. cat-item : hover { background : rgba ( 255 , 255 , 255 , 0.05 ) ; }
. cat-item . active {
background : rgba ( 253 , 246 , 227 , 0.12 ) ;
box-shadow : inset 0 0 0 1 px rgba ( 253 , 246 , 227 , 0.4 ) ;
color : #fdf6e3 ;
}
2026-05-16 09:41:04 +03:00
/* ── Паспорт узла (iter6) ── */
# passport-section p { font-size : 12 px ; color : #eee8d5 ; line-height : 1.6 ; }
# passport-section p . pp-k { color : #839496 ; }
2026-05-16 09:54:44 +03:00
/* ── Кнопки режимов в футере (iter6) ── */
. cat-ctl-sep { width : 1 px ; align-self : stretch ; background : #586e75 ; margin : 0 4 px ; }
. cat-ctl {
background : #002b36 ; border : 1 px solid #586e75 ; color : #93a1a1 ;
border-radius : 4 px ; padding : 2 px 8 px ; font-size : 11 px ; cursor : pointer ;
transition : background 0.12 s , box-shadow 0.12 s ; user-select : none ;
}
. cat-ctl : hover { background : #0d4a5a ; color : #fdf6e3 ; }
. cat-ctl . active {
background : rgba ( 253 , 246 , 227 , 0.12 ) ;
box-shadow : inset 0 0 0 1 px rgba ( 253 , 246 , 227 , 0.4 ) ;
color : #fdf6e3 ;
}
2026-05-16 15:03:48 +03:00
/* ── Панель «Разделы» (функциональная квалификация) ── */
# legend-sections-content { display : flex ; flex-direction : column ; gap : 10 px ; }
# legend-sections-title { font-size : 15 px ; font-weight : 600 ; color : #fdf6e3 ; }
. sect-bucket-h { font-size : 11 px ; text-transform : uppercase ; letter-spacing : 0.06 em ; color : #b58900 ; font-weight : 600 ; margin : 8 px 0 2 px ; }
. sect-row { background : #073642 ; border-radius : 6 px ; padding : 7 px 10 px ; }
. sect-row . sect-empty { opacity : 0.5 ; }
. sect-name { font-size : 12 px ; color : #eee8d5 ; font-weight : 600 ; }
. sect-name . sect-id { color : #839496 ; font-weight : 400 ; }
. sect-cnt { font-size : 11 px ; color : #839496 ; }
. sect-empty-mark { font-size : 11 px ; color : #586e75 ; font-style : italic ; margin-top : 3 px ; }
. sect-chips { display : flex ; flex-wrap : wrap ; gap : 4 px ; margin-top : 5 px ; }
. sect-chip { font-size : 10 px ; color : #93a1a1 ; background : #002b36 ; border : 1 px solid #586e75 ; border-radius : 3 px ; padding : 1 px 5 px ; cursor : pointer ; }
. sect-chip : hover { background : #0d4a5a ; color : #fdf6e3 ; }
2026-05-16 22:31:26 +03:00
/* ── Панель «Хотелки» (отложенный backlog развития мозга) ── */
# legend-wishlist-content { display : flex ; flex-direction : column ; gap : 10 px ; }
# legend-wishlist-title { font-size : 15 px ; font-weight : 600 ; color : #fdf6e3 ; }
. wish-row { background : #073642 ; border-radius : 6 px ; padding : 8 px 10 px ; border-left : 3 px solid #586e75 ; }
. wish-row . wish-next { border-left-color : #859900 ; }
. wish-row . wish-blocked { border-left-color : #b58900 ; }
. wish-row . wish-idea { border-left-color : #586e75 ; }
. wish-head { font-size : 12 px ; color : #eee8d5 ; font-weight : 600 ; }
. wish-head . wish-id { color : #839496 ; font-weight : 400 ; }
. wish-status { font-size : 11 px ; margin-top : 3 px ; }
. wish-note { font-size : 11 px ; color : #93a1a1 ; margin-top : 4 px ; line-height : 1.5 ; }
. wish-sect { font-size : 10 px ; color : #586e75 ; margin-top : 4 px ; }
. wish-legend { font-size : 10 px ; color : #586e75 ; display : flex ; flex-wrap : wrap ; gap : 8 px ; margin-top : 6 px ; }
2026-05-13 17:05:59 +03:00
< / style >
< / head >
< body >
< div id = "toolbar" >
< h1 > 🗺 Лидерра — карта автоматизации< / h1 >
< input id = "search" type = "text" placeholder = "Поиск узла…" autocomplete = "off" >
< button class = "btn" id = "btn-freeze" > ❄ Зафиксировать< / button >
< button class = "btn" id = "btn-unfreeze" > ▶ Расшевелить< / button >
< button class = "btn" id = "btn-reset" > ⊙ Сбросить вид< / button >
< button class = "btn" id = "btn-clear" > ✕ Снять выделение< / button >
< / div >
< div id = "main" >
< div id = "network" > < / div >
< div id = "legend-panel" >
2026-05-14 12:17:08 +03:00
< div id = "legend-handle" title = "Перетащи, чтобы изменить ширину" > < / div >
2026-05-13 17:05:59 +03:00
< button id = "legend-close" > × < / button >
2026-05-14 13:14:20 +03:00
< div id = "legend-node-content" >
< div id = "legend-title" > —< / div >
< div id = "legend-category" > < / div >
2026-05-16 09:41:04 +03:00
< div class = "legend-section" id = "passport-section" >
< h4 > 📇 Паспорт узла< / h4 >
< p > < span class = "pp-k" > Внедрён:< / span > < span id = "ld-since" > —< / span > < / p >
< p > < span class = "pp-k" > Последнее изменение:< / span > < span id = "ld-changed" > —< / span > < / p >
2026-05-16 15:03:48 +03:00
< p > < span class = "pp-k" > Раздел:< / span > < span id = "ld-section" > —< / span > < / p >
2026-05-16 09:41:04 +03:00
< p > < span class = "pp-k" > Использований за 7 дней:< / span > < span id = "ld-uses" > —< / span > < / p >
< p id = "ld-dup-row" style = "display:none;" > < span class = "pp-k" > Дубль:< / span > < span id = "ld-dup" > —< / span > < / p >
< / div >
2026-05-14 13:14:20 +03:00
< 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 >
< div id = "legend-edge-content" style = "display:none;" >
< div id = "legend-edge-title" > —< / div >
< div class = "legend-section" > < h4 > Источник запроса< / h4 > < p id = "le-from" > —< / p > < / div >
< div class = "legend-section" > < h4 > Конечный получатель< / h4 > < p id = "le-to" > —< / p > < / div >
< div class = "legend-section" > < h4 > Тип связи< / h4 > < p id = "le-type" > —< / p > < / div >
< div class = "legend-section" > < h4 > Когда срабатывает< / h4 > < p id = "le-when" > —< / p > < / div >
< div class = "legend-section" > < h4 > Что передаёт< / h4 > < p id = "le-transfers" > —< / p > < / div >
< div class = "legend-section" > < h4 > Обязательность< / h4 > < p id = "le-mandatory" > —< / p > < / div >
< div class = "legend-section" > < h4 > Регламент< / h4 > < p id = "le-rule" > —< / p > < / div >
2026-05-13 17:05:59 +03:00
< / div >
2026-05-16 15:03:48 +03:00
< div id = "legend-sections-content" style = "display:none;" >
< div id = "legend-sections-title" > 📂 Разделы деятельности Лидерры< / div >
< div class = "legend-section" >
< p > Узлы карты распределены по функциональным разделам. Пустые разделы — будущие домены «мозга», под которые в карте dev-автоматики ещё нет узлов (playbook не наполнен).< / p >
< / div >
< div id = "sect-list" > < / div >
< / div >
2026-05-16 22:31:26 +03:00
< div id = "legend-wishlist-content" style = "display:none;" >
< div id = "legend-wishlist-title" > 💡 Хотелки — отложенный backlog< / div >
< div class = "legend-section" >
< p > Отложенные «хотелки» развития мозга и портала — то, что решили сделать позже, чтобы не забыть. Источник правды — массив WISHLIST в этом HTML-файле; новая хотелка = новый объект.< / p >
< div class = "wish-legend" > < span > ▶ к работе< / span > < span > ⏸ ждёт зависимости< / span > < span > 💭 идея< / span > < / div >
< / div >
< div id = "wish-list" > < / div >
< / div >
2026-05-13 17:05:59 +03:00
< / div >
< / div >
2026-05-15 06:12:43 +03:00
<!-- data - filter - key атрибуты потребляются SECTION 8 (interactive highlighting) -->
2026-05-13 17:05:59 +03:00
< div id = "cat-legend" >
2026-05-15 06:07:16 +03:00
< div class = "cat-item" data-filter-key = "group:rules" > < div class = "cat-dot" style = "background:#268bd2" > < / div > Правила< / div >
< div class = "cat-item" data-filter-key = "group:plugins" > < div class = "cat-dot" style = "background:#859900" > < / div > Плагины< / div >
< div class = "cat-item" data-filter-key = "group:skills_sp" > < div class = "cat-dot" style = "background:#6c71c4" > < / div > Скилы Superpowers< / div >
< div class = "cat-item" data-filter-key = "group:skills_proj" > < div class = "cat-dot" style = "background:#d33682" > < / div > Скилы проекта< / div >
< div class = "cat-item" data-filter-key = "group:hooks" > < div class = "cat-dot" style = "background:#2aa198" > < / div > Хуки< / div >
< div class = "cat-item" data-filter-key = "group:agents" > < div class = "cat-dot" style = "background:#b58900" > < / div > Агенты< / div >
< div class = "cat-item" data-filter-key = "group:mcp" > < div class = "cat-dot" style = "background:#cb4b16" > < / div > MCP-серверы< / div >
< div class = "cat-item" data-filter-key = "group:lefthook" > < div class = "cat-dot" style = "background:#dc322f" > < / div > Lefthook jobs< / div >
< div class = "cat-item" data-filter-key = "group:memory" > < div class = "cat-dot" style = "background:#586e75" > < / div > Memory files< / div >
2026-05-18 17:10:49 +03:00
< div class = "cat-item" data-filter-key = "group:ruflo" > < div class = "cat-dot" style = "background:#555555; border:1px dashed #888888" > < / div > 🔇 ruflo (изолирован 18.05)< / div >
2026-05-15 06:07:16 +03:00
< div class = "cat-item" data-filter-key = "conflict:RED" > < div class = "cat-dot" style = "background:#ff5f57; border:1px dashed #ff5f57" > < / div > 🔴 Не закрыт правилом< / div >
< div class = "cat-item" data-filter-key = "conflict:BLACK" > < div class = "cat-dot" style = "background:#888888; border:1px dashed #888888" > < / div > ⚫ Возник на практике< / div >
< div class = "cat-item" data-filter-key = "conflict:GREEN" > < div class = "cat-dot" style = "background:#859900; border:1px dashed #859900" > < / div > 🟢 Закрыт правилом< / div >
2026-05-16 09:54:44 +03:00
< span class = "cat-ctl-sep" > < / span >
< button class = "cat-ctl" id = "cat-ctl-heat" title = "Подсветить узлы по числу вызовов за 7 дней" > 🔥 По использованию< / button >
< button class = "cat-ctl" id = "cat-ctl-dup" title = "Подсветить явные пары дублей (D1–D5, D7)" > ⧉ Дубли< / button >
2026-05-16 15:03:48 +03:00
< button class = "cat-ctl" id = "cat-ctl-sect" title = "Показать функциональные разделы и распределение узлов по ним" > 📂 Разделы< / button >
2026-05-16 22:31:26 +03:00
< button class = "cat-ctl" id = "cat-ctl-wish" title = "Показать отложенные хотелки — backlog развития мозга и портала" > 💡 Хотелки< / button >
2026-05-13 17:05:59 +03:00
< / div >
< script >
// ════════════════════════════════════════════════════
// SECTION 1: NODES
// ════════════════════════════════════════════════════
2026-05-14 09:22:45 +03:00
2026-05-19 15:36:31 +03:00
// RADII, pos() — moved to automation-graph-data.js
2026-05-14 09:22:45 +03:00
2026-05-19 15:36:31 +03:00
// NODES — moved to automation-graph-data.js
2026-05-13 17:05:59 +03:00
// ════════════════════════════════════════════════════
// SECTION 2: EDGES
// ════════════════════════════════════════════════════
2026-05-19 15:36:31 +03:00
// CONFLICT_TYPES, E, CONFLICT — moved to automation-graph-data.js
2026-05-13 17:05:59 +03:00
2026-05-19 15:36:31 +03:00
// EDGES — moved to automation-graph-data.js
2026-05-13 17:05:59 +03:00
// ════════════════════════════════════════════════════
// SECTION 3: NODE DETAILS
// ════════════════════════════════════════════════════
2026-05-19 15:36:31 +03:00
// CATEGORY_LABELS — moved to automation-graph-data.js
2026-05-13 17:05:59 +03:00
2026-05-14 09:10:57 +03:00
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 and shift args.
if ( Array . isArray ( when ) ) {
return {
desc ,
when : '' ,
limits : '' ,
reportsTo : when ,
manages : limits ,
together : reportsTo ,
conflicts : ( manages || [ ] ) ,
} ;
}
return { desc , when : when || '' , limits : limits || '' , reportsTo , manages , together , conflicts : conflicts || [ ] } ;
2026-05-13 17:05:59 +03:00
}
const NODE _DETAILS = {
// ── ПРАВИЛА ──────────────────────────────────────
pravila : nd (
2026-05-14 12:29:21 +03:00
'Главный свод правил работы Клода — кто чем командует, что запрещено, какие обязательные действия.' ,
'Действует всегда — Клод читает его при старте каждой сессии.' ,
2026-05-16 13:44:14 +03:00
'§12 Superpowers — hard-rule уровня 0 цепочки приоритетов: скил инвокируется первым, §9 «Отступления» не применяется, economy-режим §12 не отменяет. Расходимость с другими документами — нарушение §7.' ,
[ ] ,
2026-05-13 17:05:59 +03:00
[
2026-05-14 12:29:21 +03:00
{ name : 'CLAUDE.md' , cond : 'подчинён, уровень 2a в цепочке приоритетов' } ,
{ name : 'PSR_v1' , cond : 'подчинён, уровень 3 в цепочке приоритетов' } ,
2026-05-14 17:15:39 +03:00
{ name : 'плагин Superpowers' , cond : '§12 обязывает запускать скил первым' } ,
2026-05-13 17:05:59 +03:00
{ name : 'Все компоненты' , cond : 'через цепочку приоритетов §1' }
] ,
2026-05-15 15:56:36 +03:00
[ { name : 'CLAUDE.md' , cond : 'оба читаются при старте сессии' } ] ,
2026-05-16 13:44:14 +03:00
[ { name : 'ruflo Queen' , desc : 'iter4– iter5: нормативка декларировала ruflo Queen-led routing уровнем − 1 (overlord) — расходилось с рантаймом (рой idle, 0 задач). Реколлаж 16.05.2026 (Pravila v1.16 / CLAUDE.md v2.2 / PSR_v1 v3.2 / Tooling v2.2) привёл нормативку к факту: ruflo переописан в advisory/automation-подсистему, уровень −1 убран. Конфликт «декларация ≠ рантайм» закрыт.' , type : 'GREEN' } ]
2026-05-13 17:05:59 +03:00
) ,
claude _md : nd (
2026-05-16 13:44:14 +03:00
'Оперативная карта проекта — технологии, команды, фазы, 7-уровневая цепочка приоритетов (§1, уровни 0–6) и §3.5 — ruflo как advisory/automation-подсистема, ссылки на документы.' ,
2026-05-14 12:29:21 +03:00
'Читается при старте каждой сессии; обновляется при новом инструменте или новой фазе.' ,
'Править можно только через скил `/claude-md-management:claude-md-improver` или `:revise-claude-md` (правило §5 п.10). Прямые Edit/Write блокируются хуком предупреждения.' ,
[ { name : 'Pravila' , cond : 'всегда подчинён (уровень 2a)' } ] ,
2026-05-13 17:05:59 +03:00
[
2026-05-18 16:48:21 +03:00
{ name : 'Tooling v2.15' , cond : 'ссылается как на реестр инструментов' } ,
2026-05-14 17:15:39 +03:00
{ name : 'плагин claude-md-management' , cond : 'правило §5 п.10 — единственный канал правок' }
2026-05-13 17:05:59 +03:00
] ,
[
2026-05-14 12:29:21 +03:00
{ name : 'Pravila' , cond : 'оба читаются при старте сессии' } ,
{ name : 'Tooling' , cond : 'оба — оперативные карты уровня 2' }
2026-05-13 17:05:59 +03:00
] ,
2026-05-14 12:59:25 +03:00
[ { name : 'PSR_v1' , desc : 'Правило §5 п.10 запрещает прямые правки, но PSR_v1 это явно не повторяет — есть риск Edit без скила' , type : 'GREEN' } ]
2026-05-13 17:05:59 +03:00
) ,
psr _v1 : nd (
2026-05-16 13:44:14 +03:00
'Правила совместной работы плагинов — кто с кем работает, какая процедура обязательна. R0 — головной фильтр выбора плагинов (с реколлажа 16.05.2026 снова на вершине стека, не sub-policy под ruflo).' ,
2026-05-14 17:15:39 +03:00
'При выборе 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-выводе плагинов.' ,
2026-05-14 12:29:21 +03:00
[ { name : 'Pravila' , cond : 'подчинён, уровень 3 в цепочке' } ] ,
2026-05-13 17:05:59 +03:00
[
2026-05-14 17:15:39 +03:00
{ name : 'плагин Superpowers + плагин Frontend Design' , cond : 'координирует как пару плагинов' } ,
{ name : 'плагин UI UX Pro Max' , cond : 'R14.3: включается только через процедуру' } ,
{ name : 'MCP-сервер 21st Magic' , cond : 'R14.4: включается только через процедуру' }
2026-05-13 17:05:59 +03:00
] ,
2026-05-14 12:29:21 +03:00
[ { name : 'CLAUDE.md' , cond : 'обе — оперативные карты, правятся согласованно' } ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'CLAUDE.md' , desc : 'CLAUDE.md §5 п.10 требует править только через скил claude-md-management, а PSR_v1 это ограничение не повторяет — риск прямых Edit' , type : 'GREEN' } ]
2026-05-13 17:05:59 +03:00
) ,
tooling : nd (
2026-05-18 11:14:01 +03:00
'Реестр 80 позиций — 60 формализованных инструментов + 20 ruflo-плагинов; §4.10 — ruflo как advisory/automation-подсистема. Когда что использовать, команды установки, конфликты.' ,
2026-05-14 17:15:39 +03:00
'При выборе инструмента для фазы (нулевая документация / первая backend / вторая frontend / третья перед запуском в боевую среду), при добавлении нового инструмента, при обновлении версий.' ,
2026-05-14 12:29:21 +03:00
'При прямом конфликте с CLAUDE.md побеждает CLAUDE.md (оперативная карта уровня 2a). Любая правка требует синхронизации с CLAUDE.md §3.' ,
2026-05-13 17:05:59 +03:00
[
2026-05-14 12:29:21 +03:00
{ name : 'Pravila' , cond : 'уровень 2b — оперативная карта рядом с CLAUDE.md' } ,
{ name : 'CLAUDE.md' , cond : 'при прямом конфликте побеждает CLAUDE.md' }
2026-05-13 17:05:59 +03:00
] ,
[ ] ,
2026-05-14 12:29:21 +03:00
[ { name : 'CLAUDE.md' , cond : 'обе — оперативные карты, правятся синхронно' } ]
2026-05-13 17:05:59 +03:00
) ,
// ── ПЛАГИНЫ ──────────────────────────────────────
superpowers : nd (
2026-05-14 12:29:21 +03:00
'Плагин поведения Клода — 14 скилов для тестов, отладки, планирования, параллельной работы.' ,
2026-05-14 17:15:39 +03:00
'При творческих, отладочных, тестовых и многошаговых задачах: скил brainstorming (продумать варианты) / скил TDD (разработка через тесты — failing test first) / скил systematic-debugging / скил verification-before-completion (обязательная проверка готовности) / скил writing-plans / скил parallel-work / скил worktree / скил finishing-PR (запрос на слияние кода) / скил subagent-driven-development / скил writing-skills (карта типов в §12.2 Pravila).' ,
2026-05-16 13:44:14 +03:00
'§12 Superpowers — hard-rule уровня 0 цепочки приоритетов: скил инвокируется первым. Единственная отмена — явная просьба заказчика «не используй superpowers сейчас» на текущее действие; §9 «Отступления» к §12 не применяется; economy-режим §12 не отменяет.' ,
2026-05-13 17:05:59 +03:00
[
2026-05-14 12:29:21 +03:00
{ name : 'Pravila §12' , cond : 'обязательное правило: скил запускается первым' } ,
2026-05-14 17:15:39 +03:00
{ name : 'PSR_v1' , cond : 'координирует как пару с плагином Frontend Design' }
2026-05-13 17:05:59 +03:00
] ,
2026-05-14 17:15:39 +03:00
[ { name : 'Все 14 скилов Superpowers' , cond : 'содержит' } ] ,
[ { name : 'плагин Frontend Design' , cond : 'пара — работают вместе при UI-задачах' } ] ,
2026-05-16 13:44:14 +03:00
[ { name : 'хук economy-mode' , desc : 'Режим экономии 100% теоретически может «сэкономить» запуск скила — §12 (hard-rule уровня 0) economy-режим не отменяет.' , type : 'GREEN' } ]
2026-05-13 17:05:59 +03:00
) ,
fd _plugin : nd (
2026-05-14 17:15:39 +03:00
'Плагин знаний о UI — Vue, Vuetify, доступность (accessibility), паттерны компонентов для Лидерры.' ,
'При UI/UX задачах — компоненты, экраны, паттерны взаимодействия; в паре с плагином Superpowers (даёт процесс).' ,
2026-05-14 12:29:21 +03:00
'Фильтр стека R6.0: срезать React/Tailwind/shadcn/JSX в Vue 3 + Vuetify 3. Обязательное правило палитры Forest R6.1 для цветов, шрифтов и иконок.' ,
[ { name : 'PSR_v1' , cond : 'R5: подчинён как часть пары плагинов' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'плагин Superpowers' , cond : 'пара — Frontend Design даёт UI-знания, Superpowers даёт процесс' } ] ,
2026-05-13 17:05:59 +03:00
[
2026-05-14 17:15:39 +03:00
{ name : 'плагин UI UX Pro Max' , desc : 'Правило PSR_v1 R14.5: нельзя одновременно — оба включены в настройках, но должны чередоваться' , type : 'GREEN' } ,
{ name : 'MCP-сервер 21st Magic' , desc : 'Правило PSR_v1 R14.5: нельзя одновременно с Frontend Design — оба потенциально доступны' , type : 'GREEN' }
2026-05-13 17:05:59 +03:00
]
) ,
upm : nd (
2026-05-14 12:29:21 +03:00
'Резервная библиотека UI — 50+ стилей, 161 палитра, 99 правил-подсказок UX. Только по процедуре.' ,
2026-05-14 17:15:39 +03:00
'Только по процедуре PSR_v1 R14.3: запасной вариант к плагину Frontend Design ИЛИ «третий вариант» в архитектурном решении.' ,
'R14.5: нельзя одновременно с плагином Frontend Design / MCP-сервером 21st Magic. Фильтр стека R6.0 и обязательное правило палитры Forest R6.1 — обязательны. Проверка доступности Pa11y (автопроверка accessibility — доступности) перед выкаткой.' ,
2026-05-14 12:29:21 +03:00
[ { name : 'PSR_v1' , cond : 'R14.3: включается только через процедуру, не сам по себе' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'плагин Frontend Design' , desc : 'Правило PSR_v1 R14.5: нельзя одновременно — UI UX Pro Max как материал, Frontend Design как решатель; риск смешать роли' , type : 'GREEN' } ]
2026-05-13 17:05:59 +03:00
) ,
claude _md _mgmt : nd (
2026-05-14 12:29:21 +03:00
'Единственный разрешённый способ править CLAUDE.md — через скил claude-md-improver или revise-claude-md.' ,
'При любой правке CLAUDE.md (новая фаза, новый инструмент, смена версии, новые особенности — всё через скил).' ,
'Правило PSR_v1 R10.1 блок 1 (инфраструктурная категория). Внутри процедуры продолжают действовать §4 правил Клода (синхронизация Pravila + Tooling).' ,
2026-05-13 17:05:59 +03:00
[ { name : 'PSR_v1' , cond : 'R10.1 Блок 1: инфраструктурная категория' } ] ,
2026-05-14 12:29:21 +03:00
[ { name : 'CLAUDE.md' , cond : 'правило §5 п.10: единственный канал правок' } ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'скил q-item-add' , cond : 'скил делегирует правки CLAUDE.md через этот плагин' } ]
2026-05-13 17:05:59 +03:00
) ,
hookify _plugin : nd (
2026-05-14 12:29:21 +03:00
'Плагин создания хуков — анализирует разговоры и предлагает новые автоматизации в виде хуков.' ,
'При запросе «давай повесим хук на это поведение» или после серии повторяющихся ошибок — анализ через агента conversation-analyzer.' ,
2026-05-18 11:14:01 +03:00
'PSR_v1 R10.1 блок 1 #58 (authoring-tooling). HK1 hard-rule: только по явному /hookify, не проактивно; перед генерацией хука — обязательный pre-check на коллизию с зарегистрированными хуками settings.json; перезапись 6-компонентной economy/skill-discipline архитектуры запрещена. ADR-010.' ,
[ { name : 'PSR_v1' , cond : 'R10.1 блок 1 #58: authoring-tooling, HK1 pre-check (ADR-010)' } ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'агент hookify:conversation-analyzer' , cond : 'запускает анализ разговоров' } ] ,
[ { name : 'агент hookify:conversation-analyzer' , cond : 'плагин и агент работают в паре' } ] ,
2026-05-13 17:05:59 +03:00
[
2026-05-18 11:14:01 +03:00
{ name : 'хук pre-claude-warn' , desc : 'Закрыто правилом HK1 (ADR-010): hookify — только по явному /hookify, перед генерацией хука обязательный pre-check на коллизию с существующими хуками settings.json; перезапись 6-компонентной economy/skill-discipline архитектуры запрещена' , type : 'GREEN' }
2026-05-13 17:05:59 +03:00
]
) ,
2026-05-17 04:46:32 +03:00
// ── A6 ARCHITECTURE-TOOLING (17.05.2026) ─────────
adr _kit : nd (
'Плагин ADR (Architecture Decision Records) — фиксация закрытых архитектурных решений в docs/adr/ (формат Nygard, 7 секций) + декларативный энфорсер adr-judge.' ,
'При фиксации архитектурного решения — стек, паттерн, граница слоёв; ADR-NNN в docs/adr/. Открытые вопросы — не сюда, они в реестре Открытые_вопросы.' ,
'Правило PSR_v1 R10.1 блок 1 (architecture-tooling, off-phase). adr-judge врезан в lefthook pre-commit job 9 — декларативный regex без --llm, 0 вызовов Claude API. init/install-hooks НЕ запускаются (конфликт-аудит AK1/AK2). Не UI → вне фильтров R6.0/R6.1/R14. Tooling §4.11, CLAUDE.md §3.3 #36.' ,
[ { name : 'PSR_v1' , cond : 'R10.1 блок 1: architecture-tooling' } , { name : 'Tooling' , cond : '§4.11 #36 — реестр' } ] ,
[ { name : 'lefthook job 9 (adr-judge)' , cond : 'врезан как pre-commit проверка Enforcement-блоков' } ] ,
[ { name : 'docs/adr/' , cond : 'хранилище ADR — ADR-000/001/002' } ]
) ,
arch _patterns : nd (
'Скил-плагин — справочник архитектурных паттернов (Clean / Hexagonal / layered architecture, Domain-Driven Design). Knowledge-only, не решатель.' ,
'При архитектурном вопросе «какой паттерн подходит» — playbook паттернов; код не генерирует, файлы не правит.' ,
'Правило PSR_v1 R10.1 блок 1 (architecture-tooling, off-phase). Knowledge-only — без хуков и машинерии. Не UI → вне фильтров R6.0/R6.1/R14. Tooling §4.13, CLAUDE.md §3.3 #38.' ,
[ { name : 'PSR_v1' , cond : 'R10.1 блок 1: architecture-tooling' } , { name : 'Tooling' , cond : '§4.13 #38 — реестр' } ] ,
[ ] ,
[ ]
) ,
mermaid _skill : nd (
'Вендоренный standalone-скил (.claude/skills/mermaid/) — генерирует исходник Mermaid-диаграмм (23 типа, включая C4/architecture). Рендера mmdc/Chromium не требует.' ,
'При построении C4/архитектурной диаграммы — результат в docs/architecture/ (Mermaid рендерится на GitHub нативно).' ,
'Вендорен — не плагин, не marketplace, не подсистема (конфликт-аудит CC1: иммунен к потере апстрима). lefthook markdownlint+cspell исключают .claude/skills/mermaid/** (MK1). Tooling §4.12, CLAUDE.md §3.3 #37.' ,
[ { name : 'Tooling' , cond : '§4.12 #37 — реестр' } ] ,
[ ] ,
[ { name : 'docs/architecture/' , cond : 'C4-диаграммы → c4-context.md' } ]
) ,
2026-05-17 11:32:37 +03:00
deptrac : nd (
'Composer dev-dependency deptrac/deptrac v4.6.1 (BSD-3) — статический анализ направления зависимостей между слоями App\\ (Controller/Service/Model/Job/…). Чистый PHP, 0 вызовов LLM.' ,
'Архитектурный fitness-гейт: проверяет, что код не нарушает границы слоёв. Конфиг app/deptrac.yaml (13 слоёв) + ruleset; запускается автоматически как lefthook pre-commit job 10 на staged app/**/*.php.' ,
'Правило PSR_v1 R10.1 блок 1 note (architecture-tooling, off-phase — composer dev-dep, не marketplace-плагин). Первый прогон 0 нарушений → baseline-файл не нужен (red-green доказан). Не UI → вне фильтров R6.0/R6.1/R14. Tooling §4.18, CLAUDE.md §3.3 #43.' ,
[ { name : 'PSR_v1' , cond : 'R10.1 блок 1 note: architecture-tooling' } , { name : 'Tooling' , cond : '§4.18 #43 — реестр' } ] ,
[ { name : 'lefthook job 10 (deptrac)' , cond : 'врезан как pre-commit гейт направления зависимостей' } ] ,
[ { name : 'docs/architecture/' , cond : 'mermaidjs-форматтер → c4-component-layers.md' } ]
) ,
2026-05-17 04:46:32 +03:00
2026-05-17 12:35:00 +03:00
// ── A4 DESIGN-TOOLING (17.05.2026) ──────────────
mcp _figma : nd (
'MCP Figma (#44) — DEFERRED, precondition: Figma-аккаунт. Extract-only (ADR-006): извлечение токенов/variables из источника дизайна. FD #30 остаётся единственным UI-решателем.' ,
'При наличии Figma-аккаунта и нужде извлечь дизайн-токены/variables напрямую из Figma-файла.' ,
2026-05-17 12:40:49 +03:00
'DEFERRED — не установлен, требует Figma-аккаунт (Б-1). Не UI-решатель → вне R6.0/R6.1/R14. Extract-only, не генерирует UI-решения. PSR_v1 R10.1 блок 3.' ,
[ { name : 'PSR_v1' , cond : 'R10.1 блок 3: design-tooling (DEFERRED)' } ] ,
2026-05-17 12:35:00 +03:00
[ ] ,
[ { name : 'Frontend Design' , cond : 'FD остаётся единственным UI-решателем; Figma MCP — только источник токенов' } ]
) ,
mcp _icons : nd (
'MCP Universal Icons (#45) — поиск/вставка SVG-иконок, 10 коллекций включая Lucide. Tools search_icons/get_icon. SVG framework-neutral (R6.0).' ,
'При поиске иконки из коллекции Lucide или других (Heroicons, Tabler, Phosphor и др.) — получить SVG-исходник для вставки в Vue-компонент.' ,
2026-05-17 12:40:49 +03:00
'SVG framework-neutral — результат нужно обернуть в Vue-компонент вручную. R6.0 фильтр не блокирует (SVG — не React/Tailwind). Lucide — branded иконочный стек проекта (CLAUDE.md §2). PSR_v1 R10.1 блок 3.' ,
[ { name : 'PSR_v1' , cond : 'R10.1 блок 3: design-tooling' } ] ,
2026-05-17 12:35:00 +03:00
[ ] ,
[ { name : 'Frontend Design' , cond : 'FD использует результат поиска как материал при UI-задачах' } ]
) ,
design _plugin : nd (
'Плагин Design (#46, Anthropic Verified) — дизайн-критика, a11y-аудит дизайн-уровня, UX-копирайт, research synthesis. Pre-code (ADR-006); Pa11y остаётся техническим a11y SoT.' ,
'При дизайн-критике макета или компонента, при UX-анализе flow, при написании UX-копирайта, при synthesis пользовательских исследований.' ,
'Pre-code инструмент (ADR-006) — не генерирует финальный код, даёт дизайн-рекомендации. Pa11y остаётся техническим a11y SoT (§5 п.3). Не UI-решатель в смысле PSR_v1 R14 → вне R14 pipeline. PSR_v1 R10.1 блок 1.' ,
[ { name : 'PSR_v1' , cond : 'R10.1 блок 1: design-tooling' } ] ,
[ ] ,
[ { name : 'Frontend Design' , cond : 'Design plugin — pre-code критика; FD — post-spec UI-решатель; разные фазы' } ]
) ,
2026-05-17 08:54:31 +03:00
// ── C9 PROJECT-MANAGEMENT-TOOLING (17.05.2026) ──
ccpm : nd (
'Vendored-скил CCPM: PRD→эпик→GitHub-issue→код с трассируемостью. Раздел C9 опирается также на reuse — GitHub MCP (issues/Projects v2) + Superpowers writing-plans + q-item-add.' ,
'При создании PRD, декомпозиции на эпики/задачи, связывании с GitHub Issues — стек CCPM + GitHub MCP + writing-plans.' ,
'Вендорен в .claude/skills/ccpm/ (C9 project-management-tooling, off-phase). Раздел C9. Tooling #41, CLAUDE.md §3.3 #41.' ,
[ { name : 'Tooling' , cond : '§4.16 #41 — реестр' } ] ,
[ ] ,
[ { name : 'GitHub MCP' , cond : 'CCPM использует GitHub Issues/Projects v2 как source-of-truth' } ]
) ,
product _mgmt : nd (
'Плагин Anthropic (product-management@knowledge-work-plugins): PRD/роадмап/метрики — product-strategy церемонии.' ,
'При написании PRD, обновлении роадмапа, анализе метрик продукта — skills product-management плагина.' ,
'Правило PSR_v1 R10.1 блок 1 (project-management-tooling, off-phase). Не UI → вне фильтров R6.0/R6.1/R14. Tooling #42, CLAUDE.md §3.3 #42.' ,
[ { name : 'PSR_v1' , cond : 'R10.1 блок 1: project-management-tooling' } , { name : 'Tooling' , cond : '§4.17 #42 — реестр' } ] ,
[ ] ,
[ ]
) ,
2026-05-17 06:10:12 +03:00
// ── D3 AUDIT-SECURITY (17.05.2026) ───────────────
tob _skills : nd (
'Marketplace-плагин Trail of Bits (`trailofbits/skills`) — курированный субсет 8 audit-плагинов: `differential-review`, `audit-context-building`, `supply-chain-risk-auditor`, `insecure-defaults`, `sharp-edges`, `static-analysis`, `variant-analysis`, `agentic-actions-auditor`. Глубокие on-demand аудит-кампании. Раздел D3. Tooling #39, off-phase audit-security.' ,
'При глубоком аудите безопасности: diff-ревью, supply-chain риски зависимостей, поиск вариантов уязвимостей, статический анализ (SARIF). Глубокие кампании — не inline SAST.' ,
'Правило PSR_v1 R10.1 блок 1 (audit-security, off-phase). Граница TB1: Semgrep MCP (#25) = inline SAST, ToB = глубокие on-demand кампании. CC-BY-SA-4.0 — не вендорено, лицензионный триггер TB4 не применяется. Не UI → вне R6.0/R6.1/R14. Tooling §4.14, CLAUDE.md §3.3 #39.' ,
[ { name : 'PSR_v1' , cond : 'R10.1 блок 1: audit-security' } , { name : 'Tooling' , cond : '§4.14 #39 — реестр' } ] ,
[ ] ,
[ { name : 'MCP: semgrep' , cond : 'TB1: граница — Semgrep inline SAST, ToB глубокие кампании' } ] ,
[ { name : 'MCP: semgrep' , desc : 'TB1: граница разграничена регламентом — Semgrep = inline SAST в процессе работы, Trail of Bits = глубокие аудит-кампании по запросу. Параллельное использование разрешено при разных сценариях.' , type : 'GREEN' } ]
) ,
sec _guidance : nd (
2026-05-17 07:25:31 +03:00
'Anthropic-плагин (`security-guidance@claude-plugins-official`, Anthropic Verified) — один блокирующий PreToolUse-хук, inline-предупреждения уязвимостей при правке кода (8 контентных правил + 1 path-правило). При первом за сессию совпадении уязвимого паттерна в файле — sys.exit(2), блокирует правку (одноразовый speed-bump, retry проходит). Раздел D3. Tooling #40.' ,
'Активен автоматически при каждом Write/Edit/MultiEdit — при уязвимом паттерне печатает предупреждение и блокирует первую такую правку файла за сессию; повторная попытка проходит.' ,
'Правило PSR_v1 R10.1 блок 1 (audit-security, off-phase). SG1: 5-й PreToolUse-хук, блокирующий (sys.exit 2), одноразовый per «файл+правило» за сессию — economy/ruflo-цепочка не нарушается, +~34 мс/правку. SG2: Windows-починка — bundled hooks.json зовёт python3 (нет в PATH), решено python3.exe-шимом в каталоге Python. Не UI → вне R6.0/R6.1/R14. Tooling §4.15, CLAUDE.md §3.3 #40.' ,
2026-05-17 06:10:12 +03:00
[ { name : 'PSR_v1' , cond : 'R10.1 блок 1: audit-security' } , { name : 'Tooling' , cond : '§4.15 #40 — реестр' } ] ,
[ ] ,
[ { name : 'скил security-review' , cond : 'оба — D3 audit-security; sec_guidance inline, sk_security_review ручной' } ]
) ,
sk _security _review : nd (
'Кастомизированная Anthropic-команда `/security-review` — копия в `.claude/commands/security-review.md` с проектным FP-фильтром (RLS / ПДн / economy-хуки). Раздел D3. D3 #2.' ,
'При ручном security-review кода или PR — запуск `/security-review` с проектным контекстом для фильтрации ложных срабатываний.' ,
'Проектный FP-фильтр: RLS-политики / ПДн-поля / economy-хуки — не считаются уязвимостями. Раздел D3.' ,
[ { name : 'Tooling' , cond : 'D3 #2 — проектная кастомизация' } ] ,
[ ] ,
[ { name : 'sec_guidance' , cond : 'оба D3 audit-security; sec_guidance — inline warn, security-review — ручной аудит' } , { name : 'audit-portal' , cond : 'sk_audit_portal оркеструет security-review как фазу аудита' } ]
) ,
sk _audit _portal : nd (
'Проектный скил — 14-фазный портальный аудит (дистилляция аудитов #1/#2/#3). Покрывает: PHP/Vue статический анализ, RLS, a11y, coverage, зависимости, secrets. Раздел D3.' ,
'При проведении полного аудита портала — запуск 14 фаз последовательно с документированием находок P0/P1/P2/P3.' ,
'Раздел D3. Оркеструет несколько инструментов: sk_security_review, Trail of Bits Skills, regression-скил. Находки фиксируются в docs/superpowers/audits/.' ,
[ { name : 'Tooling' , cond : 'D3 — проектный аудит-скил' } ] ,
[ { name : 'скил security-review' , cond : 'оркеструет как security-фазу аудита' } , { name : 'Trail of Bits Skills' , cond : 'оркеструет для глубоких кампаний' } , { name : 'скил regression' , cond : 'использует на фазе тестов' } ] ,
[ { name : 'скил security-review' , cond : 'пара в D3 audit-security' } ]
) ,
2026-05-17 15:39:30 +03:00
// ── A3 INTEGRATION-TOOLING (17.05.2026) ──────────
ag _apidocs : nd (
'Агент claude-flow — генерирует OpenAPI-спеку REST API по роутам и контроллерам Laravel. Pattern learning. 0 установки — агент доступен в сессии.' ,
'При фиксации контракта REST API: генерация/обновление OpenAPI-спеки группы эндпоинтов. Результат — docs/api/.' ,
'Sub-агент claude-flow — узел карты, но без отдельного номера в реестре Tooling Прил. Н (реестр — plugin-grain; 11 agent-узлов карты так же без Tooling-номеров). Не UI → вне фильтров R6.0/R6.1/R14.' ,
[ { name : 'CLAUDE.md' , cond : '§3.3 — упомянут при #47 openapi-mcp' } ] ,
[ ] ,
[ { name : 'MCP: openapi' , cond : 'генерирует спеку → openapi-mcp отдаёт её как MCP-ресурс' } ]
) ,
mcp _openapi : nd (
'MCP-сервер (npm, stdio) — отдаёт OpenAPI-спеку как MCP-ресурс/тулы; introspection своей и чужих API при интеграционной разработке.' ,
'При работе с интеграциями (API/вебхуки) — обращение к структуре OpenAPI-спеки из сессии Claude. READ-ONLY introspection.' ,
'Правило PSR_v1 R10.1 блок 3 (integration-tooling, off-phase — 9-я подкатегория). stdio-режим, без port-conflict. Не UI → вне фильтров R6.0/R6.1/R14. Tooling §4.22 #47, CLAUDE.md §3.3 #47.' ,
[ { name : 'PSR_v1' , cond : 'R10.1 блок 3: integration-tooling' } , { name : 'Tooling' , cond : '§4.22 #47 — реестр' } ] ,
[ ] ,
[ { name : 'docs/api/' , cond : 'источник OpenAPI-спеки' } ]
) ,
2026-05-17 17:42:18 +03:00
// ── A11 ML-AI-TOOLING (17.05.2026) ──────────────
claude _api : nd (
'Скил сборки AI-фич на Anthropic SDK (prompt-кэш). Reuse — раздел A11 опирается также на context7 MCP (доки) и Sentry MCP (LLM-наблюдаемость).' ,
'При разработке AI-фич на Anthropic API / Claude SDK — скил задаёт паттерны prompt-кэша, batch-запросов, tool use.' ,
'Reuse-узел раздела A11 (ml-ai-tooling). claude-api — встроенный скил Claude Code, не нумерованная Tooling-позиция; регистрация — Tooling «built-in skills» + PSR_v1 R10.1 блок 2. В A11 — reuse-слой (CLAUDE.md §6). Не UI → вне фильтров R6.0/R6.1/R14.' ,
[ { name : 'Tooling' , cond : 'built-in skill — PSR_v1 R10.1 блок 2 (reuse)' } ] ,
[ ] ,
[ { name : 'context7 MCP' , cond : 'документация Anthropic SDK' } , { name : 'Sentry MCP' , cond : 'LLM-наблюдаемость (off-phase reuse)' } ]
) ,
promptfoo : nd (
'npm-CLI eval LLM-промптов: ассерты, регрессия, red-team. Запуск вручную/CI — не в хуках (платные LLM-вызовы).' ,
'При разработке и проверке AI-промптов — запуск test-suite promptfoo вручную или в CI. Никогда в pre-commit хук (ML1: платные вызовы).' ,
'Правило PSR_v1 R10.1 блок 1 note (ml-ai-tooling, off-phase). npm devDependency, тяжёлый (~1090 пакетов). Не UI → вне фильтров R6.0/R6.1/R14. Tooling §4.23 #48, CLAUDE.md §3.3 #48.' ,
[ { name : 'PSR_v1' , cond : 'R10.1 блок 1: ml-ai-tooling' } ] ,
[ { name : 'ML1' , cond : 'никогда в хук/pre-commit — платные LLM-вызовы' } ] ,
[ ]
) ,
data _scientist : nd (
'Vendored-скил: классический ML-воркфлоу — выбор алгоритма, feature engineering, оценка модели.' ,
'При ML-задаче (выбор алгоритма, feature engineering, валидация модели) — knowledge-only playbook без генерации кода.' ,
'Вендорен в .claude/skills/data-scientist/ (ML3 — lefthook markdownlint+cspell исключают через job-exclude). Knowledge-only, не решатель. Не UI → вне фильтров R6.0/R6.1/R14. Tooling §4.24 #49, CLAUDE.md §3.3 #49.' ,
[ { name : 'Tooling' , cond : '§4.24 #49 — реестр' } ] ,
[ ] ,
[ ]
) ,
2026-05-18 04:19:42 +03:00
// ── C10 BUSINESS-PROCESS (17.05.2026) ────────────
ops _plugin : nd (
'Плагин Anthropic operations — 9 скилов бизнес-процессов: документирование, оптимизация, change-management, capacity-планирование.' ,
'При работе с бизнес-процессом — документировать процесс, спланировать change-request, рассчитать capacity. Marketplace-плагин, 0 lifecycle-хуков.' ,
'Правило PSR_v1 R10.1 блок 1 (business-process, off-phase). Marketplace `operations@knowledge-work-plugins` v1.2.0, тот же marketplace что #42/#46. Не UI → вне фильтров R6.0/R6.1/R14. Tooling §4.26 #51, CLAUDE.md §3.3 #51.' ,
[ { name : 'PSR_v1' , cond : 'R10.1 блок 1: business-process' } ] ,
[ { name : 'OPS1' , cond : 'process-doc → Mermaid-исходник; рендер за mermaid' } , { name : 'OPS5' , cond : 'generic ↔ self-authored stack-grounded скилы' } ] ,
[ { name : 'mermaid' , cond : 'рендер диаграмм процесса' } ]
) ,
process _modeling : nd (
'Self-authored скил: моделирование to-be бизнес-процесса — BPMN 2.0, карты процессов, RACI, state-машины.' ,
'При проектировании бизнес-процесса — выбрать артефакт (BPMN/swimlane/journey/RACI), построить модель. Рендер делегируется скилу mermaid.' ,
'Свой project-скил в .claude/skills/process-modeling/ (не вендоренный → линтуется, конфликт-аудит LINT1). Не UI → вне фильтров R6.0/R6.1/R14. Tooling §4.27 #52, CLAUDE.md §3.3 #52.' ,
[ { name : 'Tooling' , cond : '§4.27 #52 — реестр' } ] ,
[ { name : 'BPMN1' , cond : 'нотация process-modeling ≠ mermaid рендер' } ] ,
[ { name : 'mermaid' , cond : 'рендер BPMN/диаграмм' } , { name : 'process-analysis' , cond : 'as-is ↔ to-be пара' } ]
) ,
process _analysis : nd (
'Self-authored скил: анализ as-is бизнес-процесса — discovery из кода Laravel, узкие места, трассировка, метрики.' ,
'При вскрытии существующего процесса — реконструировать из routes/jobs/audit-логов, найти узкие места, посчитать KPI.' ,
'Свой project-скил в .claude/skills/process-analysis/ (не вендоренный → линтуется, LINT1). Не UI → вне фильтров R6.0/R6.1/R14. Tooling §4.28 #53, CLAUDE.md §3.3 #53.' ,
[ { name : 'Tooling' , cond : '§4.28 #53 — реестр' } ] ,
[ { name : 'PA1' , cond : 'процессные узкие места ≠ runtime (perf-analyzer)' } ] ,
[ { name : 'process-modeling' , cond : 'as-is ↔ to-be пара' } ]
) ,
2026-05-18 07:35:36 +03:00
// ── DISCOVERY-TOOLING (18.05.2026) ────────────
discovery _interview : nd (
'Self-authored скил: структурированное интервью-discovery до проектирования — FEATURE (JTBD-интервью заказчика) + SYSTEM (ориентация по мета-слою проекта).' ,
'При расплывчатом проблемном запросе — провести JTBD-интервью, отдать discovery-brief в brainstorming; при «сориентируй по проекту» — синтез по карте/CLAUDE.md/MEMORY/Открытые_вопросы/Tooling.' ,
'Свой project-скил в .claude/skills/discovery-interview/ (не вендоренный → линтуется, LINT1). Не UI → вне фильтров R6.0/R6.1/R14. Триггер-eval 20/20. Tooling §4.30 #55, CLAUDE.md §3.3 #55, ADR-009.' ,
[ { name : 'PSR_v1' , cond : 'R10.1 блок 1 note: discovery-tooling' } , { name : 'Tooling' , cond : '§4.30 #55 — реестр' } ] ,
[ { name : 'DI2' , cond : 'разрез по слою-источнику с process-analysis (ADR-009)' } ] ,
[ { name : 'process-analysis' , cond : 'граница: app-код ↔ голова заказчика/мета-слой' } , { name : 'brainstorming' , cond : 'хэндофф FEATURE-brief' } ]
) ,
2026-05-20 09:54:25 +03:00
// ── FINANCE-TOOLING C6+C7 (20.05.2026, ADR-012) ──
finance _plugin : nd (
'Marketplace-плагин (Anthropic): финансы/бухгалтерия — сверка, variance-анализ, US-GAAP-отчётность, закрытие периода, проводки. 8 скилов.' ,
'При учётно-финансовой работе C7 (и сверке/variance для C6). РФ: reconciliation/variance ✅; US-GAAP-скилы ⚠️; SOX ❌; warehouse-MCP DEFERRED.' ,
'plugin finance@knowledge-work-plugins (enabledPlugins). Категория finance-tooling, homed C7. Не UI → вне R6/R14. Tooling §4.36 #61, CLAUDE.md §3.3 #61, ADR-012.' ,
[ { name : 'Tooling' , cond : '§4.36 #61 — реестр' } ] ,
[ { name : 'FIN2' , cond : 'SOX not-applicable РФ' } , { name : 'FIN3' , cond : 'граница с operations #51' } ] ,
[ { name : 'ru-tax-accounting' , cond : 'РФ-специфика поверх US-механики' } ]
) ,
billing _audit : nd (
'Self-authored скил: аудит денежных инвариантов биллинга Лидерры — сумма (bcmath), идемпотентность, tier-резолюция, дрейф reconcile, charge_source.' ,
'При правке/ревью кода Billing — проверить денежную корректность начисления.' ,
'Свой project-скил .claude/skills/billing-audit/ (линтуется, LINT1). Не UI → вне R6/R14. Tooling §4.37 #62, CLAUDE.md §3.3 #62, ADR-012.' ,
[ { name : 'Tooling' , cond : '§4.37 #62 — реестр' } ] ,
[ { name : 'FIN5' , cond : 'объект ≠ process-*/D3/ru-tax' } ] ,
[ { name : 'Pest' , cond : 'инварианты через тесты' } , { name : 'Boost' , cond : 'модели биллинга' } ]
) ,
ru _tax : nd (
'Self-authored скил: РСБУ/НК РФ контекст для выручки Лидерры — НДС/УСН, налоговая база, налогооблагаемое событие, выгрузки бухгалтеру.' ,
'При «как учесть/обложить по РФ» — перевод billing-выручки (выход C6) в учётно-налоговый контекст C7.' ,
'Свой project-скил .claude/skills/ru-tax-accounting/ (линтуется, LINT1). Закрывает РФ-gap US-плагина finance. Не UI → вне R6/R14. Tooling §4.38 #63, CLAUDE.md §3.3 #63, ADR-012.' ,
[ { name : 'Tooling' , cond : '§4.38 #63 — реестр' } ] ,
[ { name : 'FIN6' , cond : '≠ finance plugin/billing-audit/D1/D2' } ] ,
[ { name : 'billing-audit' , cond : 'выручка C6 → налог.база C7' } , { name : 'finance plugin' , cond : 'US-механика' } ]
) ,
2026-05-21 04:35:43 +03:00
// ── A1 BACKEND-TOOLING (20.05.2026, ADR-013) ──
rector : nd (
'Composer dev-dep (Rector + rector-laravel): авто-рефакторинг и version-upgrade PHP-кода — dead-code, code-quality наборы, апгрейды под версию Laravel.' ,
'При «обнови/почини/рефактори backend-код», апгрейде Laravel-версии, удалении мёртвого кода. Запуск manual/CI (composer rector / rector:fix).' ,
'Composer dev-dep, app/rector.php (deadCode+codeQuality conservative). manual/CI — НЕ блокирующий lefthook (dry-run baseline 16 файлов). Не UI → вне R6/R14. Tooling §4.39 #64, CLAUDE.md §3.3 #64, ADR-013.' ,
[ { name : 'Tooling' , cond : '§4.39 #64 — реестр' } ] ,
[ { name : 'BT1' , cond : '↔ Pint трансформация vs стиль' } , { name : 'BT2' , cond : '↔ Larastan чинит vs находит' } , { name : 'BT3' , cond : '↔ deptrac vs граф слоёв' } ] ,
[ { name : 'PHP Insights' , cond : 'backend-quality chain L14' } , { name : 'Larastan' , cond : 'L14 типы' } ]
) ,
php _insights : nd (
'Composer dev-dep: метрики качества кода — complexity / architecture / maintainability (cyclomatic, code smells, распределение архитектуры).' ,
'При «оцени качество/сложность кода», «где код запутан», в портальном аудите. on-demand/CI (composer insights).' ,
'Composer dev-dep, app/config/insights.php (SyntaxCheck removed — Windows-краш, style-ось off — владелец Pint). on-demand/CI — НЕ блокирующий (BT9). Не UI → вне R6/R14. Tooling §4.40 #65, CLAUDE.md §3.3 #65, ADR-013.' ,
[ { name : 'Tooling' , cond : '§4.40 #65 — реестр' } ] ,
[ { name : 'BT4' , cond : 'style/code оси off — уникум complexity+architecture' } , { name : 'BT9' , cond : 'не блокирующий — без четверного гейта' } ] ,
[ { name : 'Rector' , cond : 'backend-quality chain L14' } , { name : 'Larastan' , cond : 'L14 типы' } ]
) ,
backend _patterns : nd (
'Self-authored скил: backend-конвенции Лидерры — слоистость controller→service→job, RLS-aware Eloquent, деньги bcmath/LedgerService, идемпотентные джобы, partition-aware запросы.' ,
'При «как писать backend в Лидерре», «паттерн контроллера/сервиса/джоба», scaffolding новой backend-фичи.' ,
'Свой project-скил .claude/skills/laravel-backend-patterns/ (линтуется, LINT1). Не UI → вне R6/R14. Tooling §4.41 #66, CLAUDE.md §3.3 #66, ADR-013.' ,
[ { name : 'Tooling' , cond : '§4.41 #66 — реестр' } ] ,
[ { name : 'BT5' , cond : '≠ architecture-patterns #38 (generic)' } , { name : 'BT6' , cond : '≠ billing-audit #62 (аудит)' } ] ,
[ { name : 'billing-audit' , cond : '«как писать» ↔ «аудит денег»' } , { name : 'Boost' , cond : 'Eloquent-контекст' } ]
) ,
nightowl : nd (
'Self-hosted runtime-телеметрия (laravel/nightwatch + nightowl-agent): коррелированный трейс request↔job↔query↔cache в свой PostgreSQL. DEFERRED.' ,
'DEFERRED — при появлении Linux/боевого сервера (Б-1). Сейчас не маршрутизировать (нет pcntl/posix на Windows, OSS без MCP, hosted = 152-ФЗ).' ,
'DEFERRED pending-слот (как Sentry #34 / Figma #44 / Jupyter #50). Spike docs/backend/nightowl-spike.md. Не UI → вне R6/R14. Tooling §4.42 #67, CLAUDE.md §3.3 #67, ADR-013.' ,
[ { name : 'Tooling' , cond : '§4.42 #67 — реестр' } ] ,
[ { name : 'BT7' , cond : '↔ Sentry трейс vs ошибки' } , { name : 'BT8' , cond : '↔ Pail/Boost трейс vs tail/снапшот' } ] ,
[ { name : 'Sentry' , cond : 'трейс ↔ ошибки (ADR-013)' } ]
) ,
2026-05-13 17:05:59 +03:00
// ── СКИЛЫ SUPERPOWERS ────────────────────────────
sk _brainstorm : nd (
'Продумывает задачу вместе с заказчиком, формулирует варианты A/B/C и согласует дизайн до написания кода.' ,
2026-05-14 12:42:32 +03:00
'При творческой задаче — новая фича, непростой рефакторинг, дизайн-решение; ДО любого кода или плана.' ,
2026-05-14 17:15:39 +03:00
'Обязательно явное «Approved» от заказчика до перехода к скилу writing-plans. Запрет: нельзя запускать скилы реализации до утверждения дизайна.' ,
[ { name : 'плагин Superpowers' , cond : 'содержит' } , { name : 'Pravila §12' , cond : 'обязательное правило (см. §12) для творческих задач' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'скил writing-plans' , cond : 'вызывается сразу после brainstorming для создания плана' } ]
2026-05-13 17:05:59 +03:00
) ,
sk _tdd : nd (
2026-05-14 17:15:39 +03:00
'Ведёт разработку через написание падающего теста до кода: сначала RED (тест провален), потом GREEN (тест проходит). TDD (разработка через тесты — failing test first).' ,
2026-05-14 12:42:32 +03:00
'При любом новом боевом коде — backend (Pest) и frontend (Vitest).' ,
'Падающий тест пишется ДО реализации; формулировка «код должен работать» без проверенного теста — нарушение правила §12.' ,
2026-05-14 17:15:39 +03:00
[ { name : 'плагин Superpowers' , cond : 'содержит' } , { name : 'Pravila §12' , cond : 'обязательное правило (см. §12) для любого нового кода' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'скил executing-plans' , cond : 'TDD встроен в каждый шаг плана выполнения' } ]
2026-05-13 17:05:59 +03:00
) ,
sk _debug : nd (
2026-05-14 12:42:32 +03:00
'Системная отладка: минимум 3 гипотезы, опровержение каждой реальной проверкой до того, как править код — никаких «должно работать».' ,
'При неожиданном поведении, падении теста, ошибке во время работы, неожиданном выводе.' ,
'Минимум 3 гипотезы. Опровержение через реальные команды и тесты, а не «логика подсказывает». Никаких «попробую исправить» без подтверждённой причины.' ,
2026-05-14 17:15:39 +03:00
[ { name : 'плагин Superpowers' , cond : 'содержит' } , { name : 'Pravila §12' , cond : 'обязательное правило (см. §12) при неожиданном поведении' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'MCP-сервер redis' , cond : 'используется для отладки очередей Redis' } ]
2026-05-13 17:05:59 +03:00
) ,
sk _wplans : nd (
'Создаёт детальный план реализации с полным кодом, командами и шагами по 2-5 минут.' ,
2026-05-14 17:15:39 +03:00
'После скила brainstorming (творческая задача) или сразу для многошаговой (≥3 шагов) технической задачи.' ,
2026-05-14 12:42:32 +03:00
'Никаких заглушек (TBD, TODO, «add validation»). Каждый шаг — реальный код или команда. Покрытие спецификации обязательно.' ,
2026-05-14 17:15:39 +03:00
[ { name : 'плагин Superpowers' , cond : 'содержит' } , { name : 'Pravila §12' , cond : 'обязательное правило (см. §12) для многошаговых задач (≥3 шагов)' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'скил executing-plans или скил subagent-driven' , cond : 'план передаётся в один из них для выполнения' } ]
2026-05-13 17:05:59 +03:00
) ,
sk _eplans : nd (
'Выполняет готовый план шаг за шагом, отмечает чекбоксы, делает коммиты после каждого шага.' ,
2026-05-14 17:15:39 +03:00
'После скила writing-plans (если выбрано выполнение в текущей сессии); альтернатива — скил subagent-driven-development в той же сессии.' ,
2026-05-14 12:42:32 +03:00
'Каждый шаг отмечается галочкой, коммиты не объединяются — атомарно по одному за шаг (Pravila §4.2).' ,
2026-05-14 17:15:39 +03:00
[ { name : 'плагин Superpowers' , cond : 'содержит' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'скил writing-plans' , cond : 'получает план от writing-plans' } , { name : 'скил subagent-driven-development' , cond : 'альтернатива — зависит от выбора пользователя' } ]
2026-05-13 17:05:59 +03:00
) ,
sk _verify : nd (
2026-05-14 12:42:32 +03:00
'Обязательная проверка перед заявлением «готово»: запускает тесты, видит реальный вывод, никаких предположений.' ,
'Перед любым заявлением «готово»/«passed»/«closed»/«merged» — обязательно (правило §12 + экономия 0% как жёсткое требование).' ,
'Реальный запуск, не «должно пройти». Вывод тестов виден полностью. Выборочные результаты запрещены («tests pass» = ровно столько, сколько действительно прошло).' ,
2026-05-14 17:15:39 +03:00
[ { name : 'плагин Superpowers' , cond : 'содержит' } , { name : 'Pravila §12' , cond : 'обязательное правило (см. §12) перед любым заявлением «готово»' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'MCP-сервер laravel-boost' , cond : 'запросы к БД для проверки данных' } ]
2026-05-13 17:05:59 +03:00
) ,
sk _parallel : nd (
2026-05-14 12:42:32 +03:00
'Разбивает независимые задачи на параллельные потоки с изоляцией через git worktrees (отдельные рабочие копии репозитория).' ,
'При нескольких независимых рабочих фронтах одновременно (CTO-задача + Plan-задача + audit-fix).' ,
'Изоляция через worktree обязательна — никакого «работаю в одной директории на 3 ветках сразу». Иначе риск конфликта файлов и веток.' ,
2026-05-14 17:15:39 +03:00
[ { name : 'плагин Superpowers' , cond : 'содержит' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'скил worktree' , cond : 'parallel-work использует worktree для изоляции' } ] ,
2026-05-18 16:15:07 +03:00
[ { name : 'MCP-сервер playwright' , desc : 'Профили per-cwd hash (квирк #95) → worktrees получают разные mcp-chrome-{hash} директории, не конфликтуют. Same-dir parallel — редкий runtime, регулируется Pravila §15.2 claim' , type : 'GREEN' } ]
2026-05-13 17:05:59 +03:00
) ,
sk _worktree : nd (
2026-05-14 12:42:32 +03:00
'Создаёт изолированную копию репозитория (worktree) для рискованной или параллельной работы.' ,
'При параллельной работе нескольких задач или при рискованной работе (рефакторинг с возможным откатом, ветка экспериментов).' ,
'Очистка через ExitWorktree обязательна. Не оставлять забытые worktree — захламляют файловую систему.' ,
2026-05-14 17:15:39 +03:00
[ { name : 'плагин Superpowers' , cond : 'содержит' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'скил parallel-work' , cond : 'worktree — инструмент для parallel-work' } ]
2026-05-13 17:05:59 +03:00
) ,
sk _pr : nd (
2026-05-14 17:15:39 +03:00
'Чеклист финальной готовности PR (запроса на слияние кода): тесты, документация, чистота кода, проверки перед push.' ,
2026-05-14 12:42:32 +03:00
'Перед `gh pr create` или `git push` в общую ветку — обязательная проверка готовности.' ,
2026-05-14 17:15:39 +03:00
'Проверки перед push (job gitleaks в lefthook по всей истории + job lychee) — не обходить через `--no-verify`. Pravila §4.2.' ,
[ { name : 'плагин Superpowers' , cond : 'содержит' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'MCP-сервер github' , cond : 'создаёт PR (запрос на слияние кода) через GitHub' } , { name : 'lefthook (job-набор перед push)' , cond : 'запускает job gitleaks + job lychee' } ]
2026-05-13 17:05:59 +03:00
) ,
sk _subagent : nd (
'Запускает суб-агентов для крупных задач — каждый в отдельном контексте без накопленного шума.' ,
2026-05-14 12:42:32 +03:00
'При выполнении плана в той же сессии ИЛИ при делегировании поиска/анализа большого объёма.' ,
'Суб-агент в режиме экономии 0%: запрашивать полный сырой вывод, а не сводку — решения принимать самому.' ,
2026-05-14 17:15:39 +03:00
[ { name : 'плагин Superpowers' , cond : 'содержит' } ] ,
2026-05-13 17:05:59 +03:00
[
2026-05-14 17:15:39 +03:00
{ name : 'агент Explore' , cond : 'запускает для поиска по кодовой базе' } ,
{ name : 'агент general-purpose' , cond : 'запускает для сложных задач' } ,
{ name : 'агент Plan' , cond : 'запускает для архитектурного планирования' }
2026-05-13 17:05:59 +03:00
] ,
2026-05-14 17:15:39 +03:00
[ { name : 'скил writing-plans' , cond : 'subagent-driven — основной способ выполнения планов' } ]
2026-05-13 17:05:59 +03:00
) ,
sk _wskills : nd (
2026-05-14 12:42:32 +03:00
'Создаёт новые скилы по стандартному шаблону: файл SKILL.md, заголовочный блок (frontmatter), описание процесса.' ,
'При формализации повторяющегося процесса в переиспользуемый скил (после 2-3 примеров одинаковой работы).' ,
'Шаблон SKILL.md, заголовочный блок (name, description, when_to_use, allowed-tools), описание процесса с DOT-диаграммой.' ,
2026-05-14 17:15:39 +03:00
[ { name : 'плагин Superpowers' , cond : 'содержит' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'агент plugin-dev:skill-reviewer' , cond : 'агент проверяет созданный скил' } ]
2026-05-13 17:05:59 +03:00
) ,
sk _spreview : nd (
2026-05-14 12:42:32 +03:00
'Проверяет документ-спецификацию на полноту, противоречия, заглушки и объём работ.' ,
2026-05-14 17:15:39 +03:00
'После скила writing-plans на отдельном этапе ДО реализации — для крупных планов с несколькими задачами.' ,
'Самопроверка прямо в скиле brainstorming достаточна для небольшой спецификации; для крупных — отдельный запуск этого скила.' ,
[ { name : 'плагин Superpowers' , cond : 'содержит' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'скил brainstorming' , cond : 'spec-review вызывается в конце brainstorming после записи спека' } ]
2026-05-13 17:05:59 +03:00
) ,
sk _coderev : nd (
2026-05-14 12:42:32 +03:00
'Систематический разбор кода — безопасность, тесты, архитектура, соответствие правилам.' ,
2026-05-14 17:15:39 +03:00
'Перед слиянием PR (запроса на слияние кода); после крупной серии коммитов; при подготовке к релизу; при подозрении на регрессию (возврат к старому багу).' ,
'Без выборочности: разбор всех изменений, а не только подозрительных. SAST (статический анализ кода на уязвимости, через MCP-сервер semgrep) включается обязательно.' ,
[ { name : 'плагин Superpowers' , cond : 'содержит' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'MCP-сервер semgrep' , cond : 'SAST-проверка при ревью кода' } ]
2026-05-13 17:05:59 +03:00
) ,
sk _elements : nd (
'Улучшает написание текстов и документации — ясность, лаконичность, без воды.' ,
2026-05-14 17:15:39 +03:00
'При написании спецификации/плана/CHANGELOG/описания PR (запроса на слияние кода) — для общения с командой.' ,
2026-05-14 12:42:32 +03:00
'Без воды. Без «легко», «просто», «всего лишь». Каждое утверждение измеримо.' ,
2026-05-14 17:15:39 +03:00
[ { name : 'плагин Superpowers' , cond : 'содержит' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ]
) ,
// ── СКИЛЫ ПРОЕКТА ────────────────────────────────
sk _rls : nd (
2026-05-14 17:15:39 +03:00
'7-шаговый чеклист RLS (защита строк по тенанту) для новой таблицы: tenant_id, ENABLE RLS (включение защиты строк), политики, права для 5 ролей, CHANGELOG, проверка через squawk, дымовой тест (быстрая проверка функциональности).' ,
'При создании новой таблицы в db/schema.sql ИЛИ при правках существующих политик RLS (защиты строк по тенанту).' ,
'Права для 5 ролей обязательны (crm_app_user / crm_app_admin / crm_supplier_worker BYPASSRLS (право обходить защиту строк — для системных задач) / crm_readonly / crm_migrator). Запись в CHANGELOG_schema.md обязательна.' ,
2026-05-13 17:05:59 +03:00
[ { name : 'Tooling §3.2' , cond : 'использует squawk (#15) и команды grep' } ] ,
[ ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'MCP-сервер laravel-boost' , cond : 'SQL запросы к schema.sql для проверки' } ] ,
2026-05-16 08:48:30 +03:00
[ { name : 'агент rls-reviewer' , desc : 'граница задана регламентом (spec 2026-05-16): скил — ручная проверка одной названной таблицы + живой дымовой тест; агент — разбор diff/ветки/PR. См. секцию «Граница с агентом rls-reviewer» в SKILL.md.' , type : 'GREEN' } ]
2026-05-13 17:05:59 +03:00
) ,
sk _qitem : nd (
'Добавляет новый открытый вопрос в реестр Открытые_вопросы_v8_3.md с обновлением счётчиков §0 и версии.' ,
2026-05-14 12:42:32 +03:00
'При появлении нового открытого вопроса (Биз-/CTO-/Ю-/Диз-/DO-/OPEN-) — формальная запись в реестр.' ,
'Категория (Биз-/CTO-/...) обязательна. Связанные документы (CLAUDE.md/Pravila/PSR_v1/Tooling) — синхронизируются.' ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'плагин claude-md-management' , cond : 'скил делегирует правку CLAUDE.md через плагин (правило §5п.10 в нормативке)' } ]
2026-05-13 17:05:59 +03:00
) ,
// ── ХУКИ ─────────────────────────────────────────
hk _pre _claude : nd (
'Блокирует прямое редактирование CLAUDE.md — срабатывает на Edit/Write по этому файлу.' ,
2026-05-14 17:15:39 +03:00
'PreToolUse (перед каждым вызовом инструмента) — перед каждым Edit/Write, фильтр путей нацелен на CLAUDE.md.' ,
'Обход запрещён. Единственный способ редактировать — плагин claude-md-management (правило §5п.10 в нормативке).' ,
2026-05-14 12:42:32 +03:00
[ { name : '.claude/settings.json' , cond : 'описан как хук PreToolUse' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'плагин hookify' , desc : 'плагин hookify динамически создаёт новые хуки PreToolUse — может перезаписать или конкурировать с этим хуком' , type : 'RED' } ]
2026-05-13 17:05:59 +03:00
) ,
hk _post _md : nd (
2026-05-14 12:42:32 +03:00
'После каждого Edit .md-файла запускает markdownlint --fix автоматически.' ,
2026-05-14 17:15:39 +03:00
'PostToolUse (после каждого вызова инструмента) — после Edit/Write на *.md (кроме корневого CLAUDE.md, чтобы не зациклить).' ,
2026-05-14 12:42:32 +03:00
'Не правит CLAUDE.md (исключён из фильтра путей). При неисправимой ошибке (например, битая ссылка) — предупреждение, не блокировка.' ,
[ { name : '.claude/settings.json' , cond : 'описан как хук PostToolUse' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'job markdownlint в lefthook' , cond : 'дублируют задачу: хук — в сессии, lefthook — при коммите' } ]
2026-05-13 17:05:59 +03:00
) ,
hk _post _schema : nd (
'После правки db/schema.sql напоминает обновить db/CHANGELOG_schema.md.' ,
2026-05-14 17:15:39 +03:00
'PostToolUse (после каждого вызова инструмента) — после Edit/Write на `db/schema.sql`.' ,
2026-05-14 12:42:32 +03:00
'Напоминание, не блокировка. Дисциплина ведения CHANGELOG_schema — на разработчике (§4.2 Pravila).' ,
[ { name : '.claude/settings.json' , cond : 'описан как хук PostToolUse' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'job squawk в lefthook' , cond : 'оба реагируют на изменения SQL' } ]
2026-05-13 17:05:59 +03:00
) ,
hk _session : nd (
2026-05-14 12:42:32 +03:00
'При старте каждой сессии подгружает CLAUDE.md, Pravila и ключевые memory-файлы в контекст.' ,
2026-05-14 17:15:39 +03:00
'SessionStart (при старте сессии) — единожды при инициализации сессии Claude Code.' ,
2026-05-14 12:42:32 +03:00
'Список memory-файлов фиксированный — для расширения править настройку хука. Не читает 80+ квирков целиком — выборочно по релевантности.' ,
[ { name : '.claude/settings.json' , cond : 'описан как хук SessionStart' } ] ,
2026-05-13 17:05:59 +03:00
[
2026-05-14 17:15:39 +03:00
{ name : 'память user_profile' , cond : 'читает' } ,
{ name : 'память feedback_environment' , cond : 'читает' } ,
{ name : 'память project_state' , cond : 'читает' } ,
{ name : 'память feedback_superpowers_hard_rule' , cond : 'читает' } ,
{ name : 'память feedback_plugin_paired_stack' , cond : 'читает' }
2026-05-13 17:05:59 +03:00
] ,
[ ]
) ,
hk _economy : nd (
2026-05-14 12:42:32 +03:00
'Перед каждым промптом разбирает «экономия X%» и выставляет режим строгости (0% = максимальное качество, 100% = по умолчанию).' ,
2026-05-14 17:15:39 +03:00
'UserPromptSubmit (перед отправкой промпта пользователя) — ищет шаблон /экономия\\s*(\\d+)%/.' ,
2026-05-16 13:44:14 +03:00
'§12 Superpowers — hard-rule уровня 0, economy-режим §12 НЕ отменяет ни на каком уровне. Действует только на текущую задачу — следующий промпт разбирается заново.' ,
2026-05-14 12:42:32 +03:00
[ { name : '.claude/settings.json' , cond : 'описан как хук UserPromptSubmit' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ] ,
2026-05-16 13:44:14 +03:00
[ { name : 'плагин Superpowers (§12)' , desc : 'Экономия=100% теоретически может «сэкономить» вызов скила — §12 (hard-rule уровня 0) economy-режим не отменяет ни на каком уровне (Pravila §12.4).' , type : 'GREEN' } ]
2026-05-13 17:05:59 +03:00
) ,
// ── АГЕНТЫ ───────────────────────────────────────
ag _pest : nd (
2026-05-16 15:39:47 +03:00
'Разбирает падения тестов Pest --parallel: отличает настоящую ошибку от известных квирков (73/77 и др.; квирк 72 устранён 16.05.2026 — commit 0fa1a73).' ,
2026-05-14 17:15:39 +03:00
'При падении Pest --parallel ИЛИ при дымовом тесте (быстрой проверке функциональности) только из подкаталога (как в аудите Phase 3 SyncSupplierProjectsJobTest).' ,
'READ-ONLY (только чтение — только читает код, ничего не правит). Каждую гипотезу подтверждает реальным запуском, а не «похоже на квирк».' ,
2026-05-13 17:05:59 +03:00
[ { name : 'CLAUDE.md §6' , cond : 'описывает когда вызывать' } ] ,
[ ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'MCP-сервер redis' , cond : 'читает Redis для отладки квирка 72 (гонка supplier:session)' } ] ,
2026-05-16 06:48:46 +03:00
[
2026-05-16 15:39:47 +03:00
{ name : 'MCP-сервер redis' , desc : 'Квирк 72 (гонка с кэшем Redis при Pest --parallel из подкаталога) устранён 16.05.2026 — commit 0fa1a73, array-стор в тестах. Конфликт закрыт.' , type : 'GREEN' } ,
{ name : 'демон ruflo' , desc : 'Worker-jitter фонового демона ruflo (PM2) усиливает частоту Pest-квирков 73/77. Квирк 72 устранён 16.05 — его jitter больше не усиливает. На baseline-регрессии — `pm2 stop ruflo-daemon` (квирк #93, переоценён).' , type : 'BLACK' }
2026-05-16 06:48:46 +03:00
]
2026-05-13 17:05:59 +03:00
) ,
ag _rls : nd (
2026-05-14 12:47:10 +03:00
'Проверяет миграции на соответствие RLS (защите строк по тенанту) — 7 пунктов чеклиста с реальными командами, только чтение.' ,
2026-05-14 17:15:39 +03:00
'При создании/правке миграции в db/migrations/ ИЛИ при правке db/schema.sql ИЛИ при ревью PR (запроса на слияние кода) с изменениями БД.' ,
'READ-ONLY (только чтение — только Read/Grep/Glob/Bash) — код не пишет. Не замена скилу rls-check — у них разные сценарии.' ,
2026-05-14 12:47:10 +03:00
[ { name : 'CLAUDE.md' , cond : 'описывает в §6 и в директории агентов' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'MCP-сервер laravel-boost' , cond : 'SQL запросы к db/schema.sql' } ] ,
2026-05-16 08:48:30 +03:00
[ { name : 'скил rls-check' , desc : 'граница задана регламентом (spec 2026-05-16): агент — разбор diff/ветки/PR со статическим 7-пунктовым чеклистом; скил — ручная проверка одной названной таблицы + живой дымовой тест. См. секцию «Граница со скилом /rls-check» в rls-reviewer.md.' , type : 'GREEN' } ]
2026-05-13 17:05:59 +03:00
) ,
ag _statusline : nd (
2026-05-14 12:47:10 +03:00
'Настраивает строку состояния Claude Code через правку файла настроек.' ,
2026-05-14 17:15:39 +03:00
'При запросе пользователя «настрой строку состояния» — редкая разовая задача.' ,
2026-05-14 12:47:10 +03:00
'Правит только секцию statusline в settings.json, другие части файла не трогает.' ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ] ,
[ ]
) ,
ag _guide : nd (
2026-05-14 17:15:39 +03:00
'Отвечает на вопросы про API Claude Code, SDK, MCP-серверы (внешние сервисы-инструменты Claude), хуки, slash-команды.' ,
2026-05-14 09:17:37 +03:00
'При вопросе про возможности Claude Code/SDK/API — «Can Claude...», «How do I...», «Does Claude...».' ,
2026-05-14 17:15:39 +03:00
'READ-ONLY (только чтение): ищет в документации, код не правит. Не для отладки кода — только вопросы о платформе.' ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'MCP-сервер github' , cond : 'при необходимости ищет примеры в репозитории' } ]
2026-05-13 17:05:59 +03:00
) ,
ag _explore : nd (
2026-05-14 12:47:10 +03:00
'Быстрый поиск файлов по шаблону имени или по символу — только чтение, без анализа.' ,
'При точечном поиске — найти файл по имени или сделать grep по символу/ключевому слову.' ,
'Не для свободного исследования. Не для ревью/аудита (читает отрывки, теряет контекст за пределами окна чтения).' ,
2026-05-14 17:15:39 +03:00
[ { name : 'скил subagent-driven-development' , cond : 'запускается для задач поиска' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ]
) ,
ag _general : nd (
2026-05-14 12:47:10 +03:00
'Универсальный агент для сложных многошаговых исследований — с полным набором инструментов.' ,
2026-05-14 17:15:39 +03:00
'При сложных многошаговых задачах исследования или написания кода, когда агента Explore не хватает (нужен анализ, не только поиск).' ,
2026-05-14 12:47:10 +03:00
'Полный набор инструментов — может писать код. Дороже Explore по токенам.' ,
2026-05-14 17:15:39 +03:00
[ { name : 'скил subagent-driven-development' , cond : 'запускается для основных задач' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ]
) ,
ag _plan : nd (
2026-05-14 12:47:10 +03:00
'Архитектор: разрабатывает планы реализации, находит критичные файлы, разбирает компромиссы.' ,
2026-05-14 17:15:39 +03:00
'При архитектурном планировании задачи из нескольких компонентов (не для мелкого рефакторинга).' ,
'READ-ONLY (только чтение — без Edit/Write/NotebookEdit). Возвращает план, сам его не реализует.' ,
[ { name : 'скил subagent-driven-development' , cond : 'запускается для архитектурных задач' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'скил writing-plans' , cond : 'агент Plan и скил writing-plans решают похожую задачу в разных контекстах' } ]
2026-05-13 17:05:59 +03:00
) ,
ag _hookify : nd (
2026-05-14 12:47:10 +03:00
'Разбирает транскрипты диалогов и ищет поведение, которое стоит предотвратить хуком.' ,
2026-05-14 09:17:37 +03:00
'При триггере /hookify без аргументов ИЛИ при запросе «look back at this conversation, what mistakes to prevent».' ,
2026-05-14 17:15:39 +03:00
'READ-ONLY (только чтение — только Read+Grep). Рекомендует хуки, сам их не создаёт — передаёт в плагин hookify.' ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'плагин hookify' , cond : 'агент передаёт рекомендации в плагин' } ]
2026-05-13 17:05:59 +03:00
) ,
ag _pcreator : nd (
2026-05-14 12:47:10 +03:00
'Создаёт настройку новых агентов по описанию от пользователя.' ,
2026-05-14 09:17:37 +03:00
'При запросе «create an agent that...» — генерация agent.md по описанию функциональности.' ,
2026-05-14 17:15:39 +03:00
'Только инструменты Write/Read. Созданного агента сам не проверяет — передаёт в агент plugin-validator.' ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'агент plugin-dev:plugin-validator' , cond : 'валидатор проверяет созданного агента' } ]
2026-05-13 17:05:59 +03:00
) ,
ag _pvalid : nd (
2026-05-14 12:47:10 +03:00
'Проверяет структуру плагина на корректность — plugin.json, инструменты, манифест.' ,
'После создания/правки plugin.json или компонентов плагина — превентивная проверка.' ,
2026-05-14 17:15:39 +03:00
'READ-ONLY (только чтение — Read/Grep/Glob/Bash). Сам не правит — выдаёт список нарушений.' ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'агент plugin-dev:agent-creator' , cond : 'валидатор и создатель работают в паре' } ]
2026-05-13 17:05:59 +03:00
) ,
ag _skreview : nd (
2026-05-14 12:47:10 +03:00
'Оценивает качество написанного скила — описание, ход работы, примеры, лучшие практики.' ,
2026-05-14 17:15:39 +03:00
'После создания/правки скила через скил writing-skills — превентивное ревью.' ,
'READ-ONLY (только чтение — Read/Grep/Glob). Не правит — выдаёт рекомендации.' ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'скил writing-skills' , cond : 'skill-reviewer проверяет то, что создал writing-skills' } ]
2026-05-13 17:05:59 +03:00
) ,
// ── MCP-СЕРВЕРЫ ──────────────────────────────────
mcp _pw : nd (
2026-05-14 12:47:10 +03:00
'Управляет браузером — снимает скриншоты, кликает, заполняет формы для smoke- и a11y-тестов.' ,
2026-05-14 09:18:45 +03:00
'При визуальной проверке прототипов (фаза 0), при a11y smoke (axe-core), при UI integration smoke.' ,
2026-05-18 16:15:07 +03:00
'Не для боевых пользователей. Профиль persistent кэшируется per-cwd hash (квирк #95 в memory) → разные worktrees получают разные mcp-chrome-{hash} директории и не конфликтуют. Конфликт остаётся только при same-dir parallel (две Claude-сессии в одной dir одновременно вызывают browser).' ,
2026-05-13 17:05:59 +03:00
[ { name : 'CLAUDE.md §3.1 #2' , cond : 'активен с фазы 0' } ] ,
[ ] ,
2026-05-14 12:59:25 +03:00
[ { name : 'SessionStart хук' , cond : 'используется для визуальной проверки прототипов' } ] ,
2026-05-18 16:15:07 +03:00
[ { name : 'parallel-work скил' , desc : 'Профили per-cwd hash → worktrees не конфликтуют (квирк #95). Same-dir parallel регулируется Pravila §15.2 claim в CURRENT.md' , type : 'GREEN' } ]
2026-05-13 17:05:59 +03:00
) ,
mcp _gh : nd (
2026-05-14 12:47:10 +03:00
'GitHub API — читает/создаёт PR, issues, коммиты, ветки в репозитории CoralMinister/lidpotok.' ,
'При работе с PR/issues, при поиске в репозитории, при создании PR через скил finishing-pr.' ,
'Не делать push в main без явного одобрения. Pravila §4: атомарные коммиты, не объединять их через MCP.' ,
2026-05-13 17:05:59 +03:00
[ { name : 'CLAUDE.md §3.1 #3' , cond : 'активен с фазы 0' } ] ,
[ ] ,
[ { name : 'finishing-pr скил' , cond : 'создаёт PR через этот MCP' } ]
) ,
mcp _boost : nd (
2026-05-14 12:47:10 +03:00
'Laravel Boost — SQL-запросы к dev-БД, схема таблиц, журналы ошибок, поиск по документации Laravel.' ,
2026-05-14 17:15:39 +03:00
'С первой фазы (старт backend) и далее — при SQL-запросах, поиске в документации Laravel, работе с моделями Eloquent.' ,
2026-05-14 12:47:10 +03:00
'**READ-ONLY к prod** — `.env.production` не должен попадать в локальный конфиг. Не использовать правила-подсказки Inertia/Livewire/Tailwind/Filament.' ,
[ { name : 'CLAUDE.md §3.2 #10' , cond : 'активен с фазы 1, доступ к prod только на чтение' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ { name : 'ag_rls агент' , cond : 'rls-reviewer использует Boost для SQL' } , { name : 'sk_rls скил' , cond : 'rls-check использует Boost' } ]
) ,
mcp _semgrep : nd (
2026-05-14 12:47:10 +03:00
'SAST (статический анализ кода на уязвимости) — ищет уязвимости, XSS (внедрение JS), SQLi (внедрение SQL), нарушения правил по шаблонам.' ,
2026-05-14 17:15:39 +03:00
'На третьей фазе проекта (перед запуском в боевую среду) — при просмотре кода через скил code-review и при автозапуске проверок CI (continuous integration) перед выпуском новой версии.' ,
2026-05-14 12:47:10 +03:00
'Настройка в .semgrep.yml. Ложные срабатывания документируются прямо в коде.' ,
2026-05-14 17:15:39 +03:00
[ { name : 'CLAUDE.md §3.4 #25' , cond : 'третья фаза — перед запуском в боевую среду' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
2026-05-14 17:15:39 +03:00
[ { name : 'скил code-review' , cond : 'MCP-сервер semgrep используется при разборе кода' } ]
2026-05-13 17:05:59 +03:00
) ,
mcp _sentry : nd (
2026-05-14 12:47:10 +03:00
'Читает ошибки из self-hosted Sentry в Yandex Cloud — события, стектрейсы, метрики. READ-ONLY (только чтение).' ,
'При расследовании ошибок боевой среды во время работы (после развёртывания Б-1).' ,
'**READ-ONLY** (org:read/project:read/event:read). Ждёт развёртывания инстанса Sentry по Б-1 (зависит от регистрации ООО).' ,
2026-05-14 17:15:39 +03:00
[ { name : 'CLAUDE.md §3.3 #34' , cond : 'вне основных фаз (для отладки во время работы); ждёт развёртывания Sentry по Б-1' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ]
) ,
mcp _redis : nd (
2026-05-14 12:47:10 +03:00
'Читает Redis/Memurai — ключи, очереди, кэш для отладки гонок (race conditions). СТРОГО READ-ONLY.' ,
2026-05-16 15:39:47 +03:00
'При отладке очередей Redis (Pest --parallel квирки 73/77), при анализе инвалидации кэша.' ,
2026-05-14 12:47:10 +03:00
'**СТРОГО READ-ONLY** — никаких DEL/FLUSHDB/SET/LPUSH из Claude (только GET/KEYS/LIST). Источник Anthropic устарел — миграция post-MVP.' ,
2026-05-14 17:15:39 +03:00
[ { name : 'CLAUDE.md §3.3 #35' , cond : 'вне основных фаз (для отладки во время работы); PSR_v1 R10.1 блок 3' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
2026-05-14 12:59:25 +03:00
[ { name : 'pest-parallel-debugger агент' , cond : 'агент использует для квирка 72 (гонка в Redis)' } ] ,
2026-05-16 15:39:47 +03:00
[ { name : 'агент pest-parallel-debugger' , desc : 'Квирк 72 (гонка с кэшем Redis при Pest --parallel из подкаталога) устранён 16.05.2026 — commit 0fa1a73. Конфликт закрыт.' , type : 'GREEN' } ]
2026-05-13 17:05:59 +03:00
) ,
mcp _21st : nd (
2026-05-14 12:47:10 +03:00
'Генератор стартовых шаблонов UI-компонентов через LLM. Активация только через процедуру R14.4.' ,
'Только через процедуру PSR_v1 R14.4: предпроверка из 9 условий (брендовый App*? есть аналог в Vuetify? есть уже существующий компонент?).' ,
'R14.5: не запускать параллельно с FD/UPM. Обязательны: JSX→Vue, Tailwind→utility, shadcn→Vuetify. Pa11y a11y на готовом виде.' ,
[ { name : 'PSR_v1 R14.4' , cond : 'строгая предпроверка: 9 условий перед активацией' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ] ,
2026-05-14 12:59:25 +03:00
[ { name : 'Frontend Design' , desc : 'PSR_v1 R14.5: нельзя параллельно — 21st как генератор материала, FD как решатель; риск смешать роли и нарушить R6 (фильтр стека)' , type : 'GREEN' } ]
2026-05-13 17:05:59 +03:00
) ,
// ── LEFTHOOK JOBS ─────────────────────────────────
lh _gitleaks : nd (
2026-05-14 12:53:35 +03:00
'Ищет ПДн (персональные данные), токены и API-ключи в файлах, готовых к коммиту. Если находит — коммит блокируется.' ,
'Перед каждым коммитом — проверяет только те файлы, что добавлены через `git add`.' ,
'Обход через `--no-verify` запрещён (правило §4.2 Pravila). Находка = блокирующая ошибка, не предупреждение. Известные ложные срабатывания — в файл `.gitleaksignore`.' ,
[ { name : 'lefthook.yml' , cond : 'задача №1 в наборе перед коммитом, без параллельного запуска' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
2026-05-14 12:53:35 +03:00
[ { name : 'lefthook:gitleaks pre-push' , cond : 'версия для push сканирует всю историю' } ]
2026-05-13 17:05:59 +03:00
) ,
lh _mdlint : nd (
2026-05-14 12:53:35 +03:00
'Проверяет и авто-исправляет стиль файлов Markdown перед коммитом.' ,
'Перед каждым коммитом, когда в нём есть файлы `.md`.' ,
'Настройки в `.markdownlint-cli2.cjs`. Авто-исправление включено (исправленные файлы авто-сохраняются обратно в коммит).' ,
[ { name : 'lefthook.yml' , cond : 'задача №2 в наборе перед коммитом' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
2026-05-14 12:53:35 +03:00
[ { name : 'PostToolUse:markdownlint-fix хук' , cond : 'делают одно и то же — хук сразу после правки, lefthook при коммите' } ]
2026-05-13 17:05:59 +03:00
) ,
lh _cspell : nd (
2026-05-14 12:53:35 +03:00
'Проверяет орфографию в `.md` файлах по словарю `cspell-words.txt`.' ,
'Перед каждым коммитом, когда в нём есть файлы `.md`.' ,
'Словарь: `cspell-words.txt`. Кириллица — в нижнем регистре. Не обходить через `--no-verify` — добавлять валидные слова в словарь.' ,
[ { name : 'lefthook.yml' , cond : 'задача №3 в наборе перед коммитом' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ]
) ,
lh _stylelint : nd (
2026-05-14 12:53:35 +03:00
'Линтует CSS в HTML-прототипах (`web/v8/*.html`).' ,
'Перед каждым коммитом, когда в нём есть файлы `.html`/`.css`.' ,
'Настройки Stylelint в `.stylelintrc`. Устаревшие свойства (например `word-break: break-word`) блокируют коммит.' ,
[ { name : 'lefthook.yml' , cond : 'задача №4 в наборе перед коммитом' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ]
) ,
lh _pint : nd (
2026-05-14 12:53:35 +03:00
'Авто-форматирует код PHP по PSR-стандарту (стиль кода PHP). Исправленные файлы авто-сохраняются обратно в коммит.' ,
'Перед каждым коммитом — на каждый файл `.php` в директории `app/`.' ,
'Авто-исправление включено. Настройки в `app/pint.json`.' ,
[ { name : 'lefthook.yml' , cond : 'задача №5 в наборе перед коммитом, корень `app/`' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ]
) ,
lh _larastan : nd (
2026-05-14 12:53:35 +03:00
'Статический анализ PHP (Larastan, уровень L9) — находит ошибки типов выше базового уровня.' ,
'Перед каждым коммитом, когда в нём есть файлы `.php` в `app/`.' ,
'Базовый уровень `phpstan-baseline.neon` зафиксирован — новые ошибки блокируют коммит. Не повышать базовый уровень без обоснования.' ,
[ { name : 'lefthook.yml' , cond : 'задача №6 в наборе перед коммитом, корень `app/`' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
2026-05-14 12:53:35 +03:00
[ { name : 'MCP: laravel-boost' , cond : 'Boost даёт контекст типов через IDE-подсказки' } ]
2026-05-13 17:05:59 +03:00
) ,
lh _squawk : nd (
2026-05-14 12:53:35 +03:00
'Линтер SQL-миграций — проверяет безопасные шаблоны (без блокировки таблиц, параллельный CREATE INDEX и т.п.).' ,
'Перед каждым коммитом, когда в нём есть файлы миграций (`database/migrations/*.php` или `db/*.sql`).' ,
'Настройки в `squawk.toml`. Небезопасные миграции (`ALTER TABLE ADD COLUMN NOT NULL DEFAULT`) запрещены без явной метки `-- squawk-ignore`.' ,
[ { name : 'lefthook.yml' , cond : 'задача №7 в наборе перед коммитом, фильтр путей `*.sql`' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
2026-05-14 12:53:35 +03:00
[ { name : 'Tooling #15 squawk' , cond : 'соответствует записи §3.2 в Tooling' } ]
2026-05-13 17:05:59 +03:00
) ,
lh _eslint : nd (
2026-05-14 12:53:35 +03:00
'Линтует файлы Vue/TypeScript в `app/resources/js/`.' ,
'Перед каждым коммитом, когда в нём есть файлы `.vue`/`.ts`/`.tsx` в `app/`.' ,
'Flat-config ESLint 10 + plugin-vue 10. Обход через `--no-verify` запрещён. Ошибки блокируют коммит, предупреждения допустимы.' ,
[ { name : 'lefthook.yml' , cond : 'задача №8 в наборе перед коммитом, корень `app/`' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ]
) ,
lh _gitleaks2 : nd (
2026-05-14 12:53:35 +03:00
'Полный скан всей истории коммитов на секреты — строже задачи перед коммитом.' ,
'pre-push (перед `git push` на удалённый репозиторий) — сканирует историю новых коммитов целиком.' ,
'Обход через `--no-verify` запрещён (правило §4.2 Pravila). На больших push (200+ коммитов) занимает 30+ секунд.' ,
[ { name : 'lefthook.yml' , cond : 'задача в наборе перед push' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
2026-05-14 12:53:35 +03:00
[ { name : 'lefthook:gitleaks' , cond : 'версия для push строже: проверяет всю историю, а не только staged' } ]
2026-05-13 17:05:59 +03:00
) ,
lh _lychee : nd (
2026-05-14 12:53:35 +03:00
'Проверяет все ссылки в `.md` файлах на битые (`docs/**/*.md`, `db/**/*.md`, корневые `*.md`).' ,
'pre-push (перед `git push`) — проверяет ссылки во всех `.md` файлах репозитория.' ,
'Внешние ссылки проверяются с таймаутом 10 секунд; при отсутствии интернета — ошибка. Настройки в `lychee.toml`. Обход через `--no-verify` запрещён.' ,
[ { name : 'lefthook.yml' , cond : 'задача в наборе перед push' } ] ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ { name : 'CLAUDE.md' , cond : 'проверяет ссылки в CLAUDE.md в том числе' } ]
) ,
// ── MEMORY FILES ─────────────────────────────────
mem _user : nd (
'Профиль заказчика: Дмитрий, Windows Server 2022, VSCode, русский язык, путь к проекту.' ,
2026-05-14 12:53:35 +03:00
'Читается при старте каждой сессии через хук SessionStart — для языка и предпочтений.' ,
2026-05-14 09:20:54 +03:00
'Не содержит секретов. При смене заказчика — переписать полностью.' ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ] ,
[ { name : 'SessionStart хук' , cond : 'читается при старте каждой сессии' } ]
) ,
mem _comm : nd (
2026-05-14 12:53:35 +03:00
'Стиль общения: короткие команды («а», «б», «делай»), варианты A/B/C, явная фиксация переоткрытий.' ,
'Читается при работе с заказчиком — чтобы соответствовать его стилю общения.' ,
'Это не код, а правила коммуникации. Корректировки — только через явный отзыв заказчика.' ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ] ,
2026-05-14 12:53:35 +03:00
[ { name : 'memory:user_profile' , cond : 'дополняет профиль заказчика' } ]
2026-05-13 17:05:59 +03:00
) ,
mem _env : nd (
2026-05-14 12:53:35 +03:00
'80+ квирков (особенностей) окружения: специфика Windows Server, баги инструментов, обходные пути.' ,
'При неожиданном поведении — сначала проверить memory:env на известный квирк.' ,
'Не дублировать — добавлять только новые квирки. Счётчик квирков актуализируется в `project_state.md`.' ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ] ,
[
2026-05-16 15:39:47 +03:00
{ name : 'pest-parallel-debugger агент' , cond : 'квирки 73/77 используются агентом' } ,
2026-05-13 17:05:59 +03:00
{ name : 'SessionStart хук' , cond : 'читается при старте' }
]
) ,
mem _sp : nd (
2026-05-16 13:44:14 +03:00
'Правило §12 (hard-rule уровня 0) + архитектура хука economy из 6 компонентов — дисциплина вызова скилов.' ,
2026-05-14 12:53:35 +03:00
'При работе со скилами — для соответствия обязательному правилу §12 Pravila.' ,
'Описывает архитектуру хука economy (6 компонентов) — менять только при изменении самого хука.' ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ] ,
2026-05-14 12:53:35 +03:00
[ { name : 'economy-mode хук' , cond : 'memory описывает архитектуру хука' } ]
2026-05-13 17:05:59 +03:00
) ,
mem _plugins : nd (
2026-05-14 12:53:35 +03:00
'Правила парного стека плагинов, MCP-серверы для отладки, уровневая структура PSR_v1.' ,
'При работе с плагинами FD/UPM/21st/Sentry/Redis MCP — для уровневого разделения по PSR_v1.' ,
2026-05-14 09:20:54 +03:00
'Синхронизируется с PSR_v1 — изменения в memory только если изменился сам PSR_v1.' ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ] ,
[ { name : 'PSR_v1' , cond : 'memory отражает актуальные версии PSR_v1' } ]
) ,
mem _state : nd (
2026-05-14 12:53:35 +03:00
'Текущее состояние проекта: ветка, тесты (Pest/Vitest), последние коммиты, активные задачи.' ,
2026-05-14 09:20:54 +03:00
'Читается при старте сессии — для быстрого контекста; обновляется после крупных вех.' ,
2026-05-14 12:53:35 +03:00
'Может устаревать — перечитать при сомнении. Не доверять данным старше 2-3 дней без проверки.' ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ] ,
2026-05-16 06:48:46 +03:00
[ { name : 'SessionStart хук' , cond : 'читается при старте для быстрого контекста' } ] ,
[ { name : 'память ruflo' , desc : 'Два хранилища памяти не синхронизированы: проектные `memory/*.md` (16 файлов) и база ruflo `.swarm/memory.db`. Фактически память ruflo почти пуста — MCP-сервер репортит 0 записей (+2 тестовых призрака от alpha-бага HNSW #1122). Recall-хук срабатывает на каждый промпт, но извлекать ему почти нечего.' , type : 'BLACK' } ]
2026-05-13 17:05:59 +03:00
) ,
mem _phase1 : nd (
2026-05-14 12:53:35 +03:00
'Стратегия фазы 1: нативный стек Windows без Docker, расширение pg_partman заменено Artisan-задачей в cron.' ,
'При работе с инфраструктурой фазы 1 (PG/Redis/PHP-CLI нативно на Windows).' ,
'Стратегия зафиксирована до закрытия блокера Б-1 (Managed PG в Yandex Cloud) или 6 месяцев — пересмотр указан в файле.' ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ] ,
[ ]
) ,
mem _archive : nd (
'Карта источников истины: версии всех 13+ ключевых документов проекта.' ,
2026-05-14 09:20:54 +03:00
'При вопросах «какая версия документа X» или «где источник истины для Y».' ,
2026-05-14 12:53:35 +03:00
'Синхронизируется с §0 CLAUDE.md. Изменения в memory — только если изменился §0 CLAUDE.md.' ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ] ,
2026-05-14 12:53:35 +03:00
[ { name : 'CLAUDE.md' , cond : 'memory синхронизирует версии с §0 CLAUDE.md' } ]
2026-05-13 17:05:59 +03:00
) ,
mem _github : nd (
2026-05-14 12:53:35 +03:00
'Репозиторий GitHub CoralMinister/lidpotok: HEAD, хуки, правила push.' ,
'При работе с GitHub — push, PR, операции с ветками.' ,
'Не делать `push --force` на main (предупреждение в Pravila). Хуки перед push обязательны.' ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ] ,
[ { name : 'MCP: github' , cond : 'MCP и memory дополняют друг друга для работы с GitHub' } ]
) ,
mem _handoff : nd (
2026-05-14 12:53:35 +03:00
'Дизайн-передача от Платона: что из `liderra_v8_handoff/` используем, что нет.' ,
'При UI/дизайн-задачах — для разделения «брендбук используем» vs «состав фич — по ТЗ v8.5».' ,
'Передача — только дизайн/токены/компоненты. Функционал и состав экранов — НЕ из передачи (берём из ТЗ).' ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ] ,
[ ]
) ,
mem _audit : nd (
2026-05-14 12:53:35 +03:00
'Полный аудит портала 13.05.2026: 38 находок, вердикт жёлтый, 10 отложенных вопросов закрыты.' ,
'При вопросах про аудит или его последствия (Q.DEFER, распределение P0/P1/P2).' ,
'Это снимок состояния — не редактировать при последующих аудитах, создавать новые memory-файлы.' ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ] ,
[ ]
) ,
mem _supplier : nd (
2026-05-14 12:53:35 +03:00
'Прогресс интеграции с поставщиком лидов (планы 1-5): задачи, коммиты, блокеры.' ,
'При работе с интеграцией поставщика (планы 1-5) — для текущего состояния и блокеров.' ,
'Блокеры (Б-1, доступы) — внешние, не разрешаются силами Claude. Только отслеживание.' ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ] ,
[ ]
) ,
mem _brain : nd (
2026-05-14 12:53:35 +03:00
'Claude Brain v1.0 — отдельный репозиторий «мозга», тег `brain-v1.0`, скрипт `install.sh`.' ,
'При работе с репозиторием brain или скриптом `install.sh` для синхронизации потребителей.' ,
'Push на репозиторий brain в GitHub заблокирован (вопрос 8.2). Не пытаться push без разрешения.' ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ] ,
[ ]
) ,
mem _redesign : nd (
2026-05-14 12:53:35 +03:00
'Редизайн Quiet Luxury: 20 коммитов, базовый CSS + composables + переписанный AppSidebar.' ,
'При работе с редизайном портала (frontend, AppSidebar, базовый CSS).' ,
'Бэклог итерации I2 — в §15 спека, 10 пунктов отложены. Не реализовывать пункты I2 без явного запроса.' ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ] ,
[ ]
) ,
mem _devindices : nd (
2026-05-14 12:53:35 +03:00
'Dev Element Indices — временная фича обратной связи для разработки; к удалению в продакшене.' ,
'При работе с dev-фидбеком (например «1030 измени цвет») — для соответствия номер → элемент.' ,
'**ВРЕМЕННАЯ** — заказчик прямо сказал «уберём в конечном релизе». Не вкладываться в долгосрочную инфраструктуру.' ,
2026-05-13 17:05:59 +03:00
[ ] ,
[ ] ,
[ ]
) ,
2026-05-15 15:34:39 +03:00
2026-05-16 06:48:46 +03:00
// ── RUFLO ОРКЕСТРАТОР (фактический реколлаж iter5) ──
2026-05-15 15:34:39 +03:00
ruflo _queen : nd (
2026-05-16 13:44:14 +03:00
'Queen оркестратора ruflo v3.7.0-alpha.38 — стратегическая «королева» роя hive-mind (топология hierarchical-mesh, консенсус byzantine). С реколлажа 16.05.2026 (CLAUDE.md §3.5, Tooling §4.10) — advisory/automation-подсистема, не entry-point: рой работает параллельно, Клод — напрямую.' ,
'Запускается только по триггеру queen/королева в промпте (Pravila §14 — hard-rule маршрутизации). Без триггера рой простаивает — Клод работает напрямую.' ,
'Фактическая инспекция рантайма 15.05.2026: Queen активна (term 1, нагрузка 0), но за всё время — 0 задач, 0 раундов консенсуса, 0 общей памяти. Реколлаж 16.05.2026 привёл нормативку к этому факту — ruflo переописан в advisory/automation-подсистему, декларация уровня −1 убрана. Alpha-версия, LLM API-ключей нет.' ,
[
{ name : 'Pravila §14' , cond : 'queen-триггер — hard-rule маршрутизации задачи через Queen' } ,
{ name : 'CLAUDE.md §3.5 / Tooling §4.10' , cond : 'нормативно описан как advisory/automation-подсистема' }
] ,
2026-05-15 15:34:39 +03:00
[
2026-05-16 06:48:46 +03:00
{ name : '10 воркеров hive-mind' , cond : 'координирует рой — все 10 простаивают' } ,
{ name : 'каталог агентов ruflo' , cond : 'ruflo init высыпал в .claude/agents/ — не задействовано' } ,
{ name : 'slash-команды ruflo' , cond : 'ruflo init высыпал в .claude/commands/ — не задействовано' } ,
{ name : 'плагины ruflo' , cond : 'установлено 0 из ~20 в реестре' }
] ,
[
{ name : 'memory:project_ruflo_integration' , cond : 'memory-файл документирует интеграцию' } ,
{ name : 'ruflo MCP' , cond : 'MCP-сервер экспонирует инструменты управления роем' }
2026-05-15 15:34:39 +03:00
] ,
2026-05-16 13:44:14 +03:00
[ { name : 'Pravila' , desc : 'iter4– iter5: нормативка декларировала ruflo Queen-led routing уровнем − 1 (overlord над всей иерархией) — расходилось с рантаймом (рой idle, 0 задач, 0 раундов консенсуса). Реколлаж 16.05.2026 (Pravila v1.16 / CLAUDE.md v2.2 / PSR_v1 v3.2 / Tooling v2.2) привёл нормативку к факту: ruflo переописан в advisory/automation-подсистему, уровень −1 убран. Конфликт «декларация ≠ рантайм» закрыт.' , type : 'GREEN' } ]
2026-05-15 15:34:39 +03:00
) ,
2026-05-16 06:48:46 +03:00
ruflo _workers : nd (
'Рабочие агенты роя hive-mind ruflo — 10 штук. Все одного типа (generic worker), без специализации. На карте до iter5 рисовались 9 «ролей» (Архитектор/Кодер/…) — таких ролей в рантайме не существует.' ,
'По задумке — Queen раздаёт воркерам подзадачи. Фактически — ни разу.' ,
'Инспекция рантайма 15.05.2026: 10 воркеров, все в статусе «простаивает» (idle), у каждого 0 выполненных задач. LLM API-ключей нет → реальная агентская работа невозможна. Последний рой запущен с тестовой задачей «ответь словом READY и ничего не меняй».' ,
[ { name : 'ruflo Queen' , cond : 'подчинены — Queen-led иерархия hive-mind' } ] ,
2026-05-15 15:34:39 +03:00
[ ] ,
[ ]
) ,
2026-05-16 06:48:46 +03:00
ruflo _daemon : nd (
'Фоновый демон ruflo под управлением PM2 (процесс `ruflo-daemon`). По расписанию запускает 5 воркеров: map (каждые 15 мин), audit (10 мин), optimize (15 мин), consolidate (30 мин), testgaps (20 мин). Переживает перезагрузку через планировщик задач Windows.' ,
'Работает постоянно в фоне.' ,
2026-05-16 15:39:47 +03:00
'Инспекция рантайма 15.05.2026: воркеры audit / optimize / testgaps пытаются запустить `claude` и КАЖДЫЙ РАЗ падают с ошибкой «файл не найден» (spawn claude ENOENT) — результат пустой (за сутки: audit 29 запусков, optimize 19, testgaps 14 — все пустые). Журнал демона при этом помечает их «успешными» — расхождение метрики и факта. Локально работают только воркеры map и consolidate (без вызова `claude`). Worker-jitter усиливает частоту Pest-квирков 73/77 (квирк 72 устранён 16.05) — на baseline-регрессии нужно `pm2 stop ruflo-daemon`.' ,
2026-05-15 15:34:39 +03:00
[ ] ,
[ ] ,
2026-05-16 06:48:46 +03:00
[ { name : 'память ruflo' , cond : 'воркер consolidate обращается к хранилищу' } ] ,
2026-05-16 15:39:47 +03:00
[ { name : 'агент pest-parallel-debugger' , desc : 'Worker-jitter фонового демона ruflo (PM2) усиливает частоту Pest-квирков 73/77. Квирк 72 устранён 16.05 (commit 0fa1a73) — его jitter больше не усиливает. На baseline-регрессии — `pm2 stop ruflo-daemon` (квирк #93, переоценён).' , type : 'BLACK' } ]
2026-05-15 15:34:39 +03:00
) ,
2026-05-16 06:48:46 +03:00
ruflo _mcp : nd (
'MCP-сервер ruflo (внешний сервис-инструмент Клода) — отдельный процесс `ruflo mcp start`, режим stdio, 7-й сервер в `.mcp.json`. Экспонирует ~210 инструментов (агенты / память / рой / хуки / нейросеть и др.).' ,
'Инструменты доступны Клоду постоянно. Это единственная по-настоящему рабочая точка интеграции ruflo — через неё и собрана фактическая инспекция 15.05.2026.' ,
'Клод НЕ обязан вызывать ruflo-инструменты — отсюда статус ruflo как параллельной подсистемы, а не overlord. Память, опрашиваемая через MCP, почти пуста (0 записей). Alpha-версия.' ,
2026-05-15 15:34:39 +03:00
[ ] ,
2026-05-16 06:48:46 +03:00
[ ] ,
[
{ name : 'ruflo Queen' , cond : 'экспонирует инструменты управления роем' } ,
{ name : 'память ruflo' , cond : 'читает/пишет через инструменты memory_*' }
]
2026-05-15 15:34:39 +03:00
) ,
ruflo _memory : nd (
2026-05-16 06:48:46 +03:00
'Хранилище памяти ruflo — файл базы `.swarm/memory.db` (SQLite через sql.js) + векторный индекс HNSW с реальными embeddings Xenova/all-MiniLM-L6-v2 (384 измерения).' ,
'Должно накапливать факты между сессиями; recall-хук и MCP-инструменты обращаются к нему.' ,
'Инспекция рантайма 15.05.2026: MCP-сервер репортит 0 записей. В базе — 2 тестовых «призрака» (h7-fixed-verify, hook-e2e) от alpha-бага HNSW #1122 (`memory delete` убирает строку, но не вектор). Проектные `memory/*.md` (16 файлов) в неё не проиндексированы. Наполняется только вручную через `ruflo memory store`.' ,
[ ] ,
2026-05-15 15:34:39 +03:00
[ ] ,
2026-05-16 06:48:46 +03:00
[
{ name : 'ruflo MCP' , cond : 'MCP читает/пишет через инструменты memory_*' } ,
{ name : 'хук recall' , cond : 'recall-хук запускает поиск по памяти' } ,
{ name : 'демон ruflo' , cond : 'воркер consolidate обращается к памяти' }
] ,
[ { name : 'memory:project_state' , desc : 'Два хранилища памяти не синхронизированы: проектные `memory/*.md` (16 файлов) и база ruflo `.swarm/memory.db`. Фактически память ruflo почти пуста — MCP-сервер репортит 0 записей (+2 тестовых призрака от alpha-бага HNSW #1122). Recall-хук срабатывает на каждый промпт, но извлекать ему почти нечего.' , type : 'BLACK' } ]
2026-05-15 15:34:39 +03:00
) ,
2026-05-16 06:48:46 +03:00
ruflo _recall _hook : nd (
'Хук типа UserPromptSubmit, зарегистрирован в `.claude/settings.json` — скрипт `tools/ruflo-recall-hook.mjs`. На каждый промпт пользователя запускает `ruflo memory search` и подмешивает топ-3 найденных записи в контекст. Единственный хук ruflo, реально вшитый в сессию Claude Code.' ,
'Перед каждым промптом пользователя.' ,
'Срабатывает «мягко» (fail-open): при ошибке/таймауте — пустой инжект, промпт не блокируется. Хук работает (виден в системных напоминаниях этой сессии), но память ruflo почти пуста — извлекать почти нечего (recall возвращает 2 тестовых призрака). У самого ruflo есть 26-27 внутренних хуков, но в `.claude/settings.json` вшит только этот один.' ,
2026-05-15 15:34:39 +03:00
[ ] ,
[ ] ,
2026-05-16 06:48:46 +03:00
[ { name : 'память ruflo' , cond : 'запускает поиск по памяти ruflo' } ]
2026-05-15 15:34:39 +03:00
) ,
2026-05-16 06:48:46 +03:00
ruflo _agents _catalog : nd (
'Каталог определений агентов, который `ruflo init` высыпал в `.claude/agents/` — 100 файлов в 23 категориях (core, consensus, sparc, github, v3, flow-nexus, optimization, sublinear, templates и др.). Из них 98 — от ruflo, 2 — проектные (rls-reviewer, pest-parallel-debugger).' ,
'Определения видны Claude Code как доступные типы суб-агентов.' ,
'Статичные файлы-заготовки. «ruflo использует каталог» — нет: воркеры роя безымянные generic, у демона свой набор воркеров. Каталог просто лежит.' ,
[ { name : 'ruflo Queen' , cond : 'высыпан установкой ruflo init' } ] ,
[ ] ,
[ ]
) ,
ruflo _commands : nd (
'Slash-команды, которые `ruflo init` высыпал в `.claude/commands/` — 88 файлов (категории sparc, github, hooks, analysis, automation, optimization, monitoring).' ,
'Доступны как slash-команды Claude Code.' ,
'Статичные файлы. Это ближайший аналог «скилов» у ruflo — но НЕ Claude Code скилы; в `.claude/skills/` ruflo не положил ничего (там только 2 проектных скила). Команды лежат, в работе проекта не задействуются.' ,
[ { name : 'ruflo Queen' , cond : 'высыпаны установкой ruflo init' } ] ,
[ ] ,
[ ]
) ,
ruflo _plugins : nd (
'Плагины ruflo. В IPFS-реестре оркестратора заявлено ~20 плагинов. Установлено — 0.' ,
'Никогда — ни один плагин не подключён.' ,
'Фактически: папки `.claude-flow/plugins/` не существует, ни один плагин не установлен. `ruflo plugins list` зависает на IPFS-discovery (реестр недоступен — Pinata/Cloudflare не отвечают). Отдельно: Claude Code скилов ruflo не привнёс — в `.claude/skills/` только 2 проектных (rls-check, q-item-add). Прямой ответ на вопрос «какие плагины и скилы использует ruflo»: ноль и ноль.' ,
[ { name : 'ruflo Queen' , cond : 'часть установки ruflo' } ] ,
2026-05-15 15:34:39 +03:00
[ ] ,
[ ]
) ,
mem _ruflo : nd (
2026-05-16 06:48:46 +03:00
'Memory-файл `project_ruflo_integration` — история ruflo big-bang (установка, нормативная инверсия, активация рантайма) и alpha-баги.' ,
2026-05-15 15:34:39 +03:00
'При работе с ruflo — для контекста интеграции и известных alpha-багов.' ,
2026-05-16 06:48:46 +03:00
'Снимок на 15.05.2026. iter5 карты опирается на фактическую инспекцию рантайма, а не только на этот файл.' ,
2026-05-15 15:34:39 +03:00
[ ] ,
[ ] ,
[ { name : 'ruflo Queen' , cond : 'документирует ruflo-интеграцию' } ]
) ,
2026-05-16 15:39:47 +03:00
// ── АУДИТ-АКТУАЛИЗАЦИЯ 16.05.2026 ────────────────
skill _creator : nd (
'Плагин Anthropic для создания новых скилов — eval-driven подход: датасеты сценариев, train/test split, бенчмарк-цикл.' ,
'При формализации повторяющегося процесса в скил с проверяемым выводом (генерация кода, преобразование файлов).' ,
'Включён в настройках (~/.claude/settings.json). Для discipline-скилов (TDD-типа) предпочтительнее скил writing-skills плагина Superpowers — у них разные философии.' ,
2026-05-18 11:14:01 +03:00
[ { name : 'PSR_v1' , cond : 'R10.1 блок 1 #56: authoring-tooling (ADR-010)' } ] ,
2026-05-16 15:39:47 +03:00
[ ] ,
[ { name : 'скил writing-skills' , cond : 'обе создают скилы — skill-creator eval-driven, writing-skills через TDD' } ]
) ,
claude _setup : nd (
'Плагин Anthropic — рекомендатель автоматизаций (claude-automation-recommender): анализирует репозиторий и советует, какие MCP-серверы, скилы, хуки, суб-агентов добавить.' ,
'При настройке/ревизии автоматизации проекта — «чего не хватает в тулчейне».' ,
'Включён в настройках (~/.claude/settings.json). Рекомендации — совещательные, решение за заказчиком.' ,
2026-05-18 11:14:01 +03:00
[ { name : 'PSR_v1' , cond : 'R10.1 блок 1 #59: dev-support — рекомендации фильтруются R0/R10.1 (CCS1, ADR-010)' } ] ,
2026-05-16 15:39:47 +03:00
[ ] ,
[ ]
) ,
plugin _dev : nd (
'Плагин Anthropic для разработки плагинов Claude Code — 7 скилов (структура плагина, разработка скилов / агентов / хуков / команд, интеграция MCP, настройки).' ,
'При создании или правке плагина и его компонентов.' ,
'Включён в настройках. Содержит 3 агента, уже представленные на карте (agent-creator / plugin-validator / skill-reviewer).' ,
2026-05-18 11:14:01 +03:00
[ { name : 'PSR_v1' , cond : 'R10.1 блок 1 #57: authoring-tooling — только для marketplace-плагинов, не для вендоренного/self-authored (PD1, ADR-010)' } ] ,
2026-05-16 15:39:47 +03:00
[
{ name : 'агент plugin-dev:agent-creator' , cond : 'входит в плагин' } ,
{ name : 'агент plugin-dev:plugin-validator' , cond : 'входит в плагин' } ,
{ name : 'агент plugin-dev:skill-reviewer' , cond : 'входит в плагин' }
] ,
[ ]
) ,
context7 : nd (
'Плагин Anthropic — актуальная документация библиотек / фреймворков / API через MCP-инструменты query-docs и resolve-library-id.' ,
'При вопросах по библиотеке / фреймворку / SDK / CLI — синтаксис API, конфигурация, миграция версий. Предпочтительнее веб-поиска для документации библиотек.' ,
'Включён в настройках. Не для рефакторинга / отладки бизнес-логики / ревью — только документация.' ,
2026-05-18 11:14:01 +03:00
[ { name : 'PSR_v1' , cond : 'R10.1 блок 1 #60: dev-support — первый выбор для документации библиотек; WebFetch/WebSearch как fallback (CTX1, ADR-010)' } ] ,
2026-05-16 15:39:47 +03:00
[ ] ,
[ ]
) ,
hk _self _check : nd (
'Хук SessionStart — economy-self-check.py: при старте сессии восстанавливает уровень экономии из файла состояния и проверяет согласованность.' ,
'SessionStart — единожды при инициализации сессии.' ,
'Часть архитектуры economy-хука из 6 компонентов (memory feedback_superpowers_hard_rule). §12 economy-режим не отменяет.' ,
[ { name : '~/.claude/settings.json' , cond : 'хук SessionStart (user-level)' } ] ,
[ ] ,
[ { name : 'хук economy-mode' , cond : 'оба — часть системы экономии' } ]
) ,
hk _skill _marker : nd (
'Хук PreToolUse на вызов Skill — skill-marker.py: фиксирует факт инвокации скила в состоянии сессии (пара со skill-check).' ,
'PreToolUse, matcher Skill — перед каждым вызовом скила.' ,
'Часть пары skill-marker / skill-check — runtime-энфорсмент §12 (скил инвокируется первым).' ,
[ { name : '~/.claude/settings.json' , cond : 'хук PreToolUse (user-level)' } ] ,
[ ] ,
[ { name : 'хук skill-check' , cond : 'пара: marker фиксирует вызов скила, check проверяет' } ]
) ,
hk _skill _check : nd (
'Хук PreToolUse на Edit/Write/MultiEdit — skill-check.py: проверяет, был ли инвокирован подходящий скил перед правкой кода (§12 дисциплина).' ,
'PreToolUse, matcher Edit|Write|MultiEdit.' ,
'Пара со skill-marker. Энфорсит §12 — нельзя править код, минуя обязательный скил.' ,
[ { name : '~/.claude/settings.json' , cond : 'хук PreToolUse (user-level)' } ] ,
[ ] ,
[ { name : 'хук skill-marker' , cond : 'пара skill-marker / skill-check' } ]
) ,
hk _state _guard : nd (
'Хук PreToolUse на Edit/Write/MultiEdit/Bash/Agent — economy-state-guard.py: ловит обходы режима экономии (в т.ч. Bash-обход Edit и наследование суб-агентами).' ,
'PreToolUse, matcher Edit|Write|MultiEdit|Bash|Agent.' ,
'Часть системы экономии из 6 компонентов. Закрывает bypass-пути (Bash вместо Edit, суб-агенты).' ,
[ { name : '~/.claude/settings.json' , cond : 'хук PreToolUse (user-level)' } ] ,
[ ] ,
[ { name : 'хук economy-mode' , cond : 'оба — система экономии' } ]
) ,
hk _postcompact : nd (
'Хук PostCompact — economy-postcompact.py: после компактификации сессии переинжектит состояние режима экономии в контекст.' ,
'PostCompact — после сжатия истории сессии.' ,
'Часть системы экономии из 6 компонентов — гарантирует, что режим переживает компакт.' ,
[ { name : '~/.claude/settings.json' , cond : 'хук PostCompact (user-level)' } ] ,
[ ] ,
[ ]
) ,
hk _verifier : nd (
'Хук Stop — агент-верификатор (модель Sonnet 4.6): после ответа проверяет соответствие режиму экономии — заявления «готово» без тестов, правки без тестов, выборочные результаты.' ,
'Stop — после каждого ответа Claude (кроме тривиальных Q&A-ходов).' ,
'Решение decision:block при нарушении. На уровне экономии 5 — short-circuit {compliant:true}. Стоит денег (вызовы Sonnet).' ,
[ { name : '~/.claude/settings.json' , cond : 'хук Stop типа agent (user-level)' } ] ,
[ ] ,
[ { name : 'скил verification-before-completion' , cond : 'верификатор энфорсит то, что требует скил' } ]
) ,
hk _ruflo _queen : nd (
'Хук UserPromptSubmit — ruflo-queen-hook.mjs: при триггер-словах queen/королева в промпте инжектит жёсткую директиву маршрутизации задачи через ruflo Queen (Pravila §14).' ,
'UserPromptSubmit — перед каждым промптом; срабатывает на queen / королева.' ,
'Энфорсит §14 Pravila (hard-rule). Перед платным спавном роя — превью. Зарегистрирован в project .claude/settings.json.' ,
[
{ name : '.claude/settings.json' , cond : 'хук UserPromptSubmit (project-level)' } ,
{ name : 'Pravila §14' , cond : 'энфорсит queen-триггер' }
] ,
[ ] ,
[ { name : 'ruflo Queen' , cond : 'хук маршрутизирует queen-задачи на Queen' } ]
) ,
sk _regression : nd (
'Проектный скил /regression — единый прогон регрессии: Pest --parallel + Vitest + сборка, парсинг результатов (JSON-first для pest --parallel, см. квирк 94).' ,
'Перед коммитом/пушем или при запросе полной регрессии — единая сводка по тестам.' ,
'Реализация — .claude/skills/regression/ (SKILL.md + run.mjs + run.test.mjs). parsePest: JSON.parse строки {"tool":"pest"}, regex — fallback.' ,
[ ] ,
[ ] ,
[ { name : 'агент pest-parallel-debugger' , cond : 'при падениях Pest --parallel передаёт разбор агенту' } ]
) ,
mem _audit _b : nd (
'Memory-файл audit_B_status — статус и находки аудитов D и B (закрыты, 6 коммитов, 34/34 RLS после хотфикса).' ,
'При вопросах про аудиты D / B — историческая запись, аудит не запускать повторно.' ,
'Снимок-история. Не редактировать — новые аудиты в новые файлы.' ,
[ ] , [ ] , [ ]
) ,
mem _audit _c : nd (
'Memory-файл audit_C_pending — аудит C, полностью реализован 07.05 (4 коммита).' ,
'При вопросах про аудит C — историческая запись, не запускать повторно.' ,
'Снимок-история. Детали — реестр §13.10, CHANGELOG §Y.' ,
[ ] , [ ] , [ ]
) ,
mem _suppliercrm : nd (
'Memory-файл supplier_crm — бизнес-модель поставщика лидов crm.bp-gr.ru: B1/B2/B3 = платформы-источники, проекты = каналы, сделки = лиды, 14 статусов.' ,
'При работе с интеграцией поставщика — для доменной модели.' ,
'Доменное описание, синхронизировано со схемой Лидерры.' ,
[ ] , [ ] , [ ]
) ,
mem _audit12 : nd (
'Memory-файл full_audit_2026-05-12 — аудит портала 12.05 + post-audit + закрытия Q.DEFER.003/004.' ,
'При вопросах про аудит 12.05 и его последствия.' ,
'Снимок-история. Содержит уроки про axe-core race-condition и mis-attribution квирка 72.' ,
[ ] , [ ] , [ ]
) ,
mem _audit14 : nd (
'Memory-файл full_audit_2026-05-14 — аудит портала #3 (14 фаз, 26 находок, вердикт зелёный).' ,
'При вопросах про аудит #3 от 14.05.' ,
'Снимок-история. Не редактировать при последующих аудитах.' ,
[ ] , [ ] , [ ]
) ,
mem _sprint1 : nd (
'Memory-файл sprint1_p0_closure — закрытие 5 P0 UI-находок аудита (DealsView, Kanban DnD, BulkActionsBar, Admin-экраны).' ,
'При вопросах про Sprint 1 / P0-фиксы портала.' ,
'Снимок-история спринта. 10 атомарных коммитов.' ,
[ ] , [ ] , [ ]
) ,
mem _sprint2 : nd (
'Memory-файл sprint2_p1_progress — Sprint 2 P1 wave 1: планы A (Auth) / B (Settings) / C (Billing) — закрыты и запушены.' ,
'При вопросах про Sprint 2 / P1-фиксы.' ,
'Снимок-история. Содержит коррекцию: SyncSupplierProjectsJobTest — реальный баг времени, не квирк 72.' ,
[ ] , [ ] , [ ]
) ,
mem _sprint3 : nd (
'Memory-файл sprint3_progress — Sprint 3 (P1 wave 2): под-планы 3A-3F, 3A-3D закрыты и запушены, 3E-3F в ожидании.' ,
'При вопросах про Sprint 3 / P1 wave 2.' ,
'Снимок-история, обновляется по ходу спринта.' ,
[ ] , [ ] , [ ]
) ,
2026-05-20 05:12:24 +03:00
// ── BRAIN GOVERNANCE iter9 (19.05.2026, ADR-011) ──
router _procedure : nd (
'Единый источник истины процедуры роутера «задача → узел(ы)» — docs/router-procedure.md v1.0. 5 шагов: hard-floor (§12/§14/§15) → классификация → выбор по триггерам (Tooling Прил. Н §4.X) → проверка связок L1-L12 → исполнение. ADR-011.' ,
'При любой задаче (имплицитно) определяет узел/связку; явно — при разборе routing-решений и в /brain-retro.' ,
'Не вводит новый реестр — формализует процедуру над существующим (Tooling §4.X). Кэша «проверенных цепочек» нет (router-only). Каждая задача — свежая сборка пути.' ,
[ { name : 'Pravila §12/§14/§15' , cond : 'hard-floor — шаг 1 процедуры' } , { name : 'CLAUDE.md §3.6' , cond : 'cross-ref на router-procedure.md' } ] ,
[ { name : 'Tooling Прил. Н §4.X' , cond : 'реестр узлов — вход шага 3' } ] ,
[ { name : 'observer (Stop-хук)' , cond : 'пишет evidence о routing-решениях' } , { name : '/brain-retro' , cond : 'факторный анализ routing' } ] ,
[ ]
) ,
observer _stophook : nd (
'Stop-хук observer (tools/observer-stop-hook.mjs, project-level) — пишет один JSONL-эпизод в docs/observer/episodes-YYYY-MM.jsonl в конце каждого хода + routing-gate. Внутри: transcript-parser (схема v2), routing-detector + choice-detector (provenance), pii-filter (маскирование ПДн). ADR-011 + observer factor-analysis.' ,
'Конец каждого хода (Stop-event). routing-gate: при навязанном методе без routing-тега → decision:block (необойдёмо).' ,
'Только пишет evidence, не вмешивается в нормативку. При внутреннем отказе — маркер observer_error, не тихий пропуск. HK1 §5.3: сосуществует с economy-verifier на Stop (append-chain).' ,
[ { name : 'Pravila §16' , cond : 'observer + routing-тег-дисциплина' } , { name : '.claude/settings.json' , cond : 'зарегистрирован как Stop-хук' } ] ,
[ { name : 'observer-transcript-parser / routing-detector / choice-detector / pii-filter' , cond : 'внутренние .mjs модули' } ] ,
[ { name : 'docs/observer/ evidence' , cond : 'пишет эпизоды' } , { name : '/brain-retro' , cond : 'читает то, что хук пишет' } ] ,
[ { name : 'hk_verifier' , desc : 'HK1 §5.3: оба на Stop-event — коллизии нет (append-chain), оба decision:block отрабатываются' , type : 'GREEN' } ]
) ,
sk _brain _retro : nd (
'Проектный скил /brain-retro (.claude/skills/brain-retro/) — раз в спринт читает docs/observer/episodes-*.jsonl и строит факторный анализ: распределение path_type, топ-узлы/связки, вывод исхода, факторная матрица (9 осей × outcome). Анализатор tools/brain-retro-analyzer.mjs.' ,
'Раз в спринт по команде заказчика («брейн-ретро»). Read-only агрегатор.' ,
'Только читает и предлагает кандидатов на корректировку нормативки — не пишет в логи, не правит Tooling/Pravila/PSR_v1. Решение по правкам — за заказчиком.' ,
[ { name : 'Pravila §16' , cond : 'evidence-loop, раз в спринт' } , { name : 'PSR_v1 R16' , cond : 'brain evidence loop' } ] ,
[ { name : 'tools/brain-retro-analyzer.mjs' , cond : 'детерминированный анализатор' } ] ,
[ { name : 'docs/observer/ evidence' , cond : 'читает эпизоды' } ] ,
[ ]
) ,
observer _evidence : nd (
'Хранилище evidence «мозга» — docs/observer/: помесячные episodes-YYYY-MM.jsonl (схема v2), STATUS.md (панель C1-C5), .read-counter.json (для C3), notes/. Визуализируется страницей docs/observer/dashboard.html (Карта/Лента/Разбор/Агрегат/конфликты; кормится из общего automation-graph-data.js).' ,
'Пишется Stop-хуком (эпизоды) + контролёрами (STATUS.md, счётчик); читается /brain-retro и dashboard.' ,
'ПДн маскируется pii-filter перед записью (§5.4). Помесячное rotation; архив после 12 месяцев. Память ruflo (.swarm/memory.db) — отдельное хранилище, не связано.' ,
[ { name : 'observer Stop-хук' , cond : 'источник эпизодов' } ] ,
[ ] ,
[ { name : '/brain-retro' , cond : 'читатель' } , { name : 'C3/C4/C5 контролёры' , cond : 'счётчик / STATUS / покрытие' } ] ,
[ ]
) ,
lh _l1watcher : nd (
'Контролёр C1 (lefthook pre-commit job 11, tools/l1-watcher.mjs) — детектор «плагин включён в settings.json без формализации в Tooling Прил. Н». Закрывает трижды повторившийся L1-паттерн (UPM/21st, Sentry/Redis, Anthropic dev-tooling). 0 LLM-вызовов.' ,
'pre-commit при правке .claude/settings.json или docs/Tooling_v8_3.md.' ,
'STRICT: блокирует коммит при drift. Групповые/human-имена разрешаются через tools/.l1-watcher-aliases.txt. ADR-011 spec §6.1.' ,
[ { name : 'lefthook.yml' , cond : 'job 11 pre-commit' } , { name : 'ADR-011 §6.1' , cond : 'C1' } ] ,
[ ] ,
[ { name : 'tooling' , cond : 'сверяет settings.json ↔ Tooling' } , { name : 'C2 cross-ref' , cond : 'оба — нормативная консистентность' } ] ,
[ ]
) ,
lh _crossref : nd (
'Контролёр C2 (lefthook pre-commit job 12, tools/cross-ref-checker.mjs) — детектор version drift между нормативными файлами (Tooling v2.11 collision 17.05). Сверяет версии в §0 cross-refs vs шапки целевых файлов. 0 LLM-вызовов.' ,
'pre-commit при правке Pravila / Tooling / PSR_v1 / CLAUDE.md / MEMORY.md.' ,
'STRICT: блокирует коммит при расхождении версии. Link-anchored детекция + scope-cut по history-маркерам (исторические «наследие»-цепочки не дают ложных срабатываний). ADR-011 spec §6.2.' ,
[ { name : 'lefthook.yml' , cond : 'job 12 pre-commit' } , { name : 'ADR-011 §6.2' , cond : 'C2' } ] ,
[ ] ,
[ { name : 'claude_md / pravila / tooling / psr_v1' , cond : 'сверяет 5 нормативных файлов' } , { name : 'C1 l1-watcher' , cond : 'оба — нормативная консистентность' } ] ,
[ ]
) ,
lh _obs _obs : nd (
'Контролёр C3 (lefthook pre-commit job 13, tools/observer-of-observer.mjs) — счётчик чтений docs/observer/ + 54-недельный self-prune. «Кто наблюдает за наблюдателями»: если evidence-loop не читается ≥54 недель — предлагает архивировать observer.' ,
'pre-commit (каждый коммит) — обновляет/проверяет docs/observer/.read-counter.json.' ,
'Warn-only (скрипт всегда exit 0) — не блокирует. 54 недели (≈год) — порог осознанно поднят заказчиком с 4 недель. ADR-011 spec §6.3.' ,
[ { name : 'lefthook.yml' , cond : 'job 13 pre-commit' } , { name : 'ADR-011 §6.3' , cond : 'C3' } ] ,
[ ] ,
[ { name : 'docs/observer/ evidence' , cond : 'читает .read-counter.json' } ] ,
[ ]
) ,
lh _status _md : nd (
'Контролёр C4 (lefthook post-commit job, tools/status-md-generator.mjs) — генерит docs/observer/STATUS.md (панель: C1-C5 + информационные метрики). Pure JS, Security Guidance #40 compliant.' ,
'post-commit (после каждого коммита) — перегенерит STATUS.md, git add (для следующего коммита).' ,
'Через `|| true` — не блокирует. Метрика «N раз использован» — информационная, не алерт (capability-readiness). ADR-011 spec §6.4.' ,
[ { name : 'lefthook.yml' , cond : 'post-commit job' } , { name : 'ADR-011 §6.4' , cond : 'C4' } ] ,
[ ] ,
[ { name : 'docs/observer/ evidence' , cond : 'пишет STATUS.md' } , { name : 'C1/C2/C3' , cond : 'агрегирует их сигнал' } ] ,
[ ]
) ,
lh _obs _cov : nd (
'Контролёр C5 (lefthook pre-commit job 15, tools/observer-coverage-checker.mjs) — observer factor-analysis spec §5.2. Флагует пропуски покрытия (git-активность есть, эпизодов 0) + поломки регистрации (Stop-хук снят из settings.json, post-commit не установлен).' ,
'pre-commit (каждый коммит).' ,
'Warn-only (скрипт всегда exit 0) — не блокирует; находки в docs/observer/STATUS.md строка C5.' ,
[ { name : 'lefthook.yml' , cond : 'job 15 pre-commit' } , { name : 'observer factor-analysis §5.2' , cond : 'C5' } ] ,
[ ] ,
[ { name : 'docs/observer/ evidence' , cond : 'проверяет покрытие + регистрацию' } , { name : 'C4 status-md' , cond : 'находки в STATUS.md' } ] ,
[ ]
) ,
2026-05-13 17:05:59 +03:00
} ;
2026-05-14 13:11:12 +03:00
// ════════════════════════════════════════════════════
// SECTION 3.5: EDGE DETAILS (iter2 §5)
// ════════════════════════════════════════════════════
const edgeKey = ( from , to ) => from + '->' + to ;
const EDGE _DETAILS = {
// ── ПРАВИЛА — иерархия ──────────────────────────
'pravila->claude_md' : { type : 'подчиняет' , when : 'всегда — CLAUDE.md уровень ниже Pravila' , transfers : 'контроль' , mandatory : 'обязательно' , rule : 'Pravila §1 (уровень 1→2a)' } ,
'pravila->psr_v1' : { type : 'подчиняет' , when : 'всегда — PSR_v1 уровень 3 ниже Pravila' , transfers : 'контроль' , mandatory : 'обязательно' , rule : 'Pravila §1 (уровень 1→3)' } ,
'claude_md->tooling' : { type : 'документирует' , when : 'при правке реестра инструментов' , transfers : 'документация' , mandatory : 'обязательно' , rule : 'CLAUDE.md §0, §3 (ссылка на Прил. Н)' } ,
2026-05-16 13:44:14 +03:00
'pravila->superpowers' : { type : 'подчиняет' , when : 'задача попадает под карту §12.2 (14 типов)' , transfers : 'контроль' , mandatory : 'hard-block' , rule : 'Pravila §12 (hard-rule уровня 0; скил первым, §9 не применяется)' } ,
2026-05-14 13:11:12 +03:00
// ── PSR_v1 координирует плагины ─────────────────
'psr_v1->superpowers' : { type : 'координирует' , when : 'paired-stack: процесс/решатель' , transfers : 'контроль' , mandatory : 'обязательно' , rule : 'PSR_v1 R5 (paired stack ядро)' } ,
'psr_v1->fd_plugin' : { type : 'координирует' , when : 'paired-stack: процесс/решатель' , transfers : 'контроль' , mandatory : 'обязательно' , rule : 'PSR_v1 R5 (paired stack ядро)' } ,
2026-05-14 17:15:39 +03:00
'psr_v1->upm' : { type : 'координирует' , when : 'вне основных фаз — активация через процедуру R14.3' , transfers : 'контроль' , mandatory : 'опционально' , rule : 'PSR_v1 R10.1, R11.5, R14.3' } ,
'psr_v1->mcp_21st' : { type : 'координирует' , when : 'вне основных фаз — активация через процедуру R14.4' , transfers : 'контроль' , mandatory : 'опционально' , rule : 'PSR_v1 R10.1, R14.4' } ,
2026-05-14 13:11:12 +03:00
'psr_v1->claude_md_mgmt' : { type : 'координирует' , when : 'инфраструктурный плагин для CLAUDE.md edits' , transfers : 'контроль' , mandatory : 'обязательно' , rule : 'PSR_v1 R10.1 блок 1' } ,
// ── CLAUDE.md — документирует ──────────────────
'claude_md->mcp_boost' : { type : 'документирует' , when : 'фаза 1+ Laravel SQL/Eloquent/docs' , transfers : 'документация' , mandatory : 'рекомендуется' , rule : 'CLAUDE.md §3.2 #10' } ,
2026-05-14 17:15:39 +03:00
'claude_md->mcp_sentry' : { type : 'документирует' , when : 'вне основных фаз — для отладки во время работы, ждёт Б-1' , transfers : 'документация' , mandatory : 'опционально' , rule : 'CLAUDE.md §3.3 #34' } ,
'claude_md->mcp_redis' : { type : 'документирует' , when : 'вне основных фаз — Memurai только на чтение' , transfers : 'документация' , mandatory : 'опционально' , rule : 'CLAUDE.md §3.3 #35' } ,
2026-05-14 13:11:12 +03:00
'claude_md->claude_md_mgmt' : { type : 'документирует' , when : 'единственный канал правок CLAUDE.md' , transfers : 'документация' , mandatory : 'hard-block' , rule : 'CLAUDE.md §5 п.10' } ,
'claude_md->ag_pest' : { type : 'документирует' , when : 'агент для Pest TDD задач' , transfers : 'документация' , mandatory : 'рекомендуется' , rule : 'CLAUDE.md §3 (агенты)' } ,
'claude_md->ag_rls' : { type : 'документирует' , when : 'агент для RLS-аудита и smoke-тестов' , transfers : 'документация' , mandatory : 'рекомендуется' , rule : 'CLAUDE.md §3 (агенты)' } ,
// ── HOOKS — триггеры ────────────────────────────
'hk_pre_claude->claude_md' : { type : 'триггерит' , when : 'PreToolUse Edit/Write CLAUDE.md' , transfers : 'проверка' , mandatory : 'hard-block' , rule : 'settings.json hooks (claude-md-management канал)' } ,
'hk_post_md->lh_mdlint' : { type : 'триггерит' , when : 'PostToolUse Edit *.md → markdownlint --fix' , transfers : 'триггер' , mandatory : 'обязательно' , rule : 'settings.json hooks + lefthook' } ,
'hk_post_schema->claude_md' : { type : 'триггерит' , when : 'PostToolUse Edit db/schema.sql → напоминание sync' , transfers : 'триггер' , mandatory : 'обязательно' , rule : 'settings.json hooks (§4.2 правил Claude)' } ,
'hk_session->mem_user' : { type : 'триггерит' , when : 'SessionStart инжектит memory-блок' , transfers : 'данные' , mandatory : 'обязательно' , rule : 'settings.json hooks (memory inject)' } ,
'hk_session->mem_env' : { type : 'триггерит' , when : 'SessionStart инжектит memory-блок' , transfers : 'данные' , mandatory : 'обязательно' , rule : 'settings.json hooks (memory inject)' } ,
'hk_session->mem_sp' : { type : 'триггерит' , when : 'SessionStart инжектит memory-блок' , transfers : 'данные' , mandatory : 'обязательно' , rule : 'settings.json hooks (memory inject)' } ,
'hk_session->mem_plugins' : { type : 'триггерит' , when : 'SessionStart инжектит memory-блок' , transfers : 'данные' , mandatory : 'обязательно' , rule : 'settings.json hooks (memory inject)' } ,
'hk_session->mem_state' : { type : 'триггерит' , when : 'SessionStart инжектит memory-блок' , transfers : 'данные' , mandatory : 'обязательно' , rule : 'settings.json hooks (memory inject)' } ,
// ── SUPERPOWERS — содержит skills ───────────────
'superpowers->sk_brainstorm' : { type : 'содержит' , when : 'plugin содержит skill' , transfers : 'контроль' , mandatory : 'обязательно' , rule : 'Pravila §12.2 (карта 14 типов)' } ,
'superpowers->sk_tdd' : { type : 'содержит' , when : 'plugin содержит skill' , transfers : 'контроль' , mandatory : 'обязательно' , rule : 'Pravila §12.2 (карта 14 типов)' } ,
'superpowers->sk_debug' : { type : 'содержит' , when : 'plugin содержит skill' , transfers : 'контроль' , mandatory : 'обязательно' , rule : 'Pravila §12.2 (карта 14 типов)' } ,
'superpowers->sk_wplans' : { type : 'содержит' , when : 'plugin содержит skill' , transfers : 'контроль' , mandatory : 'обязательно' , rule : 'Pravila §12.2 (карта 14 типов)' } ,
'superpowers->sk_eplans' : { type : 'содержит' , when : 'plugin содержит skill' , transfers : 'контроль' , mandatory : 'обязательно' , rule : 'Pravila §12.2 (карта 14 типов)' } ,
'superpowers->sk_verify' : { type : 'содержит' , when : 'plugin содержит skill' , transfers : 'контроль' , mandatory : 'обязательно' , rule : 'Pravila §12.2 (карта 14 типов)' } ,
'superpowers->sk_parallel' : { type : 'содержит' , when : 'plugin содержит skill' , transfers : 'контроль' , mandatory : 'обязательно' , rule : 'Pravila §12.2 (карта 14 типов)' } ,
'superpowers->sk_worktree' : { type : 'содержит' , when : 'plugin содержит skill' , transfers : 'контроль' , mandatory : 'обязательно' , rule : 'Pravila §12.2 (карта 14 типов)' } ,
'superpowers->sk_pr' : { type : 'содержит' , when : 'plugin содержит skill' , transfers : 'контроль' , mandatory : 'обязательно' , rule : 'Pravila §12.2 (карта 14 типов)' } ,
'superpowers->sk_subagent' : { type : 'содержит' , when : 'plugin содержит skill' , transfers : 'контроль' , mandatory : 'обязательно' , rule : 'Pravila §12.2 (карта 14 типов)' } ,
'superpowers->sk_wskills' : { type : 'содержит' , when : 'plugin содержит skill' , transfers : 'контроль' , mandatory : 'обязательно' , rule : 'Pravila §12.2 (карта 14 типов)' } ,
'superpowers->sk_spreview' : { type : 'содержит' , when : 'plugin содержит skill' , transfers : 'контроль' , mandatory : 'обязательно' , rule : 'Pravila §12.2 (карта 14 типов)' } ,
'superpowers->sk_coderev' : { type : 'содержит' , when : 'plugin содержит skill' , transfers : 'контроль' , mandatory : 'обязательно' , rule : 'Pravila §12.2 (карта 14 типов)' } ,
'superpowers->sk_elements' : { type : 'содержит' , when : 'plugin содержит skill (using-superpowers)' , transfers : 'контроль' , mandatory : 'обязательно' , rule : 'Pravila §12 (старт сессии)' } ,
// ── SKILLS — последовательности ─────────────────
'sk_brainstorm->sk_wplans' : { type : 'запускает' , when : 'после brainstorming → writing-plans' , transfers : 'триггер' , mandatory : 'рекомендуется' , rule : 'PSR_v1 R5 (paired-stack flow)' } ,
'sk_wplans->sk_eplans' : { type : 'запускает' , when : 'plan готов → executing-plans' , transfers : 'триггер' , mandatory : 'рекомендуется' , rule : 'Superpowers process chain' } ,
'sk_wplans->sk_subagent' : { type : 'альтернатива' , when : 'если в текущей сессии — subagent-driven-development вместо executing' , transfers : 'триггер' , mandatory : 'опционально' , rule : 'Superpowers process chain (in-session alt)' } ,
'sk_subagent->ag_explore' : { type : 'запускает' , when : 'параллельный поиск/исследование' , transfers : 'триггер' , mandatory : 'опционально' , rule : 'subagent-driven-development (Task agent)' } ,
'sk_subagent->ag_general' : { type : 'запускает' , when : 'general-purpose subagent для независимых задач' , transfers : 'триггер' , mandatory : 'опционально' , rule : 'subagent-driven-development (Task agent)' } ,
'sk_subagent->ag_plan' : { type : 'запускает' , when : 'агент планирования больших задач' , transfers : 'триггер' , mandatory : 'опционально' , rule : 'subagent-driven-development (Task agent)' } ,
'sk_parallel->sk_worktree' : { type : 'запускает' , when : 'parallel agents требует изоляцию worktree' , transfers : 'триггер' , mandatory : 'рекомендуется' , rule : 'PSR_v1 R5 (dispatching-parallel-agents)' } ,
'sk_rls->tooling' : { type : 'читает' , when : 'RLS-аудит сверяется с реестром инструментов' , transfers : 'данные' , mandatory : 'обязательно' , rule : 'Tooling Прил. Н (squawk/Boost)' } ,
'sk_rls->mcp_boost' : { type : 'запускает' , when : 'RLS-смоук читает БД через Boost MCP' , transfers : 'данные' , mandatory : 'обязательно' , rule : 'CLAUDE.md §3.2 #10 (Boost)' } ,
'sk_qitem->claude_md_mgmt' : { type : 'запускает' , when : 'правки реестра открытых вопросов → бамп CLAUDE.md' , transfers : 'триггер' , mandatory : 'обязательно' , rule : 'CLAUDE.md §5 п.10 (единственный канал)' } ,
'claude_md_mgmt->claude_md' : { type : 'запускает' , when : 'skills claude-md-improver / revise-claude-md правят файл' , transfers : 'контроль' , mandatory : 'hard-block' , rule : 'CLAUDE.md §5 п.10' } ,
// ── HOOKIFY — генерирует hooks ──────────────────
'ag_hookify->hookify_plugin' : { type : 'запускает' , when : 'агент hookify создаёт правила через plugin' , transfers : 'триггер' , mandatory : 'опционально' , rule : 'hookify plugin docs' } ,
'hookify_plugin->hk_economy' : { type : 'содержит' , when : 'hookify сгенерировал economy hook' , transfers : 'контроль' , mandatory : 'обязательно' , rule : 'Pravila §12 economy hook architecture' } ,
// ── АГЕНТЫ → MCP/инструменты ────────────────────
'ag_rls->mcp_boost' : { type : 'запускает' , when : 'RLS-аудит через Boost MCP' , transfers : 'данные' , mandatory : 'обязательно' , rule : 'CLAUDE.md §3.2 #10' } ,
'ag_guide->mcp_gh' : { type : 'запускает' , when : 'агент гайдов работает с GitHub issues/PR' , transfers : 'триггер' , mandatory : 'опционально' , rule : 'CLAUDE.md §3.1 #3 (GitHub MCP)' } ,
// ── LEFTHOOK jobs ───────────────────────────────
'lh_gitleaks->mem_plugins' : { type : 'документирует' , when : 'gitleaks-job описан в memory о плагинах' , transfers : 'документация' , mandatory : 'рекомендуется' , rule : 'Tooling Прил. Н §8 (lefthook.yml)' } ,
'lh_larastan->mcp_boost' : { type : 'запускает' , when : 'Larastan job использует Boost для контекста' , transfers : 'проверка' , mandatory : 'обязательно' , rule : 'lefthook.yml job + Boost' } ,
'lh_squawk->tooling' : { type : 'читает' , when : 'squawk-конфиг описан в реестре инструментов' , transfers : 'документация' , mandatory : 'обязательно' , rule : 'Tooling Прил. Н #15' } ,
'lh_gitleaks2->lh_gitleaks' : { type : 'альтернатива' , when : 'второй gitleaks-job (pre-push) вариант pre-commit' , transfers : 'проверка' , mandatory : 'опционально' , rule : 'lefthook.yml (дубль pre-push)' } ,
'lh_lychee->claude_md' : { type : 'читает' , when : 'lychee валидирует ссылки в CLAUDE.md и docs' , transfers : 'проверка' , mandatory : 'обязательно' , rule : 'CLAUDE.md §4 + lefthook' } ,
// ── MEMORY → плагины/правила ────────────────────
'mem_env->ag_pest' : { type : 'документирует' , when : 'memory о квирках окружения нужен для Pest agent' , transfers : 'данные' , mandatory : 'рекомендуется' , rule : 'memory/feedback_environment.md' } ,
'mem_plugins->psr_v1' : { type : 'документирует' , when : 'memory о парном стеке отражает PSR_v1' , transfers : 'данные' , mandatory : 'рекомендуется' , rule : 'memory/feedback_plugin_paired_stack.md' } ,
'mem_archive->claude_md' : { type : 'документирует' , when : 'memory об архиве содержит refs на CLAUDE.md' , transfers : 'данные' , mandatory : 'рекомендуется' , rule : 'memory/reference_archive.md' } ,
// ── MCP → агенты/skills ─────────────────────────
'mcp_pw->hk_session' : { type : 'триггерит' , when : 'Playwright MCP вызывается из SessionStart hook' , transfers : 'триггер' , mandatory : 'опционально' , rule : 'settings.json hooks + Playwright' } ,
'mcp_gh->sk_pr' : { type : 'запускает' , when : 'finishing-a-development-branch использует gh-команды' , transfers : 'триггер' , mandatory : 'обязательно' , rule : 'Superpowers finishing-a-development-branch' } ,
'mcp_boost->ag_rls' : { type : 'запускает' , when : 'Boost MCP отдаёт данные RLS-агенту' , transfers : 'данные' , mandatory : 'обязательно' , rule : 'CLAUDE.md §3.2 #10' } ,
// ── КОНФЛИКТЫ (8 рёбер; 3 из них имеют ту же пару from/to, что и обычные — здесь объединены под одним ключом) ─
2026-05-16 08:48:30 +03:00
'sk_rls->ag_rls' : { type : 'конфликт' , when : 'граница задана: скил — по таблице, агент — по diff/ветке/PR' , transfers : 'coverage' , mandatory : 'опционально' , rule : 'секции «Граница…» в SKILL.md + rls-reviewer.md (spec 2026-05-16)' } ,
2026-05-14 13:11:12 +03:00
'hookify_plugin->hk_pre_claude' : { type : 'конфликт' , when : 'hookify plugin генерирует hook — двойное owner-ship vs settings.json' , transfers : 'coverage' , mandatory : 'опционально' , rule : 'нет регламента (plugin vs settings.json)' } ,
2026-05-18 16:15:07 +03:00
'mcp_pw->sk_parallel' : { type : 'конфликт' , when : 'Playwright и parallel-agents оба требуют изоляцию' , transfers : 'coverage' , mandatory : 'опционально' , rule : 'GREEN: квирк #95 — профили per-cwd hash → worktrees не конфликтуют; same-dir parallel под Pravila §15.2 claim' } ,
2026-05-14 13:11:12 +03:00
'ag_pest->mcp_redis' : { type : 'конфликт' , when : 'Pest --parallel race на Redis cache (quirk 72/77)' , transfers : 'coverage' , mandatory : 'опционально' , rule : 'CLAUDE.md §3.3 #35 (Redis MCP) — race остаётся вне регламента' } ,
'psr_v1->claude_md' : { type : 'конфликт' , when : 'PSR_v1 уровень 3 vs CLAUDE.md 2a — приоритет CLAUDE.md' , transfers : 'контроль' , mandatory : 'hard-block' , rule : 'CLAUDE.md §1 (priority chain)' } ,
'upm->fd_plugin' : { type : 'конфликт' , when : 'UPM и FD оба претендуют на UI-решения' , transfers : 'coverage' , mandatory : 'hard-block' , rule : 'PSR_v1 R14.5 (не параллельно)' } ,
'mcp_21st->fd_plugin' : { type : 'конфликт' , when : '21st Magic и FD оба генераторы UI' , transfers : 'coverage' , mandatory : 'hard-block' , rule : 'PSR_v1 R14.5 (не параллельно)' } ,
2026-05-16 13:44:14 +03:00
'hk_economy->superpowers' : { type : 'конфликт' , when : 'economy-режим теоретически может «сэкономить» вызов скила — §12 (hard-rule уровня 0) economy не отменяет' , transfers : 'контроль' , mandatory : 'hard-block' , rule : 'Pravila §12.4 (только явный «не используй»)' } ,
2026-05-15 15:34:39 +03:00
2026-05-16 13:44:14 +03:00
// ── RUFLO ОРКЕСТРАТОР — реколлаж (iter5 2026-05-15 + нормативный sync 2026-05-16) ──
'ruflo_queen->ruflo_workers' : { type : 'подчиняет' , when : 'hive-mind активен, но рой ни разу не получал задач' , transfers : 'контроль' , mandatory : 'опционально (рой idle)' , rule : 'Tooling §4.10 (ruflo как advisory-подсистема)' } ,
2026-05-16 06:48:46 +03:00
'ruflo_queen->ruflo_agents_catalog' : { type : 'артефакт' , when : '`ruflo init` высыпал каталог в .claude/agents/' , transfers : 'ничего (файлы лежат)' , mandatory : 'не задействовано' , rule : 'артефакт установки ruflo' } ,
'ruflo_queen->ruflo_commands' : { type : 'артефакт' , when : '`ruflo init` высыпал команды в .claude/commands/' , transfers : 'ничего (файлы лежат)' , mandatory : 'не задействовано' , rule : 'артефакт установки ruflo' } ,
'ruflo_queen->ruflo_plugins' : { type : 'артефакт' , when : 'плагины ruflo — 0 установлено из ~20 в реестре' , transfers : 'ничего' , mandatory : 'не задействовано' , rule : 'артефакт установки ruflo' } ,
'ruflo_mcp->ruflo_memory' : { type : 'читает' , when : 'MCP-инструменты memory_* обращаются к хранилищу' , transfers : 'данные' , mandatory : 'опционально' , rule : 'Tooling §4.10' } ,
'ruflo_recall_hook->ruflo_memory' : { type : 'читает' , when : 'recall-хук на каждый промпт запускает `ruflo memory search`' , transfers : 'данные' , mandatory : '«мягко» (fail-open)' , rule : '.claude/settings.json (UserPromptSubmit)' } ,
'ruflo_daemon->ruflo_memory' : { type : 'читает' , when : 'воркер consolidate демона обращается к памяти' , transfers : 'данные' , mandatory : 'опционально' , rule : '.claude-flow daemon' } ,
'ruflo_mcp->ruflo_queen' : { type : 'экспонирует' , when : 'MCP-сервер отдаёт инструменты hive-mind_*/agent_*/swarm_*' , transfers : 'инструменты' , mandatory : 'опционально' , rule : 'Tooling §4.10' } ,
2026-05-16 13:44:14 +03:00
'ruflo_queen->pravila' : { type : 'конфликт' , when : 'реколлаж 16.05.2026 привёл нормативку к рантайму — конфликт «декларация ≠ рантайм» закрыт' , transfers : 'coverage' , mandatory : 'закрыто' , rule : 'Закрыто реколлажем: Pravila v1.16 / CLAUDE.md v2.2 / PSR_v1 v3.2 / Tooling v2.2' } ,
'pravila->ruflo_queen' : { type : 'триггерит' , when : 'триггер-слова queen/королева в промпте — задача маршрутизируется через ruflo Queen' , transfers : 'триггер' , mandatory : 'hard-rule' , rule : 'Pravila §14 (queen/королева → hive-mind spawn)' } ,
'claude_md->ruflo_queen' : { type : 'документирует' , when : 'CLAUDE.md §3.5 описывает ruflo как advisory/automation-подсистему' , transfers : 'документация' , mandatory : 'рекомендуется' , rule : 'CLAUDE.md §3.5' } ,
'psr_v1->ruflo_queen' : { type : 'документирует' , when : 'PSR_v1 §14 — cross-ref на queen-триггер Pravila §14' , transfers : 'документация' , mandatory : 'рекомендуется' , rule : 'PSR_v1 §14' } ,
'tooling->ruflo_queen' : { type : 'документирует' , when : 'Tooling §4.10 — реестр ruflo как advisory/automation-подсистемы' , transfers : 'документация' , mandatory : 'рекомендуется' , rule : 'Tooling §4.10' } ,
2026-05-16 06:48:46 +03:00
'mem_ruflo->ruflo_queen' : { type : 'документирует' , when : 'memory-файл хранит историю ruflo-интеграции' , transfers : 'данные' , mandatory : 'рекомендуется' , rule : 'memory/project_ruflo_integration.md' } ,
'ruflo_memory->mem_state' : { type : 'конфликт' , when : 'два хранилища памяти не синхронизированы; память ruflo почти пуста' , transfers : 'coverage' , mandatory : 'опционально' , rule : 'нет регламента синхронизации (alpha-баг HNSW #1122)' } ,
'ruflo_daemon->ag_pest' : { type : 'конфликт' , when : 'daemon worker-jitter усиливает частоту Pest-квирка 72' , transfers : 'coverage' , mandatory : 'опционально' , rule : 'memory feedback_environment квирк #93' } ,
2026-05-20 05:12:24 +03:00
// ── BRAIN GOVERNANCE iter9 (19.05.2026, ADR-011) ──
'claude_md->router_procedure' : { type : 'документирует' , when : 'CLAUDE.md §3.6 — cross-ref на router-procedure.md v1.0' , transfers : 'документация' , mandatory : 'обязательно' , rule : 'CLAUDE.md §3.6 (single SoT routing procedure)' } ,
'tooling->router_procedure' : { type : 'питает' , when : 'реестр Прил. Н §4.X — вход шага 3 процедуры роутера' , transfers : 'данные' , mandatory : 'обязательно' , rule : 'router-procedure.md §4.2 шаг 3' } ,
'pravila->router_procedure' : { type : 'подчиняет' , when : 'hard-floor §12/§14/§15 — шаг 1 процедуры роутера' , transfers : 'контроль' , mandatory : 'hard-floor' , rule : 'router-procedure.md §4.2 шаг 1 (Pravila §12/§14/§15)' } ,
'pravila->observer_stophook' : { type : 'подчиняет' , when : '§16: observer + routing-тег-дисциплина' , transfers : 'контроль' , mandatory : 'обязательно' , rule : 'Pravila §16.2/§16.7 (ADR-011)' } ,
'observer_stophook->observer_evidence' : { type : 'пишет' , when : 'конец каждого хода (Stop-event)' , transfers : 'данные (эпизод JSONL)' , mandatory : 'обязательно (exit-0-safe)' , rule : 'ADR-011 §5.2 (observer scope B)' } ,
'pravila->sk_brain_retro' : { type : 'подчиняет' , when : '§16: факторный анализ раз в спринт' , transfers : 'контроль' , mandatory : 'по команде заказчика' , rule : 'Pravila §16 + PSR_v1 R16' } ,
'sk_brain_retro->observer_evidence' : { type : 'читает' , when : 'раз в спринт — агрегирует эпизоды' , transfers : 'данные' , mandatory : 'read-only' , rule : 'ADR-011 §5.5 (/brain-retro — читатель)' } ,
'lh_l1watcher->tooling' : { type : 'проверяет' , when : 'pre-commit при правке settings.json / Tooling' , transfers : 'проверка' , mandatory : 'STRICT (блокирует)' , rule : 'ADR-011 §6.1 (C1) + lefthook.yml job 11' } ,
'lh_crossref->claude_md' : { type : 'проверяет' , when : 'pre-commit при правке любого из 5 нормативных файлов' , transfers : 'проверка' , mandatory : 'STRICT (блокирует)' , rule : 'ADR-011 §6.2 (C2) + lefthook.yml job 12' } ,
'lh_obs_obs->observer_evidence' : { type : 'проверяет' , when : 'pre-commit (каждый коммит) — счётчик чтений' , transfers : 'проверка' , mandatory : 'warn-only' , rule : 'ADR-011 §6.3 (C3) + lefthook.yml job 13' } ,
'lh_status_md->observer_evidence' : { type : 'пишет' , when : 'post-commit — перегенерит STATUS.md' , transfers : 'данные' , mandatory : 'не блокирует (|| true)' , rule : 'ADR-011 §6.4 (C4) + lefthook.yml post-commit' } ,
'lh_obs_cov->observer_evidence' : { type : 'проверяет' , when : 'pre-commit (каждый коммит) — покрытие + регистрация' , transfers : 'проверка' , mandatory : 'warn-only' , rule : 'observer factor-analysis §5.2 (C5) + lefthook.yml job 15' } ,
2026-05-14 13:11:12 +03:00
} ;
2026-05-16 09:30:49 +03:00
// ════════════════════════════════════════════════════
2026-05-18 15:30:40 +03:00
// SECTION 3.6: NODE META (iter6 → iter8 — даты, использование, дубли)
2026-05-16 09:30:49 +03:00
// ════════════════════════════════════════════════════
// Данные — фактический снимок: даты из git/changelog/mtime, счётчик uses —
// из разбора транскриптов сессий Claude Code за окно META_WINDOW.
// Методика и воспроизводимость — план iter6, Приложение А.
2026-05-18 15:30:40 +03:00
//
// iter8 (18.05.2026): окно расширено 09– 16.05 → 09– 18.05 (10 дней).
// Узлы интеграционных волн 17-18.05 (A6 / D3 / C9 / A4 / A3 / A11 / C10 / discovery /
// ADT) получают baseline 1 = факт интеграции (коммит + plan/spec/ADR + Tooling §4).
// Реальные вызовы (за пределами интеграций) не подсчитаны — транскрипты Claude Code
// не доступны как источник в репо. mcp_figma — uses=0, usesSrc='DEFERRED'.
// null сохраняется только для принципиально неизмеримых: правила, superpowers,
// hookify_plugin, ruflo_daemon, ruflo_memory, фоновые economy/skill-discipline
// хуки (hk_self_check / skill_marker / skill_check / state_guard / postcompact /
// verifier / ruflo_queen) и старые mem_* без активных Read-вызовов в окне.
2026-05-20 05:12:24 +03:00
const META _SNAPSHOT = '20.05.2026' ; // дата генерации значений
const META _WINDOW = '09– 20.05.2026' ; // окно подсчёта использования (12 дней)
2026-05-16 09:30:49 +03:00
// uses: number — измеримый узел (0 = реально простаивал); null — измерить нельзя
// (узел-правило / плагин-обёртка / автономный демон / пассивное хранилище) → «нет данных».
2026-05-18 15:30:40 +03:00
// usesSrc: 'скил' | 'агент' | 'MCP' | 'хук' | 'memory-чтение' | 'коммиты' | 'инспекция' | 'интеграция' | 'DEFERRED' | '—'
2026-05-16 09:30:49 +03:00
const NODE _META = {
// ── ПРАВИЛА (4) — узлы-правила, напрямую не вызываются ──
2026-05-20 05:12:24 +03:00
pravila : { since : '06.05.2026' , changed : '19.05.2026' , uses : null , usesSrc : '—' } ,
claude _md : { since : '06.05.2026' , changed : '19.05.2026' , uses : null , usesSrc : '—' } ,
psr _v1 : { since : '09.05.2026' , changed : '19.05.2026' , uses : null , usesSrc : '—' } ,
tooling : { since : '06.05.2026' , changed : '19.05.2026' , uses : null , usesSrc : '—' } ,
2026-05-16 09:30:49 +03:00
// ── ПЛАГИНЫ (5) ──
superpowers : { since : '09.05.2026' , changed : '—' , uses : null , usesSrc : '—' } ,
fd _plugin : { since : '10.05.2026' , changed : '—' , uses : 1 , usesSrc : 'скил' } ,
upm : { since : '10.05.2026' , changed : '—' , uses : 0 , usesSrc : 'скил' } ,
claude _md _mgmt : { since : '10.05.2026' , changed : '—' , uses : 15 , usesSrc : 'скил' } ,
2026-05-18 11:14:01 +03:00
hookify _plugin : { since : '—' , changed : '18.05.2026' , uses : null , usesSrc : '—' } ,
2026-05-16 09:30:49 +03:00
// ── СКИЛЫ SUPERPOWERS (14) — связка подключена 09.05.2026 ──
sk _brainstorm : { since : '09.05.2026' , changed : '—' , uses : 44 , usesSrc : 'скил' } ,
sk _wplans : { since : '09.05.2026' , changed : '—' , uses : 54 , usesSrc : 'скил' } ,
sk _eplans : { since : '09.05.2026' , changed : '—' , uses : 11 , usesSrc : 'скил' } ,
sk _subagent : { since : '09.05.2026' , changed : '—' , uses : 33 , usesSrc : 'скил' } ,
sk _tdd : { since : '09.05.2026' , changed : '—' , uses : 2 , usesSrc : 'скил' } ,
sk _verify : { since : '09.05.2026' , changed : '—' , uses : 25 , usesSrc : 'скил' } ,
sk _debug : { since : '09.05.2026' , changed : '—' , uses : 10 , usesSrc : 'скил' } ,
sk _parallel : { since : '09.05.2026' , changed : '—' , uses : 3 , usesSrc : 'скил' } ,
sk _worktree : { since : '09.05.2026' , changed : '—' , uses : 3 , usesSrc : 'скил' } ,
sk _pr : { since : '09.05.2026' , changed : '—' , uses : 10 , usesSrc : 'скил' } ,
sk _coderev : { since : '09.05.2026' , changed : '—' , uses : 1 , usesSrc : 'скил' } ,
sk _spreview : { since : '09.05.2026' , changed : '—' , uses : 0 , usesSrc : 'скил' } ,
sk _wskills : { since : '09.05.2026' , changed : '—' , uses : 0 , usesSrc : 'скил' } ,
sk _elements : { since : '09.05.2026' , changed : '—' , uses : 0 , usesSrc : 'скил' } ,
// ── СКИЛЫ ПРОЕКТА (2) — файлы добавлены в репозиторий 13.05.2026 ──
sk _rls : { since : '13.05.2026' , changed : '—' , uses : 0 , usesSrc : 'скил' } ,
sk _qitem : { since : '13.05.2026' , changed : '—' , uses : 1 , usesSrc : 'скил' } ,
// ── ХУКИ (5) ──
hk _session : { since : '—' , changed : '—' , uses : 67 , usesSrc : 'хук' } ,
hk _economy : { since : '10.05.2026' , changed : '—' , uses : 276 , usesSrc : 'хук' } ,
hk _pre _claude : { since : '13.05.2026' , changed : '—' , uses : 249 , usesSrc : 'хук' } ,
hk _post _md : { since : '06.05.2026' , changed : '—' , uses : 1334 , usesSrc : 'хук' } ,
hk _post _schema : { since : '13.05.2026' , changed : '—' , uses : 22 , usesSrc : 'хук' } ,
// ── АГЕНТЫ (11) ──
ag _explore : { since : 'встроено в Claude Code' , changed : '—' , uses : 26 , usesSrc : 'агент' } ,
ag _general : { since : 'встроено в Claude Code' , changed : '—' , uses : 512 , usesSrc : 'агент' } ,
ag _plan : { since : 'встроено в Claude Code' , changed : '—' , uses : 0 , usesSrc : 'агент' } ,
ag _pest : { since : '13.05.2026' , changed : '—' , uses : 2 , usesSrc : 'агент' } ,
ag _guide : { since : 'встроено в Claude Code' , changed : '—' , uses : 4 , usesSrc : 'агент' } ,
ag _statusline : { since : 'встроено в Claude Code' , changed : '—' , uses : 0 , usesSrc : 'агент' } ,
ag _hookify : { since : '—' , changed : '—' , uses : 0 , usesSrc : 'агент' } ,
ag _pcreator : { since : '—' , changed : '—' , uses : 0 , usesSrc : 'агент' } ,
ag _pvalid : { since : '—' , changed : '—' , uses : 0 , usesSrc : 'агент' } ,
ag _skreview : { since : '—' , changed : '—' , uses : 0 , usesSrc : 'агент' } ,
ag _rls : { since : '13.05.2026' , changed : '—' , uses : 2 , usesSrc : 'агент' } ,
// ── MCP-СЕРВЕРЫ (7) ──
mcp _21st : { since : '10.05.2026' , changed : '—' , uses : 0 , usesSrc : 'MCP' } ,
mcp _pw : { since : '06.05.2026' , changed : '—' , uses : 706 , usesSrc : 'MCP' } ,
mcp _gh : { since : '06.05.2026' , changed : '—' , uses : 0 , usesSrc : 'MCP' } ,
mcp _boost : { since : '08.05.2026' , changed : '—' , uses : 73 , usesSrc : 'MCP' } ,
mcp _redis : { since : '13.05.2026' , changed : '—' , uses : 0 , usesSrc : 'MCP' } ,
mcp _sentry : { since : '13.05.2026' , changed : '—' , uses : 0 , usesSrc : 'MCP' } ,
mcp _semgrep : { since : '10.05.2026' , changed : '—' , uses : 0 , usesSrc : 'MCP' } ,
// ── LEFTHOOK JOBS (10) — uses ≈ число коммитов в окне, фильтр по типу файла ──
lh _mdlint : { since : '06.05.2026' , changed : '—' , uses : 232 , usesSrc : 'коммиты' } ,
lh _cspell : { since : '06.05.2026' , changed : '—' , uses : 232 , usesSrc : 'коммиты' } ,
lh _stylelint : { since : '06.05.2026' , changed : '—' , uses : 43 , usesSrc : 'коммиты' } ,
lh _eslint : { since : '08.05.2026' , changed : '—' , uses : 120 , usesSrc : 'коммиты' } ,
lh _lychee : { since : '06.05.2026' , changed : '—' , uses : 56 , usesSrc : 'коммиты' } ,
lh _gitleaks : { since : '06.05.2026' , changed : '—' , uses : 514 , usesSrc : 'коммиты' } ,
lh _gitleaks2 : { since : '06.05.2026' , changed : '—' , uses : 56 , usesSrc : 'коммиты' } ,
lh _pint : { since : '08.05.2026' , changed : '—' , uses : 134 , usesSrc : 'коммиты' } ,
lh _larastan : { since : '08.05.2026' , changed : '—' , uses : 134 , usesSrc : 'коммиты' } ,
lh _squawk : { since : '08.05.2026' , changed : '—' , uses : 19 , usesSrc : 'коммиты' } ,
// ── MEMORY FILES (15) — uses = вызовы Read; changed = mtime файла ──
mem _user : { since : '07.05.2026' , changed : '08.05.2026' , uses : 0 , usesSrc : 'memory-чтение' } ,
mem _comm : { since : '07.05.2026' , changed : '08.05.2026' , uses : 0 , usesSrc : 'memory-чтение' } ,
mem _env : { since : '07.05.2026' , changed : '15.05.2026' , uses : 41 , usesSrc : 'memory-чтение' } ,
mem _sp : { since : '09.05.2026' , changed : '10.05.2026' , uses : 1 , usesSrc : 'memory-чтение' } ,
mem _plugins : { since : '09.05.2026' , changed : '13.05.2026' , uses : 9 , usesSrc : 'memory-чтение' } ,
mem _handoff : { since : '08.05.2026' , changed : '—' , uses : 0 , usesSrc : 'memory-чтение' } ,
mem _redesign : { since : '12.05.2026' , changed : '—' , uses : 0 , usesSrc : 'memory-чтение' } ,
mem _devindices : { since : '12.05.2026' , changed : '—' , uses : 1 , usesSrc : 'memory-чтение' } ,
mem _phase1 : { since : '08.05.2026' , changed : '—' , uses : 1 , usesSrc : 'memory-чтение' } ,
mem _state : { since : '07.05.2026' , changed : '15.05.2026' , uses : 73 , usesSrc : 'memory-чтение' } ,
mem _brain : { since : '11.05.2026' , changed : '—' , uses : 1 , usesSrc : 'memory-чтение' } ,
mem _supplier : { since : '10.05.2026' , changed : '12.05.2026' , uses : 13 , usesSrc : 'memory-чтение' } ,
mem _audit : { since : '13.05.2026' , changed : '—' , uses : 3 , usesSrc : 'memory-чтение' } ,
mem _archive : { since : '07.05.2026' , changed : '15.05.2026' , uses : 21 , usesSrc : 'memory-чтение' } ,
mem _github : { since : '07.05.2026' , changed : '15.05.2026' , uses : 33 , usesSrc : 'memory-чтение' } ,
// ── RUFLO ОРКЕСТРАТОР (9) — все внедрены big-bang'ом 15.05.2026 ──
2026-05-18 15:30:40 +03:00
// 🔇 ИЗОЛИРОВАН 18.05.2026 (Rec2 SYSTEM-аудита): hooks сняты из settings.json,
// MCP удалён из .mcp.json, PM2 daemon stopped+saved-empty. См. Pravila §14.9 /
// Tooling §4.10 / memory feedback_ruflo_isolated.md. uses=0 — реальные вызовы 0.
ruflo _queen : { since : '15.05.2026' , changed : '18.05.2026' , uses : 0 , usesSrc : 'инспекция' , isolated : true } ,
ruflo _plugins : { since : '15.05.2026' , changed : '18.05.2026' , uses : 0 , usesSrc : 'инспекция' , isolated : true } ,
ruflo _workers : { since : '15.05.2026' , changed : '18.05.2026' , uses : 0 , usesSrc : 'инспекция' , isolated : true } ,
ruflo _agents _catalog : { since : '15.05.2026' , changed : '18.05.2026' , uses : 0 , usesSrc : 'инспекция' , isolated : true ,
2026-05-16 09:30:49 +03:00
dupNote : '100 определений агентов дублируют реестр агентов; каталог буквально содержит 2 проектных агента' } ,
2026-05-18 15:30:40 +03:00
ruflo _commands : { since : '15.05.2026' , changed : '18.05.2026' , uses : 0 , usesSrc : 'инспекция' , isolated : true ,
2026-05-16 09:30:49 +03:00
dupNote : '88 slash-команд дублируют роль скилов — именованные вызываемые процедуры; команды инертны' } ,
2026-05-18 15:30:40 +03:00
ruflo _daemon : { since : '15.05.2026' , changed : '18.05.2026' , uses : 0 , usesSrc : 'pm2 stopped+deleted' , isolated : true } ,
ruflo _memory : { since : '15.05.2026' , changed : '18.05.2026' , uses : 0 , usesSrc : 'не читается' , isolated : true ,
dupNote : 'дублирует роль 16 memory-файлов проекта — постоянная память между сессиями; ⚫-конфликт с project_state снят изоляцией' } ,
ruflo _mcp : { since : '15.05.2026' , changed : '18.05.2026' , uses : 36 , usesSrc : 'MCP (был активен 15-17.05; снят 18.05)' , isolated : true } ,
ruflo _recall _hook : { since : '15.05.2026' , changed : '18.05.2026' , uses : 220 , usesSrc : 'хук (был активен 15-17.05; снят 18.05)' , isolated : true } ,
2026-05-16 09:30:49 +03:00
// ── MEMORY +1 (артефакт ruflo big-bang) ──
mem _ruflo : { since : '15.05.2026' , changed : '16.05.2026' , uses : 18 , usesSrc : 'memory-чтение' } ,
2026-05-16 15:39:47 +03:00
2026-05-18 15:30:40 +03:00
// ── АУДИТ-АКТУАЛИЗАЦИЯ 16.05.2026 + iter8 18.05.2026 ──
// ADT (18.05): baseline 1 = факт формализации в Tooling §4.31–4.35 + интеграционный коммит 515acb6.
skill _creator : { since : '11.05.2026' , changed : '18.05.2026' , uses : 1 , usesSrc : 'интеграция' } ,
claude _setup : { since : '11.05.2026' , changed : '18.05.2026' , uses : 1 , usesSrc : 'интеграция' } ,
plugin _dev : { since : '—' , changed : '18.05.2026' , uses : 1 , usesSrc : 'интеграция' } ,
context7 : { since : '—' , changed : '18.05.2026' , uses : 1 , usesSrc : 'интеграция' } ,
// Фоновые economy/skill-discipline хуки — измерение требует доступа к user-level логам, не репо.
2026-05-16 15:39:47 +03:00
hk _self _check : { since : '10.05.2026' , changed : '—' , uses : null , usesSrc : '—' } ,
hk _skill _marker : { since : '10.05.2026' , changed : '—' , uses : null , usesSrc : '—' } ,
hk _skill _check : { since : '10.05.2026' , changed : '—' , uses : null , usesSrc : '—' } ,
hk _state _guard : { since : '10.05.2026' , changed : '—' , uses : null , usesSrc : '—' } ,
hk _postcompact : { since : '10.05.2026' , changed : '—' , uses : null , usesSrc : '—' } ,
hk _verifier : { since : '10.05.2026' , changed : '—' , uses : null , usesSrc : '—' } ,
2026-05-18 15:30:40 +03:00
hk _ruflo _queen : { since : '15.05.2026' , changed : '18.05.2026' , uses : 0 , usesSrc : 'снят 18.05' , isolated : true } , // 🔇 ИЗОЛИРОВАН (см. ruflo блок выше)
sk _regression : { since : '15.05.2026' , changed : '—' , uses : 2 , usesSrc : 'скил' } , // verification в Sprint 1-6
2026-05-16 15:39:47 +03:00
mem _audit _b : { since : '08.05.2026' , changed : '—' , uses : null , usesSrc : '—' } ,
mem _audit _c : { since : '07.05.2026' , changed : '—' , uses : null , usesSrc : '—' } ,
mem _suppliercrm : { since : '10.05.2026' , changed : '—' , uses : null , usesSrc : '—' } ,
mem _audit12 : { since : '12.05.2026' , changed : '—' , uses : null , usesSrc : '—' } ,
mem _audit14 : { since : '14.05.2026' , changed : '—' , uses : null , usesSrc : '—' } ,
mem _sprint1 : { since : '15.05.2026' , changed : '—' , uses : null , usesSrc : '—' } ,
mem _sprint2 : { since : '15.05.2026' , changed : '—' , uses : null , usesSrc : '—' } ,
mem _sprint3 : { since : '16.05.2026' , changed : '—' , uses : null , usesSrc : '—' } ,
2026-05-17 04:46:32 +03:00
2026-05-18 15:30:40 +03:00
// ── A6 ARCHITECTURE-TOOLING 17.05.2026 (iter8: baseline 1 = факт интеграции) ──
adr _kit : { since : '17.05.2026' , changed : '—' , uses : 1 , usesSrc : 'интеграция' } ,
arch _patterns : { since : '17.05.2026' , changed : '—' , uses : 1 , usesSrc : 'интеграция' } ,
mermaid _skill : { since : '17.05.2026' , changed : '—' , uses : 1 , usesSrc : 'интеграция' } ,
deptrac : { since : '17.05.2026' , changed : '—' , uses : 1 , usesSrc : 'интеграция' } ,
// ── D3 AUDIT-SECURITY 17.05.2026 (iter8: baseline 1) ──
tob _skills : { since : '17.05.2026' , changed : '—' , uses : 1 , usesSrc : 'интеграция' } ,
sec _guidance : { since : '17.05.2026' , changed : '—' , uses : 1 , usesSrc : 'хук' } ,
sk _security _review : { since : '17.05.2026' , changed : '—' , uses : 1 , usesSrc : 'интеграция' } ,
sk _audit _portal : { since : '17.05.2026' , changed : '—' , uses : 1 , usesSrc : 'интеграция' } ,
// ── C9 PROJECT-MANAGEMENT-TOOLING 17.05.2026 (iter8: baseline 1) ──
ccpm : { since : '17.05.2026' , changed : '—' , uses : 1 , usesSrc : 'интеграция' } ,
product _mgmt : { since : '17.05.2026' , changed : '—' , uses : 1 , usesSrc : 'интеграция' } ,
// ── A4 DESIGN-TOOLING 17.05.2026 (iter8: baseline 1, mcp_figma=0 DEFERRED) ──
mcp _figma : { since : '17.05.2026' , changed : '—' , uses : 0 , usesSrc : 'DEFERRED' } ,
mcp _icons : { since : '17.05.2026' , changed : '—' , uses : 1 , usesSrc : 'MCP' } ,
design _plugin : { since : '17.05.2026' , changed : '—' , uses : 1 , usesSrc : 'интеграция' } ,
// ── A3 INTEGRATION-TOOLING (17.05.2026, iter8: baseline 1) ──
ag _apidocs : { since : '17.05.2026' , changed : '—' , uses : 1 , usesSrc : 'интеграция' } ,
mcp _openapi : { since : '17.05.2026' , changed : '—' , uses : 1 , usesSrc : 'интеграция' } ,
// ── A11 ML-AI-TOOLING (17.05.2026, iter8: baseline 1) ──
claude _api : { since : '17.05.2026' , changed : '—' , uses : 1 , usesSrc : 'интеграция' } ,
promptfoo : { since : '17.05.2026' , changed : '—' , uses : 1 , usesSrc : 'CLI' } ,
data _scientist : { since : '17.05.2026' , changed : '—' , uses : 1 , usesSrc : 'интеграция' } ,
// ── C10 BUSINESS-PROCESS (17.05.2026, iter8: baseline 1) ──
ops _plugin : { since : '17.05.2026' , changed : '—' , uses : 1 , usesSrc : 'интеграция' } ,
process _modeling : { since : '17.05.2026' , changed : '—' , uses : 1 , usesSrc : 'интеграция' } ,
process _analysis : { since : '17.05.2026' , changed : '—' , uses : 1 , usesSrc : 'интеграция' } ,
// ── DISCOVERY-TOOLING (18.05.2026, iter8: factual в сессии) ──
// snapshot 2026-05-18-system-audit-brain.md (утро) + это интервью (вечер) + последующие вызовы
discovery _interview : { since : '18.05.2026' , changed : '—' , uses : 3 , usesSrc : 'скил, factual' } ,
2026-05-20 05:12:24 +03:00
2026-05-20 09:54:25 +03:00
// ── FINANCE-TOOLING C6+C7 (20.05.2026) ──
finance _plugin : { since : '20.05.2026' , changed : '—' , uses : 0 , usesSrc : 'новый узел' } ,
billing _audit : { since : '20.05.2026' , changed : '—' , uses : 0 , usesSrc : 'новый узел' } ,
ru _tax : { since : '20.05.2026' , changed : '—' , uses : 0 , usesSrc : 'новый узел' } ,
2026-05-21 04:35:43 +03:00
// ── A1 BACKEND-TOOLING (20.05.2026, ADR-013) ──
rector : { since : '20.05.2026' , changed : '—' , uses : 0 , usesSrc : 'новый узел' } ,
php _insights : { since : '20.05.2026' , changed : '—' , uses : 0 , usesSrc : 'новый узел' } ,
backend _patterns : { since : '20.05.2026' , changed : '—' , uses : 0 , usesSrc : 'новый узел' } ,
nightowl : { since : '20.05.2026' , changed : '—' , uses : 0 , usesSrc : 'новый узел (DEFERRED)' } ,
2026-05-20 05:12:24 +03:00
// ── BRAIN GOVERNANCE iter9 (19.05.2026, ADR-011) ──
// uses: observer_stophook=31 эпизодов; lh_obs_obs/status_md/obs_cov=112 коммитов с 19.05
// (glob-less, каждый коммит); lh_l1watcher=10, lh_crossref=13 (коммиты по glob с 19.05);
// observer_evidence=0 (.read-counter.json — 0 чтений); router_procedure=null (rule-like).
router _procedure : { since : '19.05.2026' , changed : '—' , uses : null , usesSrc : '—' } ,
observer _stophook : { since : '19.05.2026' , changed : '—' , uses : 31 , usesSrc : 'хук (эпизоды)' } ,
sk _brain _retro : { since : '19.05.2026' , changed : '—' , uses : 1 , usesSrc : 'интеграция' } ,
observer _evidence : { since : '19.05.2026' , changed : '—' , uses : 0 , usesSrc : 'observer counter' } ,
lh _l1watcher : { since : '19.05.2026' , changed : '—' , uses : 10 , usesSrc : 'коммиты (с 19.05)' } ,
lh _crossref : { since : '19.05.2026' , changed : '—' , uses : 13 , usesSrc : 'коммиты (с 19.05)' } ,
lh _obs _obs : { since : '19.05.2026' , changed : '—' , uses : 112 , usesSrc : 'коммиты (с 19.05)' } ,
lh _status _md : { since : '19.05.2026' , changed : '—' , uses : 112 , usesSrc : 'коммиты (с 19.05)' } ,
lh _obs _cov : { since : '19.05.2026' , changed : '—' , uses : 112 , usesSrc : 'коммиты (с 19.05)' } ,
2026-05-16 09:30:49 +03:00
} ;
// Явные парные дубли (Фича 3) — попадают в кнопку «⧉ Дубли».
const DUPLICATE _GROUPS = [
{ id : 'D1' , pct : 90 , members : [ 'hk_post_md' , 'lh_mdlint' ] ,
reason : 'оба запускают markdownlint --fix на .md — разница только в триггере (после правки в сессии против при коммите)' } ,
{ id : 'D2' , pct : 85 , members : [ 'lh_gitleaks' , 'lh_gitleaks2' ] ,
reason : 'оба — скан секретов gitleaks; pre-commit проверяет staged-файлы, pre-push — всю историю (надмножество)' } ,
{ id : 'D3' , pct : 85 , members : [ 'sk_rls' , 'ag_rls' ] ,
reason : 'оба — 7-пунктовая проверка RLS-соответствия; уже отмечено 🔴-конфликтом «нет регламента кто когда»' } ,
{ id : 'D4' , pct : 80 , members : [ 'sk_eplans' , 'sk_subagent' ] ,
reason : 'оба исполняют план writing-plans пошагово; разница — параллельная сессия против суб-агентов в текущей' } ,
{ id : 'D5' , pct : 80 , members : [ 'sk_wplans' , 'ag_plan' ] ,
reason : 'оба производят план задачи; скил writing-plans — inline с полным кодом, агент Plan — архитектурный набросок READ-ONLY' } ,
{ id : 'D7' , pct : 80 , members : [ 'ruflo_recall_hook' , 'hk_session' ] ,
reason : 'оба инжектят память в контекст Клода; recall-хук — на каждый промпт из базы ruflo, SessionStart — при старте из .md-файлов' } ,
] ;
// Производный индекс: nodeId -> { partner, pct, reason } — для рендера легенды и подсветки.
const DUP _BY _NODE = new Map ( ) ;
DUPLICATE _GROUPS . forEach ( g => g . members . forEach ( m => {
const partner = g . members . find ( x => x !== m ) ;
DUP _BY _NODE . set ( m , { partner , pct : g . pct , reason : g . reason } ) ;
} ) ) ;
const DUP _NODE _SET = new Set ( DUP _BY _NODE . keys ( ) ) ; // 12 узлов-членов парных дублей
2026-05-16 15:03:48 +03:00
// ════════════════════════════════════════════════════
// SECTION 3.5: ФУНКЦИОНАЛЬНЫЕ РАЗДЕЛЫ (функциональная квалификация)
// ════════════════════════════════════════════════════
// Разделы деятельности Лидерры. Каждый узел карты отнесён к одному разделу
// (NODE_SECTION). Часть разделов пока пустая — это бизнес-домены, под которые
// в карте dev-автоматики ещё нет узлов. Основа будущего «мозга»: 1 раздел =
// 1 playbook «как и что делать».
2026-05-19 15:36:31 +03:00
// SECTION_BUCKETS — moved to automation-graph-data.js
// SECTIONS — moved to automation-graph-data.js
// NODE_SECTION — moved to automation-graph-data.js
// NODE_SECTION_SECONDARY — moved to automation-graph-data.js
2026-05-16 15:03:48 +03:00
// Производные индексы для рендера панели и Паспорта.
const SECTION _BY _ID = new Map ( SECTIONS . map ( s => [ s . id , s ] ) ) ;
const SECTION _NODES = new Map ( SECTIONS . map ( s => [ s . id , [ ] ] ) ) ;
NODES . forEach ( n => {
const sid = NODE _SECTION [ n . id ] ;
if ( sid && SECTION _NODES . has ( sid ) ) SECTION _NODES . get ( sid ) . push ( n . id ) ;
2026-05-17 15:34:41 +03:00
( NODE _SECTION _SECONDARY [ n . id ] || [ ] ) . forEach ( secId => {
if ( SECTION _NODES . has ( secId ) ) SECTION _NODES . get ( secId ) . push ( n . id ) ;
} ) ;
2026-05-16 15:03:48 +03:00
} ) ;
2026-05-16 22:31:26 +03:00
// ════════════════════════════════════════════════════
// SECTION 3.5: WISHLIST — отложенный backlog (todo-лист хотелок)
// ════════════════════════════════════════════════════
// Редактируемый список отложенных «хотелок» развития мозга/портала.
// Добавить хотелку = добавить объект. status: 'next' | 'blocked' | 'idea'.
const WISH _STATUS = {
next : { emoji : '▶' , label : 'к работе' , color : '#859900' } ,
blocked : { emoji : '⏸' , label : 'ждёт зависимости' , color : '#b58900' } ,
idea : { emoji : '💭' , label : 'идея' , color : '#586e75' } ,
} ;
const WISHLIST = [
{ id : 'W1' , status : 'next' , section : 'E8' ,
title : 'K7-spike — починка embeddings ruflo' ,
note : 'Tensor.location / onnxruntime version sync. Гейт жизнеспособности моста claude-mem→ReasoningBank. ~1-2 ч, systematic-debugging, ≥3 гипотезы.' } ,
{ id : 'W2' , status : 'blocked' , section : 'E8' ,
title : 'Мост claude-mem → ReasoningBank' ,
note : 'Замкнутый self-learning loop: захват (claude-mem) → адаптер+LLM-трансформ → сток (ruflo memory) → recall. Gated на W1.' } ,
{ id : 'W3' , status : 'blocked' , section : 'E8' ,
title : 'claude-mem #1 — установка плагином' ,
note : 'Слой авто-захвата моста. Ставить как плагин (не npx — риск перезаписи settings.json). Роль решается после W1.' } ,
{ id : 'W4' , status : 'blocked' , section : 'E8' ,
title : 'Двухуровневый ремонтник моста' ,
note : 'Tier 1 — auto-heal операционки (рестарт демона, re-run h7-patch, retry). Tier 2 — circuit-breaker на семантику (halt, не чинить). Часть W2.' } ,
] ;
2026-05-13 17:05:59 +03:00
// ════════════════════════════════════════════════════
// SECTION 4: VIS INIT
// ════════════════════════════════════════════════════
2026-05-19 15:36:31 +03:00
// GROUPS — moved to automation-graph-data.js
2026-05-13 17:05:59 +03:00
const nodesDS = new vis . DataSet ( NODES ) ;
const edgesDS = new vis . DataSet ( EDGES ) ;
const network = new vis . Network (
document . getElementById ( 'network' ) ,
{ nodes : nodesDS , edges : edgesDS } ,
{
groups : GROUPS ,
nodes : {
shape : 'dot' ,
borderWidth : 2 ,
borderWidthSelected : 3 ,
font : { multi : 'html' } ,
} ,
edges : {
2026-05-14 09:23:46 +03:00
smooth : { type : 'continuous' , roundness : 0.5 } ,
2026-05-13 17:05:59 +03:00
selectionWidth : 2 ,
} ,
physics : {
2026-05-14 09:23:46 +03:00
enabled : false ,
2026-05-13 17:05:59 +03:00
} ,
interaction : {
hover : true ,
tooltipDelay : 400 ,
multiselect : false ,
} ,
}
) ;
2026-05-14 09:23:46 +03:00
network . once ( 'afterDrawing' , ( ) => {
network . fit ( { animation : { duration : 600 , easingFunction : 'easeInOutQuad' } } ) ;
2026-05-13 17:05:59 +03:00
} ) ;
// ════════════════════════════════════════════════════
// SECTION 5: LEGEND PANEL
// ════════════════════════════════════════════════════
function renderLegendItem ( item ) {
return ` <li> ${ item . name } ${ item . cond ? ` <span class="cond">— ${ item . cond } </span> ` : '' } </li> ` ;
}
2026-05-14 13:14:20 +03:00
function showNodeLegend ( nodeId ) {
document . getElementById ( 'legend-node-content' ) . style . display = '' ;
document . getElementById ( 'legend-edge-content' ) . style . display = 'none' ;
2026-05-16 15:03:48 +03:00
document . getElementById ( 'legend-sections-content' ) . style . display = 'none' ;
2026-05-16 22:31:26 +03:00
document . getElementById ( 'legend-wishlist-content' ) . style . display = 'none' ;
2026-05-13 17:05:59 +03:00
const node = NODES . find ( n => n . id === nodeId ) ;
const details = NODE _DETAILS [ nodeId ] ;
const panel = document . getElementById ( 'legend-panel' ) ;
if ( ! node || ! details ) { panel . classList . remove ( 'visible' ) ; return ; }
document . getElementById ( 'legend-title' ) . textContent = node . label . replace ( /\n/g , ' ' ) ;
const catLabel = CATEGORY _LABELS [ node . group ] || node . group ;
const catColor = GROUPS [ node . group ] && GROUPS [ node . group ] . color ? GROUPS [ node . group ] . color . border : '#839496' ;
document . getElementById ( 'legend-category' ) . innerHTML =
` <span style="color: ${ catColor } ; font-weight:600;">● ${ catLabel } </span> ` ;
2026-05-16 09:41:04 +03:00
// ── Паспорт узла (iter6) ──
const meta = NODE _META [ nodeId ] || { since : '—' , changed : '—' , uses : null , usesSrc : '—' } ;
document . getElementById ( 'ld-since' ) . textContent = meta . since || '—' ;
document . getElementById ( 'ld-changed' ) . textContent = meta . changed || '—' ;
2026-05-16 15:03:48 +03:00
const _sec = NODE _SECTION [ nodeId ] ? SECTION _BY _ID . get ( NODE _SECTION [ nodeId ] ) : null ;
2026-05-17 15:34:41 +03:00
const _secExtra = ( NODE _SECTION _SECONDARY [ nodeId ] || [ ] )
. map ( id => SECTION _BY _ID . get ( id ) ) . filter ( Boolean ) ;
let _secText = _sec ? ` ${ _sec . id } · ${ _sec . label } ` : '—' ;
if ( _secExtra . length ) _secText += ` (+ ${ _secExtra . map ( s => s . id ) . join ( ', ' ) } ) ` ;
document . getElementById ( 'ld-section' ) . textContent = _secText ;
2026-05-16 09:41:04 +03:00
const usesEl = document . getElementById ( 'ld-uses' ) ;
if ( meta . uses === null || meta . uses === undefined ) {
usesEl . textContent = 'нет данных (узел не вызывается напрямую)' ;
usesEl . style . color = '#586e75' ;
} else {
usesEl . innerHTML = ` <b> ${ meta . uses } </b> <span style="color:#839496;">( ${ meta . usesSrc } ) · срез ${ META _WINDOW } </span> ` ;
usesEl . style . color = '' ;
}
// строка «Дубль» — парный дубль (DUPLICATE_GROUPS) либо ролевая заметка ruflo (dupNote)
const dupRow = document . getElementById ( 'ld-dup-row' ) ;
const dupEl = document . getElementById ( 'ld-dup' ) ;
const pair = DUP _BY _NODE . get ( nodeId ) ;
if ( pair ) {
const partnerNode = NODES . find ( n => n . id === pair . partner ) ;
const partnerLabel = partnerNode ? partnerNode . label . replace ( /\n/g , ' ' ) : pair . partner ;
dupEl . innerHTML = ` ⧉ <b> ${ partnerLabel } </b> (~ ${ pair . pct } %) — ${ pair . reason } ` ;
dupRow . style . display = '' ;
} else if ( meta . dupNote ) {
dupEl . innerHTML = ` ⧉ ${ meta . dupNote } ` ;
dupRow . style . display = '' ;
} else {
dupRow . style . display = 'none' ;
}
2026-05-13 17:05:59 +03:00
document . getElementById ( 'ld-desc' ) . textContent = details . desc ;
2026-05-14 09:10:57 +03:00
document . getElementById ( 'ld-when' ) . textContent = details . when || '—' ;
document . getElementById ( 'ld-limits' ) . textContent = details . limits || 'без особых ограничений' ;
2026-05-13 17:05:59 +03:00
const ldReports = document . getElementById ( 'ld-reports' ) ;
ldReports . innerHTML = details . reportsTo . length
? details . reportsTo . map ( renderLegendItem ) . join ( '' )
: '<li style="color:#586e75; font-style:italic;">Не подчиняется никому</li>' ;
const ldManages = document . getElementById ( 'ld-manages' ) ;
ldManages . innerHTML = details . manages . length
? details . manages . map ( renderLegendItem ) . join ( '' )
: '<li style="color:#586e75; font-style:italic;">Никто не подчиняется</li>' ;
const ldTogether = document . getElementById ( 'ld-together' ) ;
ldTogether . innerHTML = details . together . length
? details . together . map ( renderLegendItem ) . join ( '' )
: '<li style="color:#586e75; font-style:italic;">Нет особых одновременных связей</li>' ;
const ldConflicts = document . getElementById ( 'ld-conflicts' ) ;
if ( details . conflicts && details . conflicts . length ) {
2026-05-14 13:16:56 +03:00
const sorted = [ ... details . conflicts ] . sort ( ( a , b ) =>
( CONFLICT _TYPES [ a . type ] ? CONFLICT _TYPES [ a . type ] . rank : 999 ) -
( CONFLICT _TYPES [ b . type ] ? CONFLICT _TYPES [ b . type ] . rank : 999 )
) ;
ldConflicts . innerHTML = sorted . map ( c => {
const t = CONFLICT _TYPES [ c . type ] || CONFLICT _TYPES . RED ;
return ` <div class="conflict-item" style="background: ${ t . bg } "> ` +
` <div class="cname" style="color: ${ t . color } "> ${ t . emoji } ${ c . name } </div> ` +
` <div class="cdesc"> ${ c . desc } </div> ` +
` </div> ` ;
} ) . join ( '' ) ;
2026-05-13 17:05:59 +03:00
} else {
ldConflicts . innerHTML = '<div id="legend-no-conflicts" style="font-size:12px;color:#586e75;">Конфликтов не выявлено</div>' ;
}
document . getElementById ( 'conflicts-section' ) . style . display = '' ;
panel . classList . add ( 'visible' ) ;
}
2026-05-14 13:14:20 +03:00
function showEdgeLegend ( edgeId ) {
const edge = edgesDS . get ( edgeId ) ;
if ( ! edge ) return ;
const panel = document . getElementById ( 'legend-panel' ) ;
document . getElementById ( 'legend-node-content' ) . style . display = 'none' ;
document . getElementById ( 'legend-edge-content' ) . style . display = '' ;
2026-05-16 15:03:48 +03:00
document . getElementById ( 'legend-sections-content' ) . style . display = 'none' ;
2026-05-16 22:31:26 +03:00
document . getElementById ( 'legend-wishlist-content' ) . style . display = 'none' ;
2026-05-14 13:14:20 +03:00
const fromNode = NODES . find ( n => n . id === edge . from ) ;
const toNode = NODES . find ( n => n . id === edge . to ) ;
if ( ! fromNode || ! toNode ) return ;
const fromCat = CATEGORY _LABELS [ fromNode . group ] || fromNode . group ;
const toCat = CATEGORY _LABELS [ toNode . group ] || toNode . group ;
const fromColor = ( GROUPS [ fromNode . group ] && GROUPS [ fromNode . group ] . color ) ? GROUPS [ fromNode . group ] . color . border : '#839496' ;
const toColor = ( GROUPS [ toNode . group ] && GROUPS [ toNode . group ] . color ) ? GROUPS [ toNode . group ] . color . border : '#839496' ;
const edgeColor = ( edge . color && edge . color . color ) ? edge . color . color : '#586e75' ;
document . getElementById ( 'legend-edge-title' ) . innerHTML =
'<span style="color:' + fromColor + '">' + fromNode . label . replace ( /\n/g , ' ' ) + '</span>' +
' <span style="color:' + edgeColor + '">→</span> ' +
'<span style="color:' + toColor + '">' + toNode . label . replace ( /\n/g , ' ' ) + '</span>' ;
document . getElementById ( 'le-from' ) . innerHTML =
fromNode . label . replace ( /\n/g , ' ' ) +
' <span style="color:' + fromColor + ';font-size:11px;text-transform:uppercase;">(' + fromCat + ')</span>' ;
document . getElementById ( 'le-to' ) . innerHTML =
toNode . label . replace ( /\n/g , ' ' ) +
' <span style="color:' + toColor + ';font-size:11px;text-transform:uppercase;">(' + toCat + ')</span>' ;
const details = EDGE _DETAILS [ edgeKey ( edge . from , edge . to ) ] ;
if ( details ) {
document . getElementById ( 'le-type' ) . textContent = details . type ;
document . getElementById ( 'le-when' ) . textContent = details . when ;
document . getElementById ( 'le-transfers' ) . textContent = details . transfers ;
document . getElementById ( 'le-mandatory' ) . textContent = details . mandatory ;
document . getElementById ( 'le-rule' ) . textContent = details . rule ;
} else {
[ 'le-type' , 'le-when' , 'le-transfers' , 'le-mandatory' ] . forEach ( id =>
document . getElementById ( id ) . textContent = '—' ) ;
document . getElementById ( 'le-rule' ) . textContent = 'Регламент не задокументирован' ;
}
panel . classList . add ( 'visible' ) ;
}
2026-05-16 15:03:48 +03:00
// ── Панель «Разделы» — функциональная квалификация (3-й режим легенды) ──
function showSectionsLegend ( ) {
document . getElementById ( 'legend-node-content' ) . style . display = 'none' ;
document . getElementById ( 'legend-edge-content' ) . style . display = 'none' ;
2026-05-16 22:31:26 +03:00
document . getElementById ( 'legend-wishlist-content' ) . style . display = 'none' ;
2026-05-16 15:03:48 +03:00
document . getElementById ( 'legend-sections-content' ) . style . display = '' ;
let html = '' ;
for ( const bucket of SECTION _BUCKETS ) {
html += ` <div class="sect-bucket-h"> ${ bucket . id } . ${ bucket . label } </div> ` ;
for ( const sec of SECTIONS . filter ( s => s . bucket === bucket . id ) ) {
const nodeIds = SECTION _NODES . get ( sec . id ) || [ ] ;
const empty = nodeIds . length === 0 ;
html += ` <div class="sect-row ${ empty ? ' sect-empty' : '' } "> ` ;
html += ` <div><span class="sect-name"><span class="sect-id"> ${ sec . id } </span> ${ sec . label } </span> <span class="sect-cnt">· ${ nodeIds . length } </span></div> ` ;
if ( empty ) {
html += ` <div class="sect-empty-mark">— пусто (playbook ещё не наполнен) —</div> ` ;
} else {
html += '<div class="sect-chips">' + nodeIds . map ( id => {
const node = NODES . find ( n => n . id === id ) ;
const lbl = node ? node . label . replace ( /\n/g , ' ' ) : id ;
return ` <span class="sect-chip" data-node=" ${ id } "> ${ lbl } </span> ` ;
} ) . join ( '' ) + '</div>' ;
}
html += '</div>' ;
}
}
document . getElementById ( 'sect-list' ) . innerHTML = html ;
document . getElementById ( 'legend-panel' ) . classList . add ( 'visible' ) ;
}
2026-05-16 22:31:26 +03:00
// ── Панель «Хотелки» — отложенный backlog (режим легенды) ──
function showWishlistLegend ( ) {
document . getElementById ( 'legend-node-content' ) . style . display = 'none' ;
document . getElementById ( 'legend-edge-content' ) . style . display = 'none' ;
document . getElementById ( 'legend-sections-content' ) . style . display = 'none' ;
document . getElementById ( 'legend-wishlist-content' ) . style . display = '' ;
let html = '' ;
for ( const w of WISHLIST ) {
const st = WISH _STATUS [ w . status ] || WISH _STATUS . idea ;
html += ` <div class="wish-row wish- ${ w . status } "> ` ;
html += ` <div class="wish-head"><span class="wish-id"> ${ w . id } </span> ${ w . title } </div> ` ;
html += ` <div class="wish-status" style="color: ${ st . color } "> ${ st . emoji } ${ st . label } </div> ` ;
html += ` <div class="wish-note"> ${ w . note } </div> ` ;
if ( w . section ) {
const sec = SECTION _BY _ID . get ( w . section ) ;
html += ` <div class="wish-sect">Раздел: ${ w . section } ${ sec ? ' · ' + sec . label : '' } </div> ` ;
}
html += '</div>' ;
}
document . getElementById ( 'wish-list' ) . innerHTML = html ;
document . getElementById ( 'legend-panel' ) . classList . add ( 'visible' ) ;
}
2026-05-13 17:05:59 +03:00
network . on ( 'click' , params => {
if ( params . nodes . length === 1 ) {
2026-05-15 06:24:06 +03:00
const id = params . nodes [ 0 ] ;
2026-05-16 09:54:44 +03:00
// iter6 — в режиме heat/dup клик открывает паспорт, но не трогает подсветку режима
if ( HIGHLIGHT . state . viewMode === null ) {
HIGHLIGHT . setSelectedNode ( id ) ;
HIGHLIGHT . applyHighlight ( ) ;
}
2026-05-15 06:24:06 +03:00
// Right panel still shows details of the clicked node (last-clicked, even after toggle-off)
showNodeLegend ( id ) ;
2026-05-14 13:14:20 +03:00
} else if ( params . edges . length === 1 ) {
showEdgeLegend ( params . edges [ 0 ] ) ;
2026-05-13 17:05:59 +03:00
} else if ( params . nodes . length === 0 && params . edges . length === 0 ) {
2026-05-16 09:54:44 +03:00
if ( HIGHLIGHT . state . viewMode === null ) {
HIGHLIGHT . setSelectedNode ( null ) ;
HIGHLIGHT . applyHighlight ( ) ;
}
2026-05-13 17:05:59 +03:00
document . getElementById ( 'legend-panel' ) . classList . remove ( 'visible' ) ;
}
} ) ;
document . getElementById ( 'legend-close' ) . addEventListener ( 'click' , ( ) => {
document . getElementById ( 'legend-panel' ) . classList . remove ( 'visible' ) ;
} ) ;
// ════════════════════════════════════════════════════
// SECTION 6: TOOLBAR
// ════════════════════════════════════════════════════
let highlightedNode = null ;
document . getElementById ( 'search' ) . addEventListener ( 'input' , function ( ) {
2026-05-15 06:30:55 +03:00
// Search is a separate mode — last-wins over highlight state
HIGHLIGHT . clearAll ( ) ;
HIGHLIGHT . updateLegendVisuals ( ) ;
2026-05-13 17:05:59 +03:00
const q = this . value . trim ( ) . toLowerCase ( ) ;
if ( ! q ) {
nodesDS . update ( NODES . map ( n => ( { id : n . id , borderWidth : 2 , opacity : 1.0 } ) ) ) ;
highlightedNode = null ;
return ;
}
const matches = NODES . filter ( n => n . label . toLowerCase ( ) . includes ( q ) ) ;
const updates = NODES . map ( n => {
const match = matches . some ( m => m . id === n . id ) ;
return {
id : n . id ,
borderWidth : match ? 5 : 1 ,
opacity : match ? 1.0 : 0.25 ,
} ;
} ) ;
nodesDS . update ( updates ) ;
if ( matches . length === 1 ) {
network . focus ( matches [ 0 ] . id , { scale : 1.4 , animation : { duration : 500 , easingFunction : 'easeInOutQuad' } } ) ;
2026-05-14 13:14:20 +03:00
showNodeLegend ( matches [ 0 ] . id ) ;
2026-05-13 17:05:59 +03:00
highlightedNode = matches [ 0 ] . id ;
}
} ) ;
document . getElementById ( 'btn-freeze' ) . addEventListener ( 'click' , ( ) => {
network . setOptions ( { physics : { enabled : false } } ) ;
} ) ;
document . getElementById ( 'btn-unfreeze' ) . addEventListener ( 'click' , ( ) => {
2026-05-14 09:23:46 +03:00
network . setOptions ( {
physics : {
enabled : true ,
solver : 'forceAtlas2Based' ,
forceAtlas2Based : {
gravitationalConstant : - 50 ,
centralGravity : 0.0 ,
springLength : 100 ,
springConstant : 0.02 ,
damping : 0.6 ,
avoidOverlap : 0.4 ,
} ,
} ,
} ) ;
2026-05-13 17:05:59 +03:00
} ) ;
document . getElementById ( 'btn-reset' ) . addEventListener ( 'click' , ( ) => {
2026-05-14 09:23:46 +03:00
// (a) Restore radial positions
nodesDS . update ( NODES . map ( n => ( { id : n . id , x : n . x , y : n . y } ) ) ) ;
// (b) Refit camera
2026-05-13 17:05:59 +03:00
network . fit ( { animation : { duration : 600 , easingFunction : 'easeInOutQuad' } } ) ;
} ) ;
document . getElementById ( 'btn-clear' ) . addEventListener ( 'click' , ( ) => {
document . getElementById ( 'search' ) . value = '' ;
2026-05-15 06:30:55 +03:00
HIGHLIGHT . clearAll ( ) ;
HIGHLIGHT . updateLegendVisuals ( ) ;
HIGHLIGHT . applyHighlight ( ) ;
nodesDS . update ( NODES . map ( n => ( { id : n . id , borderWidth : 2 } ) ) ) ; // reset borderWidth used by search-highlight
2026-05-13 17:05:59 +03:00
document . getElementById ( 'legend-panel' ) . classList . remove ( 'visible' ) ;
highlightedNode = null ;
} ) ;
2026-05-14 12:17:08 +03:00
// ════════════════════════════════════════════════════
// SECTION 7: RESIZE HANDLE + LOCALSTORAGE
// ════════════════════════════════════════════════════
const LEGEND _STORAGE _KEY = 'liderra-map-legend-width' ;
const LEGEND _MIN _W = 300 , LEGEND _MAX _W = 900 ;
2026-05-14 12:22:52 +03:00
let redrawScheduled = false ;
2026-05-14 12:17:08 +03:00
function applyLegendWidth ( w ) {
const clamped = Math . max ( LEGEND _MIN _W , Math . min ( LEGEND _MAX _W , w ) ) ;
const panel = document . getElementById ( 'legend-panel' ) ;
panel . style . width = clamped + 'px' ;
panel . style . minWidth = clamped + 'px' ;
2026-05-14 12:22:52 +03:00
if ( typeof network !== 'undefined' && network && ! redrawScheduled ) {
redrawScheduled = true ;
requestAnimationFrame ( ( ) => {
redrawScheduled = false ;
network . redraw ( ) ;
} ) ;
}
2026-05-14 12:17:08 +03:00
}
function restoreLegendWidth ( ) {
2026-05-14 12:22:52 +03:00
let saved = 300 ;
try {
saved = parseInt ( localStorage . getItem ( LEGEND _STORAGE _KEY ) || '300' , 10 ) ;
} catch ( e ) { /* private mode or quota — keep default */ }
2026-05-14 12:17:08 +03:00
applyLegendWidth ( saved ) ;
}
( function setupResizeHandle ( ) {
const handle = document . getElementById ( 'legend-handle' ) ;
if ( ! handle ) return ;
let dragging = false ;
handle . addEventListener ( 'mousedown' , e => {
dragging = true ;
handle . classList . add ( 'dragging' ) ;
document . body . style . userSelect = 'none' ;
e . preventDefault ( ) ;
} ) ;
document . addEventListener ( 'mousemove' , e => {
if ( ! dragging ) return ;
const w = window . innerWidth - e . clientX ;
applyLegendWidth ( w ) ;
} ) ;
document . addEventListener ( 'mouseup' , ( ) => {
if ( ! dragging ) return ;
dragging = false ;
handle . classList . remove ( 'dragging' ) ;
document . body . style . userSelect = '' ;
const w = parseInt ( document . getElementById ( 'legend-panel' ) . style . width , 10 ) ;
2026-05-14 12:22:52 +03:00
try { localStorage . setItem ( LEGEND _STORAGE _KEY , String ( w ) ) ; } catch ( e ) { /* private mode or quota */ }
2026-05-14 12:17:08 +03:00
} ) ;
} ) ( ) ;
2026-05-15 06:12:43 +03:00
// ════════════════════════════════════════════════════
// SECTION 8: HIGHLIGHTING (legend filter + node focus)
// ════════════════════════════════════════════════════
const HIGHLIGHT = ( function setupHighlight ( ) {
const FILTER _GROUP _PREFIX = 'group:' ;
const FILTER _CONFLICT _PREFIX = 'conflict:' ;
const OPACITY _FOCUS = 1.0 ;
const OPACITY _FILTER = 0.55 ;
const OPACITY _DIM = 0.15 ;
const CONFLICT _EDGE _MIN _OPACITY = 0.85 ;
const state = {
selectedNode : null ,
legendFilter : new Set ( ) ,
2026-05-16 09:54:44 +03:00
viewMode : null , // null | 'heat' | 'dup' — взаимоисключающие режимы (iter6)
2026-05-15 06:12:43 +03:00
} ;
2026-05-16 09:54:44 +03:00
// ── Теплокарта использования (iter6) — 4 яруса по NODE_META[id].uses ──
function heatOpacity ( nodeId ) {
const m = NODE _META [ nodeId ] ;
const u = m ? m . uses : null ;
if ( u === null || u === undefined ) return 0.5 ; // нет данных — нейтрально
if ( u >= 21 ) return 1.0 ; // часто
if ( u >= 6 ) return 0.65 ; // иногда
if ( u >= 1 ) return 0.35 ; // редко
return 0.12 ; // простаивает (uses === 0)
}
// Узлы верхнего яруса теплокарты получают акцентную рамку.
function heatBorderWidth ( nodeId ) {
if ( state . viewMode !== 'heat' ) return 2 ;
const m = NODE _META [ nodeId ] ;
const u = m ? m . uses : null ;
return ( typeof u === 'number' && u >= 21 ) ? 4 : 2 ;
}
// Переключатель режима — toggle; включение режима гасит пофильтровую подсветку.
function setViewMode ( mode ) {
state . viewMode = ( state . viewMode === mode ) ? null : mode ;
if ( state . viewMode !== null ) {
state . legendFilter . clear ( ) ;
state . selectedNode = null ;
}
}
2026-05-15 06:12:43 +03:00
// ── Pre-computed indices ──────────────────────────
const NODES _BY _ID = new Map ( ) ;
const NEIGHBOURS = new Map ( ) ;
const CONFLICT _ENDPOINTS = { RED : new Set ( ) , BLACK : new Set ( ) , GREEN : new Set ( ) } ;
const CONFLICT _EDGE _TYPE = new Map ( ) ;
NODES . forEach ( n => {
NODES _BY _ID . set ( n . id , n ) ;
if ( ! NEIGHBOURS . has ( n . id ) ) NEIGHBOURS . set ( n . id , new Set ( ) ) ;
} ) ;
edgesDS . get ( ) . forEach ( edge => {
// Both directions — Q5; conflict edges count as connections — Q6
if ( NEIGHBOURS . has ( edge . from ) ) NEIGHBOURS . get ( edge . from ) . add ( edge . to ) ;
if ( NEIGHBOURS . has ( edge . to ) ) NEIGHBOURS . get ( edge . to ) . add ( edge . from ) ;
if ( edge . dashes && edge . color && edge . color . color ) {
for ( const t of [ 'RED' , 'BLACK' , 'GREEN' ] ) {
if ( CONFLICT _TYPES [ t ] . color === edge . color . color ) {
CONFLICT _ENDPOINTS [ t ] . add ( edge . from ) ;
CONFLICT _ENDPOINTS [ t ] . add ( edge . to ) ;
CONFLICT _EDGE _TYPE . set ( edge . id , t ) ;
break ;
}
}
}
} ) ;
// ── Opacity computations ──────────────────────────
function computeNodeOpacity ( nodeId ) {
2026-05-16 09:54:44 +03:00
// Row 0: view-mode (iter6) — глобальная картина, поверх focus/filter
if ( state . viewMode === 'heat' ) return heatOpacity ( nodeId ) ;
if ( state . viewMode === 'dup' ) return DUP _NODE _SET . has ( nodeId ) ? OPACITY _FOCUS : OPACITY _DIM ;
2026-05-15 06:12:43 +03:00
// Row 1: focus
if ( state . selectedNode !== null ) {
if ( state . selectedNode === nodeId ) return OPACITY _FOCUS ;
const neigh = NEIGHBOURS . get ( state . selectedNode ) ;
if ( neigh && neigh . has ( nodeId ) ) return OPACITY _FOCUS ;
}
// Row 2: idle
if ( state . legendFilter . size === 0 && state . selectedNode === null ) return OPACITY _FOCUS ;
// Row 3: in filter?
const node = NODES _BY _ID . get ( nodeId ) ;
let inFilter = false ;
if ( node && state . legendFilter . has ( FILTER _GROUP _PREFIX + node . group ) ) inFilter = true ;
if ( ! inFilter ) {
for ( const t of [ 'RED' , 'BLACK' , 'GREEN' ] ) {
if ( state . legendFilter . has ( FILTER _CONFLICT _PREFIX + t ) && CONFLICT _ENDPOINTS [ t ] . has ( nodeId ) ) {
inFilter = true ;
break ;
}
}
}
if ( inFilter ) return state . selectedNode ? OPACITY _FILTER : OPACITY _FOCUS ;
// Row 4: everything else
return OPACITY _DIM ;
}
function computeEdgeOpacity ( edge ) {
const fromO = computeNodeOpacity ( edge . from ) ;
const toO = computeNodeOpacity ( edge . to ) ;
const baseline = Math . min ( fromO , toO ) ;
// Conflict edge directly selected via 🔴/⚫/🟢 in filter — boost to ≥0.85
const ctype = CONFLICT _EDGE _TYPE . get ( edge . id ) ;
if ( ctype && state . legendFilter . has ( FILTER _CONFLICT _PREFIX + ctype ) ) {
return Math . max ( CONFLICT _EDGE _MIN _OPACITY , baseline ) ;
}
return baseline ;
}
function applyHighlight ( ) {
const nodeUpdates = NODES . map ( n => ( {
id : n . id ,
opacity : computeNodeOpacity ( n . id ) ,
2026-05-16 09:54:44 +03:00
borderWidth : heatBorderWidth ( n . id ) , // 4 для верхнего яруса теплокарты, иначе 2 (iter6)
2026-05-15 06:12:43 +03:00
} ) ) ;
const edgeUpdates = edgesDS . get ( ) . map ( e => ( {
id : e . id ,
color : Object . assign ( { } , e . color || { } , { opacity : computeEdgeOpacity ( e ) } ) ,
} ) ) ;
nodesDS . update ( nodeUpdates ) ;
edgesDS . update ( edgeUpdates ) ;
}
// ── State manipulators ────────────────────────────
function toggleFilter ( key ) {
if ( state . legendFilter . has ( key ) ) state . legendFilter . delete ( key ) ;
else state . legendFilter . add ( key ) ;
}
function setSelectedNode ( id ) {
if ( state . selectedNode === id ) state . selectedNode = null ; // toggle on repeat
else state . selectedNode = id ;
}
function clearAll ( ) {
state . selectedNode = null ;
state . legendFilter . clear ( ) ;
2026-05-16 09:54:44 +03:00
state . viewMode = null ;
2026-05-15 06:12:43 +03:00
}
function updateLegendVisuals ( ) {
document . querySelectorAll ( '#cat-legend .cat-item' ) . forEach ( item => {
const key = item . dataset . filterKey ;
if ( ! key ) return ;
if ( state . legendFilter . has ( key ) ) item . classList . add ( 'active' ) ;
else item . classList . remove ( 'active' ) ;
} ) ;
2026-05-16 09:54:44 +03:00
const heatBtn = document . getElementById ( 'cat-ctl-heat' ) ;
const dupBtn = document . getElementById ( 'cat-ctl-dup' ) ;
if ( heatBtn ) heatBtn . classList . toggle ( 'active' , state . viewMode === 'heat' ) ;
if ( dupBtn ) dupBtn . classList . toggle ( 'active' , state . viewMode === 'dup' ) ;
2026-05-15 06:12:43 +03:00
}
2026-05-15 06:20:22 +03:00
// ── Legend click delegation ───────────────────────
document . getElementById ( 'cat-legend' ) . addEventListener ( 'click' , e => {
2026-05-16 09:54:44 +03:00
// iter6 — клик по кнопке режима heat/dup
const ctl = e . target . closest ( '.cat-ctl' ) ;
if ( ctl ) {
2026-05-16 15:03:48 +03:00
if ( ctl . id === 'cat-ctl-sect' ) { showSectionsLegend ( ) ; return ; }
2026-05-16 22:31:26 +03:00
if ( ctl . id === 'cat-ctl-wish' ) { showWishlistLegend ( ) ; return ; }
2026-05-16 09:54:44 +03:00
setViewMode ( ctl . id === 'cat-ctl-heat' ? 'heat' : 'dup' ) ;
applyHighlight ( ) ;
updateLegendVisuals ( ) ;
return ;
}
2026-05-15 06:20:22 +03:00
const item = e . target . closest ( '.cat-item' ) ;
if ( ! item || ! item . dataset . filterKey ) return ;
toggleFilter ( item . dataset . filterKey ) ;
applyHighlight ( ) ;
updateLegendVisuals ( ) ;
} ) ;
2026-05-15 06:12:43 +03:00
// Expose API (closes over state)
return {
applyHighlight ,
toggleFilter ,
setSelectedNode ,
clearAll ,
updateLegendVisuals ,
state , // exposed for debug only
} ;
} ) ( ) ;
2026-05-16 15:03:48 +03:00
// Клик по чипу узла в панели «Разделы» — открыть паспорт узла + сфокусировать граф.
document . getElementById ( 'sect-list' ) . addEventListener ( 'click' , e => {
const chip = e . target . closest ( '.sect-chip' ) ;
if ( ! chip ) return ;
const id = chip . dataset . node ;
if ( HIGHLIGHT . state . viewMode === null ) {
HIGHLIGHT . setSelectedNode ( id ) ;
HIGHLIGHT . applyHighlight ( ) ;
}
network . focus ( id , { scale : 1.2 , animation : { duration : 500 , easingFunction : 'easeInOutQuad' } } ) ;
showNodeLegend ( id ) ;
} ) ;
2026-05-14 12:17:08 +03:00
window . addEventListener ( 'DOMContentLoaded' , restoreLegendWidth ) ;
2026-05-13 17:05:59 +03:00
< / script >
< / body >
< / html >