---
name: error-to-lesson
description: >
  [STATUS: confirmed] [CONFIDENCE: high] [VALIDATED: 2026-04-18]
  После исправления бага или инцидента — структурирует урок в переиспользуемый
  паттерн с причиной, fix-ом, и kill criterion. Автоматически сохраняет в
  patterns.md как [AVOID]. Предотвращает повторение одних и тех же ошибок.
  Триггеры: "что мы узнали", "зафиксируй урок", "error to lesson",
  "сохрани паттерн", "добавь в patterns", "что пошло не так",
  "постмортем", "почему это сломалось".
  НЕ использовать для: активного дебага — только после того как баг уже исправлен.
---

# Error-to-Lesson — Превращаем баги в паттерны

## Зачем это нужно

Баг исправили → забыли → наступили снова.
Этот skill закрывает цикл: **ошибка → урок → паттерн → защита**.

После каждого значимого бага или инцидента тратим 3 минуты чтобы
следующий Claude (или ты через месяц) не повторил то же самое.

---

## Шаг 1: Вскрытие (Root Cause Analysis)

Ответь на 5 вопросов по методу 5 Whys:

```
Симптом: [что сломалось / что увидели]

Почему 1: [непосредственная причина]
Почему 2: [почему случилась причина 1]
Почему 3: [почему случилась причина 2]
Почему 4: [системная причина]
Почему 5: [корневая причина — где реально нужно чинить]
```

**Правило:** Настоящая root cause обычно на уровне 4-5, не 1-2.
Если остановился на уровне 1-2 — это patch, а не fix.

---

## Шаг 2: Формат паттерна

```markdown
## [AVOID] [Категория] Краткое название ошибки [×1]

**Симптом:** что видно снаружи когда это происходит
**Root Cause:** реальная причина (не симптом)
**Fix:** что именно исправить
**Проверка:** как убедиться что не повторится

**Kill criterion:** при каких условиях немедленно rollback
**Контекст:** в каких ситуациях особенно вероятно

*Дата: YYYY-MM-DD | Проект: [название]*
```

---

## Шаг 3: Сохранение

Автоматически добавляю в `~/.claude/memory/_auto/patterns.md`:

```bash
# Формат который понимает knowledge_librarian.py:
echo "" >> ~/.claude/memory/_auto/patterns.md
echo "## [AVOID] [Название] [×1]" >> ~/.claude/memory/_auto/patterns.md
echo "..." >> ~/.claude/memory/_auto/patterns.md
```

Если такой паттерн уже есть → инкрементирую счётчик `[×N]` → `[×N+1]`.
Счётчик — это сигнал серьёзности: `[×3]` = системная проблема, не случайность.

---

## Шаг 4: Обновление кода (防御 код)

Если можно добавить guard который предотвратит ошибку в будущем:

```python
# WHY: [краткое описание бага который это предотвращает]
# Дата обнаружения: YYYY-MM-DD
assert condition, "Описание что пошло не так и что проверить"
```

Комментарий `# WHY:` — обязателен. Без него через месяц непонятно зачем этот assert.

---

## Категории паттернов

| Категория | Примеры |
|-----------|---------|
| `[Config]` | Неправильные env vars, paths, secrets |
| `[Types]` | datetime aware/naive mix, None handling |
| `[Async]` | Race conditions, event loop blocking |
| `[DB]` | Migration без rollback, N+1 queries |
| `[API]` | Rate limits, timeout без retry, auth expiry |
| `[Test]` | Тесты которые проходят на wrong reasons |
| `[Deploy]` | Port conflicts, missing deps, wrong Python |
| `[Git]` | Squash merge теряет коммиты, force push |

---

## Пример готового паттерна

```markdown
## [AVOID] [Types] datetime.utcnow() смешан с timezone-aware [×3]

**Симптом:** TypeError: can't compare offset-naive and offset-aware datetimes
**Root Cause:** datetime.utcnow() возвращает naive datetime, а БД возвращает
  timezone-aware. При сравнении Python падает с TypeError.
**Fix:** Везде использовать datetime.now(UTC) из datetime import UTC
**Проверка:** grep -r "utcnow()" src/ — должно быть 0 результатов

**Kill criterion:** если тест с timezone comparison падает → не деплоить
**Контекст:** часто при миграции с SQLite на PostgreSQL

*Дата: 2026-03-26 | Встречался ×3*
```

---

## Gotchas

- Паттерн без Kill criterion = паттерн без последствий (никто не читает)
- Счётчик `[×N]` важнее самого описания — knowledge_librarian показывает топ по `[×N]`
- Сохраняй в глобальный `patterns.md`, не проектный — ошибки повторяются в разных проектах
