From 10eed4e7e484d964f8b826df77579726d4e1e213 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, 25 May 2026 03:27:02 +0300 Subject: [PATCH] docs(brain): spec v2.0 LLM-first router overhaul MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Brainstorming сессия 2026-05-24..25: - LLM-first классификатор (Sonnet 4.6) заменяет regex Layer 1. - §17 «universal skill-coverage» заменяет §12 (default-deny кроме conversation/micro/manual_override/escape-hatch). - Opus 4.7 ревьюер в /brain-retro заполняет review.* (auto, не пользователь). - Self-retrospect skill (opt-in) для самоанализа агента. - 7 гранулярных flag-переключателей + dry-run rollback. - 3 implementation фазы (~3.5-4.5 недели) + 5-6 месяцев passive evidence collection + фаза 4 distillation regex из эмпирики. v1.0 содержал 8 фактических ошибок (несуществующие skill-discipline файлы, отсутствующие nodes.yaml поля, L1-L16 в неверных файлах) + 11 пропусков охвата + 10 underspecified + 6 противоречий. v2.0 — полная перезапись с реальным state inventory (§18) и explicit accepted trade-offs (§19). Реализация — после закрытия Биллинга v2 Спек C (per user decision). Co-Authored-By: Claude Opus 4.7 (1M context) --- cspell-words.txt | 1 + docs/observer/STATUS.md | 28 +- ...-05-24-llm-first-router-overhaul-design.md | 1438 +++++++++++++++++ 3 files changed, 1453 insertions(+), 14 deletions(-) create mode 100644 docs/superpowers/specs/2026-05-24-llm-first-router-overhaul-design.md diff --git a/cspell-words.txt b/cspell-words.txt index e29e15c3..80b939dc 100644 --- a/cspell-words.txt +++ b/cspell-words.txt @@ -1744,3 +1744,4 @@ uniqid брейнсторме префлайт Префлайт +скоупа diff --git a/docs/observer/STATUS.md b/docs/observer/STATUS.md index 3b750ab5..db604e08 100644 --- a/docs/observer/STATUS.md +++ b/docs/observer/STATUS.md @@ -1,22 +1,22 @@ # Brain Status (auto-generated) -Last updated: 2026-05-24T13:01:24.122Z +Last updated: 2026-05-25T00:09:15.184Z | Контролёр | Состояние | Детали | |---|---|---| | C1 L1-watcher | ✅ | [l1-watcher] OK — 0 drift | -| C2 Cross-ref consistency | ✅ | [cross-ref-checker] OK — 0 drift in 4 files | +| C2 Cross-ref consistency | 🔴 | Update cross-refs in offending files. | | C3 Observer-of-observer | ✅ | [observer-of-observer] OK — last read 0 week(s) ago | | C4 Сигнальный статус | ✅ | This file (self-reference) | -| C5 Observer-coverage | ⚠️ | 135 episode(s) this month · .git/hooks/post-commit not installed (run: npx lefthook install --force) · 17 missed activation(s) — see /brain-retro | +| C5 Observer-coverage | ⚠️ | 290 episode(s) this month · Stop-hook + post-commit OK · 21 missed activation(s) — see /brain-retro | | C6 Chain map sync | ✅ | [chain-map-checker] OK — 16 chains in sync | ## Метрики (информационные, не алерты) -- Observer evidence: 135 episodes this month, 0 observer_error markers, 6 PII matches before filter -- Legacy v1 episodes (not in factor analysis): 11 -- Last /brain-retro: 1 day(s) ago -- Использование узлов: см. `/brain-retro` (раз в спринт). missed_activations: 17. **Неиспользованные узлы — не алерт, если профильной задачи не было** (Pravila §16.4 v1.36; capability-readiness; см. memory `feedback_brain_unused_tools_not_problem` — outside-repo memory store). +- Observer evidence: 290 episodes this month, 0 observer_error markers, 21 PII matches before filter +- Legacy v1 episodes (not in factor analysis): 151 +- Last /brain-retro: 0 day(s) ago +- Использование узлов: см. `/brain-retro` (раз в спринт). missed_activations: 21. **Неиспользованные узлы — не алерт, если профильной задачи не было** (Pravila §16.4 v1.36; capability-readiness; см. memory `feedback_brain_unused_tools_not_problem` — outside-repo memory store). ## Метрики дисциплины @@ -24,17 +24,17 @@ Baseline дисциплины роутера (этап 2 router discipline overh | Тип задачи | Эпизодов | % с триггер-матчем | % через скил | |---|---|---|---| -| bugfix | 7 | 28.6% | 42.9% | -| feature | 5 | 0.0% | 0.0% | -| analysis | 4 | 0.0% | 25.0% | -| planning | 2 | 0.0% | 0.0% | +| analysis | 14 | 50.0% | 28.6% | +| bugfix | 9 | 44.4% | 44.4% | +| feature | 9 | 22.2% | 0.0% | +| planning | 6 | 0.0% | 0.0% | +| monitoring | 4 | 0.0% | 0.0% | | refactor | 1 | 0.0% | 0.0% | | cleanup | 1 | 0.0% | 0.0% | -| monitoring | 1 | 0.0% | 0.0% | -Router step distribution: 1: 55, 2: 45, 3: 12, 5: 18 +Router step distribution: 1: 117, 2: 94, 3: 36, 5: 38 -Boundaries applied (ADR / границы): 13 of 130 эпизодов (10.0%). +Boundaries applied (ADR / границы): 45 of 285 эпизодов (15.8%). ## Активные многоэтапные проекты diff --git a/docs/superpowers/specs/2026-05-24-llm-first-router-overhaul-design.md b/docs/superpowers/specs/2026-05-24-llm-first-router-overhaul-design.md new file mode 100644 index 00000000..7a6e262c --- /dev/null +++ b/docs/superpowers/specs/2026-05-24-llm-first-router-overhaul-design.md @@ -0,0 +1,1438 @@ +# LLM-first router overhaul — spec v2.0 + +**Дата:** 2026-05-24 (v1.0) / 2026-05-25 (v2.0 — переписана целиком после критического анализа v1.0). +**Эпик:** пересборка маршрутизации мозга — переход с regex-первичного классификатора + §12 hard-rule (whitelist 14 типов) на LLM-first классификатор Sonnet 4.6 + §17 universal skill-coverage rule (default-deny кроме conversation/micro/manual_override) + автоматический evidence loop с Opus 4.7 ревьюером для последующей дистилляции эмпирических regex-правил. +**История версий:** v1.0 → v2.0. v1.0 содержал 8 фактических ошибок (несуществующие файлы skill-discipline, отсутствующие поля nodes.yaml, неверные пути L1-L16), 11 пропусков скоупа, 10 underspecified механизмов, 6 логических противоречий. v2.0 переписана с реальным state inventory (§18) и явными accepted trade-offs (§19). +**Реализация:** 3 implementation-фазы за один эпик (~3.5-4.5 недели), затем ~5-6 месяцев passive evidence collection, затем 4-я фаза distillation (~2-3 недели) через ~6 месяцев. + +--- + +## 0. Карта документа + +| § | Тема | +|---|---| +| 1 | Назначение и контекст | +| 2 | Принципы (с явными accepted trade-offs) | +| 3 | Архитектура — общая картина (8 слоёв) | +| 4 | Компоненты по слоям (детально) | +| 5 | Schema эпизода v4.* (поэтапные bumps) | +| 6 | §17 — формальное определение | +| 7 | Что меняется в нормативке (с реальными путями файлов) | +| 8 | Что остаётся нетронутым | +| 9 | Адаптация контролёров C1-C6 | +| 10 | Гранулярные flag-переключатели + rollback (с dry-run автоматизацией) | +| 11 | Фазы реализации (с явным разделением implementation vs passive) | +| 12 | Cost monitoring (без cap, но с daily dashboard) | +| 13 | Связанные изменения в нормативке (карта правок) | +| 14 | Risk register (расширен) | +| 15 | Открытые вопросы implementation-уровня | +| 16 | Definition of Done | +| 17 | Связь с другими эпиками (no dependencies) | +| 18 | **Pre-implementation state inventory** (новое — реальное состояние) | +| 19 | **Accepted trade-offs** (новое — явные компромиссы) | +| 20 | **Что НЕ делается этим эпиком** (явный non-goals) | + +--- + +## 1. Назначение и контекст + +### 1.1. Что не так с текущим состоянием + +- **Routing-словари вручную поддерживаются в 5 документах.** Tooling §3.3 / CLAUDE.md §3.3 / `docs/routing-off-phase.md` / `docs/router-procedure.md` / PSR_v1 R15 — пересекающееся знание «задача → узел». Каждый новый узел требует ручной правки в нескольких местах. По мере роста мозга (сейчас 84 узла) дрейф ускоряется. Реестр в `docs/registry/nodes.yaml` был введён как single source, но текстовые шпаргалки остались параллельно. +- **Regex-классификатор `tools/router-classifier.mjs` — ручной word-list (~60 ключевиков на 11 категорий)** (router-classifier.mjs:17-32) не покрывает новые домены (marketing #74-83, infosec #68-73, finance #61-63 — для них есть только узкие keyword-триггеры в nodes.yaml без category-уровня в classifier'е). +- **§12 hard-rule** (Pravila §12) принуждает Superpowers skill для 14 типов задач. Это a-priori правило (Pravila v1.4, 09.05.2026), не выведенное из эмпирики. Принуждение skill'а смещает evidence — agent выбирает skill потому что должен, не потому что лучше. +- **Brain-governance evidence — собирается, но почти не оценивается.** Episode `outcome` = `unknown` при записи, brain-retro угадывает по тону следующего prompt'а. Нет per-episode оценки качества выбора узла → дистилляция regex невозможна без human-labeled выборки. Ручной labeling 20 эпизодов раз в 2-3 недели даёт 1.3% покрытия выборки за 6 месяцев — статистически недостаточно. + +### 1.2. Что хочется получить через ~6 месяцев + +- **Эмпирическая база ~1500 эпизодов**, из которых ~70-80% (≈1000-1200) имеют заполненный `review.*` от Opus 4.7 ревьюера → пригодна для дистилляции regex. +- **Regex-правила выведены из факта**, не из угадывания. +- **§17 либо подтверждена эмпирикой и ужесточена, либо ослаблена до hybrid, либо снята** — решение по результатам distillation phase. +- **LLM-classifier остаётся как fallback** для пограничных случаев; distilled regex покрывает топ-20 паттернов нагрузки. +- **Мозг сжат** на ~30-50% за счёт удаления routing-дублей; nodes.yaml — единственный источник истины routing. + +### 1.3. Что НЕ делается этим эпиком (non-goals) + +См. §20 расширенно. + +--- + +## 2. Принципы (с явными accepted trade-offs) + +1. **Эмпирика бьёт теорию — но не в принципе skill-coverage.** Routing-правила «какой узел выбрать» дистиллируются из эмпирики, **но сам принцип «использовать skill, не direct» (§17) остаётся a-priori safety-rail** на время эксперимента. Trade-off обсуждён в §19.A. +2. **Один touchpoint для владельца.** Единственное действие, требуемое от Дмитрия — вызов `/brain-retro`. Внутри него ему задаются 3-4 простых вопроса. Sanity-check **обязательный** (без ответов /brain-retro не завершается), формат настолько простой что занимает 2-5 минут. +3. **Чистота данных vs скорость работы.** Где конфликтуют — выбираем чистоту: routing-docs архивируются одним движением, не постепенно. +4. **Гранулярный rollback.** 7 независимых flag-переключателей. Каждый можно flip независимо. +5. **Реестр узлов — единый источник routing.** Все routing-решения исходят из `docs/registry/nodes.yaml`. +6. **Universal coverage — §17.** Все задачи кроме явных conversation/micro/manual_override/escape-hatch покрыты skill или цепочкой. +7. **Backwards compatibility forward-only.** Schema эпизода bumps делаются поэтапно (v4.0 → v4.1 → v4.2 → v4.3), парсер всегда поддерживает все версии для read. +8. **Cost transparency без cap.** Жёсткого лимита нет (per user decision), но daily cost dashboard обновляется каждым Stop-hook'ом — runaway виден в течение часа, не недели. + +--- + +## 3. Архитектура — общая картина (8 слоёв) + +``` +┌──────────────────────────────────────────────────────────────────┐ +│ ТВОЙ PROMPT │ +└──────────────────────────────────────────────────────────────────┘ + ↓ +┌──────────────────────────────────────────────────────────────────┐ +│ СЛОЙ 1 — Conversation/micro/manual_override/anchor prefilter │ +│ regex, $0, ~1мс │ +│ - manual override («делай через X») → md_override, direct │ +│ - длина <15 И не содержит anchor → conv, direct │ +│ - в CONVERSATION_PATTERNS И не содержит anchor → conv, direct │ +│ - в MICRO_KEYWORDS → micro, direct │ +│ - иначе → передаётся в LLM-classifier │ +└────────────────────┬─────────────────────────────────────────────┘ + ↓ (не-conversation/не-micro/не-md_override) +┌──────────────────────────────────────────────────────────────────┐ +│ СЛОЙ 2 — LLM-classifier (Sonnet 4.6, ~$0.02/prompt, ~500-1500мс) │ +│ Вход: prompt + nodes.yaml capabilities (без полей-подсказок) │ +│ Выход (JSON): │ +│ - task_type, recommended_node, recommended_chain (array) │ +│ - alternatives_considered (топ-3 со scores + rejected_because) │ +│ - reason_for_choice │ +│ - no_skill_found (если ни один узел не подходит) │ +│ - usage (для cost tracking) │ +│ Защита от direct: prompt классификатора жёстко требует skill │ +└────────────────────┬─────────────────────────────────────────────┘ + ↓ +┌──────────────────────────────────────────────────────────────────┐ +│ СЛОЙ 3 — Embedding (local @xenova/transformers, $0, ~50мс) │ +│ prompt → 384-dim float32 vector │ +│ Pre-warm на SessionStart hook (избегает cold-start latency) │ +│ Хранится в episode как Base64 │ +└────────────────────┬─────────────────────────────────────────────┘ + ↓ +┌──────────────────────────────────────────────────────────────────┐ +│ СЛОЙ 4 — §17 enforcement (router-tool-gate.mjs расширен) │ +│ Блокирует ТОЛЬКО при mode='enforce': │ +│ - actual_node='direct' для task_type ∉ {conv,micro,override} │ +│ - no_skill_found → блок + сигнал «расширить nodes.yaml» │ +│ Mode переключатель: ~/.claude/runtime/router-gate-mode.json │ +└────────────────────┬─────────────────────────────────────────────┘ + ↓ + [ Claude исполняет skill/chain ] + execution_trace + chain_gaps пишутся Stop-hook'ом + events.error/interrupt/retry — как сейчас + ↓ +┌──────────────────────────────────────────────────────────────────┐ +│ СЛОЙ 5 — Self_assessment (Stop-hook, Opus 4.7, ~$0.03/task) │ +│ Я в конце task пишу 3 поля: │ +│ - summary, confidence_in_choice, what_could_be_better │ +│ Timeout 15сек, fallback на retroactive fill в /brain-retro │ +└────────────────────┬─────────────────────────────────────────────┘ + ↓ + [ Episode v4.3 готов, JSONL append ] + ↓ + ↓ (асинхронно, в /brain-retro) +┌──────────────────────────────────────────────────────────────────┐ +│ СЛОЙ 6 — Opus 4.7 reviewer (внутри /brain-retro, ~$10/run) │ +│ Для каждого unreviewed episode периода: │ +│ - Читает episode + outcome_inferred + alternatives │ +│ + self_assessment + period sanity-check answers │ +│ - Заполняет review.* (включая error_root_cause) │ +│ - Заполняет outcome_reviewed (proxy: outcome_inferred │ +│ + sanity-context + self_assessment.confidence) │ +│ Adaptive prompt template — handles v2/v3/v4 episodes │ +└────────────────────┬─────────────────────────────────────────────┘ + ↓ + ┌────────────────────────────────────────┐ + ↓ ↓ +┌──────────────────────────┐ ┌────────────────────────────────────┐ +│ СЛОЙ 7 — /brain-retro │ │ СЛОЙ 8 — /self-retrospect (opt-in)│ +│ (мой ход) │ │ Запускается отдельной командой │ +│ - sanity-check (3-4 ?) │ │ ИЛИ опциональным prompt'ом из │ +│ - Opus reviewer pickup │ │ /brain-retro. НЕ auto. │ +│ - factor matrix │ │ Cost ~$2-5 за запуск. │ +│ - candidates for owner │ │ Читает 150+ episodes с review.* │ +│ │ │ Lesson_learned → memory feedback. │ +└──────────────────────────┘ └────────────────────────────────────┘ + ↓ + Через ~6 месяцев → ФАЗА 4 DISTILLATION: + золотая выборка → кластеризация по embedding → regex v2.0 +``` + +--- + +## 4. Компоненты по слоям + +### 4.1. Слой 1 — Conversation/micro/manual_override/anchor prefilter + +**Файл:** `tools/router-classifier.mjs` (существующий, расширяется). + +**Зоны определения** (порядок проверки сверху вниз): + +#### Manual override detection (новое) + +Pattern: prompt начинается с глагола команды + явная ссылка на skill/node. + +Regex (примерно): `^(делай|сделай|используй|применя[йи]|запусти|вызови)\s+(через|с помощью|skill|skill[оа]м)\s+([\w\-:]+)` + +Примеры match: + +- «делай через TDD» +- «используй superpowers:brainstorming» +- «вызови billing-audit» + +→ `{ task_type: 'manual_override', node: 'direct', source: 'prefilter', requested_node: '' }` + +#### Conversation detection + +Триггер: `длина < 15 символов` ИЛИ `prompt в CONVERSATION_PATTERNS` И **не содержит anchor**. + +`CONVERSATION_PATTERNS`: + +```text +['а', 'б', 'с', 'делай', 'спасибо', 'обожди', 'дальше', 'продолжай', + 'отбой', 'да', 'нет', 'ок', 'понял', 'хорошо', 'верно', 'отлично', + 'привет', 'пока', 'пропусти', 'согласен'] +``` + +#### Anchor detection (защита от false-positives conversation) + +`Anchor` — наличие в prompt'е существительного/глагола из проектного словаря: + +- Существительные: `аудит`, `баг`, `план`, `спека`, `фича`, `тест`, `миграция`, `endpoint`, `файл`, `функция`, `класс`, `компонент`, `view`, `модель`, `биллинг`, `маркетинг`, `безопасность`, `пдн`, `регион`, `портал`, `проект`, `сделка`, `лид`, `админка`, `база`, `схема`, `воронка`... +- Императивы (если длина > 30 символов): `проанализируй`, `проверь`, `исправь`, `почини`, `создай`, `добавь`, `удали`, `переименуй`, `улучши`, `расширь`. + +Список расширяется по факту missed-conversation cases (через self-retrospect lessons). + +`Anchor` найден → fall through в LLM-classifier (несмотря на conversation-pattern). Это закрывает кейс «делай аудит» (matches conversation «делай», anchor «аудит» спасает). + +#### Micro detection + +`MICRO_KEYWORDS` (взято из router-classifier.mjs:34-42): + +```text +['опечатк', 'typo', 'переименуй', 'rename', 'удали мёртв', 'dead code', + 'формат', 'format', 'константу', 'one constant', 'увеличь', 'уменьши', + 'поменяй значени', 'измени константу', 'одну строку', 'bump'] +``` + +→ `{ task_type: 'micro', node: 'direct', source: 'prefilter' }` + +#### Иначе → передаётся в Слой 2 + +**Все 4 типа решений** (conversation/micro/manual_override/forward) пишутся в эпизод с `source: 'prefilter'` или `source: 'llm'`. + +### 4.2. Слой 2 — LLM-classifier (Sonnet 4.6) + +**Файл:** `tools/router-classifier.mjs` — функция `classify()` существующая на строке 231, переписывается. + +**Изменения vs текущее:** + +- Модель: `claude-haiku-4-5-20251001` → `claude-sonnet-4-6-` (точный ID **верифицируется на старте фазы 2** через `anthropic.models.list()` или из CLAUDE.md глобального instruction). +- `classifyByRegex` Layer 1 → **удаляется** как primary path. Logic переезжает в Layer 1 prefilter (conversation/micro/manual_override). `TASK_TYPE_KEYWORDS` (router-classifier.mjs:17-32) — частично архивируется (специфичные keyword'ы переезжают в nodes.yaml `triggers[]` если их там нет). +- `shouldEscalate` (router-classifier.mjs:195) — удаляется (всегда escalate). +- `HARD_KEYWORD_STEMS` (router-classifier.mjs:114-118) — удаляется (confidence считается LLM'ом). + +**Promпт классификатора:** + +```text + +Ты классификатор задач для CRM-проекта «Лидерра» (Laravel 13 + Vue 3 + Vuetify 3). + +ОБЯЗАТЕЛЬНЫЕ выходные правила: +1. Верни ровно один из: skill ИЛИ chain ИЛИ no_skill_found. +2. "direct" НЕ разрешён в этом классификаторе. Conversation/micro обрабатываются ДО тебя. +3. Верни топ-3 alternatives_considered со score (0-1) и причиной отклонения. +4. reason_for_choice — конкретно, со ссылкой на capability узла; не «общее». +5. recommended_chain — массив из 1-5 skill IDs в порядке исполнения. +6. Если ни один узел НЕ подходит — no_skill_found=true И no_skill_found_suggestion. + +Реестр доступных узлов (с capabilities): +{nodes_block} + +Реестр канонических цепочек (для справки, можешь предложить новую): +{chains_block} + +Output — ONLY JSON object, no prose, no code fences. + + + +Prompt: {user_prompt} + +``` + +**`nodes_block` структура** — генерится из nodes.yaml live: + +```yaml +- skill_id: superpowers:brainstorming + name: Brainstorming + capabilities: «creative work — exploring user intent, requirements, design before implementation» + triggers: [«brainstorm», «обсудим», «варианты»] +``` + +(без полей `когда выбирать` / `chain_membership` — они не передаются) + +**`chains_block`** — те 16 cепочек L1-L16 из nodes.yaml `chains:` блока, как **справка** не предписание. + +**Output (JSON):** + +```json +{ + "task_type": "feature", + "recommended_node": "superpowers:brainstorming", + "recommended_chain": [ + "superpowers:brainstorming", + "superpowers:writing-plans", + "superpowers:executing-plans" + ], + "recommended_chain_id": "L1", + "reason_for_choice": "архитектурное обсуждение перед изменением behavior; brainstorming раскрывает intent ДО plan", + "alternatives_considered": [ + { + "node": "superpowers:writing-plans", + "match_score": 0.6, + "rejected_because": "слишком ранняя стадия — требования ещё не зафиксированы" + }, + { + "node": "product-management:write-spec", + "match_score": 0.5, + "rejected_because": "product-management для PRD/roadmap, здесь архитектурная задача" + }, + { + "node": "ccpm", + "match_score": 0.3, + "rejected_because": "CCPM для PRD→issue лайфцикла, не для design-обсуждений" + } + ], + "no_skill_found": false, + "no_skill_found_suggestion": null +} +``` + +**Caching:** hash(prompt) → result. Hit-rate реалистично ~5-15%. + +**Fallback цепочка (если Sonnet недоступен):** + +1. Попробовать Haiku 4.5 как secondary classifier. +2. Если Haiku тоже down → regex Layer 1 (восстанавливается из архива в `tools/router-classifier-regex-fallback.mjs`). +3. Если и regex недоступен → `{ task_type: 'unknown', node: 'direct', source: 'fallback', degraded: true }`. В episode пишется `degraded_mode: true`. В чате я начинаю ответ с маркера `[router degraded: ]`. + +**Hot-reload classifier mode:** при каждом UserPromptSubmit hook читает `~/.claude/runtime/router-classifier-mode.json`. Перерасчёт сразу, без перезапуска сессии. Это **изменение от текущего поведения**. + +**Cost tracking writing:** classifier-call в router-prehook.mjs пишет `task_cost.classifier_input_tokens` + `classifier_output_tokens` напрямую в `~/.claude/runtime/router-state-.json`, оттуда подхватывается Stop-hook'ом. + +### 4.3. Слой 3 — Embedding layer + +**Файл:** `tools/router-embedding.mjs` (новый). + +**Модель:** `Xenova/all-MiniLM-L6-v2` — npm `@xenova/transformers`, локально, 384-dim float32, ~50мс после warmup. + +**Установка:** `npm i @xenova/transformers` (~150MB deps). Модель скачивается из HF ~80MB при первом вызове, кешируется в `~/.cache/huggingface/transformers/`. + +**Pre-warm на SessionStart** (закрывает C3 cold-start risk) — новый hook на `SessionStart` event: + +```javascript +// tools/router-embedding-warmup.mjs +import { pipeline } from '@xenova/transformers'; +async function warmup() { + const extractor = await pipeline('feature-extraction', 'Xenova/all-MiniLM-L6-v2'); + await extractor('warmup', { pooling: 'mean', normalize: true }); +} +warmup().catch(() => process.exit(0)); // fail silently +``` + +**Persistence решение в фазе 2:** keep model в long-running daemon (PM2 service) ИЛИ принять ~200мс cold-start на каждый hook-invocation. Решение по smoke-тесту latency. + +**Использование:** + +- Stop-hook вычисляет `prompt_embedding`. +- Self-retrospect использует cosine similarity. +- Brain-retro может кластеризовать в Phase 4. + +**Storage в episode:** Base64-encoded float32 array (1536 bytes raw → ~2050 chars base64). + +**Fallback:** `prompt_embedding: null` + `embedding_unavailable: true` в `environment`. Self-retrospect фоллбек на task_type-based clustering. + +### 4.4. Слой 4 — §17 enforcement + +**Файл:** `tools/router-tool-gate.mjs` (существующий, расширяется). + +**Существующая логика (line 39-53):** проверяет `state.enforcementRequired` (от router-prehook). После перехода на §17 — расширяется. + +**Триггер:** PreToolUse событие на `Edit`, `Write`, `MultiEdit`, `Bash` (не read-only). Read-only Bash list — router-tool-gate.mjs:20-25. + +**Логика §17 enforcement:** + +```javascript +const NON_BLOCKING_TASK_TYPES = ['conversation', 'micro', 'manual_override']; + +function shouldBlock(tool, state, responseText, options) { + const mode = options.mode; // 'warn-only' | 'enforce' | 'off' + if (mode === 'off') return false; + if (mode === 'warn-only') return false; // только stderr warning + + if (state.classification.no_skill_found === true) { + return { block: true, reason: 'no_skill_found_block' }; + } + + if (NON_BLOCKING_TASK_TYPES.includes(state.classification.task_type)) { + return false; + } + + if (state.skillInvokedThisTurn === true) return false; + + if (decodeRoutingTag(responseText)?.directJustified) return false; + + if (tool === 'Bash' && isReadOnlyBash(options.bashCommand)) return false; + + if (!['Edit', 'Write', 'MultiEdit', 'Bash'].includes(tool)) return false; + + return { block: true, reason: 'direct_in_non_conversation' }; +} +``` + +**Block message format:** + +```text +[§17 enforcement BLOCK] +Эта задача классифицирована как: {task_type} +Реестр рекомендует узел: {recommended_node} ({recommended_chain_summary}) +Reason: {classifier.reason_for_choice} + +Возможные действия: +1. Инвокируй skill: {recommended_node} +2. Используй escape-hatch: +3. Если узел не подходит — переклассифицируй prompt или расширь nodes.yaml. +``` + +**Manual override** — обрабатывается prefilter'ом (§4.1), gate просто пропускает (task_type='manual_override' в NON_BLOCKING). Episode помечается `decision_provenance.kind='user_directed_method'` + `requested_node` сохранён + classifier параллельно записывает свою рекомендацию в shadow-режиме. + +**Mode переключатель:** `~/.claude/runtime/router-gate-mode.json` → `{"mode": "off" | "warn-only" | "enforce"}`. По умолчанию `warn-only` ВСЁ ВРЕМЯ bootstrap-периода. Переключение в `enforce` — отдельное решение в фазе 4. + +**Permission interaction:** gate срабатывает **ДО** permission-проверки settings.json. Сознательно (gate = routing-discipline, permissions = safety; разные слои). + +### 4.5. Слой 5 — Self_assessment (Stop-hook) + +**Файл:** `tools/observer-stop-hook.mjs` (существующий, расширяется). + +**Изменения:** + +1. **Timeout** в settings.json для Stop-hook: 5s → **15s**. +2. **Опциональный self_assessment call** — если timeout позволяет. +3. **Retroactive fill** — если не успел в 15s, episode пишется без него с `self_assessment_pending: true`. /brain-retro Opus reviewer дозаполняет на reviewer-pass. + +**Action:** один API call к Claude (model = текущая сессия, обычно Opus 4.7): + +```text + +Ты завершил task. Запиши краткую самооценку в JSON. Никакого prose. + + +Original prompt: {prompt} +Recommended node: {recommended_node} +Actual node: {actual_node} +Chain executed: {chain_executed} + +Заполни: +- summary: 1-2 предложения. Что выбрал и почему. +- confidence_in_choice: 0.0-1.0 +- what_could_be_better: 1 предложение ИЛИ null +- lesson_learned: 1 предложение если ЧТО-ТО НОВОЕ узнал, иначе null + +``` + +**Стоимость:** ~$0.02-0.04/call. 50-100 task/день = ~$1-4/день, ~$30-120/мес. + +**Cost tracking:** API response содержит `usage` — пишется в episode. + +**Fallback:** `self_assessment: null` + `self_assessment_pending: true`. Reviewer дозаполнит. + +### 4.6. Слой 6 — Opus 4.7 reviewer + +**Файл:** `tools/brain-retro-opus-reviewer.mjs` (новый). + +**Триггер:** вызывается из skill `/brain-retro` шагом 6 (между existing analyzer и aggregation). + +**Логика:** + +```javascript +async function reviewPeriod(periodStart, periodEnd, sanityAnswers) { + const episodes = readEpisodesInPeriod(periodStart, periodEnd); + for (const ep of episodes) { + if (ep.review?.reviewed_at) continue; + if (['conversation', 'micro'].includes(ep.classifier_output?.task_type)) continue; + if (ep.schema_version < 2) continue; // can't review v1 + + const prompt = buildAdaptiveReviewPrompt(ep, sanityAnswers); + const review = await callOpus(prompt); + ep.review = parseReview(review); + ep.review.reviewer = 'opus-4-7'; + ep.review.reviewed_at = nowIso(); + + if (!ep.outcome_reviewed) { + ep.outcome_reviewed = inferOutcomeReviewed( + ep.outcome_inferred, + ep.self_assessment, + sanityAnswers, + review + ); + ep.outcome_reviewed_source = 'opus_proxy'; + } + + rewriteEpisodeInJsonl(ep); + } +} +``` + +**Adaptive prompt template** — handles v2/v3/v4 episodes (закрывает B5): + +- **v4 эпизоды:** полный prompt с alternatives + self_assessment + chain_gaps. +- **v3 эпизоды:** без alternatives — prompt спрашивает «оцени выбор узла на основе rationale». +- **v2 эпизоды:** без alternatives + self_assessment — prompt спрашивает «оцени выбор на основе triggers_matched + outcome». +- **v1 эпизоды:** skip. + +**Review prompt (v4 пример):** + +```text + +Ты — независимый ревьюер routing-решений Claude. Никакого prose, только JSON. + + +Эпизод: +- Original prompt: {prompt_truncated_2K} +- Period sanity answers: {sanity_block} +- Classifier рекомендовал: {recommended_node}, chain: {recommended_chain} +- Classifier reasoning: {reason_for_choice} +- Alternatives рассмотрены: {alternatives} +- Реально использовано: {actual_node}, chain: {actual_chain_executed} +- Chain gaps: {chain_gaps} +- Outcome inferred: {outcome_inferred} (по тону next-prompt) +- Self-assessment: {self_assessment} + +Оцени: +1. node_quality: correct | wrong_node | overkill | underkill | disputable +2. chain_quality: correct | missing_step | extra_step | wrong_order | n/a +3. gap_assessment: acceptable | mistake_should_complete | mistake_should_not_start | n/a +4. agent_self_assessment_accuracy: accurate | over_confident | under_confident | no_self_assessment +5. error_root_cause: wrong_skill | wrong_tool | wrong_chain_order | external_failure | n/a +6. alternative_better: если node_quality=wrong_node, какой из alternatives лучше +7. outcome_reviewed: success | soft_success | rework | blocked + (proxy: outcome_inferred + sanity + self_assessment.confidence vs actual) +8. reasoning: 1-3 предложения + +Output — ONLY JSON. + +``` + +**Стоимость:** ~$0.05-0.10/review. При ~200 эпизодов за /brain-retro = $10-20. + +**Fallback при API failure:** + +- Per-episode try/catch. Если 1 episode упал — skip, continue. +- Если упало >50% эпизодов — abort с сообщением «Opus reviewer недоступен, повторить retro позже». +- Episode с `review.reviewer_error: ` — попытка снова в следующем /brain-retro. + +### 4.7. Слой 7 — /brain-retro skill (расширенный) + +**Файл:** `.claude/skills/brain-retro/SKILL.md` (существующий, расширяется). + +**Текущая процедура** (см. строки 22-34 SKILL.md): 9 шагов с подэтапом 8a. + +**Новая процедура:** + +```text +1. Determine period (как сейчас). +2. Read evidence (включая v4.* episodes). +3. Read optional notes (как сейчас). +4. Update read-counter (как сейчас). +5. [НОВОЕ] Sanity-check questions: + - Analyzer выдаёт top-5 candidate questions. + - Я выбираю 3-4 наиболее релевантных, формулирую на русском. + - Задаю через AskUserQuestion (multiple-choice + free comment). + - Ответы пишутся в docs/observer/sanity-checks/YYYY-MM-DD.json + И ALSO event-streamed в эпизод(ы) периода как events. +6. [НОВОЕ] Opus reviewer pickup: + - Для эпизодов без review.reviewed_at → call Opus 4.7. + - Sanity-answers передаются в prompt как контекст. + - review.* + outcome_reviewed заполняются. +7. Run analyzer (расширенный для v4 факторов). +8. Aggregate (per references/aggregation-template.md, обновлённый). +9. [НОВОЕ — opt-in] Если 150+ episodes с review с last self-retrospect: + - prompt user: «Запустить self-retrospect? (~$2-5, ~3-5 минут)» + - Если да — call /self-retrospect. +10. Propose candidates for owner review (как сейчас). +11. Save retro note (с sanity-answers + cost report + Opus stats). +11a. Refresh STATUS.md (как сейчас). +12. Report to user (high-signal summary). +``` + +**Sanity-check generation logic (закрывает C1):** + +Analyzer `tools/brain-retro-sanity-generator.mjs` (новый, ~50 строк) выдаёт **5 candidate questions**: + +```text +- Если в периоде >10 эпизодов task_type=bugfix: + "10 раз я фиксил баги. Помнишь — что-то пришлось переделывать?" +- Если в периоде >5 эпизодов с overkill candidate: + "5 раз я брал большую процедуру для маленьких задач. Это напрягало?" +- Если в периоде >3 эпизода с chain_deviation: + "3 раза я бросал процедуру на полпути. Это было оправдано?" +- Если есть blocked outcome: + "Был случай когда я заявил готово, а потом нашлись косяки?" +- Generic фоллбэк: + "Общее впечатление от моей работы за период?" +``` + +Я выбираю 3-4 наиболее релевантных, formulate на русском. + +**Cost report в /brain-retro summary:** + +```text +## Cost report за период +- Classifier (Sonnet 4.6): $X.XX (Y prompts) +- Self-assessment (Opus): $X.XX (Z task ends) +- Reviewer (Opus, this run): $X.XX (W episodes) +- Self-retrospect (if invoked): $X.XX +- Embedding: $0 (local) +Total: $X.XX +``` + +### 4.8. Слой 8 — /self-retrospect skill (opt-in) + +**Файл:** `.claude/skills/self-retrospect/SKILL.md` (новый). + +**Триггер:** **opt-in** (closes C2 honest cost): + +1. Пользователь явно: `/self-retrospect` или «сделай self-retrospect». +2. /brain-retro prompt'ит «запустить?» если накопилось 150+ unreviewed-since-last episodes. + +**Не auto-trigger без подтверждения** — cost не нулевой ($2-5). + +**Action:** + +1. Read last 150+ episodes с `review.reviewed_at` filled (since last self-retrospect, tracker в `docs/observer/.self-retrospect-counter.json`). +2. Compute patterns (без LLM API — pure aggregation): + - **Промахи classifier:** group by `(task_type, recommended_node, review.node_quality)`. Если для пары ≥5 эпизодов с `wrong_node` И одинаковый `alternative_better` → паттерн. + - **Калибровка confidence:** bucket `confidence_in_choice` vs `outcome_reviewed`. Если высокий confidence + rework — over-confident. + - **Когнитивные ошибки:** group by `chain_deviation_reason`. Если одна причина в 3+ эпизодах с rework → bias. +3. Write report в `docs/observer/self-retrospect/YYYY-MM-DD.md`. +4. Update counter. +5. `lesson_learned` → новый `memory/feedback_self_calibration_YYYY-MM.md`. +6. Return summary to user. + +**Стоимость:** ~$2-5 (моя current-session Opus inference + write). **Не нулевой как в v1.0 заявлено — факт честный.** + +**Output для future sessions:** memory создаётся, auto-loaded на старте каждой сессии. + +--- + +## 5. Schema эпизода v4.* (поэтапные bumps) + +Закрывает E16 — atomic bumps вместо одного v4.1. + +| version | когда вводится | что добавляется | +|---|---|---| +| v4.0 | фаза 2 | `classifier_output` (с alternatives), `environment.classifier_model`, `environment.degraded_mode` | +| v4.1 | фаза 3 step 1 | `execution_trace` (с chain_gaps), `chain_progress` | +| v4.2 | фаза 3 step 2 | `self_assessment`, `review` (пустой template) | +| v4.3 | фаза 3 step 3 | `prompt_embedding_base64`, `outcome_reviewed`, `task_cost.*` extended | + +**Парсер** `tools/observer-transcript-parser.mjs` детектирует `schema_version` и обрабатывает все версии для read. Write — только latest available. + +**Полная финальная схема v4.3:** + +```json +{ + "schema_version": 4, + "schema_minor": 3, + "task_id": "...", + "task_ref": "...", + "timestamps": { "started_at": "ISO", "ended_at": "ISO" }, + "path_type": "improvised | regulated | mixed | alternative", + "outcome": "unknown", + "prompt_signal": "new_task | neutral | correction | approval", + + "decision_provenance": { + "kind": "autonomous | user_directed_method | user_chose_from_options", + "claude_would_have_chosen": null, + "requested_node": null + }, + + "environment": { + "economy_level": 100, + "model": "claude-opus-4-7", + "classifier_model": "claude-sonnet-4-6-YYYYMMDD", + "reviewer_model": "claude-opus-4-7", + "post_compaction": false, + "session_turn": 1, + "parallel_session": false, + "degraded_mode": false, + "embedding_unavailable": false + }, + + "task_size": { + "tool_calls": 0, + "files_touched": 0, + "files": [] + }, + + "task_cost": { + "input_tokens": 0, + "output_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation_input_tokens": 0, + "classifier_input_tokens": 0, + "classifier_output_tokens": 0, + "self_assessment_input_tokens": 0, + "self_assessment_output_tokens": 0, + "reviewer_input_tokens": 0, + "reviewer_output_tokens": 0 + }, + + "prompt_embedding_base64": "...", + + "classifier_output": { + "task_type": "feature", + "recommended_node": "superpowers:brainstorming", + "recommended_chain": ["superpowers:brainstorming", "superpowers:writing-plans"], + "recommended_chain_id": "L1", + "alternatives_considered": [ + { "node": "...", "match_score": 0.6, "rejected_because": "..." } + ], + "reason_for_choice": "...", + "no_skill_found": false, + "no_skill_found_suggestion": null, + "classifier_source": "llm | regex_fallback | haiku_fallback | unknown" + }, + + "execution_trace": { + "actual_node_invoked_first": "superpowers:brainstorming", + "actual_chain_executed": [ + { + "step": 1, + "skill": "superpowers:brainstorming", + "started_at": "ISO", + "ended_at": "ISO", + "duration_sec": 1840, + "completed": true + } + ], + "chain_gaps": [ + { + "type": "incomplete_chain", + "expected_steps": 3, + "executed_steps": 1, + "gap_after_step": 1, + "gap_reason": "L1 design-approval gate", + "gap_severity": "expected | unexpected | error" + } + ], + "chain_deviation": false, + "deviation_reason": null, + "deviation_alternative_used": null, + "chain_progress": [] + }, + + "self_assessment": { + "written_at": "ISO", + "summary": "...", + "confidence_in_choice": 0.85, + "what_could_be_better": null, + "lesson_learned": null, + "self_assessment_pending": false + }, + + "review": { + "reviewed_at": null, + "reviewer": null, + "reviewer_error": null, + "node_quality": null, + "chain_quality": null, + "gap_assessment": null, + "agent_self_assessment_accuracy": null, + "error_root_cause": null, + "alternative_better": null, + "reasoning": null + }, + + "outcome_inferred": null, + "outcome_reviewed": null, + "outcome_reviewed_source": null, + + "events": [] +} +``` + +**Sanity-check answers separate storage** `docs/observer/sanity-checks/YYYY-MM-DD-period.json`: + +```json +{ + "period_start": "ISO", + "period_end": "ISO", + "answered_at": "ISO", + "questions_and_answers": [ + { "q": "...", "a": "yes | no | unsure", "comment": "..." } + ] +} +``` + +Также — duplicate в episodes как `events: [{ kind: 'sanity_check_answer', q, a, comment, period_id }]`. + +--- + +## 6. §17 — формальное определение + +**Текст для добавления в Pravila** (новая секция, замещает §12): + +> **§17. Universal skill-coverage rule.** Все задачи, кроме явных `conversation`, `micro`, `manual_override`, должны быть покрыты skill или цепочкой skill'ов из реестра `docs/registry/nodes.yaml`. Direct-исполнение разрешено только для: +> +> 1. **Conversation** — короткие разговорные prompt'ы (length < 15 OR в `CONVERSATION_PATTERNS`), при отсутствии anchor-слова. +> 2. **Micro** — тривиальные правки (опечатка/переименование/format/bump), определённые `MICRO_KEYWORDS`. +> 3. **Manual override** — явное указание заказчика «делай через X» (помечается `decision_provenance.kind='user_directed_method'`). +> 4. **Escape-hatch** — маркер `` в начале ответа Claude с явным обоснованием. +> +> Enforcement через `tools/router-tool-gate.mjs` (PreToolUse hook). Mode: +> +> - `warn-only` (default во время bootstrap; stderr-сигнал, не блокирует); +> - `enforce` (включается отдельным решением после анализа evidence; блокирует); +> - `off` (для отката). +> +> §17 — **не hard-rule под §9 «Отступления»**. В режиме экономии 0% правило логически встроено в classifier, но enforcement-хук может быть выключен через `~/.claude/runtime/router-gate-mode.json`. **Замещает §12** полностью. + +**Pravila §12 → удаление в этом эпике** (текст в архив). + +--- + +## 7. Что меняется в нормативке + +**Архив:** `docs/archive/llm-bootstrap-2026-05/` со структурой: + +- `pravila-12/` — текст §12 (sub-секции 12.1-12.4). +- `routing-docs/` — routing-off-phase.md, router-procedure.md, CLAUDE.md §3.3 snapshot, PSR_v1 R15 snapshot. +- `tooling-when-to-use/` — извлечённые поля «когда брать» из Tooling §4.X (inventory подтвердил их отсутствие в текущей версии — папка пустая или содержит NOTE). +- `memory/` — feedback_superpowers_hard_rule.md, feedback_feature_via_writing_plans.md. +- `settings-skill-discipline/` — diff `~/.claude/settings.json` user-level до и после удаления skill-discipline hooks (фактический list определяется в фазе 1 после inventory user settings.json). +- `nodes-yaml-archive/` — снимок до правок. +- `ROLLBACK.md` — пошаговая инструкция. + +**Pravila §12 удаляется целиком.** §17 добавляется. §16.4 обновляется (missed-activations работают с §17). Cross-refs §12 → §17 в CLAUDE.md §5 п.11, PSR_v1 R0.4.A, Tooling §7. + +**CLAUDE.md §3.3 удаляется** — заменяется на однострочный pin: `См. реестр docs/registry/nodes.yaml`. §5 п.11 переписывается. §0 cross-refs обновляются. + +**PSR_v1 R10.1 счётчики** → pin на nodes.yaml. **R15** удаляется. **R0.4.A** упоминание §12 → §17. + +**Tooling Прил.Н** — поля «когда брать» (если есть в attribute-блоках) извлекаются в архив. §0 счётчики — pin на header nodes.yaml. §3.X cross-ref на router-procedure.md удаляется. + +**routing-off-phase.md, router-procedure.md** — целиком в архив. + +**nodes.yaml — изменения:** + +- Поля `triggers[].keyword` и `triggers[].classification` — **остаются** (input для classifier). +- L1-L16 chains — **остаются** (input как справка для classifier). +- Добавляется НОВОЕ поле верхнего уровня `capabilities:` для каждого узла. На старте фазы 2 — controller заполняет capabilities (~30 мин либо subagent task). +- Удаляется (если есть) поле `when_to_use` — **проверено в инвентаре §18 — поля нет, удалять нечего**. + +**Memory:** `feedback_superpowers_hard_rule.md` + `feedback_feature_via_writing_plans.md` → архив. **Другие brain-governance memory** (`feedback_brain_unused_tools_not_problem.md`, `project_brain_governance_design.md`) — **остаются** с обновлёнными cross-refs (§12 → §17). + +**`tools/observer-classification-map.json`** — **архивируется в этом эпике** (закрывает B2). DEPRECATED 24.05 — окончательно удаляется. + +--- + +## 8. Что остаётся нетронутым + +- **Pravila §1-§11** — без изменений. +- **Pravila §13** — без изменений. +- **Pravila §14** — без изменений (Ruflo dormant). +- **Pravila §15** — без изменений (procedural rule). +- **Pravila §16** — без изменений. §16.4 — minor update. +- **ADR** — все сохраняются. ADR ссылающиеся на §12 — minor добавление примечания. +- **Schema БД, открытые вопросы, schema нормативки structurе** — не трогается. +- **Memory user/project/reference** — не трогаются (кроме 2 архивируемых). +- **`router-stop-gate.mjs`, `observer-of-observer.mjs`, `observer-coverage-checker.mjs`, экономические хуки, subagent-prompt-prefix.mjs** — без изменений. +- **Project-skills** (`audit-portal`, `regression`, `brain-retro`, `billing-audit`, `security-go-live`) — не трогаются. На старте фазы 2 controller добавляет их `capabilities` в nodes.yaml. +- **Permission allowlist в settings.json** — не трогается. Gate работает независимо. + +--- + +## 9. Адаптация контролёров C1-C6 + +### 9.1. C1 L1-watcher + +**Сейчас** (`tools/l1-watcher.mjs`): проверяет `.claude/settings.json` enabledPlugins ↔ Tooling §3.3. + +**После:** переключается на `.claude/settings.json` ↔ `docs/registry/nodes.yaml` registered plugins. + +### 9.2. C2 Cross-ref-checker + +**Сейчас** (`tools/cross-ref-checker.mjs`): version cross-refs между 4 нормативными файлами. + +**После:** обновляется список ожидаемых cross-refs (§12 → §17, удаляются §3.3-cross-refs). + +### 9.3. C3 Observer-of-observer + +**Сейчас:** 54-week self-prune detection. **После:** без изменений. + +### 9.4. C4 Сигнальный статус (STATUS.md generator) + +**Сейчас** (`tools/status-md-generator.mjs`): генерит STATUS.md с C1-C5 + discipline metrics. + +**После:** расширяется секциями: + +- Cost monitoring (per-month). +- Classifier anomaly count. +- Self-retrospect last run date + key findings. +- Sanity-check coverage %. + +### 9.5. C5 Observer-coverage-checker + +**Сейчас:** missed-activations count + episode coverage. + +**После:** missed-activations логика **работает с §17** — теперь missed-activation = «classifier рекомендовал skill, но actual_node=direct без escape-hatch». + +### 9.6. C6 Chain-map-checker (closes B7) + +**Сейчас:** проверяет chains в map. + +**После:** обновляется источник — nodes.yaml chains section. + +--- + +## 10. Гранулярные flag-переключатели + откат + +**Все flag'и в `~/.claude/runtime/`:** + +| flag-файл | значения | по умолчанию (после фазы N) | управляет | +|---|---|---|---| +| `router-classifier-mode.json` | `llm-first` \| `hybrid` \| `regex-first` | `llm-first` после ф.2 | какой classifier работает | +| `router-gate-mode.json` | `off` \| `warn-only` \| `enforce` | `warn-only` всё bootstrap | §17 enforcement | +| `self-assessment-mode.json` | `on` \| `off` | `on` после ф.3 step 2 | Stop-hook self-assessment | +| `opus-reviewer-mode.json` | `on` \| `off` | `on` после ф.3 | reviewer в /brain-retro | +| `self-retrospect-mode.json` | `on` \| `off` | `on` после ф.3 step 3 | /self-retrospect доступен | +| `embedding-mode.json` | `on` \| `off` | `on` после ф.3 step 3 | embedding в episodes | +| `sanity-check-mode.json` | `mandatory` \| `optional` \| `off` | `mandatory` после ф.3 | sanity в /brain-retro | + +**Hot-reload:** каждый component читает свой flag при invocation. Flip — мгновенно, без перезапуска сессии. + +**Полный откат:** + +1. Все flag'и → pre-overhaul state. +2. Run `node tools/test-rollback.mjs --dry-run`. +3. Run `node tools/test-rollback.mjs --execute` — восстанавливает все файлы. +4. Smoke regression. +5. Время: ~1 час. + +**Granular откат:** flip один flag, smoke regression. + +**Git tag pre-overhaul:** `brain-pre-llm-bootstrap` на коммите ДО фазы 1. + +**Dry-run rollback automation** (`tools/test-rollback.mjs` — новый): + +- Создаёт временный git worktree. +- Восстанавливает all files из archive. +- Запускает smoke (lint + tests + key analyzer). +- Удаляет worktree. +- Reports: pass/fail per check. + +--- + +## 11. Фазы реализации + +### 11.A. Phase split + +**Implementation phases** (work для controller + subagents) — фазы 1, 2, 3. +**Passive phase** — evidence collection (4-6 месяцев между фазой 3 и фазой 4). +**Final implementation** — фаза 4 (distillation). + +### 11.1. Фаза 1 — Foundation + delete + archive (~1 неделя) + +**Цель:** убрать §12, заархивировать routing-docs, подготовить инфру для §17. + +**Tasks:** + +1. Git tag `brain-pre-llm-bootstrap`. +2. Создать `docs/archive/llm-bootstrap-2026-05/` со структурой. +3. **Inventory** реального state (§18 содержит initial snapshot, фаза 1 обновляет под фактическое): + - List user-level hooks из `~/.claude/settings.json` (если есть). + - Snapshot nodes.yaml. + - Snapshot затронутых settings.json. +4. Архивировать Pravila §12. +5. Удалить cross-refs §12 из CLAUDE.md §5 п.11, PSR_v1 R0.4.A, Tooling §7. +6. Удалить skill-discipline hooks из `~/.claude/settings.json` (если найдены при inventory). +7. Архивировать routing-off-phase.md, router-procedure.md. +8. Архивировать CLAUDE.md §3.3 → заменить на pin. +9. Архивировать PSR_v1 R15. +10. Архивировать `tools/observer-classification-map.json`. +11. Архивировать 2 memory-файла. +12. Создать flag-переключатели в `~/.claude/runtime/`: + - `router-gate-mode.json` = `off`. + - `skill-discipline-mode.json` = `off`. +13. Создать `ROLLBACK.md` в архиве. +14. Создать `tools/test-rollback.mjs` (dry-run автоматизация). +15. Smoke regression. +16. Добавить Pravila §17 (новая секция). +17. Создать **ADR-016 «§17 universal skill-coverage rule»** (закрывает E17). +18. Subagent-driven implementation per Pravila §15.1 (Sonnet/Opus для git-задач). + +**Выход фазы 1:** §12 нет, §17 в Pravila, ничего не enforce'ится (gate off). Routing работает по старому regex Layer 1 (временно). Это **переходное окно**, длится 1 неделю. Trade-off обсуждён в §19.B. + +### 11.2. Фаза 2 — Classifier + nodes.yaml capabilities + §17 logic (~1-1.5 недели) + +**Цель:** перевести classifier на LLM-first, ввести §17 enforcement (warn-only), schema v4.0. + +**Tasks:** + +1. Verify model ID Sonnet 4.6 через `anthropic.models.list()`. Записать точный ID в config. +2. Заполнить `capabilities:` в nodes.yaml для всех 84 узлов (subagent task ~2-4 часа). +3. Переписать `tools/router-classifier.mjs`: + - Conversation/micro/manual_override/anchor prefilter (§4.1). + - LLM-classifier на Sonnet 4.6 (§4.2). + - Удалить `classifyByRegex` primary path. Сохранить как `tools/router-classifier-regex-fallback.mjs`. + - Cost tracking writes в router-state. +4. Создать `tools/router-embedding.mjs` (§4.3). +5. Создать SessionStart hook для embedding warmup. +6. Расширить `tools/router-tool-gate.mjs` (§17 enforcement, mode warn-only). +7. Расширить `tools/router-prehook.mjs`: + - Удалить `ENFORCEMENT_TYPES` whitelist (старая §12 логика). + - Использовать новые поля classifier_output. +8. Обновить `tools/observer-transcript-parser.mjs` — handle schema v4.0. +9. Adapt `tools/registry-load.mjs` + `tools/registry-render.mjs` если требуется (закрывает A6). +10. Smoke regression + integration test «prompt → classifier → gate → tool». +11. Flip `router-classifier-mode` → `llm-first`. + +**Выход фазы 2:** новый router работает. Эпизоды v4.0 пишутся. §17 warn-only активен. + +### 11.3. Фаза 3 — Evidence loop (~1.5-2 недели) + +**Цель:** evidence pipeline (self_assessment + Opus reviewer + sanity-check + self-retrospect). + +**Step 3.1 (~3-4 дня):** + +- Расширить `tools/observer-stop-hook.mjs`: execution_trace + chain_gaps writing. +- Bump schema v4.0 → v4.1. +- Settings.json: Stop-hook timeout 5s → 15s. + +**Step 3.2 (~4-5 дней):** + +- Добавить self_assessment в Stop-hook (§4.5). +- Создать `tools/brain-retro-opus-reviewer.mjs` (§4.6). +- Bump schema v4.1 → v4.2. + +**Step 3.3 (~4-5 дней):** + +- Создать `tools/brain-retro-sanity-generator.mjs`. +- Расширить `.claude/skills/brain-retro/SKILL.md`: новые шаги 5/6/9/11. +- Обновить `.claude/skills/brain-retro/references/aggregation-template.md`. +- Создать `.claude/skills/self-retrospect/SKILL.md` (§4.8). +- Расширить `tools/brain-retro-analyzer.mjs` для v4.* факторов. +- Расширить `tools/status-md-generator.mjs` для cost + classifier anomaly + self-retrospect секций. +- Создать `docs/observer/.self-retrospect-counter.json`. +- Embedding pre-warm SessionStart hook. +- Bump schema v4.2 → v4.3. +- Smoke regression. +- Flip flags `self-assessment-mode`, `opus-reviewer-mode`, `self-retrospect-mode`, `embedding-mode`, `sanity-check-mode` → on/mandatory. + +**Выход фазы 3:** полный evidence pipeline работает. + +### 11.P. Passive period — evidence collection (~5-6 месяцев) + +- Без implementation work. +- Дмитрий вызывает `/brain-retro` раз в 1-2 недели. +- Накапливается база. +- Self-retrospect — по необходимости. +- Mid-bootstrap checkpoint (через 3 месяца, закрывает E4): + - Snapshot метрик: % эпизодов с review, distribution outcome_reviewed, top patterns. + - Decide: extend/shrink bootstrap, adjust §17 mode. + +### 11.4. Фаза 4 — Distillation (~2-3 недели, через ~6 месяцев) + +**Цель:** вывести regex-правила из эмпирики, переключить на hybrid. + +**Tasks:** + +1. **Sample selection:** `review.node_quality='correct'` AND `outcome_reviewed in {'success', 'soft_success'}`. Ожидаемо ~300-500 эпизодов. +2. **Кластеризация** по embedding (DBSCAN или hierarchical, eps подбирается на validation set). +3. **Per-cluster regex extraction** — keyword-stems из prompt'ов кластера. +4. **Сборка regex-классификатора v2.0** из дистиллированных правил. +5. **A/B тест** на holdout (20% эпизодов): accuracy regex vs LLM. +6. **Если regex accuracy < 70%** — extend bootstrap. +7. **Если regex accuracy ≥ 70%** — flip `router-classifier-mode` → `hybrid`. +8. **Обновить nodes.yaml** `triggers[]` — эмпирические. +9. **Решение по §17** — на основе evidence: + - 95%+ задач имели skill-coverage без issues → §17 confirmed, можно flip enforce. + - 70-95% → soft-§17, оставить warn-only. + - <70% → §17 не работает, снять. +10. **Spec-документ результатов** в `docs/superpowers/specs/2026-XX-XX-distillation-results.md`. +11. Update ADR-016 status. + +--- + +## 12. Cost monitoring (без cap, с daily dashboard) + +**Решение владельца:** жёсткого лимита нет. **Усиление в v2.0:** daily cost dashboard обновляется каждым Stop-hook'ом. + +**Что мониторится:** + +- `task_cost.classifier_input/output_tokens` × Sonnet 4.6 pricing +- `task_cost.self_assessment_*` × Opus 4.7 pricing +- `task_cost.reviewer_*` × Opus 4.7 pricing +- Self-retrospect cost при invocation + +**Где показывается:** + +1. **Daily aggregation:** `~/.claude/runtime/cost-daily.json` — updated по Stop-hook'у. Rolling 30-day: + + ```json + { + "2026-06-15": { + "classifier_usd": 2.10, + "self_assessment_usd": 3.40, + "reviewer_usd": 0.00, + "self_retrospect_usd": 0.00, + "total_usd": 5.50, + "episode_count": 87 + } + } + ``` + +2. **STATUS.md** секция «Cost monitoring» — top 7 days + monthly total. +3. **`/brain-retro` summary** — per-period cost report. + +**Anomaly detection** (закрывает E15): + +- Per-episode WARN: `task_cost.classifier_output_tokens > MAX(median × 3, 5000)`. +- Per-day WARN: `total_usd > 1.5 × median_30day`. +- WARN записывается в STATUS.md секцию «Anomalies» + episode `classifier_anomaly: true`. + +**Если runaway:** + +- Daily WARN видим в течение суток. +- Flip `router-classifier-mode` → `regex-first`. +- Granular rollback ~1 час. + +**Ожидаемая стоимость (revised):** + +| компонент | $$/мес ожидание | +|---|---| +| Sonnet 4.6 classifier (50-100 prompt/день × $0.02) | $30-60 | +| Self-assessment в Stop-hook (50-100 task/день × $0.03) | $30-60 | +| Opus 4.7 reviewer (200 episodes × 4 retro/мес × $0.07) | $50-90 | +| Self-retrospect (~$2-5 × 2-4 calls/мес) | $10-20 | +| Embedding (локально) | $0 | +| **Total** | **$120-230/мес** | + +За 6 месяцев bootstrap: **~$720-1380**. Шире чем v1.0 ($1140) — учитывает honest self-retrospect и variability. + +--- + +## 13. Связанные изменения в нормативке (карта правок) + +Все через subagent-driven-development, pre-flight Pravila §15.2. + +### 13.1. Pravila + +- **§12 удаляется** (sub-секции 12.1-12.4). +- **§17 добавляется**. +- **§16.4** обновляется (missed-activations интегрируются с §17). +- **§0/§1 cross-refs** обновляются. +- **§9 changelog** entry. + +### 13.2. CLAUDE.md + +- **§3.3 удаляется** (→ pin на nodes.yaml). +- **§5 п.11 переписывается** («§17 universal skill-coverage; classifier рекомендует, sturdy enforces в warn-only»). +- **§0 cross-refs** обновляются. +- **§9 history** entry. + +### 13.3. PSR_v1 + +- **R10.1 счётчики** → pin на nodes.yaml. +- **R15** удаляется. +- **R0.4.A** упоминание §12 → §17. +- **§0 cross-refs** обновляются. + +### 13.4. Tooling Прил.Н + +- **§4.X поля «когда брать»** удаляются (inventory подтвердил их отсутствие — проверить повторно на старте фазы 1). +- **§0 счётчики** — pin на nodes.yaml header. +- **§3.X cross-refs на router-procedure.md** удаляются. +- **§9.X changelog** entry. + +### 13.5. nodes.yaml + +- Добавляются `capabilities:` per узел (новое поле, фаза 2). +- `triggers[]` — остаются. +- L1-L16 chains — остаются. +- Capabilities для project-skills — добавляются если нет. + +### 13.6. ADR-016 (новый) + +«§17 universal skill-coverage rule replaces §12». Структура: + +- Status: Accepted. +- Context: §12 a-priori bias on routing evidence; empirical distillation requires removing principal bias. +- Decision: replace §12 with §17 (default-deny except conversation/micro/manual_override). +- Consequences: see §19. +- Boundaries: §17 vs Pravila §14 (Ruflo dormant) vs §15 (procedural). + +--- + +## 14. Risk register (расширен) + +| риск | вероятность | impact | митигация | +|---|---|---|---| +| Classifier систематически промахивается | средняя | высокий | Opus reviewer + sanity-check ловят, гранулярный rollback | +| Self-assessment Stop-hook жрёт $$ | высокая | средний | Daily cost dashboard, anomaly WARN, flag off | +| Sonnet/Opus API down во время /brain-retro | средняя | низкий | Fallback chain (Haiku → regex), повтор | +| Embedding-модель не загружается на Windows | низкая | высокий | Fallback NULL embedding, self-retrospect → task_type clustering | +| §17 enforcement блокирует легитимные direct | средняя | средний | warn-only всё bootstrap, escape-hatch, flag rollback | +| Anthropic breaking change в API | средняя | высокий | classifier_model в episode → датасет разделим; fallback chain | +| Cost runaway (баг в цикле) | низкая | высокий | Daily dashboard, anomaly WARN, granular rollback ~1 час | +| Дмитрий не вызывает /brain-retro | средняя | высокий | self-retrospect opt-in, reviewer накапливает queue | +| Mid-bootstrap evidence низкого качества | средняя | средний | Checkpoint через 3 месяца — decide extend | +| Spec устаревает за phase split | низкая | низкий | Refresh check перед каждой фазой | +| Conversation prefilter false-positive «делай аудит» | средняя | средний | Anchor detection ловит существительное → fall through | +| outcome_reviewed качество низкое (Opus proxy) | средняя | средний | Sanity-check answers как signal, marker source | +| Sanity-check вопросы шумные | средняя | низкий | top-5 candidates, калибровка | +| Self-retrospect не находит паттернов первые 3 месяца | высокая | низкий | OK — мало данных, calibration period | +| nodes.yaml capabilities пропускает узлы | низкая | средний | Subagent task с verification | +| Permission interaction breakage | низкая | высокий | Smoke test «все existing скрипты работают» в фазе 2 | + +--- + +## 15. Открытые вопросы implementation-уровня + +**Фаза 1:** + +- Точные имена hooks в `~/.claude/settings.json` user-level — inventory шаг. +- Точная структура архивных папок. + +**Фаза 2:** + +- Exact model ID Sonnet 4.6. +- Capabilities-описания узлов — generation strategy. +- Embedding daemon vs per-call decision (latency-based). +- Recommended_chain хранение: id vs array vs both. + +**Фаза 3:** + +- Sanity questions formulation — calibration на первых 2-3 /brain-retro. +- Self-retrospect counter — exact threshold. +- Self-retrospect skill `description` formulation. + +**Фаза 4:** + +- Embedding clustering algorithm. +- Regex extraction algorithm. +- A/B test threshold. + +--- + +## 16. Definition of Done + +### После фазы 3 + +- ✅ Pravila §12 в архиве, §17 в Pravila, ADR-016 в `docs/adr/`. +- ✅ Skill-discipline hooks (если были) в архиве, выключены в `~/.claude/settings.json`. +- ✅ Routing-docs в архиве. +- ✅ Sonnet 4.6 classifier работает с verified model ID, prefilter активен. +- ✅ §17 enforcement в warn-only mode. +- ✅ Embedding пишется в эпизоды (Base64), pre-warm SessionStart активен. +- ✅ Schema v4.3 пишется. Парсер handles v1/v2/v3/v4 для read. +- ✅ Self_assessment пишется в Stop-event (с retroactive fallback). +- ✅ /brain-retro: sanity-check (mandatory) + Opus reviewer + опциональный self-retrospect. +- ✅ /self-retrospect skill доступен (opt-in). +- ✅ Daily cost dashboard обновляется. +- ✅ STATUS.md показывает cost + classifier anomaly + self-retrospect. +- ✅ ROLLBACK.md протестирован через `tools/test-rollback.mjs --dry-run`. +- ✅ 7 flag-переключателей работают (smoke per-flag). +- ✅ Регрессия: markdownlint / cross-ref-checker / l1-watcher / observer-coverage / chain-map-checker / lychee / gitleaks — GREEN. +- ✅ nodes.yaml: `capabilities:` заполнен для всех 84 узлов. + +### Mid-bootstrap (~3 месяца после фазы 3) + +- ✅ ~500-700 episodes собрано. +- ✅ ≥70% episodes имеют review.* заполненный. +- ✅ Distribution outcome_reviewed: ≥60% success/soft_success, <10% blocked. +- ✅ Mid-bootstrap checkpoint snapshot. + +### После фазы 4 + +- ✅ Дистиллированный regex-классификатор v2.0 в production. +- ✅ A/B тест регекса vs LLM на holdout — accuracy report. +- ✅ Spec результатов дистилляции. +- ✅ Решение по §17: confirmed/amended/снят. ADR-016 status updated. + +--- + +## 17. Связь с другими активными эпиками + +- **Биллинг v2 Спек C** — отдельный эпик. Этот overhaul **не блокирует** и **не зависит**. Per user decision (2026-05-24): сначала Спек C, потом стартует этот overhaul. +- **Security go-live** — отдельный эпик. +- **Other epics** — нет зависимостей. + +Spec самостоятелен — реализация может стартовать в любой момент. + +--- + +## 18. Pre-implementation state inventory + +Реальное состояние на 2026-05-25 (после verification, фаза 1 обновит под актуальное). + +### 18.1. Hook files в проекте + +```text +.claude/settings.json hooks: +- PreToolUse Edit|Write: inline CLAUDE.md edit warning +- PreToolUse Task: tools/subagent-prompt-prefix.mjs +- PreToolUse Edit|Write|MultiEdit|Bash: tools/router-tool-gate.mjs +- PostToolUse Edit|Write: inline markdownlint --fix +- PostToolUse Edit|Write: inline db/schema.sql reminder +- Stop: tools/observer-stop-hook.mjs + tools/router-stop-gate.mjs +- UserPromptSubmit: tools/router-prehook.mjs +``` + +**Skill-discipline hooks в проекте — НЕТ.** Если есть — то в `~/.claude/settings.json` user-level (вне репо, inventory на фазе 1). + +### 18.2. tools/ inventory (relevant subset) + +```text +router-classifier.mjs (260 строк) — regex Layer 1 + Haiku Layer 2 +router-tool-gate.mjs (112 строк) — §17 enforcement текущая база +router-prehook.mjs (106 строк) — ENFORCEMENT_TYPES whitelist +router-stop-gate.mjs, router-stdin-helper.mjs, router-accuracy-runner.mjs — без изменений +observer-stop-hook.mjs (262 строк) — episode write +observer-transcript-parser.mjs — handles v1/v2/v3 read +observer-routing-detector.mjs — detects user_directed_method +observer-classification-map.json — DEPRECATED 2026-05-24 +observer-pii-filter.mjs, observer-choice-detector.mjs, observer-chain-detector.mjs, +observer-recommended-node.mjs, observer-retrofill-chain-ref.mjs, +observer-state-enricher.mjs, observer-hook-resolver.mjs, +observer-coverage-checker.mjs, observer-chain-map-checker.mjs, +observer-of-observer.mjs — без изменений +cross-ref-checker.mjs (132 строк) — C2 +l1-watcher.mjs (75 строк) — C1 +brain-retro-analyzer.mjs — будет расширен +status-md-generator.mjs — будет расширен +missed-activations.mjs — адаптирован к §17 +discipline-metrics.mjs — inventory & decide keep/remove +registry-load.mjs, registry-render.mjs, registry-to-classification-map.mjs — могут потребовать adapt +``` + +### 18.3. nodes.yaml структура (актуальная) + +Per-node fields: + +```yaml +- id: "#N" + name: "..." + slug: "..." + category: "..." + subcategory: null | "..." + status: "active" | "dormant" + dormancy_reason: null | "..." + triggers: + - {keyword: "...", weight: 1.0} + - {classification: "...", weight: 1.0} + boundaries: [] + chain_membership: ["L1", ...] + attributes: + tooling_section: "§N.M #N" +``` + +**Полей `when_to_use` / `routing_triggers` / `description` / `capabilities` — НЕТ.** Фаза 2 добавляет `capabilities:` per узел. + +L1-L16 chains: lines 1591-1713, структура `chains: {L1: {name, sequence}, ...}`. + +### 18.4. Pravila §12 — фактическое состояние + +§12 существует, sub-секции 12.1-12.4. §12.3 — SoT для exclusions. §12.4 — explicit hard-rule статус. + +### 18.5. Episode JSONL distribution + +Текущий `docs/observer/episodes-2026-05.jsonl`: 239 lines = 5 v1 + 139 v2 + 95 v3. После фазы 3 — v4.* добавятся. + +### 18.6. Memory inventory + +Brain-related: + +- `feedback_superpowers_hard_rule.md` — архивируется. +- `feedback_feature_via_writing_plans.md` — архивируется. +- `feedback_brain_unused_tools_not_problem.md` — остаётся, cross-refs обновятся. +- `feedback_brain_counter_canon.md` — остаётся. +- `project_brain_governance_design.md` — остаётся. +- `project_observer_*` — остаются. + +--- + +## 19. Accepted trade-offs + +Явные компромиссы, осознанно принятые в дизайне. + +### 19.A. §17 как a-priori правило vs эмпирический эксперимент + +**Конфликт:** §1.1 «принуждение skill смещает evidence». §17 — ТОЖЕ принуждение, шире чем §12. + +**Trade-off:** соглашаемся что эксперимент тестирует **classifier accuracy и chain-suggestion quality**, не «нужен ли skill для X». Чистый empirical без principal rule = «всё через direct», не helpful для дистилляции. + +**Accept:** §17 — safety rail для bootstrap. Pure empirical — отдельная инициатива в будущем если §17 evidence biased. + +### 19.B. Переходное окно «§12 нет, §17 ещё не включён» (1 неделя) + +**Конфликт:** в эту неделю агент работает без any rule. + +**Trade-off:** атомарная фаза 1+2 сложнее тестировать. Step-by-step безопаснее. + +**Accept:** 1 неделя evidence с пометкой `bootstrap_transition_week: true`. Исключается из дистилляции. + +### 19.C. Sanity-check mandatory, не optional + +**Конфликт:** «один touchpoint» vs «обязательно отвечать». + +**Trade-off:** optional → пользователь скипает → bias накапливается. Mandatory — 3 минуты раз в 1-2 недели, ниже порога friction. + +**Accept:** /brain-retro не завершается без ответов. Flag `sanity-check-mode` доступен для перехода в optional если будет реальная боль. + +### 19.D. Cost ~$120-230/мес без cap + +**Конфликт:** runaway risk. + +**Trade-off:** cap = false-security. Daily dashboard + anomaly WARN ловят runaway в течение часа. + +**Accept:** no cap, но honest daily dashboard. + +### 19.E. Opus reviewer заполняет outcome_reviewed как proxy + +**Конфликт:** outcome_reviewed «по идее» от пользователя; per-episode никто не пишет. + +**Trade-off:** ждать ручной per-episode review = wait forever. Opus + outcome_inferred + sanity = best available proxy. Marker `outcome_reviewed_source: 'opus_proxy'`. + +**Accept:** proxy с explicit sourcing. Не «истина», лучшее что можно автоматизировать. + +### 19.F. Self-retrospect opt-in (НЕ auto в /brain-retro) + +**Конфликт:** «self-retrospect нужен» vs «cost не нулевой». + +**Trade-off:** auto = $30-120/мес стабильно. Opt-in = пользователь решает, threshold-prompt напоминает. + +**Accept:** opt-in default. Можно forced-on flag'ом. + +--- + +## 20. Что НЕ делается этим эпиком (non-goals) + +- **НЕ** трогается Pravila §14 (Ruflo dormant). +- **НЕ** трогается Pravila §15 (procedural). +- **НЕ** трогается Pravila §16 кроме minor §16.4. +- **НЕ** трогаются ADR (только cross-ref добавления). +- **НЕ** трогается `db/schema.sql`. +- **НЕ** трогается код Лидерра-портала. +- **НЕ** трогаются другие эпики. +- **НЕ** реализуется automated regex-distillation в фазах 1-3 (only manual в фазе 4). +- **НЕ** меняется outcome_inferred logic (sentiment-based). +- **НЕ** меняется PII-filter — применяется на episode write как сейчас. Anthropic API получает prompts как раньше (см. brainstorming decision F4=a). +- **НЕ** intermediate persistence-режим «классификатор только в офисное время». +- **НЕ** A/B тестируется «§12 vs §17 vs no-rule». +- **НЕ** реализуется UI для review (chat-only через /brain-retro). +- **НЕ** Anthropic Workbench integration — direct API. + +--- + +**Версия spec:** 2.0 от 2026-05-25. +**Предыдущая версия:** v1.0 от 2026-05-24 (содержала 8 фактических ошибок, переписана целиком после критического анализа). +**Следующий шаг:** writing-plans skill для детального плана реализации фаз 1+2+3 с inventory-task на старте фазы 1.