# Node Registry

Машиночитаемый реестр узлов тулчейна Лидерры — single source of truth для `router-procedure.md`, хуков enforcement'а (этапы 2-3 router discipline overhaul) и auto-rendered секций в нормативке.

## Файлы

- **`nodes.yaml`** — реестр 83 узлов + 16 цепочек L1-L16. Источник истины.
- **`schema.json`** — JSON Schema, валидация `nodes.yaml` при загрузке.
- **`README.md`** — этот файл.

## Как читать узел

```yaml
- id: "#19"                # уникальный идентификатор из Tooling Прил. Н §0
  name: "Superpowers v5.1.0"
  slug: "superpowers"      # каноническое имя для invocation (kebab-ASCII)
  category: "phase-2"      # phase-0 / phase-1 / phase-2 / phase-3 / off-phase
  subcategory: null        # либо строка (architecture-tooling, debug-runtime, ...)
  status: "active"         # active | dormant | deferred | historic
  dormancy_reason: null    # null если active, иначе текст причины
  triggers:                # как роутер выбирает узел
    - {classification: "feature", weight: 1.0}
    - {keyword: "tdd", weight: 1.0}
    - {file_pattern: "tests/**/*.php", weight: 1.0}
  boundaries:              # связи с другими узлами (ADR, paired stack, replaces)
    - {adr: "ADR-011", role: "hard-floor source"}
    - {pair: "#30", relation: "paired stack"}
  chain_membership: ["L1", "L8"]   # в каких L-цепочках участвует (sorted)
  attributes:              # свободная map для прочих метаданных
    tooling_section: "§3.3 #19"
    install: "marketplace plugin"
```

### Status маппинг

| Status | Что значит |
|---|---|
| `active` | Узел активно используется. |
| `dormant` | Узел отключён/заменён без эквивалента. Артефакт реестра сохраняется (#17 pg_partman — заменён ручным cron'ом). |
| `deferred` | Узел запланирован, но pending Б-1 / undeployed dependencies (#34 Sentry, #44 Figma, #67 NightOwl, #82 DataForSEO, #83 Unisender Go). |
| `historic` | Узел заменён другим узлом реестра (`{pair: "#N", relation: "replaced by"}`). #1 PG MCP заменён #10 Boost. |

### Trigger типы

- `{keyword: "<lowercase trimmed>", weight}` — exact-match по фразе.
- `{classification: "<class>", weight}` — соответствие классу задачи (feature/planning/bugfix/refactor/...).
- `{file_pattern: "<glob>", weight}` — соответствие пути файла (`tests/**/*.php`).

Weight — number ∈ `[0, 1]`. По умолчанию 1.0.

### Boundaries

- `{adr: "ADR-XXX", role: "<role>"}` — узел связан с ADR-решением.
- `{pair: "#N", relation: "<rel>"}` — узел связан с другим узлом реестра (`replaces`, `replaced by`, `paired stack`).
- `{relation: "<text>"}` — свободная связь (правила PSR_v1, описательная роль).

## Как добавить новый узел

1. Получить новый `#N` из [Tooling Прил. Н §0](../Tooling_v8_3.md) (канон счётчика).
2. Открыть `nodes.yaml`, добавить блок в массив `nodes:` (в правильное место по числовой сортировке).
3. **Триггеры:** что должен сказать заказчик / какой класс задач включает узел. Lowercase, trimmed, без двоеточий.
4. **Границы:** какие ADR разделяют узел от соседей, есть ли paired stack.
5. Прогнать рендер: `node tools/registry-render.mjs` — должно перерендерить `Tooling §4.0` + `routing-off-phase` routing-table.
6. Запустить тесты: `cd app && npx vitest --config vitest.config.tools.mjs run ../tools/registry-load.test.mjs`. Все должны быть GREEN.
7. Закоммитить YAML + Tooling/routing-off-phase одним коммитом.

## Auto-render

`tools/registry-render.mjs` пишет в auto-region маркеры:

- `<!-- auto:tooling-registry-summary:begin -->` в `docs/Tooling_v8_3.md` §4.0 (краткая сводка 83 узлов).
- `<!-- auto:routing-table:begin -->` в `docs/routing-off-phase.md` (routing-table по classifications).

**Не правьте содержимое между маркерами вручную** — оно перезатрётся при следующем рендере. Для изменения структуры таблицы — правьте `tools/registry-render.mjs` renderer functions.

Запуск:

```bash
node tools/registry-render.mjs          # переписать файлы
node tools/registry-render.mjs --check  # exit 1 если drift (для lefthook)
```

## Lefthook gate

`registry-render-check` — pre-commit job 17 в `lefthook.yml`. Триггерится на изменения `docs/registry/nodes.yaml` / `docs/Tooling_v8_3.md` / `docs/routing-off-phase.md`. **Warn-only первую неделю** (`if/then/fi` block, exit 0 даже при drift). Если видишь WARN — запусти:

```bash
node tools/registry-render.mjs && git add docs/Tooling_v8_3.md docs/routing-off-phase.md
```

После стабилизации (когда команда привыкнет к workflow) — убрать warn-fallback и сделать blocking.

## Цепочки L1-L16

16 канонических связок 2+ узлов (см. `chains:` секцию в `nodes.yaml`). Источник истины — [`docs/routing-off-phase.md`](../routing-off-phase.md) §4 (таблица L1-L16). При изменении routing-off-phase — обновляйте chains в `nodes.yaml` синхронно.

## Связано

- Spec: [`docs/superpowers/specs/2026-05-23-router-discipline-overhaul-design.md`](../superpowers/specs/2026-05-23-router-discipline-overhaul-design.md)
- Plan этап 1: [`docs/superpowers/plans/2026-05-23-router-overhaul-stage-1-registry.md`](../superpowers/plans/2026-05-23-router-overhaul-stage-1-registry.md)
- Router procedure: [`docs/router-procedure.md`](../router-procedure.md) (5-шаговая процедура «task → node»)
- Routing-off-phase: [`docs/routing-off-phase.md`](../routing-off-phase.md) (триггеры + L-цепочки)
- ADR-011 — brain governance.
- Pravila §15.2 — pre-flight sync для нормативных файлов.
- Pure modules: `tools/registry-load.mjs` + `tools/registry-render.mjs` + tests `tools/registry-*.test.mjs`.
