# brain-retro #7 — 2026-05-27 03:55 UTC

**Период:** 2026-05-26 16:23 UTC (после retro #6) → 2026-05-27 03:53 UTC (≈11.5 ч).
**Эпизодов:** 23 (после dedupe + observer-errors filter; observerErrors=0).
**Задач (грouping):** 9.
**Reviewer:** batch mode (23 ≥ 20), Opus 4.7 / ProxyAPI, 23/23 reviewed, 0 errors, wall-clock 55.6с.

---

## 1. Семь обязательных цифровых срезов

### [1] Path-type breakdown

| path_type | count | % |
|---|---:|---:|
| improvised | 22 | 95.7% |
| regulated | 1 | 4.3% |

22 эпизода из 23 — improvised (никаких boundaries_applied, никаких skill_invoked).
Это **выше нормы** для retro #6 (там было ≈85% improvised). Сигнал: 11.5 часов почти без вызова навыков.

### [2] node_chosen distribution

| node_chosen | count | % |
|---|---:|---:|
| direct | 21 | 91.3% |
| superpowers:finishing-a-development-branch | 1 | 4.3% |
| subagent-driven-development | 1 | 4.3% |

Из 23 turns только 2 использовали навык. Один из них (`subagent-driven-development` на ambiguous «ставь в пендинг») reviewer пометил как **wrong_node** — навык вызван не по адресу.

### [3] recommended_node distribution

| recommended_node | count | % |
|---|---:|---:|
| NULL | 21 | 91.3% |
| #25 (Semgrep) | 2 | 8.7% |

Классификатор почти ничего не рекомендовал — большинство turns короткие или conversation-типа. 2 раза рекомендовал #25 Semgrep (security/analysis-задачи) — оба раза проигнорировано.

### [4] GAP «рекомендован но выбран direct»

| recommended | chosen | count | rework rate этого подмножества |
|---|---|---:|---:|
| #25 | direct | 2 | 0% (оба soft_success после review) |

Маленькая выборка — 2 эпизода, оба ушли в soft_success. Игнор рекомендации Semgrep не вызвал rework на этом окне.

### [5] outcome × node_chosen group

| группа | total | success | soft_success | rework | blocked | rework_rate |
|---|---:|---:|---:|---:|---:|---:|
| **skill_used** | 2 | 0 | 1 | 0 | 1 | 50% |
| **direct_no_rec** | 19 | 6 | 6 | 4 | 3 | 36.8% |
| **direct_ignored_rec** | 2 | 0 | 2 | 0 | 0 | 0% |

Главный пул — direct_no_rec (19 эпизодов): **rework+blocked = 7/19 = 36.8%**. Это плохо.
skill_used = 2 эпизода, оба problematic (1 blocked — wrong_node `subagent-driven-development`).

### [6] classifier_output presence by source

| source | count | % |
|---|---:|---:|
| prefilter | 9 | 39.1% |
| llm | 8 | 34.8% |
| regex | 3 | 13.0% |
| cache | 1 | 4.3% |
| NULL | 2 | 8.7% |

Классификатор **здоров** — NULL = 8.7% << 30% порога. Distribution разумный (prefilter+regex = быстрые пути 52%, llm для сложных 35%). На retro #6 был сломан (NULL >> 30%), теперь починен.

### [7] Per-classification trigger-match + via-skill

| classification | total | via_skill | via_skill_rate |
|---|---:|---:|---:|
| conversation | 9 | 0 | 0% |
| ambiguous | 4 | 0 | 0% |
| no_skill_found | 3 | 1 | 33% (wrong-node) |
| analysis | 2 | 0 | 0% |
| skill | 1 | 0 | 0% |
| chain | 1 | 0 | 0% |
| release | 1 | 1 | 100% |
| other | 1 | 0 | 0% |
| unknown | 1 | 0 | 0% |

Conversation 9/23 — здесь direct ок (это болтовня).
Ambiguous 4/23 + no_skill_found 3/23 — здесь должна была быть **clarification request**, а не direct-attempt (см. кандидаты ниже).
chain 1/23 — единственный кейс «chain», ушёл в direct → reviewer flag `wrong_chain_order`.

---

## 2. Reviewer-агент: распределение качества

### node_quality

| judgment | count | % |
|---|---:|---:|
| disputable | 12 | 52.2% |
| correct | 9 | 39.1% |
| wrong_node | 2 | 8.7% |

### error_root_cause

| cause | count |
|---|---:|
| n/a (без ошибок) | 13 |
| wrong_skill | **5** |
| external_failure | 4 |
| wrong_chain_order | 1 |

### agent_self_assessment_accuracy

| status | count |
|---|---:|
| no_self_assessment | 18 (78%) |
| accurate | 5 |
| inaccurate | 0 |

**Покрытие self_assessment 22% — критически низкое.** На retro #6 покрытие было выше; что-то его сломало (вероятно — hook order правлен 26.05 в `9b7de8bf`).

### Alternative-better suggestions reviewer'а

| recommended_alt | count | контекст |
|---|---:|---|
| #25 Semgrep | 2 | анализ кода |
| #8 gitleaks | 1 | перед push |
| #3 GitHub MCP | 1 | «пуш и обнови пилот» (NLU gap) |
| claude-md-management | 1 | «обнови мозг/пуш» |

---

## 3. Outcome-распределение (после review)

| outcome_reviewed | count | % |
|---|---:|---:|
| soft_success | 9 | 39% |
| success | 6 | 26% |
| rework | 4 | 17% |
| blocked | 4 | 17% |

**Проблемная доля 8/23 = 35%** (rework+blocked). На retro #6 эта доля была ≈30%; небольшой рост.

`degradedCount = 2` (классификатор был в degraded-режиме в 2 turns — нормально на старте сессии).

---

## 4. Каузальные цепочки (от → к, общие файлы)

4 цепочки выявлены автоматически:

1. `269ae4d0 → 1b0f3090` — общий `settings.json` (кросс-сессионный — настройки router-gate перетряхнули, затем восстановили).
2. `1b0f3090 → 1b0f3090` ×3 — длинная задача внутри одной сессии 1b0f3090 (5 episodes), общий `router-state-1b0f3090.json` через все 4 turns.

Сессия `1b0f3090` — самая длинная задача периода (5 эпизодов из 7 в task ref #3+#4). Один из 5 turns — blocked (recovery «обнови мозг/пуш», 15 tool calls, 81k output tokens — reviewer пометил `mistake_should_not_start`).

---

## 5. Reviewer-narrative — 8 problematic episodes (детально)

| # | task | cls | outcome | reviewer error_root_cause | reviewer alt |
|---|---|---|---|---|---|
| 1 | 135a4adf | conversation | rework | external_failure (hook errors) | n/a |
| 2 | 267fd4dc | chain | rework | wrong_chain_order | #8→#3 chain skipped |
| 3 | 1b0f3090 | ambiguous | blocked | n/a (correct: ask user) | n/a |
| 4 | 267fd4dc | conversation | rework | external_failure | n/a |
| 5 | b82510c7 | ambiguous | rework | **wrong_skill** | #3 GitHub MCP («пуш и обнови пилот») |
| 6 | b82510c7 | no_skill_found | blocked | n/a (correct: ask user) | n/a |
| 7 | 269ae4d0 | ambiguous | blocked | **wrong_skill** | claude-md-management («обнови мозг/пуш» — 15 tool calls вместо clarification) |
| 8 | b11f6b8d | no_skill_found | blocked | **wrong_skill** | (ask user, not subagent-driven-development) |

**Главный паттерн:** на ambiguous/short prompts agent **не просит уточнения**, а пытается угадать. В 3 из 4 ambiguous/no_skill_found эпизодов это привело к ошибке.

---

## 6. Sanity-check (ответы заказчика)

| вопрос | ответ |
|---|---|
| Были моменты, когда я выбрал direct, хотя нужен был навык? | **«Да, часто»** |
| Качество за период (5 blocked + 2 degraded из 23)? | **«Плохо — очевидные сбои»** |
| Что наблюдатель должен был засечь, но не засёк? | «Вроде нет» |

**Меta-расхождение:** заказчик сказал «наблюдатель ничего не пропустил», но reviewer нашёл 5 wrong_skill cases. → Наблюдатель **засёк**, заказчик не знал. Заявка на улучшенный surface STATUS.md (см. кандидаты).

Файл ответов: [docs/observer/sanity-checks/2026-05-27.json](../sanity-checks/2026-05-27.json).

---

## 7. Self-retrospect trigger

`docs/observer/.self-retrospect-counter.json`: `episodes_since_last = 542` (был 519, +23 за период). Порог 50 **превышен на порядок** — рекомендую запустить `/self-retrospect` при первом удобном моменте.

---

## 8. Cost report

`~/.claude/runtime/cost-daily.json` — **отсутствует** (cost tracking не активирован per-call). Из analyzer.costTotals:

| метрика | tokens |
|---|---:|
| classifier_input | 220 |
| classifier_output | 4 431 |
| self_assessment_input | 0 (покрытие 22%) |
| self_assessment_output | 0 |
| reviewer_input | 0 (batch-reviewer не пишет в costTotals) |
| reviewer_output | 0 |

Reviewer batch off-stream cost — ≈$1.50 (23 эпизода × Opus 4.7 ≈ avg 1.5к in / 0.4к out per call).

---

## 9. Candidates for owner review

> ⚠️ Это **кандидаты**, не действия. Заказчик решает что применить.

### C1 — NLU gap: транслит-сленг → не маппится в правильный навык

**Сигнал:** «пуш и обнови пилот» → recommended_node = NULL → direct (15 tool calls, rework). Reviewer: правильно было #3 GitHub MCP. Аналогично — «обнови мозг/пуш» (claude-md-management не вызван).

**Rationale:** classifier хорошо парсит формальные слова («deploy», «push»), но плохо — русский транслит-сленг («пуш», «пилот», «мозг», «эталон»). Между тем `ПИЛОТ.md` / `ЭТАЛОН.md` / `обнови мозг = MEMORY.md` — это формализованные паттерны заказчика (зафиксированы в MEMORY.md recovery draft).

**Suggested action (one of):**

- (A) Расширить prefilter словарь `tools/observer-prefilter.mjs` — добавить mapping «пуш+пилот → #3+deploy», «обнови мозг → claude-md-management», «обнови эталон → file Edit ЭТАЛОН.md», «обнови пилот → file Edit ПИЛОТ.md».
- (B) Добавить в classifier system-prompt список 8-10 known транслит-фраз заказчика.
- (C) Не править ничего — заказчик использует эти фразы редко, частота не оправдает усложнения.

**Rejection-option:** заказчик решает что транслит-NLU не приоритет; держать `cls:` теги в промпте как явный override.

---

### C2 — Ambiguous/short prompts: правило «ask before start»

**Сигнал:** 3 из 4 ambiguous/no_skill_found эпизодов = rework/blocked. Reviewer 2× флаг `mistake_should_not_start`: «обнови мозг/пуш» (15 tool calls вместо clarification) и «ставь в пендинг» (subagent-driven-development вместо clarification).

**Rationale:** при `classifier_output.task_type ∈ {ambiguous, no_skill_found}` AND `prompt_length < 30 chars` AND нет `cls:` тега — почти всегда правильно **спросить**, а не пытаться. Сейчас agent чаще пробует угадать (один раз с 15 tool calls).

**Suggested action (one of):**

- (A) Hook `router-tool-gate` уже блокирует на `no_skill_found` — расширить на `ambiguous + len<30` тоже.
- (B) Skill `clarification-request` (новый, минимальный) — обязательно вызывать на ambiguous/no_skill_found+short.
- (C) Дописать в `~/.claude/CLAUDE.md` правило: «на коротких ambiguous prompts — first action = AskUserQuestion».

**Rejection-option:** заказчик согласен с rework как ценой за скорость на коротких задачах.

---

### C3 — Self-assessment coverage 22% (было выше)

**Сигнал:** 18/23 эпизодов без `self_assessment` (78%). На retro #6 покрытие было выше. Скорее всего сломалось при правке hook order 26.05 (commit `9b7de8bf`).

**Rationale:** без self_assessment reviewer не может оценить «agent_self_assessment_accuracy» → теряем сигнал самооценки.

**Suggested action (one of):**

- (A) Найти что именно изменилось в hook order, восстановить self_assessment trigger.
- (B) Принять снижение покрытия как trade-off за упрощённый hook stack.

**Rejection-option:** заказчик согласен жить без self_assessment до следующего больного эпизода.

---

### C4 — Меta: «вроде нет» от заказчика vs 5 wrong_skill от reviewer

**Сигнал:** заказчик не заметил wrong_skill кейсы, которые reviewer нашёл. STATUS.md не surface'ит «wrong_skill last 24h» — заказчик не видит то, что наблюдатель видит.

**Rationale:** brain governance ADR-011 §16 говорит «evidence-collection, not enforcement», но evidence должен быть видимым.

**Suggested action (one of):**

- (A) `tools/status-md-generator.mjs` — добавить блок «Reviewer findings last 24h» (count wrong_skill / wrong_chain_order / external_failure).
- (B) Опционально — push-notification контроллеру при `wrong_skill ≥ 3 за день`.
- (C) Принять, что заказчик не должен следить за этим — оставить только в /brain-retro.

**Rejection-option:** /brain-retro раз в неделю достаточно.

---

### C5 — Chain #8 (gitleaks) → #3 (GitHub push) skipped

**Сигнал:** classifier рекомендовал chain `#8→#3` (gitleaks верификация → push), agent ушёл direct, chain_quality `missing_step`. Reviewer: «skipping #8 verification before push is risky given pending .gitleaksignore».

**Rationale:** это **повторяющийся** паттерн (см. memory `feedback_gitleaks_cross_branch.md` — pre-push gitleaks уже блокировал push'и из-за cross-branch fingerprint'а; ущерб от пропуска — низкий, но регулярный).

**Suggested action (one of):**

- (A) Hook `enforce-verify-before-push` (есть в `feedback_enforce_verify_before_push.md`) — расширить на gitleaks verify timestamp.
- (B) Добавить в memory entry «при push после правки нормативки/спеков — обязательно `git-leaks --staged` перед push».
- (C) Принять: gitleaks pre-push уже блокирует на сервере, дублирование избыточно.

**Rejection-option:** существующий pre-push gitleaks достаточен.

---

## 10. Что не правится автоматически

Per skill §«Behavioral rule reminders» — этот retro **никакие** правки не вносит. Все 5 кандидатов выше — material for owner decision. Заказчик может выбрать «все», «никакие», «только C1+C3» — любым способом.

---

## 11. Цепочки и связи с предыдущим retro

retro #6 (2026-05-26 16:23) — закрыл проблему «classifier сломан» (NULL > 30%) фиксом G/H/A1/A2/B3/C1/C3. retro #7 подтверждает: NULL = 8.7%, классификатор здоров.

Новые проблемы которые видит retro #7:

- **NLU gap на транслит** — не было в retro #6 (был мёртвый классификатор, NLU маскировался).
- **«ask before start» discipline** — старый паттерн, продолжает.
- **Self-assessment coverage drop** — регрессия от retro #6 (вероятно из-за hook order правки).
- **Reviewer judgments routing_judgment = NULL для всех 23** — мелочь schema-mismatch в reviewer prompt vs анализатор (reviewer использует `node_quality`/`error_root_cause` вместо `routing_judgment`); analyzer ожидает старое поле. Не требует действия — обе версии данных есть.

---

**Подпись:** контроллер Opus 4.7, 1M context, brain-retro skill v3 (subagent + batch hybrid), 2026-05-27 03:55 UTC.
