From ce8d9c3bd8e4e9699f63c2da293fabf09c3f73ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Mon, 8 Jun 2026 17:43:03 +0300 Subject: [PATCH] =?UTF-8?q?docs(router-mentor):=20H-block=20design=20?= =?UTF-8?q?=E2=80=94=20node=20cards=20(R-11)=20+=20conflict=20edges=20(R-1?= =?UTF-8?q?2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Дизайн блока H реестра хвостов эпика «роутер-наставник»: наполнение графа скилов данными — 86 карточек-контрактов (per-node, skill=slug) + явные конфликт-рёбра (Tooling §9 + ADR, двусторонние) + инвариант покрытия (TDD). Механику 3-A/3-B/3-C/3-D не трогаем. commit-not-push. coverage: skill:brainstorming --- ...er-mentor-H-cards-conflict-edges-design.md | 177 ++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 docs/superpowers/specs/2026-06-08-router-mentor-H-cards-conflict-edges-design.md diff --git a/docs/superpowers/specs/2026-06-08-router-mentor-H-cards-conflict-edges-design.md b/docs/superpowers/specs/2026-06-08-router-mentor-H-cards-conflict-edges-design.md new file mode 100644 index 00000000..77714e6b --- /dev/null +++ b/docs/superpowers/specs/2026-06-08-router-mentor-H-cards-conflict-edges-design.md @@ -0,0 +1,177 @@ +# Блок H — карточки узлов (R-11) + конфликт-рёбра (R-12) — дизайн + +**Дата:** 2026-06-08 · **Эпик:** «роутер-наставник» · **Ветка:** `worktree-brainrepo` +**Статус:** дизайн на согласовании → writing-plans. +**Источник задачи:** реестр хвостов `docs/superpowers/plans/2026-06-08-router-mentor-loose-ends-registry.md`, блок **H** (R-11 + R-12) + handoff `docs/superpowers/plans/2026-06-08-router-mentor-H-cards-session-handoff.md`. + +--- + +## 1. Цель и границы + +Граф скилов роутера (Машина 3) живёт, но **пуст данными**: механика 3-A (контракты) / 3-B (граф узлов) / 3-C (охват) / 3-D (движок) построена и покрыта инвариантами, а наполнения нет — роутер выбирает узлы «вслепую» без карточек-контрактов и без явных конфликт-рёбер. + +Этот блок наполняет граф **данными**: + +- **R-11** — карточки-контракты для **всех 86 узлов** реестра (`docs/registry/contracts/.contract.json`). Сейчас написаны 2 seed-файла (`writing-plans`, `operations-process-doc`). +- **R-12** — явные конфликт-рёбра `attributes.conflicts_with` в `docs/registry/nodes.yaml`. Сейчас 0. +- **Acceptance** — один новый инвариант покрытия (код, TDD). + +**Жёсткие границы (что НЕ делаем):** + +- НЕ трогаем механику 3-A/3-B/3-C/3-D (готова и протестирована) — только данные + 1 инвариант. +- НЕ парсим free-text для конфликтов — только explicit `attributes.conflicts_with` (как и заложено в `node-graph.conflictsOf`). +- НЕ добавляем конфликт-рёбра без канона (Tooling §9 / ADR). +- НЕ трогаем нормативку (§0 cross-refs Pravila/PSR/Tooling/CLAUDE.md), `CLAUDE.md` в worktree, `.claude/settings.json`. +- commit-not-push: пуш только по слову «пуш». + +--- + +## 2. Вселенная узлов (факт реестра) + +`docs/registry/nodes.yaml` — **86 узлов**: + +| status | кол-во | примеры | +|---|---|---| +| active | ~78 | phase-0/1/2/3 + off-phase инструменты | +| deferred | 6 | #44 Figma / #50 Jupyter / #54 n8n / #67 NightOwl / #82 DataForSEO / #83 Unisender | +| dormant | 1 | ruflo | +| historic | 1 | #1 PostgreSQL MCP (заменён Boost) | + +Каждый узел уже несёт: `id`, `name`, `slug`, `category`, `subcategory`, `status`, `capabilities`, `triggers`, `boundaries`, `chain_membership`, `attributes`. Это **первичный материал** для карточек. + +--- + +## 3. Зафиксированные решения (согласовано с владельцем 2026-06-08) + +| # | Решение | Значение | +|---|---|---| +| Р1 | **Гранулярность** | **per-node**: 86 карточек, по одной на узел; `contract.skill` = `node.slug`. Зонтичные узлы (superpowers #19, operations #51, marketing #74, ruflo) — **одна карточка-зонтик** на узел (общий контракт), не разворачиваются в под-скилы. | +| Р2 | **Scope** | **Все 86** полными карточками, включая 6 deferred + ruflo dormant + #1 historic. | +| Р3 | **Seed-файлы** | 2 готовых файла под-скилов (`writing-plans`, `operations-process-doc`) — **под-скилы, не узлы**; остаются как безвредные бонус-контракты. В инвариант покрытия не входят (инвариант — про узлы). | +| Р4 | **own/external** | `own` = наши self-authored project-скилы (`.claude/skills/**`, писали мы) + superpowers (по прецеденту seed `writing-plans`). `external` = marketplace-плагины + MCP-серверы + вендоренные чужие скилы + ruflo. `external` несёт `source{version,hash,path}`. | +| Р5 | **hash external** | Настоящий `sha256(SKILL.md)` + `path` — где есть локальный SKILL.md в репо (вендоренные/свои скилы). Где локального файла нет (MCP-серверы, marketplace-плагины) — нулевой плейсхолдер `0…0` + `path=""` (G4 инертен, как в seed `operations-process-doc`). | +| Р6 | **Конфликт-рёбра** | Источник — **только** Tooling §9 (запрещённые дубли) + ADR-границы (006/007/.../017). Двусторонние (A↔B оба несут ссылку). graphify — вторичная сверка кандидатов, не источник. | +| Р7 | **Acceptance** | Новый инвариант покрытия (TDD): каждый узел реестра имеет валидный контракт; конфликт-рёбра резолвятся и симметричны. | +| Р8 | **Батчинг** | По `category`/`subcategory` (фазы + off-phase подкатегории). | + +--- + +## 4. Компонент 1 — карточки-контракты (данные) + +**Где:** `docs/registry/contracts/.contract.json` (имя файла = slug узла; механика `loadRegistry` читает любой `*.contract.json`, маппинг узел↔контракт — по полю `skill`). + +**Форма** (схема `tools/skill-contract.mjs`, валидатор `validateContract`): + +| Поле | Тип | Содержание | +|---|---|---| +| `skill` | string | = `node.slug` (ключ связи узел↔контракт; роутер/`dispatchContract` ищут по нему) | +| `kind` | `own`\|`external` | по правилу Р4 | +| `needs` | string[] | что навыку нужно на входе (рёбра графа 3-C) | +| `produces` | string[] | что навык выдаёт (рёбра графа 3-C) | +| `constraints` | string[] | ограничения/область («только пишет план», «READ-ONLY», «marketplace skill — outputs doc only») | +| `preview-form` | enum | `none`\|`outline`\|`mockup`\|`sample`\|`dry-run`\|`diagram` — форма дешёвого образца (L1), по природе узла | +| `defaults` | string[] | разумные дефолты-на-вето (L3) | +| `key-decisions` | string[] | ключевые решения, которые навык поднимает (look-ahead роутера) | +| `acceptance-criteria` | string[] | критерий приёмки навыка заранее (L7) | +| `inherent` | `{need,rationale}[]` | «природные» нужды навыка (опционально). `rationale` — про **природу** навыка, НЕ про прошлый промах (гард R4: маркеры «забыл/прошлый раз/…» отклоняются валидатором) | +| `source` | `{version,hash,path}` | **только** для `external` (Р5) | + +**Источники контента (по приоритету):** + +1. `nodes.yaml` — `capabilities` / `boundaries` / `triggers` / `subcategory` (первичный, узлы уже описаны). +2. SKILL.md (для скилов) — реальное описание навыка. +3. Tooling Прил.Н §4.NN (роль/границы узла в каноне). +4. CLAUDE.md §3 (категория/роль). + +**Нейтральность (G1, `checkContractNeutrality`).** Карточка — про **сам инструмент**, без проектных фактов («лендингу нужен teal» → хардкод). Проектные термины инъецируются страж-проверкой; авторим карточки портативно. + +**Зонтичные узлы (Р1).** superpowers #19 / operations #51 / marketing #74 / ruflo — карточка описывает **узел как целое** (общие needs/produces зонтика), а не разворачивается в под-скилы. Seed-файлы `writing-plans`/`operations-process-doc` (под-скилы) остаются параллельно как бонусы. + +--- + +## 5. Компонент 2 — конфликт-рёбра (данные) + +**Где:** `nodes.yaml` → `.attributes.conflicts_with: [, …]` (ref = id/slug/name, резолвится `resolveNode`). Читается `node-graph.conflictsOf` (free-text не парсит — только explicit). + +**Источник (Р6) — только канон:** + +- **Tooling §9** — явный список «два инструмента на одну задачу» (запрещённые дубли). +- **ADR-границы** — зафиксированные разграничения (ADR-006 icon-path / 007 ml / … / 017 graphify и пр.). + +**Двусторонность.** Если A конфликтует с B — ссылка ставится **в обоих** узлах (`A.conflicts_with ⊇ [B]` И `B.conflicts_with ⊇ [A]`). Симметрию и отсутствие висячих ссылок проверяет инвариант (Компонент 3) + проход `sharp-edges`. + +**graphify — вторичная сверка (не источник).** `graphify-out/graph.json` Grep-доступен (бинарь не на PATH, но JSON читается напрямую). Используется так: Grep на `semantically_similar_to`/`conceptually_related_to` между инструментами → **кандидаты** в конфликты → каждый кандидат **проверяется по §9/ADR**; без канона ребро не добавляется. + +--- + +## 6. Компонент 3 — инвариант покрытия (код, TDD) + +Новый тест-инвариант на **реальном** реестре (стиль m3a/m3b/m3c — `tools/m3*-invariants.test.mjs`): + +1. **Покрытие контрактами:** для каждого узла `nodes.yaml` существует контракт-файл, чей `skill === node.slug`, и он проходит `validateContract` (`ok:true`). Дубли `skill` отлавливаются (как в `buildRegistry`). +2. **Целостность конфликт-рёбер:** каждый ref в любом `attributes.conflicts_with` резолвится (`resolveNode ≠ null`) **и** симметричен (`A→B ⟹ B→A`). + +Цикл TDD: тест добавляется → **RED** (карточек/рёбер нет) → авторинг данных → **GREEN**. Поскольку инвариант — это `tools/*.test.mjs` (не prod-`tools/*.mjs`), enforce-tdd-gate не блокирует (он только на prod-`tools/*.mjs`). + +**Заметка по 86 vs active.** Раз Р2 = все 86 получают карточки, инвариант покрытия проверяет **все узлы**, а не только active (сильнее и согласован с Р2). + +--- + +## 7. Поток данных + +``` +nodes.yaml (86 узлов) + │ авторинг по узлам (capabilities/SKILL.md/Tooling §N/CLAUDE.md §3) + ▼ +docs/registry/contracts/.contract.json (86) + │ loadRegistry → buildRegistry (валидация + дрейф G4 для external) + ▼ +роутер look-ahead (buildRouterPrompt.contracts) / dispatchContract(skill) + связь: node.slug == contract.skill + +nodes.yaml.attributes.conflicts_with → buildNodeGraph → conflictsOf(ref) +инвариант покрытия связывает оба слоя. +``` + +--- + +## 8. Батчи (≈18–20) и порядок + +Батч = `category` / `subcategory` (Р8). Внутри батча узлы однородны → консистентный тон карточек + удобная variant-analysis. + +- **Фазовые:** phase-0 · phase-1 · phase-2 (+Frontend Design) · phase-3. +- **Off-phase подкатегории:** architecture-tooling · audit-security · design-tooling · integration-tooling · ml-ai-tooling · business-process · discovery-tooling · authoring-tooling · dev-support · project-management · finance-tooling · backend-tooling · infosec-tooling · marketing-tooling · knowledge-graph-tooling · debug-runtime · UI-pool (UPM/21st/claude-md-management) · project-agent (#84/#85). +- **Прочее:** ruflo (dormant) + #1 historic. +- **Отдельные батчи:** (а) конфликт-рёбра R-12 — **после** всех карточек; (б) инвариант покрытия — отдельный **код-батч** (TDD). + +**Цикл per-батч:** `audit-context-building` → авторинг карточек → `validateContract` 0 ошибок + инварианты GREEN (`test-driven-development`; `systematic-debugging` на красный) → `verification-before-completion` → `variant-analysis` (консистентность полей/тона между карточками батча). + +**Гейт закрытия эпика:** `audit-context-building` → `sharp-edges` (двусторонняя согласованность конфликт-рёбер, нет висячих ref) → `variant-analysis` → `regression` (tools-only ≥ baseline) → `verification-before-completion` → **commit (не push)**. + +--- + +## 9. Тестирование (сводка) + +| Уровень | Что | Где | +|---|---|---| +| Форма контракта | `validateContract.ok` на каждом новом файле | стиль m3a | +| Охват реестра | новый инвариант покрытия (§6 п.1) | новый `tools/m3*-…test.mjs` | +| Граф конфликтов | резолв + симметрия (§6 п.2) | расширение m3b / новый | +| Регрессия | vitest tools-only ≥ baseline | `cd app && npx vitest run --config vitest.config.tools.mjs … --reporter dot` | + +--- + +## 10. Открытые мелочи (в реализацию, не блокеры) + +- Точный список конфликт-рёбер собирается в батче R-12 (Grep Tooling §9 + ADR + вторичная сверка graphify graph.json). +- Для каждого external-узла — определить наличие локального SKILL.md (Р5): есть → реальный hash+path; нет → нулевой плейсхолдер. +- Имя файла seed `operations-process-doc.contract.json` — под-скил, остаётся; узловой контракт operations пишется как `operations.contract.json` (skill=`operations`). + +--- + +## 11. Якоря + +- Реестр хвостов: `docs/superpowers/plans/2026-06-08-router-mentor-loose-ends-registry.md` (блок H). +- Handoff: `docs/superpowers/plans/2026-06-08-router-mentor-H-cards-session-handoff.md`. +- Механика: `tools/skill-contract.mjs`, `tools/skill-contract-registry.mjs`, `tools/node-graph.mjs`, `tools/router-engine.mjs`, инварианты `tools/m3a..m3d-*-invariants.test.mjs`. +- Образцы: `docs/registry/contracts/writing-plans.contract.json` (own), `…/operations-process-doc.contract.json` (external).