Premortem skill
Overview
Скилл = советник, не риск-аудитор. Показывает что юзер не видит → предлагает варианты → юзер выбирает → агент потом исполняет. Четыре фазы: pre-flight (синхронизация контекста), silent scan (3 параллельных помощника находят 5–8 дыр), live диалог (краткие решения по каждой дыре, расширение топа), запись (<plan-name>.md + история в history/).
Цель — лёгкая 10–15-минутная сессия, не тяжёлый аудит.
Главный принцип: скрипты делают всю детерминированную механику (I/O, schema, ID, sort, dedup, classifier-switch). LLM — только семантика.
Триггеры
Включаем:
- «премортем», «premortem», «premortem this», «run premortem»
- «найди дыры в плане»
- «посмотри со стороны на план»
- «что я упускаю в <конкретный план>»
- «future-proof this <plan/launch/decision>»
- «what could kill this <plan/launch>»
НЕ включаем (слишком широкие):
- «should I», «what could go wrong», «stress test», «what am I missing», «devil's advocate this» — конфликтуют с базовым поведением модели.
Когда применимо
- Конкретный план / запуск / решение с обратимым выбором.
- Юзер готов потратить 10–15 минут.
- Есть минимум контекста (предмет / аудитория / успех).
Когда НЕ применимо
- Идея без формы — сначала помочь оформить план.
- Вопрос с одним правильным ответом — просто ответить.
- Уже принятое необратимое решение — премортем не вернёт назад.
- Творческая правка черновика — это редактирование, не премортем.
Phase 1: Pre-flight — синхронизация контекста
Цель: установить 5 минимумов: предмет / аудитория / критерий успеха / горизонт оценки / reference class.
Действия:
- Прочитать контекст. Просканировать текущий разговор и доступные файлы (
Read/Glob). Извлечь то что уже сказано — не спрашивать заново.
- Найти пробелы. Сравнить с пятью минимумами. Записать что есть, что нет.
- Задать максимум 2 вопроса за раз. Если не хватает 4 элементов — спросить 2, получить ответ, спросить ещё 2. Не делать «анкету» из 5 вопросов сразу.
- Reference class — отдельный вопрос. «На что это похоже из уже сделанных проектов? Назови 1–2 примера — твоих или известных тебе». Если юзер говорит «не знаю» — двигаться дальше с пустым reference_class, помощники получат сигнал.
- Горизонт оценки — выбор из меню.
`` Через сколько оценим что план провалился? А) через 30 дней Б) через 3 месяца В) через 12 месяцев Г) после первого пилота Д) после запуска Е) после привлечения первых N клиентов Ж) иное (напиши своё) ``
- Неясности → assumption. Если после 2 раундов вопросов что-то остаётся туманным — пометить как
assumptionи передать в Phase 2 в составе угла «Допущения». Не блокировать сессию.
- Resolve plan-name. Спросить или вывести из контекста. Прогнать через CLI:
``bash uv run scripts/cli.py slugify "<plan name from user>" `` Запомнить slug — он будет именем файла.
- Существует ли файл? Запустить:
``bash uv run scripts/cli.py find docs/premortem --name "<plan_name>" `` Если файл уже есть — это повторный запуск, перейти к секции «Rerun logic» ниже. Если нет — продолжать новый сценарий.
Phase 2: Silent scan — взгляд с разных сторон
Цель: 3 параллельных помощника находят 5–8 уникальных дыр.
Действия:
- Классифицировать тип плана и выбрать углы. Запустить:
``bash uv run scripts/cli.py classify "<plan_text>" ` Получить JSON: {profile, angles, confidence, matched_keywords}`.
Если confidence < 0.4 — fallback: задать одному LLM-помощнику вопрос «какие 6 углов лучше всего видят дыры этого плана» (одной строкой, без объяснений). Использовать его ответ.
Юзеру показать только список выбранных углов одной строкой: `` Смотрю с углов: Клиент, Исполнитель, Противник, Допущения, Конкурент, Будущий поддерживающий. ``
- Установить premortem-фрейм.
> «Представим что к [горизонту] этот план провалился. Не "может провалиться" — провалился, факт. Что произошло?»
(См. references/frame-language.md.)
- Запустить 3 параллельных помощника одним сообщением.
Каждый получает свой промпт из references/helper-prompt-template.md плюс назначенные углы (по 2 угла на помощника). Распределение: 6 углов на 3 помощника = (2,2,2). Один помощник получает «Будущий поддерживающий» с обязательным WYSIATI-микрошагом.
Модель: Opus 4.7 по умолчанию. Если юзер запустил скилл с флагом --model sonnet — Sonnet. Если флага нет, скилл может предложить выбор перед stage 2 одной строкой: > «Запускаю на Opus (~$1–2). Sonnet будет дешевле (~$0.50–1) — переключить?»
Параллельно: ВСЕ 3 в ОДНОМ сообщении с тремя Task tool calls.
- Получить 6 сырых ответов (3 × до 2). Прогнать каждый через валидатор:
``bash uv run scripts/cli.py validate-helper < helper_response.json ``
Retry policy. Максимум 3 attempts на помощника. Классификация ошибок:
| Тип ошибки | Retryable? | Сообщение для retry | |---|---|---| | Невалидный JSON / extra prose | да | «Верни ТОЛЬКО JSON, без преамбулы» | | Schema fail (отсутствует поле) | да | «Не хватает поля X в дыре N» | | maxItems >2 | да | «Максимум 2 дыры; верни лучшие 2» | | Generic risks без привязки к плану | да | «Дыры слишком общие; привяжи к деталям плана» | | Empty holes ({"holes": []}) | НЕТ | принять как валидный пустой ответ | | Low confidence на всех дырах | НЕТ | принять как есть, пометить assumption |
Если после 3 attempts всё ещё ошибка — отбросить ответ помощника, продолжить с тем что есть. Не чинить вручную.
- Hash-дедуп. Прогнать все валидные дыры через:
``bash uv run scripts/cli.py dedup < all_holes.json `` Убирает явные дубли по нормализованному описанию (sha256). Оставшиеся дубли (одна дыра, разные слова) обработает шаг 6.
- Семантический дедуп (LLM clustering). Если после hash-дедупа осталось >8 дыр — попросить LLM сгруппировать близкие в кластеры. Промпт:
``` Вот N сырых дыр от трёх помощников. Какие из них на самом деле ОДНА И ТА ЖЕ дыра, видимая с разных углов? Верни JSON: [ { "merged": [индексы дыр объединённые в одну], "title": "новое объединённое название", "merged_from_angles": ["Клиент", "Допущения"], // углы-источники "merged_descriptions": ["исходное описание 1", "исходное описание 2"] }, ... ]
ПРАВИЛА:
- Не теряй нюансы: если две дыры близки но имеют разный угол атаки — оставь обе.
- Если все 8+ — действительно разные дыры, верни пустой массив (ничего не объединять).
- Объединение допустимо только если ≥80% совпадение по сути.
```
Применить кластеры: для каждой объединённой дыры в Hole.merged_from записать ID исходных дыр (после назначения ID на шаге 8), в Hole.углы — все исходные углы, в описание — выбрать самое богатое исходное описание.
- Лимит на 8. Если после семантического дедупа всё ещё >8 — ранжировать по
важность × уверенность × novelty(где novelty = 1 для новых, 0.5 для похожих на ранее найденные при rerun) и взять топ-8. Не отбрасыватьassumption-дыры приоритетно — они часто и есть самое ценное.
- Назначить ID. Каждой уникальной дыре дать ID через:
``bash uv run scripts/cli.py next-id --existing "H-001,H-002" `` На первом запуске стартуем с H-001. Сохранить порядок: первая дыра → H-001, вторая → H-002, и т.д.
- Сохранить промежуточный snapshot in-memory (объект Plan). На диск пока не пишем — это произойдёт в Phase 4.
Phase 3: Live диалог — выбор решений
Цель: юзер быстро принимает решения по 5–8 дырам в кратком режиме. Топ 1–3 + high-impact дыры расширяются до полного режима постфактум.
Per-hole loop (краткий режим по умолчанию):
- Презентация дыры.
`` ### H-NNN: <title> <описание (1 абзац)> Почему важно: <одна фраза> Угол: <угол> Уверенность: <маркер> ``
- Варианты решения. Сгенерировать 2–3 стратегических варианта (LLM, не скрипт). Каждый = направление с +/–, не задача.