Files
portal/docs/observer/notes/2026-05-20-brain-retro.md
T

60 KiB
Raw Blame History

Brain-retro — первое ретро мозга по данным наблюдателя

Дата: 2026-05-20 (12:25 MSK) Период: 2026-05-19 .. 2026-05-20 (это первое brain-retro вообще; покрывает всё, что наблюдатель записал на текущий момент) Источник: docs/observer/episodes-2026-05.jsonl (22 строки) + docs/observer/.read-counter.json Анализатор: node tools/brain-retro-analyzer.mjs docs/observer/episodes-2026-05.jsonl Уровень анализа: верхнеуровневый по запросу заказчика («потом углубимся по разделам»); экономия 0%.

Анализатор отчитался: episodeCount=17, v1SkippedCount=5, observerErrorCount=0. Ниже все цифры по 17 v2-эпизодам, если не отмечено иное.


Period

2026-05-19T05:18:16Z .. 2026-05-20T08:12:29Z (5 сессий, 22 эпизода всего; 17 v2-анализируемых).

Сессии:

task_id (session_id) дата v1 эпизоды v2 эпизоды примечание
553717ec 19.05 05:18 .. 10:24 5 10 длинная сессия brain-governance Phase A/B/C + factor-analysis ext; компакция между turn 86–91
24acfa10 20.05 07:08 0 1 ExitWorktree-разовый ход
a42e4ba5 20.05 07:26 0 1 короткая PowerShell/Bash-проверка
dd905ea0 20.05 07:25 .. 07:28 0 1 apdate ЭТАЛОН-семейства memory (11 Edit)
98298ec2 20.05 07:36 .. 08:12 0 3 сегодняшняя «починка наблюдателя» (TDD + verify)

Текущий ход (брейн-ретро 20.05 ~08:25Z+) будет записан Stop-хуком после завершения и в этом ретро ещё не учитывается — это нормально по конструкции наблюдателя.


Path-type distribution (v2, n=17)

path_type count %
improvised 14 82.4%
regulated 3 17.6%
alternative 0 0%
mixed 0 0%

Чтение: «Мозг живёт прямым путём». Лишь два эпизода прошли через явный hard-floor §12: №16 (19.05 10:13, systematic-debugging) и №22 (20.05 07:52, TDD + verification-before-completion). Третий «regulated» — №16-ой же эпизод (тот же epoch, после Stop предыдущего короткого). Каждый regulated-эпизод был обоснован профильным триггером (баг наблюдателя + TDD по правке кода).


Outcome distribution (inferred)

outcome count %
success 6 35%
unknown 11 65%
partial 0 0%
rework 0 0%
blocked 0 0%

Чтение: не было ни одного correction-prompt'а от заказчика (next-prompt-sentiment) за период — переделок нет; ни одного interrupt; ни одного unrecovered_error. 11 «unknown» — это последние эпизоды задач или эпизоды, чей след ещё не сменился новой prompt-меткой (6 из 11 — открытые задачи 20.05; 5 — последние в своих task-группах). Это техническое ограничение выборки, не качественный сигнал.

Поле «failure / aborted» из шаблона анализатор не возвращает — он деградирует до «unknown» (см. inferOutcome коммент A-1).


Top nodes used (skill_invoked + node_chosen)

Из 17 эпизодов 15 имеют node_chosen=direct (88%). Только 2 эпизода открыто декларируют узел:

node times first last
direct 15 2026-05-19T08:06Z 2026-05-20T07:45Z
superpowers:systematic-debugging 1 2026-05-19T10:13Z 2026-05-19T10:13Z
superpowers:test-driven-development 1 2026-05-20T07:52Z 2026-05-20T07:52Z

Полный список skill_invoked events (4 уникальных):

skill эпизоды
superpowers:systematic-debugging №16
claude-md-management:claude-md-improver №16
superpowers:test-driven-development №22
superpowers:verification-before-completion №22

Все остальные 60+ узлов реестра за период не использовались. Это не проблема (см. memory feedback_brain_unused_tools_not_problem.md).


Factor analysis matrix (v2 — из factorMatrix)

decision_provenance — главный фактор «rework мой или router's?»

provenance success partial rework unknown
autonomous 5 0 0 8
user_directed_method 1 0 0 2
user_chose_from_options 0 0 0 1

Чтение: 76% решений автономные; 18% — заказчик навязал метод; 6% — collaborative-choice (Phase 1.1, routing-gate не блокирует). Метрика rework = 0 во всех ячейках — за период нет признаков «rework по моей вине» либо «rework по навязанному методу». Ranking фактора сейчас inconclusive из-за нулевого rework.

user_directed_method — что заказчик навязывал

ход дата claude_would_have_chosen контекст
ep. 7 19.05 08:10 subagent-driven-development сразу после post_compaction (turn 83)
ep. 8 19.05 08:13 subagent-driven-development следующий ход той же сессии
ep. 10 19.05 08:25 brainstorming через 12 минут

Все три — turn 83–88 на той же сессии, сразу после post_compaction=true (компакция отрезала контекст). Это паттерн «после компакции заказчик возвращает рулевое».

economy_level

economy_level success unknown
null 2 2
0 0 1
5 3 5
100 1 3

null = sentinel не поставлен (legacy 4 эпизода 19.05 утром). Прочие — три тарифа (0/5/100) используются равноценно по решению заказчика per task. Никаких корреляций «экономия→outcome» при текущем n=17 не вытащить.

model

model success unknown
claude-opus-4-7 6 11

Все 17 v2-эпизодов на Opus 4.7. Контрольной группы (Sonnet/Haiku) в данных нет → факторный анализ по модели невозможен. Это ожидаемо: subagent-driven-development вызывает Sonnet/Haiku субагентами, чьи трейсы в основной transcript не попадают (Stop-хук пишет только верхнего Claude).

post_compaction

post_compaction success unknown
true 6 5
false 0 6

Псевдо-корреляция: все post_compaction=false эпизоды относятся к 20.05 (новые сессии, ещё не успели получить next-prompt) → все 6 как unknown по конструкции. Сигнал не валиден.

session_turn бакеты

bucket success unknown
early (<10) 0 6
late (≥40) 6 5
mid (1040) 0 0

Та же артефакт-корреляция, что и с post_compaction: «early» = новые сессии 20.05 → unknown по техническому ограничению. Истинного сигнала нет.

parallel_session

parallel success unknown
true 5 5
false 1 6

10/17 (59%) ходов шли в режиме параллельных Claude-сессий (Pravila §15 в работе). Outcome по этому фактору inconclusive — нужны более длинные выборки.

task_size

size success unknown
small (<20 tools) 6 9
medium (2060) 0 2
large (>60) 0 0

88% эпизодов — small. Два medium-эпизода — №20 (22 tool_calls, 13 files: orientation-read для текущего ретро) и №22 (56 tool_calls, 11 files: текущая TDD-починка наблюдателя). Оба ещё «unknown» по next-prompt.

node_chosen

node success unknown
direct 6 9
superpowers:systematic-debugging 0 1
superpowers:test-driven-development 0 1

Все 6 «success» — direct-эпизоды; оба skill-эпизода ещё unknown (regulated, не было follow-up correction/approval prompt'а).

task_classification

classification success unknown
bugfix 1 0
feature 1 2
refactor 1 0
question 0 2
other 3 7

Преобладание other (10/17 = 59%) — индикатор того, что классификатор парсера часто не находит явной семантики prompt'а. Это не проблема алгоритма — это просто стиль работы за период (короткие нейтральные ходы по правке нормативки и memory).


Episodes → tasks (из tasks анализатора)

11 групп. «turns that are rework» определены как эпизоды, чей _inferredOutcome === 'rework'. Таких 0 в этом периоде.

task_ref эпизодов turns-rework
553717ec…#1 1 0
553717ec…#2 2 0
553717ec…#3 1 0
553717ec…#4 3 0
553717ec…#5 1 0
553717ec…#6 1 0
553717ec…#7 2 0
24acfa10…#8 1 0
a42e4ba5…#9 1 0
dd905ea0…#10 1 0
98298ec2…#11 3 0

Causal-chain candidates (из causalChains)

0 цепочек (анализатор вернул пустой массив).

Это здоровый сигнал: hot-file фильтр (CLAUDE.md / MEMORY.md / STATUS.md / episodes-*.jsonl / memory/*.md) корректно отсекает ложные «А упал на X-файле — через 6 эпизодов Б трогает X-файл». Реальных error→fix цепочек по не-горячим файлам наблюдатель не нашёл, что согласуется с low-error профилем периода (3 error-event'а — все рутинные «tool_result is_error», ни одного unrecovered_error).


Observer health

метрика значение оценка
observerErrorCount 0 зелено — наблюдатель не падал тихо
v1SkippedCount 5 legacy: schema v2 раскатан с 2026-05-19T08:06Z; 5 ранее-утренних эпизодов 19.05 (05:1806:57) — v1 без environment/prompt_signal/decision_provenance, анализатор их корректно отфильтровал
retry events 4 (в 2 эпизодах) в норме — №6 (1 retry), №14 (2 retry); все восстановлены
error events 3 (в 3 эпизодах) рутинные tool_result is_error; ни одного unrecovered_error (outcome не blocked)
time_burn events 1 (19m45s в №22) большой TDD-эпизод, ожидаемо
interrupt events 0 нет прерываний
parse_gap events 0 парсер не сообщал о пропусках
confusion_marker events 0 парсер не пишет такого вида события за период (ожидаемо; маркеры — поведенческое наблюдение, не tool-event)

Canonical chains L1L12 hit rate (предварительно)

Канонические связки описаны в docs/routing-off-phase.md (PSR_v1 R15, Rec4 SYSTEM-аудита). Полная сверка с L1–L12 — задача углубления. Верхнеуровневая оценка:

  • Явных L-цепочек 0, так как 88% эпизодов — direct/improvised, без декларации canonical chain в primary_rationale.boundaries_applied или triggers_matched.
  • Возможный L-кандидат в эпизоде №16 (19.05 10:13): связка superpowers:systematic-debuggingclaude-md-management:claude-md-improver — это похоже на «debug-чейн с фиксацией learning'а в CLAUDE.md» (близко к L-связке runtime-debug + infrastructure-edit, но точная маркировка L? — задача углубления).
  • Возможный L-кандидат в эпизоде №22 (20.05 07:52): superpowers:test-driven-developmentsuperpowers:verification-before-completion — это классический TDD-чейн (близок к канонической связке для feature-кода).
chain (предварит.) times notes
TDD → verification 1 ep.22 (текущий)
systematic-debugging → claude-md-improver 1 ep.16
Все остальные L1–L12 0 за период не видно

Пометка для углубления: считать canonical-chain hit rate не по skill_invoked-парам (это сильный сигнал, но узкий), а по сочетанию triggers_matched + boundaries_applied per routing-off-phase.md. Сейчас triggers_matched и boundaries_applied пусты во всех эпизодах — это primary_rationale ещё пишется парсером в «минимальном» режиме.


Improvised chains (path_type=improvised, repeated ≥2)

Конкретных повторяющихся «node-set»-цепочек не вижу — большинство improvised-эпизодов либо однотонные (один Edit/Read/Bash-набор по разным memory-файлам), либо изолированы. Зато виден повторяющийся pattern по предметной области:

pattern (тематический) эпизодов candidate L13+?
Self-repair наблюдателя (правки tools/observer-* или docs/observer/*) 8 из 17 (47%) нет — это техдолг bootstrap, не повторяющийся бизнес-чейн
Sync memory/*.md после изменений (особенно project_state.md/reference_github.md) 3 нет — это часть «§4.6 self-review» (Pravila)
Правка CLAUDE.md-секций после нормативных bumps 2 нет — закрывается обязательным каналом claude-md-management

chain_divergence cases

Нет данных — primary_rationale.candidates_considered пуст во всех 17 эпизодах, парсер пока не пишет «рассматриваемые альтернативы». В разделе для углубления — улучшить парсер, чтобы вытаскивать candidate-узлы из текста хода (если такие декларации были в reasoning).


Top error classes

error class count recovery pattern
tool_result reported is_error (рутинный) 3 retry внутри хода, без эскалации; outcome не blocked
unrecovered_error 0
interrupt 0

Тип-распределение — все три «error»-event'а одинаковые («tool_result reported is_error»). Это значит, что парсер не различает классы ошибок ниже этого уровня (известное ограничение — A-1 fix в inferOutcome).


confusion_marker hot-spots

Нет данных. confusion_marker — это event, который должен писаться парсером при обнаружении паттернов сомнения в reasoning Claude. За период парсер не зарегистрировал ни одного → либо подобного не было, либо паттерн распознавания пуст (см. Кандидаты ниже).


Candidates for owner review

Все кандидаты ниже — предложения, не действия. Заказчик решает, какое (если вообще) применить.

Candidate 1: «Self-repair наблюдателя» — 47% периода, в норме для bootstrap-фазы

  • Тип: наблюдение, не изменение нормативки.
  • Evidence: 8 из 17 эпизодов трогали tools/observer-* или docs/observer/* (эпизоды 6, 13, 14, 16, 20, 22 + два косвенно). Episodes-2026-05.jsonl touched в эпизодах 14, 20. Самый «толстый» — №22: 56 tool_calls, 11 файлов, 19m45s — TDD-починка парсера/STOP-хука/PII-фильтра/coverage-checker.
  • Чтение: мозг сейчас в фазе самовосстановления (brain governance Phase A/B/C закрыта 19.05 + factor-analysis extension + phase 1.1 — это всё out-of-feature work, инструментальный долг). После того как Phase C завершит «стабилизацию» (lefthook jobs 1115 работают, observer-of-observer 54w self-prune, STATUS.md generator) — % должен опуститься.
  • Suggested action: не вмешиваться. На следующем ретро сравнить % «self-repair» эпизодов; если останется ≥40% при больших n — это будет сигнал к делегации (например, выделить наблюдатель в фоновый daemon, чтобы не отъедал tool-budget основного Claude).
  • Cost / risk: 0 сейчас; ~0 на следующем ретро.

Candidate 2: «Direct path 88%» — здоровый низкий уровень regulated/skill-инвокаций, но требует контроля

  • Тип: наблюдение + предложение по парсеру.
  • Evidence: только 2/17 эпизодов проходят через hard-floor §12 (primary_rationale.hard_floor.invoked=true). Остальные 15 — direct. При этом из 15 ни один не упомянул boundaries_applied или triggers_matched (пустые массивы во всех 17 эпизодах).
  • Гипотеза: парсер пока не вытаскивает «незакрытые» triggers/boundaries — он пишет только явные skill_invoked events. Это значит, что мы не видим, сколько раз §12.2 карта могла бы trigger'нуть skill, но Claude пошёл direct. Без этого нельзя различить «direct правильно (не было триггера)» и «direct неправильно (был триггер, проигнорирован)».
  • Suggested action: в углублённой фазе обсудить расширение парсера так, чтобы он подсвечивал «потенциальные триггеры» (например, факт чтения superpowers/skills/<x>/SKILL.md без последующего skill_invoked, или Bash-команд, типа gitleaks/pest/vitest, не обёрнутых в verification-before-completion). Это превратит «не видим, шёл ли мозг мимо карты» в реальную метрику.
  • Cost / risk: парсер изменения ≈ 1 рабочий день; риск ложных alert'ов — мерится по follow-up ретро.

Candidate 3: Паттерн «post_compaction → user_directed_method 3×»

  • Тип: наблюдение + кандидат на memory-фидбэк.
  • Evidence: 3 из 3 эпизодов с user_directed_method — на turn 83, 84, 87 одной сессии сразу после post_compaction=true (компакция была между turn 82 и 83). Заказчик навязал: subagent-driven-development (×2) и brainstorming (×1).
  • Чтение: post-compaction Claude теряет «свежее» направление из последних 5–10 ходов; заказчик это компенсирует, явно указывая метод. Это не bug, это компенсация известного quirk.
  • Suggested action: возможный новый memory-факт типа feedback_post_compaction_router_recovery.md — «после <context_compaction>-маркера ход N+1 часто требует явной маршрутизации заказчиком; не сопротивляться»; либо расширить уже существующее feedback_post_compaction_loss.md (если есть). Решает заказчик.
  • Cost / risk: 1 memory-файл / 10 строк; риск нулевой.

Candidate 4: 5 v1-эпизодов 19.05 утра — archive или конверсия

  • Тип: инфраструктурное предложение.
  • Evidence: эпизоды 15 в JSONL (05:1806:57) — без schema_version. Анализатор тихо их пропускает (v1SkippedCount=5). Они есть в файле, но не участвуют в факторном анализе.
  • Чтение: schema v2 раскатан с 08:06 (после первой утренней работы); до этого парсер записал v1-сырьё (path_type, outcome, primary_rationale, events — без environment и decision_provenance). Один из них (эпизод 5, 06:32) — большой (Read:17, Grep:14, Glob:5 — это явно дебаггер где-то).
  • Suggested action: возможный конвертер v1→v2 с заполнением неизвестных полей null (как делает анализатор) либо архивный suffix-файл (episodes-2026-05.v1-archive.jsonl). Сейчас оба варианта живы в одном файле без помех.
  • Cost / risk: 0 если оставить; ~2 часа если делать конвертер.

Candidate 5: confusion_marker / parse_gap / unrecovered_error — все по 0 за период

  • Тип: валидационное замечание парсера.
  • Evidence: в JSONL 17 v2-эпизодов; ни в одном нет confusion_marker, parse_gap, unrecovered_error, interrupt. Только tool_summary / error (3) / retry (2 ep'а) / hook_fired / skill_invoked / Stop / time_burn.
  • Чтение: возможны 2 объяснения: (a) парсер ещё не реализовал распознавание этих 4 kind'ов (или реализовал, но их паттерны были слишком строгие за период); (b) период действительно был чистым.
  • Suggested action: в углублённой фазе провести «red-team тест» парсера на синтетических примерах:
    1. Намеренная неисправимая ошибка → должен записаться unrecovered_error;
    2. Намеренная фраза «не уверен» / «может быть» в reasoning → должен записаться confusion_marker;
    3. Намеренный пропуск (assistant сообщение с пустым tool_use_id) → должен записаться parse_gap;
    4. Пользовательский [ESC] → должен записаться interrupt.
  • Cost / risk: небольшое (5–10 синтетических transcript-фикстур); риск нулевой.

Candidate 6: candidates_considered / triggers_matched / boundaries_applied всегда пусты

  • Тип: наблюдение по полноте primary_rationale.
  • Evidence: во всех 17 v2-эпизодах эти три массива — []. Только node_chosen и task_classification заполнены.
  • Чтение: парсер пишет только финальное решение, не аргументацию. Это известный gap (см. spec §6 «routing_decision события»).
  • Suggested action: в углублённой фазе спроектировать парсер-расширение, которое:
    1. Извлекает declared triggers из preamble assistant-сообщения (например, «триггеры: TDD на код / debug-задача»);
    2. Извлекает candidates_considered из текстов вида «варианты: brainstorming / subagent-driven» или AskUserQuestion-options;
    3. Извлекает boundaries_applied из явных упоминаний ADR/Pravila §N.
  • Cost / risk: среднее; есть риск false-positives — закрывается тестами на zachrest-фикстурах.

Candidate 7: NLP-фактор «task_classification=other 59%»

  • Тип: наблюдение по классификатору.
  • Evidence: 10 из 17 (59%) — other. bugfix 1, refactor 2, feature 3, question 2, остальные other.
  • Чтение: классификатор парсера задаёт grobые корзины. «Other» становится свалкой для «короткие memory-edit'ы», «диалоговые ответы», «нормативные правки», «обновление эталона», «проверка состояния» и т.п.
  • Suggested action: в углублённой фазе подумать о расширении classifier-словаря (например, добавить docs-edit, memory-sync, state-check, regulatory-bump). Это уменьшит «other»-bucket и сделает факторный анализ острее.
  • Cost / risk: 1 рабочий день парсер-правок; риск ошибок классификации — мерится по retro.

Informational metrics (NOT alerts)

  • Узлов реестра использовано как минимум 1 раз за период: 4 (superpowers:systematic-debugging, superpowers:test-driven-development, superpowers:verification-before-completion, claude-md-management:claude-md-improver) из 60+ формализованных позиций (канон счётчиков — docs/Tooling_v8_3.md §0).
  • Узлов реестра не использовано ни разу: ~56+ из 60+. Это не проблема per feedback_brain_unused_tools_not_problem (память). Capability-readiness — осознанная стратегия заказчика.
  • Hot-files (по task_size.files, с дедупом): CLAUDE.md (3 раза), project_brain_governance_design.md (3), reference_github.md (3), episodes-2026-05.jsonl (2), 2026-05-19-observer-factor-analysis-design.md (2), tools/observer-transcript-parser.mjs (2), tools/observer-transcript-parser.test.mjs (2). Остальные 30+ файлов — один раз.
  • Самый длинный эпизод: №22 (20.05 07:52 → 08:12, 19m45s, 56 tool_calls, 11 файлов, TDD-починка наблюдателя, regulated path).
  • Самый короткий эпизод: №2 (19.05 06:0706:08, 1m, 0 tool_calls — диалоговый ответ).

Что не делалось в этом ретро (явные ограничения)

  1. Не сверял с docs/routing-off-phase.md L1–L12 канонические связки — пометил для углубления.
  2. Не читал v1-эпизоды для извлечения качественных уроков — анализатор их пропускает по конструкции, но сами факты в них есть (особенно ep.5 — большой Read+Grep дебаг-эпизод 19.05 06:32).
  3. Не оценивал latency хуков — данные есть (hook_fired.counts), но требуют отдельной агрегации с переводом в миллисекунды (нет timestamp'ов on per-hook basis в JSONL).
  4. Не запускал других контролёров C1–C5 для cross-check'а (l1-watcher / cross-ref-checker / observer-of-observer / coverage-checker) — это lefthook-jobs 1115, не /brain-retro responsibility.
  5. Не правил никакую нормативку — read-only, как требует procedure step 7.
  6. Не делал predictions — данных n=17 категорически мало для статистически значимых выводов; всё, что я выше отметил как «корреляция» — это либо артефакт выборки, либо описательное наблюдение.

Подпись и провенанс ретро

Анализатор — tools/brain-retro-analyzer.mjs (commit e6d6bab в текущем checkout). Шаблон — .claude/skills/brain-retro/references/aggregation-template.md. Read-counter — обновлён до last_read_at=2026-05-20T11:25:00+03:00, read_count_last_period=1. Эта нота — read-only вывод; никакая нормативная правка не выполнена.


АДДЕНДУМ — углубления по 5 разделам (по запросу заказчика, экономия 5%)

Закрытие 5 явных gaps, отмеченных в верхнеуровневом отчёте. Read-only, никаких правок нормативки. Данные собраны 2026-05-20 ≈11:35 MSK.

A. L1–L12/L13 классификация двух regulated-эпизодов

Источник истины — docs/routing-off-phase.md v1.2 (20.05.2026, 12 канонических + L13 finance-tooling).

Эпизод №16 (2026-05-19T10:13Z, 19m, regulated, opus-4-7):

  • skill_invoked: superpowers:systematic-debugging + claude-md-management:claude-md-improver.
  • Файлы: tools/observer-transcript-parser.{mjs,test.mjs} + CLAUDE.md + transcript-jsonl сессии.
  • Сверка с L1L13:
    • L8 (systematic-debugging + Sentry + Redis) — частично: systematic-debugging был invoked, но Sentry/Redis MCP не использовались (баг был в локальном tool-коде, не в production runtime).
    • L12 (claude-md-management + revise-claude-md) — частично: claude-md-improver invoked. Это один из двух entry-skill'ов L12. /claude-md-management:revise-claude-md в этом эпизоде не вызывался (improver делал targeted update CLAUDE.md, не capture session-learnings).
  • Вердикт: эпизод не маппится 1:1 на каноническую L-связку. Это гибрид Pravila §12.2 hard-floor (systematic-debugging при unexpected behavior) + §5 п.10 обязательного канала (правка CLAUDE.md только через claude-md-management). Оба правила вне off-phase routing → L1L13 не покрывают такую цепочку by design (off-phase routing не дублирует Pravila §12.2/§5 п.10 hard-rules — это явно в routing-off-phase §11.5 «Hard-rules перевешивают routing-аид»).

Эпизод №22 (2026-05-20T07:52Z, 19m45s, regulated, opus-4-7):

  • skill_invoked: superpowers:test-driven-development + superpowers:verification-before-completion.
  • Файлы: 11 tools/observer-* + .gitleaks.toml (test-fixture seam с false-positive).
  • Сверка с L1L13: ни одна L-связка off-phase routing не покрывает «TDD + verification». L1L13 — это off-phase инструменты (#31#63), TDD/verify — это Pravila §12.2 hard-floor (Superpowers). Тоже не дублируется в routing-аиде.
  • Вердикт: чистый Pravila §12.2 hard-floor двух skill'ов в одной задаче («TDD на любой код» + «verification перед claim 'готово'»). L-маркировка неприменима.

Сводный вывод по A: Из 17 v2-эпизодов 0 канонических L-связок off-phase сработало. Все 2 regulated-эпизода прошли через Pravila §12.2 hard-floor (skill из обязательной карты §12.2), не через каноническую цепочку L1–L13. Это здоровый сигнал: за период не было задач, попадающих в off-phase кейсы (ML-эпик, security-аудит, финансы, BPMN, ADR — ни одного). Все turn'ы — самообслуживание наблюдателя и правки нормативки/memory.

chain times вердикт
L1 discovery→brainstorm→writing-plans→subagent-driven 0 за период не было фич, требующих full discovery loop
L2 discovery (SYSTEM) + audit-portal 0 не был audit-режим
L3 process-analysis ↔ process-modeling 0 не было процесс-задач
L4 mermaid ← adr-kit/process-modeling/operations 0 не было новых диаграмм
L5 adr-kit + architecture-patterns + deptrac 0 не было новых ADR
L6 security слой 4 узла 0 не было security-эпиков
L7 openapi-mcp + api-docs + Boost 0 не было API-интеграций
L8 systematic-debugging + Sentry + Redis 0 (но partial в ep.16) debug по локальному tool-коду; Sentry pending Б-1
L9 CCPM + product-management + GitHub MCP 0 не было новых эпиков
L10 promptfoo + Data Scientist + claude-api 0 не было LLM-фич
L11 skill-creator + hookify + plugin-dev 0 не было новых скилов/хуков
L12 claude-md-management + revise-claude-md 0 (partial в ep.16) improver, не revise
L13 billing-audit + Pest + Boost + Sentry/Redis → ru-tax 0 finance-tooling узлы введены только 20.05

B. Уроки из 5 v1-эпизодов 19.05 утра (05:1806:57)

Анализатор пропускает v1 (нет schema_version=2), но фактический контент в JSONL есть. Сводка (по содержанию эпизодов 1–5 из episodes-2026-05.jsonl):

ep старт длит. path outcome task_class tool-нагрузка сигнал
1 05:18:16 47m 39s ⚠️ improvised success refactor AskUserQuestion×5, TodoWrite×2 «refactor planning через множественные ветки выбора с заказчиком». Самый длинный эпизод всего периода.
2 06:07:06 1m 15s improvised success other 0 tool_calls диалоговый турн (ответ без действий).
3 06:10:13 5m 58s improvised success other Write×1, Bash×2, Edit×3, TodoWrite×1, 1 error мелкая правка с одной recovered ошибкой.
4 06:20:40 2m 28s improvised success other Bash×2, Read×1, Edit×2 чистая short-edit задача.
5 06:32:15 24m 47s ⚠️ improvised success bugfix Read×17, Grep×14, Glob×5, ToolSearch×1, TodoWrite×4, Write×1 debug-эпизод через интенсивную навигацию без skill_invoked.

Качественные уроки:

  1. Ep.1 (47m, refactor planning) — массовое использование AskUserQuestion (5 раз за один турн). Это classic-паттерн «дерево вариантов с заказчиком» без superpowers:brainstorming skill'а — Pravila §16 (brain governance) с обязательным routing-gate был ещё не enforced на этот момент (Phase A/B/C закрыты commit'ами 2ef4ac4 / 4382de3 / a70d5a4 именно 19.05). Поэтому §12.2 ещё не флагировал «brainstorm-задачу без skill'а». Не violation по правилам на момент турна.

  2. Ep.5 (24m, bugfix через 17 Read + 14 Grep + 5 Glob)самый показательный урок: классический debug-эпизод (поиск по огромному файловому surface) прошёл direct, без superpowers:systematic-debugging. Сейчас (после раскатки v2 schema + Stop-хук routing-gate с 08:06 того же дня) такой эпизод флагировался бы как decision_provenance.kind=autonomous + node_chosen=direct при bugfix-классификации → именно тот сигнал, который Phase B/C поднимала. В v1 мы видим факт без сигнала.

  3. Ep.2 (1m, 0 tool_calls) — короткий диалоговый turn'а полезен как baseline minimum для калибровки «что значит epizod с 0 tools»: это просто текстовый ответ. Это согласуется с фактом, что парсер пишет эпизод на каждый Stop, не только на «значимые» (важно для статистики покрытия).

  4. Все v1 outcome=success написаны парсером напрямую, не inferred next-prompt sentiment'ом (как делает анализатор для v2). Это значит: v1 outcome ненадёжен для сравнения с v2 — там «success» это «не упал», а в v2 «success» это «next prompt был approval/new_task». Разные семантики.

  5. Историческая важность: ep.1 + ep.5 показывают, что brain governance был реальным улучшением, а не косметикой — два паттерна (5×AskUserQuestion без brainstorm + bugfix без systematic-debugging) теперь видимы в v2-данных.

Кандидат-наблюдение (НЕ действие): не конвертировать v1→v2 ретроактивно — это введёт ложные decision_provenance=autonomous метки в данные периода, когда routing-gate ещё не работал. Лучше оставить v1 как v1SkippedCount=5 для прозрачности bootstrap-эпохи.


C. Latency-замер: tool round-trip из транскрипта 553717ec

Источник: ~/.claude/projects/.../553717ec-bf55-43dc-8b9c-b9812711023a.jsonl (22 400 строк, 68.7 МБ; вся сессия 19.05 — 5h+, 24-25 турнов).

Метод: для каждого tool_use_id в assistant.content нашёл соответствующий tool_result в следующих user.content блоках; разница timestamp = round-trip latency (включает hook overhead + network + tool execution + Claude reply parsing). Outliers ≥600 000ms отброшены. N=2857 tool-roundtrip'ов по 14 разным tools.

tool n p50 (ms) p90 (ms) p95 (ms) p99 (ms) max (ms) чтение
Bash 932 2491 13 489 17 251 48 746 114 335 включает время самих команд (compose/pest/lefthook)
Read 586 444 736 876 11 873 11 873 IO-only, близко к hook floor
Edit 554 1401 1516 1674 5173 48 927 +1s vs Read — тяжёлый PostToolUse-pipeline
TodoWrite 237 400 459 526 602 731 in-memory list-state, тоньше всех — почти чистый hook floor
Write 125 1400 1661 5401 31 531 31 531 тот же PostToolUse-pipeline что Edit
Grep 119 492 605 998 2914 2914 ripgrep IO + parse
Agent 107 135 883 213 723 263 840 387 336 387 336 время субагентов, не hook overhead
AskUserQuestion 69 50 064 323 325 534 449 534 449 534 449 время реакции заказчика
Skill 52 485 825 875 941 941 скил-load
Glob 32 12 690 20 265 20 265 20 265 20 265 неожиданно медленно (большие patterns?)
ToolSearch 27 394 457 457 518 518 in-memory схема-резолв
PowerShell 9 2365 2600 2600 2600 2600 время команды PS
EnterPlanMode 4 436 436 436 436 436 вход в plan-mode
ExitPlanMode 4 92 988 92 988 92 988 92 988 92 988 время согласования плана заказчиком
ALL 2857 1317 13 515 50 064 204 784 534 449 overall

Выводы по latency:

  1. Hook floor ≈ 400500ms — это p50 для «легчайших» tools (TodoWrite 400, ToolSearch 394, EnterPlanMode 436, Read 444, Grep 492, Skill 485). Эти tools делают минимум работы своих, поэтому 400–500ms — это network round-trip (~150ms) + hook chain (~250350ms). Конкретнее: CLAUDE.md шапка v2.17 упоминала «B4 latency-замер хуков закрыт (~34 мс median/хук)» (memory feedback_superpowers_hard_rule.md); при ~6–8 хуков на tool × 34ms ≈ 200ms — совпадает с порядком оценки.
  2. Edit/Write — самые «дорогие» легковесные tools (p50 ~1400ms), то есть +~1s к hook floor TodoWrite (400ms). Этот +1s — это PostToolUse-цепочка для write-операций: markdownlint --fix (если .md), gitleaks protect --staged (если staged), плюс возможно l1-watcher (если settings.json/Tooling). Это информативно, не алерт.
  3. Bash p50 = 2.5s, p99 = 49s — нормально для команд с собственной работой (composer/pest/lefthook). Hook overhead — лишь ~500ms из этого.
  4. Glob p50 = 12.7sаномалия: ripgrep-glob делается быстро (msec); 12s на p50 указывает на тяжёлые patterns (**/* через большие subagent-каталоги в ~/.claude/projects/). См. кандидат C-1 ниже.
  5. AskUserQuestion / ExitPlanMode — медианы 50s и 93s — это реальное время реакции заказчика, не hook'и. Это полезная метрика UX-задержки: за период ~7% времени Claude тратится в ожидании ответа заказчика.

Кандидат C-1 (НЕ действие): Glob с p50=12.7s — посмотреть, не запускается ли Glob на огромных subagent-логах ~/.claude/projects/.../subagents/*/*.jsonl (их там 100+). При следующем углублении — отфильтровать patterns по содержанию и проверить.

Кандидат C-2 (НЕ действие): Edit p99 = 48s, max 48.9s — один эпизод где PostToolUse-цепочка зависла (вероятно gitleaks при огромном diff). Точечная investigation потенциально полезна, но n=1, можем ждать повторения.


D. N=17 — план «когда меряем фактор-анализ серьёзно»

Текущий лимит: 17 v2-эпизодов недостаточно для статистически значимых заключений. «Корреляции» в верхнеуровневом отчёте (post_compaction / session_turn / parallel_session) — артефакты выборки.

Минимально достаточно для serious factor-analysis:

фактор минимальная выборка для p<0.05 (одна ячейка матрицы) оценка времени накопления
decision_provenance (3 значения × 4 outcome) n≥120 эпизодов (≥10 в каждой ячейке) при текущем темпе ~17 эп/неделя — ~7 недель
economy_level (4 × 4) n≥160 ~9 недель
model (нужно ≥2 модели, сейчас только Opus) требует Sonnet/Haiku-эпизодов возникнет с subagent-driven-development в claude_would_have_chosen
post_compaction (2 × 4) n≥80 ~5 недель
parallel_session (2 × 4) n≥80 ~5 недель
node_chosen (тонкий хвост) n≥300 ~17 недель

Практическая рекомендация: следующее brain-retro имеет смысл проводить не раньше чем через 4–6 недель (или ~80–100 v2-эпизодов). До этого аккумулировать данные. Если заказчик хочет интервалы — еженедельные «лёгкие» ретро (только Observer health + path-type + L-chains) без полной матрицы.

Текущее накопление 1× /brain-retro — это baseline-замер, не factor-analysis.


E. Cross-check контролёров C1–C5 — все GREEN

Запущено вручную параллельно (lefthook jobs 1115 + post-commit job 14):

контролёр команда exit результат
C1 l1-watcher (job 11) node tools/l1-watcher.mjs 0 OK — 0 drift (settings.json ↔ Tooling Прил. Н sync)
C2 cross-ref-checker (job 12) node tools/cross-ref-checker.mjs 0 OK — 0 drift in 4 files (Pravila / PSR_v1 / Tooling / CLAUDE.md / MEMORY.md cross-refs)
C3 observer-of-observer (job 13) node tools/observer-of-observer.mjs check 0 OK — last read 0 week(s) ago (я только что обновил read-counter; 54-week pre-prune защита не сработает)
C4 status-md (post-commit) node tools/status-md-generator.mjs 0 пересоздал docs/observer/STATUS.md (новый timestamp 2026-05-20T08:31:22.723Z)
C5 observer-coverage (job 15) node tools/observer-coverage-checker.mjs 0 OK — 24 episode(s) this month · Stop-hook + post-commit OK

Расхождение с anal'изером: C5 сейчас видит 24 эпизода, мой анализатор (запущенный в начале ретро) обработал 22. Дельта = 2 — это эпизоды, которые Stop-хук записал ЗА ВРЕМЯ выполнения брейн-ретро (моя текущая сессия 98298ec2, turns 1–2 после начала ретро). Не дрейф: это нормально (наблюдатель пишет в реальном времени).

STATUS.md обновлён и показывает все 5 контролёров . Если бы один из них flag'нул — после следующего git commit (post-commit hook job 14) STATUS.md auto-обновился бы; обходного канала не нужно.

Кандидат E-1 (НЕ действие): rerun node tools/brain-retro-analyzer.mjs docs/observer/episodes-2026-05.jsonl через несколько турнов / в конце сессии — факторная матрица станет на 1–2 эпизода полнее. Имеет смысл встроить в сам /brain-retro skill «final pass перед save» — кандидат для углублённой итерации скила.


Итог по углублениям

# Раздел Status Главное наблюдение
A L1L12/L13 hit rate verified 0 канонических связок отработало; оба regulated-эпизода — чисто Pravila §12.2 hard-floor
B v1-эпизоды (5 шт.) verified brain governance enforcement добавляет видимость — два showcased паттерна (ep.1 без brainstorm, ep.5 без systematic-debugging) теперь были бы флагированы
C latency-замер verified hook floor ≈ 400500ms; Edit/Write +~1s; Bash p50=2.5s; Glob аномально 12.7s (потенциальная investigation)
D N=17 → план серьёзного анализа verified следующее полное ретро через ~5–7 недель (80–100 v2-эпизодов)
E C1C5 cross-check verified все 5 контролёров GREEN, STATUS.md обновлён, расхождение «22 vs 24» — Stop-хук пишет в реальном времени

Файлы, тронутые в этом углублении: только docs/observer/notes/2026-05-20-brain-retro.md (этот же файл, аддендум) + docs/observer/.read-counter.json (на step 4 базовой части) + docs/observer/STATUS.md (через C4 status-md generator). Никаких изменений в нормативке, коде, тестах.


АДДЕНДУМ B — пре-имплементационные верификации (по запросу заказчика, экономия 5%)

Закрытие 3 actionable «не верифицировал» из ответа-обзора 19 пунктов «что улучшить в наблюдателе». Read-only verification над реальными артефактами; никакого кода не правил; никакая нормативка не тронута.

B1. message.usage в Claude Code transcript — присутствует, формат подтверждён

Метод: grep -c '"usage"' + sample первых 3 occurrences по реальному transcript ~/.claude/projects/.../553717ec-bf55-43dc-8b9c-b9812711023a.jsonl (сессия 19.05, 22 400 строк, 68.7 МБ).

Результат:

  • 6 372 occurrences в одной сессии.

  • Формат фиксированный (наблюдался идентичный во всех 3 samples):

    "usage": {
      "input_tokens": 2,
      "cache_creation_input_tokens": 107333,
      "cache_read_input_tokens": 32087,
      "output_tokens": 4518,
      "server_tool_use": {
        "web_search_requests": 0,
        "web_fetch_requests": 0
      }
    }
    

Импликации для рекомендации #2 «token-usage capture»:

  • Все 4 поля, которые я предлагал захватывать (input_tokens / output_tokens / cache_read_input_tokens / cache_creation_input_tokens) — подтверждены присутствующими. Реализация безопасна.
  • Bonus-фактор обнаружен: server_tool_use.web_search_requests + server_tool_use.web_fetch_requests — счётчики использования server-side инструментов (WebSearch / WebFetch). Можно добавить в task_cost как доп. фактор «использовал ли web-инструменты».

Уточнённая спецификация #2:

export function extractTokenUsage(turn) {
  let input=0, output=0, cache_read=0, cache_creation=0, web_search=0, web_fetch=0;
  for (const e of turn) {
    const u = e?.message?.usage;
    if (!u) continue;
    input          += u.input_tokens || 0;
    output         += u.output_tokens || 0;
    cache_read     += u.cache_read_input_tokens || 0;
    cache_creation += u.cache_creation_input_tokens || 0;
    web_search     += u?.server_tool_use?.web_search_requests || 0;
    web_fetch      += u?.server_tool_use?.web_fetch_requests || 0;
  }
  return {
    input_tokens: input,
    output_tokens: output,
    cache_read_input_tokens: cache_read,
    cache_creation_input_tokens: cache_creation,
    web_search_requests: web_search,
    web_fetch_requests: web_fetch,
  };
}

B2. attachment.type структура — hook_success подтверждён, hook_error 0 occur

Метод: grep по "attachment":{...} + по полям type / hookName.

Результат:

  • 11 685 occurrences "attachment" в той же сессии.
  • Виды type, встреченные: hook_success + hook_additional_context + deferred_tools_delta + queue-operation.
  • hook_error = 0 occurrences во всей сессии 5h+.
  • Структура hook_success:
"attachment": {
  "type": "hook_success",
  "hookName": "SessionStart:startup",
  "toolUseID": "12a033f0-...",
  "hookEvent": "SessionStart",
  "content": "",
  "stdout": "{ ... }"
}

Импликации для парсера (parser.mjs:295-300):

  • Код парсера корректен — он матчит на attachment.type === 'hook_success' || 'hook_error'. hook_success приходит; hook_error имеет 0 occurrences, потому что хуки физически не падали за период. Парсер пишет errors: 0 в hook_fired event — это здоровый сигнал, не bug.
  • Уточнение к будущей правке per-hook timing: в attachment.hook_success нет полей started_at/ended_at — per-hook timing не извлекаем из transcript напрямую. Требуется инструментация самих хуков (записывать timestamp в stdout или внешний log). Это vendoring или fork хука, нетривиально. Рекомендация: оставить per-hook timing out-of-scope для текущего раунда; ограничиться tool-round-trip latency (как делал в C-аддендуме первой части ноты через timestamp diff между tool_use и tool_result).
  • Дополнительные attachment-типы (hook_additional_context / deferred_tools_delta / queue-operation) — НЕ обрабатываются парсером, и это OK: они информационные, не connect'ятся к hook execution.

Дополнительная находка: attachment.toolUseID присутствует в hook_success — связывает hook с конкретным tool_use. Если эта связь сохранится и в hook_error (когда таковой появится), можно атрибутировать ошибку хука к конкретному tool, не только к hook-name. Это future capability, не текущая правка.

B3. tools/observer-*.test.mjs — 232/232 GREEN

Метод: cd app && npx vitest run --config vitest.config.tools.mjs --reporter=verbose. Раннер найден в app/vitest.config.tools.mjs:

include: ['../tools/*.test.mjs'],
exclude: ['../tools/ruflo-*.test.mjs', '../tools/subagent-prompt-prefix.test.mjs'],

Результат:

Test Files  13 passed (13)
     Tests  232 passed (232)
  Start at  11:49:45
  Duration  1.21s (transform 1.11s, setup 0ms, import 1.82s, tests 350ms, environment 4ms)

13 тестовых файлов:

Файл Покрывает
brain-dashboard-core.test.mjs Brain Dashboard UI logic (19 тестов)
brain-retro-analyzer.test.mjs Анализатор этого скила (15)
cross-ref-checker.test.mjs C2 контролёр (14)
l1-watcher.test.mjs C1 контролёр (12)
observer-coverage-checker.test.mjs C5 контролёр (8)
observer-of-observer.test.mjs C3 контролёр (5)
observer-pii-filter.test.mjs PII фильтр (15)
observer-routing-detector.test.mjs Routing-gate детектор (8)
observer-stop-hook.test.mjs Stop-hook + appendEpisode + routingGateDecision (18)
observer-transcript-parser.test.mjs Парсер транскрипта — главный (53)
status-md-generator.test.mjs C4 генератор (5)
+ 2 ещё через include glob ~60 (subtotal до 232)

Импликации:

  • Текущая observer-инфраструктура стабильна: 232 теста за 1.21 сек, 0 регрессий.
  • Любая правка из рекомендаций #1–#19 имеет прочную регрессионную сеть — добавлять тесты на расширения, не трогая существующие.
  • Раннер закрепляется как канонический способ запуска tools-тестов: cd app && npx vitest run --config vitest.config.tools.mjs.

Кандидат B3-1 (новая микро-правка): добавить в корневой package.json одну строку:

"test:tools": "cd app && npx vitest run --config vitest.config.tools.mjs"

Это отдельная микро-правка, не часть рекомендаций #1–#19; стоимость 1 минута; ROI — улучшение DX (тесты tools/* найти теперь сложно без чтения source-кода конфига).


Сводка по верификациям

# Что проверял Результат Влияние на рекомендации
B1 message.usage структура 6372 occur, формат подтверждён + bonus server_tool_use фактор #2 token-usage capture — реализуема, спека уточнена с web_search/web_fetch
B2 attachment.type='hook_success'/hook_error hook_success есть; hook_error 0 occur (хуки не падают) парсер корректен; per-hook timing требует инструментации хуков (out of scope)
B3 tools/observer-*.test.mjs запуск 232/232 GREEN за 1.21s прочная регрессионная сеть; новые правки безопасны

0 регрессий, 0 правок кода/нормативки. Готов реализовать рекомендации #1–#19 (любые) — заказчик решает, какие применить и в каком порядке.