diff --git a/cspell-words.txt b/cspell-words.txt index a3fb6cc9..6d63552b 100644 --- a/cspell-words.txt +++ b/cspell-words.txt @@ -1454,3 +1454,12 @@ CCS стабу клаузы коммичу + +# Brain governance design (2026-05-19) — router-only + observer + 4 контролёра +слойного +слойный +рецидивирующие +зарегламентировать +версионный +стейлнес +апдейты diff --git a/docs/superpowers/specs/2026-05-19-brain-governance-design.md b/docs/superpowers/specs/2026-05-19-brain-governance-design.md new file mode 100644 index 00000000..77bb5d93 --- /dev/null +++ b/docs/superpowers/specs/2026-05-19-brain-governance-design.md @@ -0,0 +1,474 @@ +--- +title: Brain governance design — router-only + observer scope B + 4 контролёра +date: 2026-05-19 +status: design (approved by user — awaiting written-spec user review per brainstorming flow) +author: Дмитрий (заказчик) + Claude (Opus 4.7) via superpowers:brainstorming +related: + - docs/discovery/2026-05-18-system-audit-brain.md + - memory/project_brain_governance_design.md + - memory/feedback_brain_unused_tools_not_problem.md + - docs/Pravila_raboty_Claude_v1_1.md + - docs/Plugin_stack_rules_v1.md + - docs/Tooling_v8_3.md + - docs/routing-off-phase.md +adr-target: ADR-011 (will be written during planning phase) +--- + +# Brain governance design — router-only + observer + 4 контролёра + +## 0. TL;DR + +«Мозг» Лидерры (60 формализованных позиций + 20 ruflo plugins на 18.05.2026 — счётчики канон в [Tooling Прил. Н §0](../../Tooling_v8_3.md)) накачивается быстрее, чем регулируется. SYSTEM-аудит 18.05.2026 + intervention-сессия 19.05.2026 пришли к **router-only** архитектуре регламента: реестр узлов + процедура роутера, **без** каталога «проверенных цепочек», **без** 3-слойного механизма обновления цепочек, **без** forced-choice gate. Каждая задача — свежая сборка пути через роутер. Observer-наблюдатель (scope B, полный пакет с дня 1) пишет evidence в `docs/observer/episodes-YYYY-MM.jsonl` и не вмешивается. 4 механических контролёра (lefthook-jobs + один self-pruning counter) закрывают рецидивирующие проблемы без LLM-стоимости. Поведенческое правило «не использован ≠ проблема» — встроено в дизайн, перевешивает аналитический инстинкт «прорезать неиспользуемое». + +## 1. Контекст и проблема + +### 1.1. Триггер + +SYSTEM-аудит «мозга» 18.05.2026 (snapshot `docs/discovery/2026-05-18-system-audit-brain.md`, режим SYSTEM скила discovery-interview, scope 125 узлов × 5 осей) выявил 5 приоритетов. **Rec1–Rec5 закрыты в commit-серии 18.05** (карта iter8 + ruflo isolation + routing-off-phase.md + PSR_v1 R15 + 12 канонических связок L1–L12). После закрытия — заказчик 19.05.2026 поднял **уровень глубже**: «зарегламентировать узлы и цепочки, выстроить их взаимодействие, так чтобы они реально работали и были максимально эффективны как при решении текущих задач, так и для будущих». Brainstorming-сессия (5+ итераций) пришла к финальному дизайну. + +### 1.2. Класс проблемы, который закрываем + +| Симптом | Проявление 2026-05 | Корневая причина | +|---|---|---| +| L1-паттерн «плагин включён в settings.json без формализации» | Повтор 3× в 8 дней: UPM/21st (10.05), Sentry/Redis (13.05), Anthropic dev-tooling (18.05) | Нет автоматического детектора расхождений settings.json ↔ Tooling Прил. Н | +| Version drift между 8 нормативными файлами | Tooling v2.11 collision 17.05 (две параллельные сессии заняли один версионный номер) | Нет cross-reference consistency checker | +| Спекулятивное регулирование вперёд использования | Сессия 19.05 — initial recommendation «прорезать неиспользуемое» отвергнута заказчиком | Capability-readiness — осознанная стратегия; регулирование должно её не противоречить | +| Отсутствие evidence-loop | Solo-аналитика и саморефлексия без записи трасс | Нет пассивного журнала «как реально решалась задача» | + +### 1.3. Что НЕ является проблемой (зафиксировано в `feedback_brain_unused_tools_not_problem.md`) + +Узел в реестре «мозга», который ни разу не использовался на реальной задаче, **не** считается проблемой. Capability-readiness — осознанная стратегия заказчика: иметь инструмент готовым ещё до возникновения потребности; будущие задачи непредсказуемы; оказаться без нужного инструмента в момент задачи дороже, чем держать неиспользуемый. **Это правило перевешивает аналитический инстинкт «прорезать неиспользуемое»** и встраивается в дизайн сигнального статуса (см. §5.4) и в текст ADR-011. + +## 2. Цели и не-цели + +### 2.1. Цели + +1. **Один и только один источник истины маршрутизации** «задача → узел/узлы»: процедура роутера + статический реестр узлов с обязательными атрибутами. +2. **Capability-readiness сохранена** — каждый формализованный узел остаётся доступным, никаких автоматических «зомби»-пометок. +3. **Спекулятивная регламентация устранена структурно** — нет каталога «проверенных цепочек», который бы фиксировал маршруты до их фактического возникновения. +4. **Evidence-loop работает с дня 1** — observer пишет каждую сессию в JSONL + опциональные MD-заметки; `/brain-retro`-скил раз в спринт даёт агрегаты. +5. **4 рецидивирующих класса проблем закрыты механически** — lefthook-jobs + один self-pruning counter, 0 LLM-вызовов в hot path. +6. **Чёткая дисциплина обновления нормативки** — пока новые цепочки не появятся в evidence, никаких записей о них в реестре нет. + +### 2.2. Не-цели (явно отвергнуто) + +| Что НЕ делаем | Почему | +|---|---| +| Кэш «проверенных цепочек» (history-based: «эта цепочка проверена на задаче #1234, использовать впредь») | Спекулятивная регламентация — корневая причина churn'а нормативки. Removed in router-only refinement (turn 8 brainstorming). NB: канонические связки L1–L12 в `docs/routing-off-phase.md` — это рекомендации общего вида («узлы X+Y часто работают вместе»), не record-based кэш; этот спек их сохраняет и расширяет через `/brain-retro` см. §5.5 | +| 3-слойный механизм обновления цепочек (topology+context records / flag-on-intake / forced-choice gate) | Moot после router-only — нет каталога, нечего обновлять | +| Forced-choice gate (роутер обязан явно отказаться от каждого узла) | Same — нет каталога, граничные узлы оцениваются роутером ad-hoc по реестру | +| Стейлнес-контролёр (отдельный детектор устаревания цепочек) | Removed — после router-only его две оставшиеся функции (ADR-eval раз в полгода, memory drift) — разовые задачи для `audit-portal` или ручного прохода, отдельной инфраструктуры не требуют | +| Контролёр содержания решений (auto-judge выбранного узла) | Перевес аналитики над инстинктом заказчика; capability-readiness ⇒ не машинно-судить выбор | +| Per-step nanny (контроль каждого шага решения) | Дорого, мешает; observer уже даёт post-hoc evidence | +| Smart preflight conflict-detector (per-task semantic) | LLM-стоимость в hot path; конфликты ловятся lefthook'ом на коммите | +| Echo-chamber red-team (внутренний оппонент) | Дублирует существующий `superpowers:requesting-code-review` | +| Runtime-cost мониторинг | Off-scope; экономия-режим заказчика регулирует cost вне этой архитектуры | +| Decision-size классификатор | Subjective, нагрузка без ценности | +| Авто-апдейты нормативки observer-ом | Observer **только пишет**, не вмешивается; апдейты — ручное действие заказчика через `/brain-retro` | + +## 3. Архитектурный обзор + +``` +┌──────────────────────────────────────────────────────────────────────────┐ +│ User task │ +└────────────────────────────────────┬─────────────────────────────────────┘ + │ + ┌──────────▼──────────┐ + │ ROUTER procedure │ (см. §4) + │ — статический │ + │ реестр узлов │ + │ — правила выбора │ + │ — Pravila §12/§14/│ + │ §15 hard-floor │ + └──────────┬──────────┘ + │ (выбор узла/узлов) + ▼ + ┌─────────────────────┐ + │ Execution by Claude│ + │ + skills/plugins │ + └──────────┬──────────┘ + │ + ┌──────────────────┴──────────────────┐ + │ Stop-hook (observer write only) │ + │ → docs/observer/episodes-YYYY-MM │ + │ .jsonl + optional notes/*.md │ + └──────────────────┬──────────────────┘ + │ + ┌────────────────────┴────────────────────┐ + │ /brain-retro skill (раз в спринт) │ + │ агрегаты + кандидаты на корректировку │ + │ ← ручное решение заказчика │ + └─────────────────────────────────────────┘ + +Параллельно (механические контролёры, см. §5): + C1 L1-watcher — lefthook job + weekly cron + C2 Cross-ref consist — lefthook job + C3 Observer-of-obs — lefthook job + 54-week self-prune + C4 Сигнальный статус — ежедневно обновляемая STATUS.md +``` + +## 4. Роутер — только реестр + процедура (без кэша цепочек) + +### 4.1. Реестр узлов (Single Source of Truth) + +**Канон**: [Tooling Прил. Н](../../Tooling_v8_3.md) §4.X + §0 (счётчики). Реестр уже существует; этот дизайн **не вводит новый реестр**, а формализует обязательные атрибуты записи и процедуру выбора. + +**Обязательные атрибуты узла** (для каждой строки #1–#60 в Tooling Прил. Н): + +| Атрибут | Описание | Пример | +|---|---|---| +| `id` | Уникальный номер #1–#60+ | `#55` | +| `name` | Каноническое имя | `discovery-interview` | +| `kind` | Тип: `plugin` / `skill` / `mcp` / `hook` / `vendored-skill` / `composer-dep` / `npm-dep` / `agent` | `skill (project)` | +| `phase` | `0` / `1` / `2` / `3` / `off-phase` | `off-phase` | +| `subcategory` | Off-phase подкатегория (если applicable) | `discovery-tooling` | +| `triggers` | Условные слова/задачи, по которым роутер выбирает узел | `«интервью», «discovery», «JTBD», «ориентация по системе»` | +| `boundaries` | Границы с соседями + ADR-cross-ref | `ADR-009 vs process-analysis #53` | +| `dormant` | Boolean — узел отключён, артефакты сохранены | `false` (для ruflo — `true` per Pravila §14.9) | +| `last-touched` | Дата последней правки записи в Tooling | `2026-05-18` | + +**Граница**: эти атрибуты — формализуемая структура существующего реестра. Никакого `last-used-on-real-task` атрибута в реестре **нет** (см. §2.2 не-цель «контролёр содержания решений» + §6 поведенческое правило). + +### 4.2. Процедура роутера + +Каждая задача — **свежая сборка** через следующие шаги (роутер — это процедура, исполняемая Claude'ом при чтении промпта; никакого отдельного daemon-а нет): + +``` +1. ПРОВЕРКА HARD-FLOOR (Pravila §12 / §14 / §15) + - Содержит ли промпт queen/королева? → Pravila §14 (dormant сейчас per §14.9) + - Задача из карты §12.2? → Skill инвокируется ПЕРВЫМ (hard-rule) + - Будет ли правка нормативки из 8-list? → §15.2 pre-flight sync обязателен + - Параллельные сессии с git/субагенты? → §15.1 Sonnet/Opus only + +2. КЛАССИФИКАЦИЯ ЗАДАЧИ + - Phase-active (0/1/2/3) или off-phase? + - Тип: TDD / debug / brainstorm / writing-plan / verification / discovery / + migration / commit / review / UI-feature / arch-decision / refactor / ... + +3. ВЫБОР УЗЛА(ОВ) ПО ТРИГГЕРАМ + - Прогон по реестру (Tooling §4.X + routing-off-phase.md для off-phase) + - Если ≥2 узла подходят — применить ADR-границы (boundaries атрибут) + - Если конфликт остаётся — применить PSR_v1 R15.3 (приоритет специфичности) + +4. ПРОВЕРКА КАНОНИЧЕСКИХ СВЯЗОК (если применимо) + - Если паттерн совпадает с L1–L12 в docs/routing-off-phase.md §4 → + вызвать связку + - Если нет — комбинация ad-hoc; observer запишет (см. §5) + +5. ИСПОЛНЕНИЕ + - Skill инвокирован (если §12), или узел применён по триггеру + - Граничные случаи документируются в комментариях или в observer-логе +``` + +**Принципиально**: шаги 3–4 **не консультируются** с каким-либо кэшем «эта цепочка проверена / эта не проверена». Каждый раз — свежий проход по реестру + ADR-границам. + +### 4.3. Что роутер делает с «не использованными» узлами + +**Ничего особенного.** Узел оценивается по триггерам и границам так же, как любой другой. Если задача подходит под триггер #50 Jupyter MCP (DEFERRED), но узел `dormant=true` или `phase=DEFERRED` — роутер сообщает: «узел подходит, но в текущем окружении не активирован; задача DEFER до выполнения предусловия». + +Это **не** «зомби-флаг» — это просто корректная отчётность о состоянии возможности. + +### 4.4. Дельта vs текущее состояние + +Сейчас процедура роутера **не задокументирована явно** — она существует имплицитно в Pravila §12/§14/§15 + PSR_v1 R0–R15 + Tooling §3 + routing-off-phase.md. Дельта дизайна: + +- **Новый файл**: `docs/router-procedure.md` v1.0 — фиксирует процедуру §4.2 в одном месте. +- **Tooling Прил. Н**: каждая строка #1–#60+ дополнена 9 атрибутами §4.1 (где их нет). Это **большая нормативная правка**; будет планироваться в writing-plans phase. +- **PSR_v1 R15** уже содержит routing-таблицу для off-phase — extends, not replaces. + +## 5. Observer scope B — пакет с дня 1 + +### 5.1. Граница + +Observer **только пишет evidence, не вмешивается**. Никаких автоматических апдейтов нормативки. Никаких блокировок Stop-events. Никаких алертов в hot path — только append в JSONL + опциональная MD-заметка. + +### 5.2. Stop-hook + +**Триггер**: end-of-session (Claude Code Stop-event hook, точка регистрации — `~/.claude/settings.json` или `.claude/settings.json` проекта). + +**Action**: append одной JSONL-строки в `docs/observer/episodes-YYYY-MM.jsonl` (rotation помесячно — простое именование, никакой инфраструктуры). + +**4 обязательных поля**: + +| Поле | Тип | Описание | +|---|---|---| +| `task_id` | string | Уникальный ID сессии (UUID или git-friendly slug) | +| `timestamps` | `{started_at, ended_at}` ISO-8601 | Начало и конец сессии (для time-burn анализа) | +| `path_type` | enum: `regulated` / `improvised` / `alternative` / `mixed` | Пошёл ли роутер по канонической связке L1–L12, импровизировал, ушёл альтернативой или смешанно | +| `outcome` | enum: `success` / `partial` / `failure` / `aborted` | Итог сессии | + +**Структурированные события** (опционально, массив `events[]`): + +| Тип | Описание | +|---|---| +| `hook_fired` | Сработал хук (skill-marker, skill-check, state-guard, postcompact, verifier, economy-mode, security-guidance, ruflo-* — текущая 6+ компонентная архитектура) | +| `chain_divergence` | Роутер пошёл не по канонической связке, хотя совпадение триггеров было | +| `skill_invoked` | Инвокирован skill — записать `skill_id` + `reason` | +| `error` | Возникла ошибка — записать `class` (например `quirk:72`) + `recovery_action` | +| `confusion_marker` | Заказчик/Claude пометил место как «запутано» (вручную через TODO-метку в промпте) | +| `time_burn` | Большой блок времени потрачен на одну операцию (порог: >5 минут на single tool-call) | + +### 5.3. Опциональные MD-заметки + +**Путь**: `docs/observer/notes/YYYY-MM-DD-.md`. Создаются **только если у сессии есть качественная история, которая не помещается в JSONL**: длинный narrative разбора, скриншот ошибки, цепочка из 5+ узлов с границами и т.д. + +Никакого автогенерата — заметка создаётся вручную (Claude или заказчиком) по итогам сессии, если она того стоит. Большинство сессий — только JSONL, без MD. + +### 5.4. ПДн-фильтр + +**Обязательный pre-write через gitleaks** (или его аналог — простая regex-фильтрация телефонов/email/токенов перед записью в JSONL). + +| Pattern | Replacement | +|---|---| +| `\+7\d{10}` | `+7XXXXXXXXXX` | +| `[\w.-]+@[\w.-]+` | `***@***` | +| API-токены (gitleaks ruleset) | `[REDACTED:]` | + +Реализация — встроена в Stop-hook script (одна regex-passes pass перед write). + +### 5.5. `/brain-retro` скил + +**Периодичность**: раз в спринт (вручную, по команде заказчика «брейн-ретро» или эквивалент). + +**Action**: + +1. Читает все `episodes-YYYY-MM.jsonl` за последний период (с момента предыдущего ретро). +2. Агрегирует: + - Распределение `path_type` (% regulated / improvised / alternative / mixed). + - Топ-узлы (использованные ≥ N раз). + - Топ-связки L1–L12 (использованы) + новые связки (path_type=improvised, повторившиеся ≥2 раз). + - Top `error` classes + recovery-патерны. + - `chain_divergence` cases — где роутер ушёл с канонической связки. +3. Возвращает **кандидатов на корректировку нормативки**: + - Новая связка L13+ (если improvised повторился ≥2 раз с success). + - Граница X ↔ Y нуждается в ADR-уточнении (если chain_divergence повторился). + - Новый ADR (если confusion_marker повторился). +4. **Заказчик решает вручную** — никаких автоматических правок Tooling/Pravila/PSR_v1. + +**Граница**: `/brain-retro` — **читатель** observer-логов. Не пишет в логи. Не правит нормативку. Только агрегирует и предлагает. + +## 6. 4 контролёра первой волны + +Все 4 — **механические**, без LLM-вызовов в hot path. 0 расход $ per execution. 3 из 4 — lefthook pre-commit jobs (на коммите); 1 — self-pruning counter (на каждое чтение observer-файлов). + +### 6.1. C1 — L1-watcher (детектор неформализованных плагинов) + +**Что закрывает**: трижды повторившийся L1-паттерн — UPM/21st 10.05 + Sentry/Redis 13.05 + Anthropic dev-tooling 18.05. «Плагин включён в settings.json user-level или project-level без формализации в Tooling Прил. Н». + +**Реализация**: + +- **Lefthook job** `l1-watcher-on-settings-change` — триггер: правка `~/.claude/settings.json` или `.claude/settings.json` (детект — diff содержит изменения в `enabledPlugins[]`). +- **Action**: diff'нуть `enabledPlugins` ↔ список имён в Tooling Прил. Н §4.X (regex `^#\d+\s+([\w-]+)` + список плагинов в `.mcp.json` `mcpServers` keys). Если плагин в settings.json есть, но в Tooling нет — **fail commit** с сообщением «Plugin `` enabled in settings.json but not formalized in Tooling Прил. Н. Run `/claude-md-management:claude-md-improver` to formalize.». +- **Weekly cron** (если у заказчика нет частых правок settings.json): GitHub Actions schedule `0 9 * * 1` (понедельник 9:00 МСК) — тот же diff в read-only режиме, отчёт в `docs/observer/notes/YYYY-MM-DD-l1-watcher-weekly.md`. + +**0 LLM-вызовов**, 0 расход $. Regex + diff. + +### 6.2. C2 — Cross-ref consistency (детектор version drift) + +**Что закрывает**: version drift между 8 нормативными файлами (Tooling v2.11 collision 17.05). Когда CLAUDE.md `§0 cross-refs row` пишет «Pravila v1.29», а фактическая шапка Pravila — v1.30, или Tooling v2.15 vs фактическая v2.16, или PSR_v1 v3.14 vs v3.15. + +**Реализация**: + +- **Lefthook job** `cross-ref-consistency` — триггер: любая правка одного из 8 нормативных файлов (Pravila / CLAUDE.md / Tooling / PSR_v1 / MEMORY.md / Открытые_вопросы / docs/adr/* / db/schema.sql). +- **Action**: regex-extract версий из шапок каждого файла; regex-extract упоминаний версий в `§0 cross-refs` других файлов. Сравнить попарно. Если расхождение — **fail commit** с сообщением `Version drift detected: §0 references v, but header is v. Update §0 cross-refs.`. +- **Стиль реализации**: `adr-judge`-like — pure regex, 0 LLM-вызовов. Возможна реализация на bash + grep + sed; либо короткий node-скрипт. + +**0 LLM-вызовов**, 0 расход $. Detects ровно тот класс инцидентов, который уже произошёл и заказчик не хочет повторять. + +### 6.3. C3 — Observer-of-observer (счётчик чтений + 54-недельный self-prune) + +**Что закрывает**: риск, что observer-инфраструктура (Stop-hook + JSONL + MD notes) сама уйдёт в no-op, если никто никогда не читает evidence. Если 54 недели подряд никто не открывал ни один `episodes-YYYY-MM.jsonl` и не вызывал `/brain-retro` — это сигнал, что observer стал ритуалом, а не инструментом. + +**Реализация**: + +- **Счётчик**: `docs/observer/.read-counter.json` — простой JSON `{"last_read_at": "ISO-8601", "read_count_last_period": N}`. +- **Hook на чтение**: lefthook job `observer-of-observer` слушает Read-tool calls на путях `docs/observer/episodes-*.jsonl` или `docs/observer/notes/*.md` — обновляет `last_read_at` на now. +- **Self-prune trigger**: lefthook pre-commit job проверяет: `now - last_read_at > 54 weeks` → **warn** (не fail) на коммите с сообщением «Observer infrastructure not read for >54 weeks. Consider self-pruning: archive `docs/observer/` to memory, remove Stop-hook, simplify governance.». + +**Почему 54 недели (≈1 год)**: + +- Заказчик 19.05.2026 явно поднял 4 недели → 54 недели. Аргумент: redco-данные observer-а должны иметь время накопить ценность для **редких** ретроспектив (раз в полгода-год — это нормальный ритм для меньших проектов). +- Уход в no-op за месяц тишины — нерелевантный сигнал (нормальный отпуск/спринт-без-ретро); за год тишины — это уже системный сигнал. + +**Самоочистка** означает: контролёр сам предлагает себя удалить, если evidence-loop не используется. Это **anti-зомби-инфраструктура** механизм. + +**0 LLM-вызовов**, 0 расход $. JSON read/write + date math. + +### 6.4. C4 — Сигнальный статус (`docs/observer/STATUS.md`) + +**Что закрывает**: отсутствие единого дашборда — сейчас сигнал размазан по lefthook-выходам, observer-логам, нормативке. Заказчик хочет приборную панель. + +**Реализация**: + +- **Файл**: `docs/observer/STATUS.md` — ежедневно (или per-commit) обновляемая markdown-табличка. +- **Содержание**: агрегирует сигнал из C1 + C2 + C3 + observer-логов. + +Пример структуры: + +```markdown +# Brain Status (auto-generated) + +Last updated: 2026-05-19T10:00:00+03:00 + +| Контролёр | Состояние | Детали | +|---|---|---| +| C1 L1-watcher | ✅ | settings.json ↔ Tooling: 0 drift. Last weekly cron: 2026-05-18 (PASS) | +| C2 Cross-ref consistency | ✅ | 8 normative files: 0 version drift | +| C3 Observer-of-observer | ⚠️ | Last read: 2026-05-19 (today). Counter: 1 read this week. Self-prune: 53w remaining | +| C4 Сигнальный статус | ✅ | This file (self-reference) | +| Observer evidence | ✅ | 47 episodes this month, 0 PII matches, 0 write failures | + +## Метрики (информационные, не алерты) + +- Узлы, использованные за последние 30 дней: 18 / 60 (30%) +- Узлы, ни разу не использованные на реальной задаче: 32 / 60 — **это не проблема** (capability-readiness, см. [feedback](../../memory/feedback_brain_unused_tools_not_problem.md)) +- Канонические связки L1–L12 за месяц: L3 — 12 раз, L7 — 8 раз, L1 — 5 раз, ... +- Improvised chains за месяц: 3 (кандидаты для `/brain-retro`) + +## Алерт-индикаторы + +✅ — норма +⚠️ — внимание (не блокирует) +🔴 — действие требуется +``` + +**Критически**: метрика «N раз использован» — **информационная**, не алерт. Никаких ✅/⚠️/🔴 на основе usage-count (per `feedback_brain_unused_tools_not_problem.md` §3 «как применять»). + +**Генерация**: lefthook post-commit hook или daily cron — собирает из C1+C2+C3+observer-логов, пишет STATUS.md. Pure shell/regex/jq. + +**0 LLM-вызовов**, 0 расход $. + +## 7. Поведенческое правило: «не использован ≠ проблема» + +**Уже зафиксировано** в `memory/feedback_brain_unused_tools_not_problem.md`. В этом spec — встраивание в дизайн: + +1. **Реестр узлов (§4.1)** — не содержит `last-used-on-real-task` атрибута. +2. **Сигнальный статус (§6.4)** — N-раз-использован показывается как информация, не алерт. +3. **`/brain-retro` (§5.5)** — не выдаёт «кандидатов на удаление по причине неиспользования». +4. **ADR-011** — будет содержать явный bullet «Capability-readiness is intentional; unused ≠ candidate for removal». + +**Исключения** (явно прописаны в feedback-памяти): + +- **deprecated upstream-пакеты или физически сломанные инструменты** — это «не работает», не «не использован»; флажить можно и нужно (отдельная категория, lefthook-job `npm audit` + `composer outdated` уже это делают). +- **Правило относится к узлам мозга** (плагины Claude Code, скилы, MCP-серверы, контролёры). Для **продуктового кода Лидерры** dead Vue-компонент / неиспользуемый Laravel-сервис / dead route — там dead code = долг (knip + Larastan + lefthook уже это ловят). + +## 8. Граничные случаи и интеграционные риски + +### 8.1. HK1 pre-check (Pravila ADR-010) + +Дизайн **вводит новый Stop-hook** для observer-а (§5.2). **Обязателен HK1 pre-check** перед его регистрацией: + +- Прочитать `~/.claude/settings.json` `hooks.Stop[]` (если уже есть). +- Проверить коллизию с 6-компонентной economy/skill-discipline хук-архитектурой (skill-marker / skill-check / state-guard / postcompact / verifier / economy-mode). +- Если Stop-event уже занят — реализовать как **append-only chain**, не overwrite. Реализация — либо одной точкой входа, которая внутренне зовёт все Stop-handlers (skill-marker hook уже это делает), либо отдельный slot с явным `name` (Claude Code 2.x поддерживает массив hooks per event). + +Это **обязательное условие** успешной реализации; нарушение → blocks Pravila ADR-010 hard-rule. + +### 8.2. Pravila §15.2 pre-flight sync + +Большинство правок этого дизайна затронут **8 нормативных файлов**: + +- `docs/Tooling_v8_3.md` (Прил. Н §4.X — добавление 9 атрибутов на 60+ строк, новая запись router-procedure) +- `docs/Pravila_raboty_Claude_v1_1.md` (§13.X или §16 — добавление параграфа про observer и контролёры) +- `docs/Plugin_stack_rules_v1.md` (R15 или новый R16 — обновление routing apparatus) +- `CLAUDE.md` (§3.6 или §3.7 — cross-ref на новый router-procedure.md) +- `docs/adr/ADR-011-brain-governance.md` (новый) +- Возможно `docs/Открытые_вопросы_v8_3.md` (если возникнут открытые вопросы по реализации) +- `MEMORY.md` (project-memory указатели обновятся автоматически) +- `db/schema.sql` — **не затронут** (это не БД-задача). + +**Каждая правка обязана начинаться с `git fetch origin && git log HEAD..origin/main --oneline` per §15.2.** + +### 8.3. Worktree-constraint для CLAUDE.md + +Если реализация в изолированном worktree (рекомендуется для атомарности) — **CLAUDE.md правится прямым Edit** (worktree-эксцепшн §5 п.10; `claude-md-management` плагин не наводится на worktree-копию CLAUDE.md; прецеденты: A11/C10/discovery v2.10–v2.13). + +### 8.4. ruflo dormant — взаимодействие с дизайном + +Дизайн **полностью совместим** с ruflo-dormant статусом (§14.9 Pravila). Router-only архитектура не зависит от ruflo daemon; observer Stop-hook независим от ruflo PreToolUse-хуков. ruflo может быть реактивирован позже без правки этого дизайна — он встанет одним из узлов реестра §4.1 с `dormant=true → false`. + +### 8.5. Параллельные сессии (Pravila §15) + +Контролёр C2 (cross-ref consistency) **closes** второй класс инцидентов параллельных сессий — version drift. Первый класс (субагент-угон-ветки) уже закрыт `tools/subagent-prompt-prefix.mjs` + git-safety-checklist в `subagent-driven-development` wrapper. **Этот дизайн дополняет**, не подменяет §15. + +### 8.6. Размер observer-логов + +**Риск**: `episodes-YYYY-MM.jsonl` растёт без bound. **Митигатор**: помесячное rotation именования (новый файл каждый месяц); один файл ≈ 30–100 сессий ≈ 50–200KB JSON; за год ≈ 12 файлов ≈ <3MB. **Архив**: после 12 месяцев — `docs/observer/archive/episodes-YYYY.tar.gz`; ручная задача. + +### 8.7. ПДн в observer-логах + +**Митигатор**: gitleaks-like pre-write filter (§5.4). **Дополнительная защита**: каталог `docs/observer/` под git с `lefthook pre-push` job — gitleaks full-history scan (уже в pre-push для всего репо). + +### 8.8. Что если контролёр сам сломается + +- **C1** failure → lefthook fails commit (видимый сигнал; не молчит). +- **C2** failure → same. +- **C3** failure → STATUS.md показывает 🔴; lefthook warn (не блокирует). +- **C4** failure → STATUS.md устаревает; видно через C3 (если STATUS.md не обновлялся — это «evidence not consumed», self-prune watchdog поймает через 54 недели). + +«Кто наблюдает за наблюдателями» закрыт C3. + +## 9. План имплементации (high-level — для следующей фазы writing-plans) + +**Этот spec НЕ имплементационный план.** Writing-plans skill после approval создаст детальный план. High-level ожидаемая раскладка: + +| Этап | Артефакты | Размер | +|---|---|---| +| 1. ADR-011 + router-procedure.md | 2 новых документа | ~300 строк | +| 2. Tooling Прил. Н — 9 атрибутов на 60 строк | Большая правка | ~600 строк изменений | +| 3. Pravila §16 (или §15.4 sub-section) | Параграф об observer + контролёрах | ~150 строк | +| 4. PSR_v1 R16 (или R15 extension) | Routing apparatus update | ~100 строк | +| 5. `docs/observer/` инфраструктура | README + .read-counter.json seed + STATUS.md template + Stop-hook script + ПДн-filter | ~5 файлов, ~400 строк | +| 6. 4 lefthook-jobs | YAML + 4 shell/node scripts | ~150 строк | +| 7. `/brain-retro` skill | `.claude/skills/brain-retro/SKILL.md` + reader script | ~200 строк | +| 8. HK1 pre-check pass | Manual + dry-run hook collision check | — | +| 9. Smoke test + verification | Запустить sample task, проверить write в JSONL, проверить C1–C4 trigger | — | +| 10. CLAUDE.md sync + 8-file pre-flight sync | Через `/claude-md-management:claude-md-improver` (или прямой Edit в worktree) | — | + +**Все правки** обязаны проходить через Pravila §15.2 pre-flight sync. + +## 10. Verification критерии (для verification-before-completion skill) + +После имплементации, перед claim «brain governance done»: + +1. ✅ `docs/router-procedure.md` v1.0 существует и описывает процедуру §4.2 буквально. +2. ✅ Tooling Прил. Н §4.X — каждая строка #1–#60+ содержит 9 атрибутов §4.1 (sample-check: 5 случайных строк). +3. ✅ `docs/observer/` существует; Stop-hook зарегистрирован; smoke test — фейк-сессия завершается записью в `episodes-YYYY-MM.jsonl`; запись содержит 4 обязательных поля; ПДн-фильтр срабатывает на тестовой строке `+79991234567`. +4. ✅ C1 — lefthook fail на тест-коммите, где settings.json содержит несуществующий в Tooling плагин; pass на чистом коммите. +5. ✅ C2 — lefthook fail на тест-коммите с deliberate version drift; pass на чистом. +6. ✅ C3 — `.read-counter.json` существует; обновляется на Read-tool call; lefthook warn срабатывает если timestamp подделан на «56 недель назад». +7. ✅ C4 — `docs/observer/STATUS.md` существует, обновляется на post-commit, содержит все 4 контролёра + информационные метрики. +8. ✅ `/brain-retro` skill инвокируется (минимум `Skill` tool принимает имя); smoke — на пустом `episodes-*.jsonl` возвращает «no data yet, expected after first sessions». +9. ✅ ADR-011 written, status `Accepted`. +10. ✅ 8-file pre-flight sync прошёл перед каждой правкой нормативки (verified в git log). +11. ✅ HK1 pre-check выполнен; Stop-hook не overwrites 6-компонентную архитектуру. +12. ✅ Поведенческое правило `feedback_brain_unused_tools_not_problem.md` упомянуто в ADR-011, STATUS.md, `/brain-retro` (для самих будущих сессий). +13. ✅ Regression: Pest, Vitest, Larastan, lefthook full-stage — 0 регрессий относительно baseline на ветке начала работ. + +## 11. Открытые вопросы (для уточнения в writing-plans / реализации) + +| # | Вопрос | Default / предположение | +|---|---|---| +| O1 | Stop-hook реализуется как python-script или node-script? | Node (consistency с другими hooks в `tools/`) | +| O2 | ПДн-фильтр — встроить gitleaks-call или regex inline? | Regex inline (быстрее, gitleaks остаётся для git-history) | +| O3 | `/brain-retro` инвокируется заказчиком вручную или есть auto-trigger «N сессий накопилось»? | Вручную (явный контроль заказчика) | +| O4 | C1 watcher cron — GitHub Actions или local Windows Task Scheduler? | GitHub Actions (отчёт виден всем, не зависит от состояния Windows-машины) | +| O5 | STATUS.md обновляется per-commit или daily cron? | Per-commit (свежее данные, lefthook post-commit hook) | +| O6 | Где жить router-procedure.md — в `docs/` корне или в `docs/governance/`? | `docs/router-procedure.md` (плоско, в корне — как routing-off-phase.md) | +| O7 | ADR-011 или ADR-012? | Следующий свободный (на 2026-05-19 — ADR-011, проверить ls docs/adr/) | + +## 12. Cross-refs + +- `docs/discovery/2026-05-18-system-audit-brain.md` — origin trigger (SYSTEM-аудит). +- `memory/project_brain_governance_design.md` — короткая memory-сводка дизайна. +- `memory/feedback_brain_unused_tools_not_problem.md` — поведенческое правило (встроено). +- `docs/Pravila_raboty_Claude_v1_1.md` §12 / §14 / §15 — hard-floor для роутера §4.2 шаг 1. +- `docs/Plugin_stack_rules_v1.md` R15 — off-phase routing, extends not replaces. +- `docs/Tooling_v8_3.md` Прил. Н §0 + §4.X — реестр узлов SoT. +- `docs/routing-off-phase.md` v1.0+ — routing-таблица off-phase + L1–L12 связки. +- `docs/adr/ADR-010-anthropic-dev-tooling.md` — HK1 hard-rule pre-check. +- `docs/superpowers/specs/2026-05-18-parallel-sessions-coordination-design.md` — §15 hard-rule context. + +--- + +**Status after this spec**: awaiting written-spec user review (brainstorming flow step 8). После approval → transition to `superpowers:writing-plans` (terminal skill brainstorming-а). Никакая имплементация **не начнётся** до approval и не до плана.