# Brain-retro #9 — 2026-05-28

**Период:** 2026-05-27 .. 2026-05-28 (с retro #8).
**Эпизоды:** 163 (Wed 143 / Thu 20). **Task-группы:** 71. **Observer errors:** 0.

---

## 0. Контекст

Первый retro после деплоя трёх enforcement-хуков retro #8 follow-up:

- `enforce-classifier-match` (commit `d1d53080`) — threshold 0.7→0.8.
- `enforce-chain-recommendation` (commits `d1d53080` + `3918f355`) — PreToolUse-блок если router дал chain ≥2 и я ни одного не вызвал.
- `enforce-graph-first` (commit `497d410e`) — Stop-блок если ≥3 Grep/Glob без graphify.

Также в период попало: adr-judge redos fix (`1e1457eb`) + brain-retro 7→10 cuts (`b1398883`).

---

## 1. Цифровые срезы (MANDATORY 10)

### Cut 1. Path-type

| path_type   | count | %     |
|-------------|------:|------:|
| improvised  | 154   | 94.5% |
| regulated   |   9   |  5.5% |

Регламент по-прежнему редкий. Это **не плохо** — большинство задач 27.05 были sysop/diagnostics/ретро (см. Cut 7), для которых канона нет.

### Cut 2. `node_chosen` (топ)

| node_chosen                              | count |
|-----------------------------------------|------:|
| direct                                   | 151   |
| superpowers:brainstorming                |   4   |
| subagent-driven-development              |   4   |
| superpowers:systematic-debugging         |   3   |
| superpowers:using-git-worktrees          |   1   |

92% direct. Скилы: brainstorming + subagent-driven + systematic-debugging.

### Cut 3. `recommended_node` (router)

Из эпизодов где router что-то посоветовал (15 из 163, ~9%):

| node | count | назначение |
|------|------:|-----------|
| #37  |   6   | mermaid     |
| #18  |   3   | Pest tests  |
| #3   |   3   | GitHub MCP  |
| #25  |   1   | Semgrep     |
| #11  |   1   | Pint        |
| #36  |   1   | adr-kit     |

### Cut 4. GAP «рекомендован, но direct»

13 missed activations (router рекомендовал → я ушла в direct без скила):

| node | missed | hits |
|------|------:|------|
| #37  |   4   | бо́льшая часть deploy/monitoring/sanity-чтения, mermaid реально не нужен — потенциальный шум маппинга |
| #18  |   3   | bugfix×2 + unknown — действительно стоило взять Pest для adr-judge regex |
| #3   |   3   | deploy×2 + analysis — GitHub MCP вместо ad-hoc `gh` |
| #25  |   1   | analysis |
| #11  |   1   | cleanup |
| #36  |   1   | unknown |

**Rework по этому подмножеству = 0** — пропуски не привели к переделкам.

### Cut 5. Outcome × node_chosen group (3 группы)

| Группа                                | Total | success | soft | blocked | rework | unknown |
|---------------------------------------|------:|--------:|-----:|--------:|-------:|--------:|
| **skill_used** (12)                   |    12 |    2    |   6  |    3    |   0    |   1     |
| **direct, no recommendation** (138)   |   138 |   55    |  68  |   12    |   2    |   1     |
| **direct, recommendation ignored** (13)|   13 |    1    |   2  |    0    |   1    |   9     |

Скилы дают **higher blocked rate** (3/12 = 25% vs 9% у direct без рекомендации). Это **brainstorming + systematic-debugging blocked после ввода ⇒ ожидаемый сигнал «нужно больше входа»**, не патология. Direct-without-rec даёт normal/healthy распределение.

### Cut 6. `classifier_source`

| source              | count | %    |
|---------------------|------:|-----:|
| llm                 |   75  | 46%  |
| prefilter           |   50  | 31%  |
| regex               |   29  | 18%  |
| cache               |    5  |  3%  |
| prefilter_inherited |    5  |  3%  |
| NULL                |    0  |  0%  |

Классификатор здоров: **0 NULL**, LLM срабатывает в 46% случаев (когда prefilter + regex не сходятся). Сравнение с retro #8: тогда было ~12% NULL — фикс classifier-match threshold помог.

### Cut 7. Per-classification breakdown

| classification | count | router rec | I took | within canon | rework |
|----------------|------:|-----------:|-------:|-------------:|-------:|
| other          |  91   |     9      |    6   |       0      |    0   |
| question       |  34   |     5      |    3   |       0      |    0   |
| release        |  14   |     9      |    2   |       0      |    0   |
| monitoring     |   9   |     3      |    0   |       0      |    0   |
| analysis       |   5   |     0      |    0   |       0      |    0   |
| planning       |   4   |     0      |    1   |       0      |    0   |
| bugfix         |   2   |     0      |    0   |       0      |    0   |
| feature        |   2   |     0      |    0   |       0      |    0   |
| cleanup        |   1   |     1      |    0   |       1      |    0   |
| memory-sync    |   1   |     0      |    0   |       0      |    0   |

«Other» = 56%, «question» = 21% — большинство задач периода это обсуждения, sysop-операции и интерактив. Канонические узлы для них действительно отсутствуют (нет смысла регламентировать «ответь на вопрос»).

**bugfix=2 (adr-judge regex fix), router не рекомендовал ничего** — связано с пропуском, который заказчик подсветил в sanity-чеке. Канон для bugfix есть (#19/#18/#34), но router не сработал. Дёрнуть бы Pest (#18) и systematic-debugging — этого не было.

### Cut 8. Class × canon coverage

| classification | count | canon-узлы | router rec | взял | within canon | rework |
|----------------|------:|------------|-----------:|-----:|-------------:|-------:|
| other          |  91   | —          |    9       |   6  |     0        |   0    |
| question       |  34   | —          |    5       |   3  |     0        |   0    |
| release        |  14   | —          |    9       |   2  |     0        |   0    |
| monitoring     |   9   | —          |    3       |   0  |     0        |   0    |
| analysis       |   5   | #25/#39/#53|    0       |   0  |     0        |   0    |
| planning       |   4   | #19/#41/#42|    0       |   1  |     0        |   0    |
| bugfix         |   2   | #19/#18/#34|    0       |   0  |     0        |   0    |
| feature        |   2   | #19        |    0       |   0  |     0        |   0    |
| cleanup        |   1   | #11/#12    |    1       |   0  |     1        |   0    |
| memory-sync    |   1   | —          |    0       |   0  |     0        |   0    |

**Канон-покрытие = 1/163 ≈ 0.6%.** Это сильно ниже здорового уровня. Причина: router рекомендации либо были вне канона (например, #37 mermaid для deploy/monitoring задач — нерелевантно), либо отсутствовали для bugfix/feature/planning/analysis где канон есть. **Router нужно дообучить.**

### Cut 9. Router vs Opus (sample N=30 из 164)

**Секция A — Router посоветовал, Opus не согласен** (2 случая):

| time | task | classification | router → claude | opus verdict |
|------|------|----------------|-----------------|--------------|
| 27.05 01:46 | b11f6b8d | question | #18 → systematic-debugging | wrong_node (нужен был #18) — blocked |
| 27.05 01:48 | b11f6b8d | other | #18 → direct | disputable — soft_success |

**Секция B — Router молчал, Opus говорит «нужен был скил»** (4 случая):

| time | task | classification | opus suggests | outcome | reasoning (sample) |
|------|------|----------------|---------------|---------|---------------------|
| 27.05 01:16 | e3bdbeac | question | operations | soft_success | SSH-access — стоило runbook (#51) |
| 27.05 01:33 | b11f6b8d | other | clarify | **rework** | 10-символьный «сделай сам» — стоило уточнить, ушла в 4 Bash + 15k tokens |
| 27.05 01:35 | 0ade4c82 | planning | discovery-interview | soft_success | «делай план интеграции» → brainstorming + AskUserQuestion (✅ верно) |
| 27.05 02:05 | 3d61dc18 | planning | brainstorming | **rework** | Stop-hook fired 3× — coverage сигнализировал, я игнорила |

**Секция C — Router посоветовал, Opus согласен что skill излишен:** 0 случаев.

**Sample-bias:** reviewer прошёл по 30/164 эпизодам. Reviewed outcomes: 21 soft / 4 success / 3 blocked / 2 rework. Если экстраполировать sectionB rework rate ≈ 2/30 ≈ 7% → 11 потенциальных rework за период. **Это сильный сигнал.**

### Cut 10. Chain-ignore breakdown

| chain length | recommended | ignored | rework |
|-------------:|------------:|--------:|-------:|
| 1 (single)   |     3       |    2    |   0    |
| 2            |     1       |    1    |   0    |
| 3+           |     8       |    7    |   0    |
| **TOTAL**    |    **12**   |  **10** | **0**  |

**Игнор chain-рекомендаций = 83%.** При этом rework=0 — игнор не приводит к переделкам в этом периоде. Но это означает либо (а) chain-рекомендации были нерелевантны → надо чистить маппинг, либо (б) я систематически их обхожу → надо смотреть на enforce-chain-recommendation эффект.

NB: новый хук `enforce-chain-recommendation` залит вечером 27.05 (commit `3918f355`), эпизодов после него **125 hook fires** — но реальные блоки/inline-overrides не подсчитаны (анализатор пока не разбирает hook outcomes).

---

## 2. Outcome distribution (inferred)

| outcome      | count | %    |
|--------------|------:|-----:|
| soft_success |  76   | 47%  |
| success      |  58   | 36%  |
| blocked      |  15   |  9%  |
| unknown      |  11   |  7%  |
| rework       |   3   |  2%  |

Здоровый паттерн. **blocked=15** — большинство это AskUserQuestion (legitimate clarification), не реальные провалы.

---

## 3. Factor analysis matrix (выборочно)

### decision_provenance

| provenance               | success | soft | blocked | rework | unknown |
|--------------------------|--------:|-----:|--------:|-------:|--------:|
| autonomous (138)         |   51    |  62  |   14    |    2   |    9    |
| user_chose_from_options (25)|  7   |  14  |    1    |    1   |    2    |

74% решений автономные / 18% collaborative-выбор / 0% «навязал метод заказчик». **Здоровый расклад.**

### economy_level

| level | count | success | soft | blocked | rework | unknown |
|-------|------:|--------:|-----:|--------:|-------:|--------:|
| 100   | 140   |   55    |  59  |   15    |    2   |    9    |
| null  |  23   |    3    |  17  |    0    |    1   |    2    |

Экономия 100% дала больше blocked (легитимно — AskUserQuestion / hook-блоки), null = чистые vue/spec/long-running без режима.

### session_segment

| segment | count | success | soft | blocked |
|---------|------:|--------:|-----:|--------:|
| early   |   51  |   18    |  27  |    3    |
| mid     |   95  |   32    |  44  |   11    |
| late    |   17  |    8    |   5  |    1    |

**11/95 blocked в mid** — пик плотности hook-блоков в середине сессии (cascading enforce). **На late сегментах падает skill-инициатив** — после длинной сессии я ухожу в direct.

### post_compaction

Все 163 эпизода: `post_compaction=false`. Компакции в период не было.

---

## 4. Hook scripts breakdown (schema v3)

| script | times fired | заметки |
|--------|------------:|---------|
| `inline:e2f5fa75…` | 1991 | inline hooks (universal) |
| `tools/router-tool-gate.mjs` | 1954 | главный gate |
| `tools/enforce-branch-switch.mjs` | 1615 | branch safety |
| `tools/enforce-verify-before-push.mjs` | 1615 | verify gate |
| `tools/enforce-rationalization-audit.mjs` | 1231 | flag-10 audit |
| `tools/enforce-verify-record.mjs` | 1076 | verify-pass writer |
| `inline:62a129f5…` | 339 | inline |
| `tools/enforce-memory-coverage.mjs` | 339 | memory coverage |
| `tools/enforce-tdd-gate.mjs` | 339 | TDD gate |
| `inline:171492…` | 155 | inline |
| `inline:0d75e3df…` | 155 | inline |
| **`tools/enforce-chain-recommendation.mjs`** | **125** | **NEW 27.05** |
| `tools/observer-stop-hook.mjs` | 99 | Stop / per-turn observer |
| `tools/router-stop-gate.mjs` | 99 | Stop / router gate |
| `tools/enforce-coverage-verify.mjs` | 99 | Stop / coverage |
| `tools/enforce-classifier-match.mjs` | 99 | Stop / classifier match |
| **`tools/enforce-graph-first.mjs`** | **5** | **NEW 27.05** |

**Discipline highlights:**

- observer-stop-hook = 99 при 163 эпизодах ⇒ ~64 turn'а без Stop-хука. **Это нормально:** subagent-driven turns + некоторые multi-prompt batches не триггерят Stop. Не дроп.
- enforce-chain-recommendation = 125 fires — хук реально нагружен. Но статистики блоков/override-фраз пока нет.
- enforce-graph-first = 5 fires — низкая активация (Grep/Glob кластеры редкие в этом периоде).

---

## 5. Missed Activations (Pravila §16.4 v1.36)

**Total: 13** (рекомендован → я ушла в direct):

### By node

| Node | Missed | Назначение | Классификации |
|------|-------:|-----------|---------------|
| #37  |   4    | mermaid    | deploy×3, monitoring×1 — нерелевантно, шум маппинга |
| #18  |   3    | Pest tests | bugfix×2, unknown×1 — **легитимный промах для adr-judge fix** |
| #3   |   3    | GitHub MCP | deploy×2, analysis×1 — частично шум, частично легитимный |
| #25  |   1    | Semgrep    | analysis — disputable |
| #11  |   1    | Pint       | cleanup |
| #36  |   1    | adr-kit    | unknown — связано с adr-judge fix |

### By classification

| Classification | Missed | Top рекомендованные |
|----------------|-------:|---------------------|
| deploy         |   3    | #37, #3 |
| monitoring     |   3    | #37 |
| unknown        |   3    | #18, #36 |
| bugfix         |   2    | #18 |
| analysis       |   1    | #25 |
| cleanup        |   1    | #11 |

**Interpretation:**

- #37 mermaid spread across deploy/monitoring = **routing-map noise**, требует чистки `tools/observer-classification-map.json`.
- #18 для bugfix = **легитимный hit** — adr-judge regex fix должна была пройти через Pest TDD.

---

## 6. Канонические цепочки L1–L16

| chain | times | outcome split | заметки |
|-------|------:|---------------|---------|
| L1    |   4   | soft 2 / success 1 / unknown 1 | brainstorming chain |
| L8    |   3   | blocked 2 / soft 1 | security chain — blocked это AskUserQuestion |
| L16   |   4   | soft 2 / success 1 / unknown 1 | новая (?) |
| null  | 152   | success 57 / soft 73 / blocked 13 / rework 3 / unknown 6 | вне канона |

---

## 7. Sanity-check (вход от заказчика)

**Q1: Явный пропуск.** Ответ: **«Исправление adr-judge regex (вечер 27.05)»**.

Что произошло: catastrophic backtracking в `ENFORCEMENT_BLOCK_RE` (nested `(?:.*?\n)*?` + DOTALL) виснет >60s на ADR-011/ADR-016. Я починила декомпозицией regex'а, не вызвав systematic-debugging skill и не написав tests-first (Pest #18). Reviewer-Opus в Section A (запись 27.05 01:46) подтверждает: для этого кейса нужен был именно #18.

**Урок:** на bugfix с blocking hook'ом — TDD цепочка (systematic-debugging → Pest #18 → debugging session) обязательна. Сейчас канон в `observer-classification-map.json` для bugfix есть (#19/#18/#34), но router не сработал — нужно проверить, почему классификатор не дал рекомендацию (видимо «исправь regex» классифицировалось как «other», не «bugfix»).

**Q2: Слепая зона наблюдателя.** Ответ: **«Не видел причину timeouts в adr-judge»**.

Что упустил наблюдатель: висящий python-процесс (PID 6444, 7h+ CPU=25435s) не фиксируется в episodes. Episodes видят только tool_calls в текущей сессии. Системные процессы (background python из прошлой сессии, утечки PM2 daemon'ов, висящие lefthook jobs) — вне scope наблюдателя.

**Кандидат на расширение наблюдателя:** добавить опциональный `system_health` срез — высокие CPU процессы > 1h без owning session, в STATUS.md C5. Но это **не блокирующий gap** — текущий retro #9 это обнаружил через sanity-check, не через автоматику.

---

## 8. Causal-chain candidates

6 цепочек найдено анализатором. Все умеренные (<5 разделённых эпизодов с общим файлом). **Без острых сигналов retry-storm** — отдельной разборки не требуется.

---

## 9. Observer health

- `observerErrorCount` = **0**.
- Stop-hook fires (99) / total episodes (163) = 60.7% coverage. Остальное — turns без Stop (subagent / multi-prompt batches).
- 30/164 reviewed (sample), reviewer 0 errors.

---

## 10. Cost report

`~/.claude/runtime/cost-daily.json` отсутствует. **Data gap** — cost-tracker не пишет файл. Не критично для этого retro, но **candidate** на проверку (см. ниже).

---

## 11. Skill invocations

| skill | count |
|-------|------:|
| superpowers:brainstorming | 4 |
| subagent-driven-development | 4 |
| superpowers:systematic-debugging | 3 |
| superpowers:using-git-worktrees | 1 |
| superpowers:subagent-driven-development | 1 |

13 invocations total (≈ Skill tool calls). 8% от 163 эпизодов.

---

## 12. Tool use (top)

| tool | count |
|------|------:|
| Bash | 413 |
| Read | 99 |
| PowerShell | 92 |
| Edit | 75 |
| TodoWrite | 47 |
| Write | 18 |
| AskUserQuestion | 17 |
| Grep | 16 |
| Agent | 15 |
| Skill | 13 |

Bash доминирует (413) — много sysop/diagnostics в период. Grep=16, Glob=9 — низко, что объясняет `enforce-graph-first` срабатывания (5 раз).

---

## Candidates for owner review

### Candidate 1: Router не рекомендует ничего для bugfix-задач с reduced prompt context

- **Type:** classifier improvement.
- **Evidence:** sanity-кейс «adr-judge regex fix» — задача классифицирована как `other`, не `bugfix`. В period: 2 эпизода `bugfix`, 0 router-рекомендаций.
- **Suggested action:** проверить `tools/router-classifier-llm.mjs` примеры — добавить «исправь / починить regex / fix bug / catastrophic backtracking» к bugfix-классу. Минимум eval-кейс. Не править прямо — открыть spec.
- **Cost / risk:** низкий. Smoke-tests на classifier eval-set перед merge.

### Candidate 2: chain-ignore 83% при rework=0 — нужна оценка эффекта `enforce-chain-recommendation`

- **Type:** hook effectiveness measurement.
- **Evidence:** 12 chain recs, 10 ignored. Хук залит 27.05 вечером (`3918f355`). Из 125 fires нет статистики «блок vs inline-override».
- **Suggested action:** добавить в analyzer `chainHookEffectiveness` — парсить `events[].hook_fired.scripts['tools/enforce-chain-recommendation.mjs']` с разбивкой `blocked / override_inline / passed`. Surface в retro #10.
- **Cost / risk:** низкий, analyzer-only.

### Candidate 3: #37 mermaid spread across deploy/monitoring — noise в classification map

- **Type:** routing-map cleanup.
- **Evidence:** missed_activations.byNode.#37 = 4 (deploy×3 + monitoring×1).
- **Suggested action:** убрать #37 из рекомендаций для классов `deploy` / `monitoring` в `tools/observer-classification-map.json`. Mermaid релевантен только для `documentation` / `analysis`.
- **Cost / risk:** низкий, после правки прогнать retro еще раз на тех же эпизодах — должно упасть 13→9.

### Candidate 4: cost-daily.json пуст — cost-tracker не пишет

- **Type:** infrastructure gap.
- **Evidence:** `~/.claude/runtime/cost-daily.json` отсутствует (null при readFile).
- **Suggested action:** проверить hook, который должен писать cost-tracking (где он установлен — `~/.claude/settings.json`?). Возможно retro #6 commit `4b9a8b` (A1 cost tracking) не залит финально, либо hook сломан.
- **Cost / risk:** низкий. Read-only диагностика.

### Candidate 5: System-process visibility gap (sanity-выявленный)

- **Type:** observer scope расширение, **опционально**.
- **Evidence:** sanity Q2 — наблюдатель не видел висящий python adr-judge.
- **Suggested action:** добавить в `tools/status-md-generator.mjs` опциональный блок «System health» — top-3 long-running процессы > 1h. Не блокирующий, инфо-only.
- **Cost / risk:** низкий, info-only. Можно отложить.

---

## Informational metrics

- Эпизодов с reviewer-pass: **30/164** (sample). Остальные 134 — кандидаты на next retro batch.
- Узлов canon, использованных в период: 5 (brainstorming, subagent-driven-dev, systematic-debugging, git-worktrees + brain-retro/this).
- Узлов, никогда не использованных с начала observer-логов: ≥40 — **не проблема** per Pravila §16.4 v1.36 (нет профильных задач для них в период).

---

## Self-retrospect trigger

- `episodes_since_last` (в `.self-retrospect-counter.json`) = **609**.
- Threshold = 50.
- **Сильно превышен.** Кандидат на запуск `/self-retrospect` отдельной сессией (когда заказчик решит).

---

## Сводка для заказчика (простым языком)

**Что я делала 27-28 мая:**

- 163 шага, 71 задача. Большинство — обсуждения, диагностика, починки.
- 92% времени работала напрямую, без «инструментов» (скилов). Это нормально для разговорного периода.

**Чему я научилась за период:**

- Поймана catastrophic backtracking баг в `adr-judge.py`. Починила, но **должна была** делать через TDD-инструмент (написать тест → починить → проверить). Ушла в direct. **Урок:** на bugfix с зависшим хуком — Pest и systematic-debugging обязательны.
- Расширила brain-retro 7→10 срезов. Хорошо, что обнаружила что мои новые срезы (Cut 8/9/10) сразу подсветили реальные проблемы.

**Где автоматика подвела:**

- Router не понял что «исправь regex» — это bugfix. Классифицировал как «other». Нужна правка примеров классификатора.
- 83% chain-рекомендаций я игнорировала. Новый хук `enforce-chain-recommendation` залит вчера вечером — пока не понятно, останавливает ли он меня. Проверим на retro #10.
- Cost-tracker не пишет файл. Не знаю, сколько я стою. Надо починить.

**Что заказчик подсветил вручную:**

- Adr-judge fix должна была быть через инструмент, а не голыми руками. Согласна.
- Наблюдатель не видел висящий 7-часовой python-процесс. Это слепая зона — episodes видят только tool_calls, не системные процессы.

**Запуск /self-retrospect** — 609 эпизодов с прошлого, порог 50 давно превышен.

---

## Метаданные

- Анализатор: `tools/brain-retro-analyzer.mjs` (10-cuts post-`b1398883`).
- Reviewer: `tools/brain-retro-batch-reviewer.mjs` (batch, 30 episodes / 69s, 0 errors).
- Sanity: `docs/observer/sanity-checks/2026-05-28.json` (schema v1).
- PII filter applied to free comments: yes.
- Retro session ref: `brain-retro-9`.
