Постмортем: документ, который меняет систему, а не ищет виноватого
Один инцидент, два документа.
Первый: полторы страницы, раздел «Root cause: human error», список из четырёх пунктов, где три начинаются со слова «усилить», один — «напомнить команде». Документ согласован за день, лежит в вики, за год его открывали дважды: автор и человек, который искал шаблон.
Второй: три страницы про тот же инцидент. В резюме — четыре числа. В хронологии у каждой строки указан источник. В разделе про факторы человек не упоминается ни разу, зато написано, что метрика, по которой можно было понять происходящее, не выведена ни на один дашборд. В плане — два пункта с фамилиями, тикетами и датами. Через три недели инструмент деплоя перестал принимать конфиг без пересчёта числа запросов на транзакцию.
Разница между документами — не в стиле и не в объёме. Первый описывал прошлое, второй требовал изменения в настоящем. Постмортем — это заявка на инженерную работу, которую ещё не оплатили, и текст либо эту заявку обосновывает, либо нет.
Постмортем существует ради правок, которые кто-то должен приоритизировать и сделать. Всё, что не помогает принять решение о правке, — украшение; всё, что переводит разговор на людей, — вредная примесь.
Процессную сторону разбора — порог, роли, культуру безобвинительности, метрики программы, расчёт бюджета ошибок — подробно разбирает трек SRE: «Постмортемы» и «Реакция на инцидент». Здесь мы занимаемся текстом: какими словами это записывается, где документ врёт незаметно для автора, как выглядит абзац до и после переписывания.
Читатель и решение: у постмортема их несколько, и они спорят
Проверка из главы «Читатель и решение» — назвать читателя и назвать решение — на постмортеме работает жёстче, чем на любом другом жанре, потому что читателей минимум четыре и решения у них разные.
| Читатель | Когда открывает | Какое решение принимает | Что ему нужно в тексте |
|---|---|---|---|
| Команда сервиса | в течение недели | что чинить в первую очередь | факторы, план правок, оценка трудоёмкости |
| Тот, кто распределяет время | на планировании | дать ли квартальный слот на правку | влияние в деньгах, риске, доле бюджета ошибок |
| Дежурный соседней команды | через полгода, ночью | «у меня то же самое или нет?» | симптомы, класс отказа, что делали, что помогло |
| Инженер, который проектирует похожее | через год-два | как не повторить в новом сервисе | механизм отказа, а не список действий |
| Клиент или регулятор | сразу после | доверять ли сервису дальше | факты, влияние, сроки — без внутренней кухни |
закрыт"] --> D["Постмортем"] D --> R1["Команда сервиса"] D --> R2["Тот, кто даёт слот
в плане"] D --> R3["Дежурный через
полгода"] D --> R4["Проектировщик
нового сервиса"] D --> R5["Клиент
внешний отчёт"] R1 --> A1["Правка в бэклоге
с владельцем и датой"] R2 --> A2{"Слот выделен?"} A2 -->|"да"| A1 A2 -->|"нет"| A3["Риск принят явно
и записан"] R3 --> A4["Диагноз за 10 минут
вместо часа"] R4 --> A5["Класс отказа
исключён на проектировании"] R5 --> A6["Доверие удержано
или потеряно"] A1 --> S["Система изменилась"] A3 --> S A4 --> S A5 --> S
Обратите внимание на ветку A3. Постмортем не обязан приводить к правке: явно принятый
и записанный риск — тоже результат, и часто честный. Плохо не «не починили», плохо
«решение не было принято и растворилось».
Главный адресат у постмортема — тот, кто решает, дадут ли на правку время, потому что без него всё остальное остаётся текстом. Отсюда следует конкретное требование к структуре: влияние и план правок стоят вверху, а не после трёх страниц хронологии, куда этот читатель не дойдёт. Как раскладывать материал по слоям — глава «Структура».
Тест на пустоту для постмортема
Три вопроса до первой строки. Если хотя бы на один нет ответа — вы пишете отчёт, а не постмортем.
- Какая правка должна появиться в бэклоге после этого текста? Если ответ «никакая, просто зафиксировать» — это либо запись в журнал инцидентов на три строки, либо документ ради процесса (см. раздел ниже), но не постмортем.
- Кто может её отклонить и какими аргументами? Под этого человека пишется резюме и раздел про влияние. Он отклонит по цене — значит, цена инцидента должна стоять рядом с ценой правки.
- По какому запросу этот документ найдут через год? Если ответа нет, документ станет невидимым через месяц — это главный способ смерти постмортемов, и мы разберём его отдельно.
Обвинение живёт в грамматике, а не только в культуре
«Пишем без обвинений» — правильный лозунг, который ничего не объясняет автору, сидящему перед пустым файлом. Обвинение попадает в текст не потому, что автор хочет кого-то наказать: оно встроено в самые естественные способы построить русскую и английскую фразу. Человек в позиции подлежащего, глагол несовершенного вида с отрицанием, модальность долженствования — и документ уже про человека, хотя автор этого не планировал.
Разберём механику. Вот пять конструкций, которые протаскивают обвинение мимо намерений автора.
| Конструкция | Пример | Что она делает с расследованием | Чем заменить |
|---|---|---|---|
| Человек в подлежащем | «Инженер запустил миграцию на проде» | расследование заканчивается на человеке: дальше объяснять нечего | подлежащее — механизм: «инструмент миграции берёт строку подключения из истории shell» |
| Глагол недостатка | «не проверил», «забыл», «пропустил», «проигнорировал» | описывает отсутствие действия, а отсутствие нельзя исследовать | что было в поле зрения: «в выводе команды целевой хост не печатается» |
| Модальность долженствования | «должен был проверить дашборд» | вводит норму, которой не было в момент события | «дашборд существовал, ссылки на него в алерте не было» |
| Оценка внутри факта | «ошибочно решил», «необоснованно предположил» | смешивает наблюдение и вывод, тащит послезнание в данные | «решил X. Основание: на экране было Y» |
| Пассив без агента | «конфиг был некорректно настроен» | выглядит нейтрально, но прячет и человека, и механизм | «валидация конфига не проверяет соотношение лимитов; CI пропускает такой конфиг» |
Последняя строка важнее, чем кажется. Пассивный залог часто советуют как лекарство от обвинения — это плохой совет. «Была допущена ошибка» не обвиняет никого, но и не сообщает ничего: правку из такой фразы вывести нельзя. Лекарство не в залоге, а в смене подлежащего с человека на механизм. Про пассив и номинализации как источник мутности — глава «Ясность».
Пара абзацев: причина инцидента
Как пишут обычно:
Root cause: human error. During the incident the on-call engineer did not check the
recent deploys dashboard and spent 12 minutes investigating the payment gateway
instead of the database. The engineer should have escalated earlier. Action item:
remind the team to always check deploys first and to escalate within 10 minutes.
Что здесь сломано, по пунктам: подлежащее — человек (the engineer), два глагола
недостатка (did not check, spent ... instead of), модальность (should have),
и единственная правка — «напомнить», то есть обещание, что в следующий раз человек
будет другим. При этом текст выглядит спокойным и вежливым: слово «виноват»
не произнесено ни разу. Обвинение здесь — в синтаксисе.
Переписано:
Contributing factor: the alert "checkout 5xx rate high" contains no link to recent
deploys, and the deploys dashboard is not part of the checkout runbook. The gateway
dashboard was the first place the alert did link to, and it showed p99 = 1.4 s —
a real symptom, caused downstream by retries from checkout.
We reproduced the path with two engineers who were not involved in the incident:
both started from the gateway dashboard and reached the same hypothesis within
90 seconds.
Action items:
1. Alert template includes deploys in the last 60 minutes for the owning service
(own: a.petrov, TICK-4409, by 24 Mar).
2. Checkout runbook step 1 becomes "check deploys", with a direct query link
(own: s.kim, TICK-4410, by 20 Mar).
Что изменилось. Подлежащими стали алерт, дашборд и раннбук — вещи, которые можно изменить в PR. Появилась воспроизводимость: двое непричастных прошли тот же путь, значит, дело не в конкретном дежурном, а в устройстве сигнала. Каждая правка проверяема: можно открыть шаблон алерта и увидеть, есть там блок деплоев или нет. Двенадцать потерянных минут никуда не делись — они просто перестали быть характеристикой человека и стали характеристикой системы оповещения.
Тест подстановки и тест воспроизведения
Два механических приёма, которые ловят обвинение в собственном черновике.
Тест подстановки. Замените фамилию на «любой инженер такой же квалификации, с тем же контекстом, в это же время суток». Если фраза стала бессмысленной («любой инженер был невнимателен») — это была оценка человека, а не описание системы. Если осталась осмысленной («любой инженер увидел бы на этом дашборде только шлюз») — вы описали систему.
Тест воспроизведения. Прежде чем написать «очевидно, что», посадите двух коллег, не участвовавших в инциденте, дайте им ровно те данные, которые были на экране в момент T, и спросите, что бы они сделали. Результат — данные, и его можно вставить в документ одной строкой. Это самый дешёвый способ убить фразу «это же было очевидно»: она не переживает эксперимента.
Отдельно: если после разбора действительно нужен разговор с конкретным человеком — это другой жанр, другой канал и другой документ. Постмортем публичен, разговор — нет; смешивать их значит гарантированно испортить оба. Как устроен такой разговор, см. обратную связь и трудные разговоры.
Хронология: где текст врёт незаметно
Хронология — сырьё для всего остального документа, и именно в ней автор чаще всего портит данные, не замечая этого. Портит одним способом: пишет её после того, как узнал ответ.
Верхняя лента — реконструкция, доступная только сейчас, когда причина известна. Нижняя — то, чем человек располагал в момент решения. Документ обязан описывать обе, и обязан их не путать. Классическая формулировка «дежурный пошёл не туда» описывает нижнюю ленту в терминах верхней: это не факт, это послезнание в маскировке.
Формат строки
Одна строка хронологии = время + наблюдаемое + источник. Три обязательных элемента, и ни одного четвёртого.
20:33 Дашборд gateway-latency: p99 = 1,4 с (норма 0,2 с). Скриншот в тикете.
[источник: #inc-checkout-2026-03-17, 20:33:41]
20:34 В канале: «похоже на шлюз, смотрю их графики». [источник: тот же тред]
20:41 Запрос к checkout-db: активных соединений 200 из 200.
Метрика на дашбордах отсутствует, значение получено вручную через psql.
[источник: терминал a.petrov, вставлено в тред 20:42]
Три вещи, которые делают этот фрагмент рабочим:
- Решения записаны как факты. «Решили, что дело в шлюзе» — это факт: решение действительно было принято. «Ошибочно решили» — уже интерпретация. Слово «ошибочно» в хронологии запрещено; ему место в разделе факторов, и там оно относится не к человеку, а к тому, чего не хватило.
- У каждой строки есть источник. Через полгода никто не вспомнит, откуда взялась цифра, а без источника её нельзя перепроверить при агрегате по классу отказов.
- Отсутствие данных зафиксировано явно. Строка 20:41 сообщает не только значение, но и то, что значение пришлось добывать руками. Это готовая правка, найденная в процессе записи хронологии, а не в процессе размышлений о правках.
Что генерируется, а что пишется руками
Хронологию не надо писать целиком вручную — это дорого и неточно. Половину можно собрать автоматически и вставить как сырьё, а руками добавить только то, чего в машинных источниках нет: что человек видел и что решил.
| Часть хронологии | Откуда берётся | Кто пишет |
|---|---|---|
| Деплои, изменения флагов, миграции | журнал CI/CD, аудит-лог | скрипт |
| Срабатывания и затухания алертов | система оповещения | скрипт |
| Значения метрик в ключевые моменты | запрос к хранилищу метрик, вставленный текстом | скрипт |
| Реплики в канале инцидента | экспорт треда с временными метками | скрипт |
| Что было на экране и почему выбрали гипотезу | только память участников | человек |
| Что решили и на каком основании | память + тред | человек |
Отсюда практическое правило: сырьё собирается в первые часы, пока тред не прокрутился и дашборды не переключили ретеншен. Через неделю строка «что было видно в 20:33» восстанавливается уже не памятью, а логикой — и логика непременно подставит то, что известно сейчас.
Резюме: пять строк, которые прочитают все
Из всего документа гарантированно прочитывают только резюме — и именно по нему принимается решение о слоте в плане. Поэтому резюме пишется последним и переписывается дольше остального текста.
Как пишут обычно:
Summary: On March 17 the checkout service experienced a period of degradation.
The team investigated and applied a fix. The root cause was related to the database.
The service was fully restored. Follow-up items have been created.
Формально всё правда. Практически — ни одного числа, ни одного существительного, за которое можно зацепиться, и ноль оснований для решения. Такой абзац сообщает единственное: «ничего страшного, идите дальше».
Переписано:
Summary: For 28 minutes (20:23–20:51 MSK, 17 Mar) 41% of checkout requests failed
with HTTP 500. About 12 400 customers could not complete a purchase; 93% of the
monthly error budget for checkout was spent in this single event.
The connection pool of checkout-db (200 connections) was exhausted after a config
change raised the number of queries per checkout from 3 to 11. Neither code review,
nor CI, nor any dashboard represented this change as a change in pool demand.
Two P0 items, both owned and dated: pool saturation metric with an alert at 80%
(a.petrov, TICK-4411, by 24 Mar); CI check that computes queries-per-request from
the config diff and fails the build above the pool budget (s.kim, TICK-4412, by 31 Mar).
Формула, по которой это собрано, механическая:
- Сколько и кому. Длительность, доля затронутых запросов, число людей в единицах, понятных не инженеру.
- Цена в валюте организации. Доля бюджета ошибок, деньги, нарушенные обязательства — что принято считать у вас. Как считается бюджет и почему доля бюджета честнее минут — «Бюджет ошибок».
- Механизм одним предложением. Не «проблема с базой», а что именно с чем не сошлось.
- Чего не хватило, чтобы это увидеть. Обычно самая ценная строка резюме: она прямо превращается в правку.
- Правки P0 с владельцем и датой. Прямо в резюме, а не только в конце документа.
Проверка: закройте документ и оставьте только резюме. Может ли человек, не участвовавший в инциденте, по нему одобрить или отклонить выделение времени? Если нет — резюме не готово.
Влияние: в единицах читателя, а не в единицах монитора
«Сервис был недоступен 28 минут» — это единица монитора. Она не переводится в решение, потому что не отвечает на вопрос «сколько это стоило». Одна и та же длительность означает разное в 04:00 вторника и в 20:23 предпраздничной пятницы.
Три единицы, в которых стоит писать влияние, — и их лучше давать все три:
- Пользовательская. «12 400 человек не смогли оформить заказ», «у 340 партнёров вебхуки не доставлялись 40 минут». Понятно любому читателю без контекста.
- Деловая. «Оценка недополученной выручки — 1,9 млн RUB, по средней конверсии того же часа предыдущих четырёх пятниц». Обязательно с методом оценки: число без метода первый же скептик развалит одним вопросом.
- Инженерная. Доля бюджета ошибок за окно SLO, число нарушенных SLA-обязательств.
И одна честная строка, которую почти все пропускают: где не повезло бы сильнее. «Инцидент пришёлся на 20:23, дежурный был за компьютером; в 03:00 обнаружение заняло бы не 9 минут, а от 30 — алерт идёт в тот же канал, эскалации по телефону для этого класса нет». Эта строка стоит одно предложение и часто оказывается более сильным аргументом за правку, чем весь остальной документ.
Способствующие факторы: как записать граф словами
Соблазн жанра — написать «Root cause» в единственном числе. Почему единственной коренной причины в сложных системах не бывает, подробно объяснено в SRE-главе; нас интересует текстовая сторона: как записать несколько факторов так, чтобы читатель увидел структуру, а не список.
Рабочая формула на каждый фактор — три части:
Что было устроено так → из-за чего не сработала защита → что стало возможно
Плохо:
Contributing factors:
- The config change was not tested under load.
- Monitoring was insufficient.
- The runbook was outdated.
Это не факторы, это три оценки. «Недостаточный», «устаревший», «не протестировано» — слова, из которых нельзя сделать ни задачу, ни проверку в CI. Читатель не может ни возразить, ни согласиться: возражать не с чем.
Хорошо:
Contributing factors
1. Query fan-out is invisible in review. The change added a per-item lookup inside
a loop; the diff shows +4 lines in a mapper. Nothing in the review UI, in CI, or
in the config schema expresses "queries per request", so the reviewer had no
artifact to react to.
2. Pool saturation has no signal. checkout_db_pool_in_use is exported by the driver
but is not scraped, not on any dashboard, and not used by any alert. Between
20:09 and 20:41 the only observable effect was 5xx downstream.
3. Retries amplified the failure into the gateway. checkout retries 3 times with
no jitter; the gateway's own p99 rose as a consequence, which made the gateway
the most plausible suspect for the first 12 minutes.
4. Load testing does not cover config-only changes. The pipeline runs the load
suite for code changes; the config repository has a separate pipeline without it.
У каждого пункта есть механизм, наблюдаемое следствие и естественное место для правки. Пункт 3 объясняет, почему диагностика ушла в сторону, — и объясняет через устройство системы ретраев, а не через качества человека. Пункт 4 — типичная находка: правило существует, но применяется не ко всем путям изменения.
Отдельно проговорим порядок пунктов: он не хронологический и не «по важности вообще». Сортируйте по силе правки: сверху те факторы, устранение которых закрывает целый класс отказов, снизу — точечные. Читатель, который бросит после второго пункта, должен унести главное.
Правки: грамматика проверяемого пункта
Тут постмортем чаще всего превращается в макулатуру. Пункт плана — это, по сути, критерий приёмки, и требования к нему те же, что к критериям приёмки в аналитике: проверяемость и однозначность (см. критерии приёмки).
Анатомия рабочего пункта:
Кто (человек, не «команда») · что сделает (глагол совершенного вида) · какой наблюдаемый признак появится · к какому сроку · тикет · как проверим, что это работает
| Слабая формулировка | Что с ней не так | Сильная версия |
|---|---|---|
| «Команда рассмотрит улучшение мониторинга БД» | нет субъекта, нет действия, нет признака | «a.petrov: метрика checkout_db_pool_in_use/max на дашборде checkout и алерт при >80% в течение 5 мин. TICK-4411, до 24.03. Проверка: алерт срабатывает на нагрузочном прогоне в staging» |
| «Усилить ревью конфигов» | «усилить» непроверяемо | «s.kim: CI считает число запросов на транзакцию из диффа конфига и падает при превышении лимита пула. TICK-4412, до 31.03» |
| «Обновить раннбук» | неизвестно, что именно | «m.orlov: шаг 1 раннбука checkout — «проверить деплои за 60 мин», ссылка-запрос. TICK-4410, до 20.03» |
| «Напомнить команде про чек-лист» | правка направлена на память людей | «убрать чек-лист, перенести два его пункта в предполётную проверку деплой-скрипта» |
| «Провести обучение по инцидентам» | не меняет систему, меняет намерения | «добавить этот класс отказа в учебный сценарий ежеквартальных учений» |
Главный фильтр — одна фраза: если выполнение пункта нельзя увидеть в диффе, в CI, на дашборде или в конфиге, это не правка, а пожелание. Пожелания не запрещены — их просто не надо записывать в план как работу.
Правки полезно разложить по двум осям: насколько проверяема формулировка и насколько сильно изменится поведение системы.
Квадрант 4 — ловушка добросовестного автора: пункты выполнимые, проверяемые и совершенно безобидные для системы. План, состоящий только из них, закрывается на сто процентов и не меняет ничего. Полезная привычка — считать долю пунктов из верхней половины: если их ноль, разбор был ритуалом.
Две секции, которые вырезают первыми
«Где нам повезло». Условия, при отсутствии которых было бы существенно хуже. Записываются одной строкой каждое, без объяснений: «повезло, что вторая реплика не перезапускалась в этот момент»; «повезло, что откат конфига был возможен — неделю назад обсуждали, не сделать ли его необратимым». Каждая такая строка — бесплатно полученные данные о том, где система держится на удаче.
«Что осталось непонятным». Открытые вопросы, на которые ответа нет. Авторы прячут этот раздел, потому что он выглядит как признание некомпетентности; на деле он единственный, по которому видно, что расследование было настоящим. Формат — вопрос плюс что нужно, чтобы ответить:
Open questions
- Why did the pool not recover after the config was reverted at 20:47?
Recovery took 4 more minutes. Needs: driver-level pool metrics with 1s
resolution; currently unavailable. Owner of the question: s.kim.
- Was the 20:31 gateway latency spike fully explained by our retries?
Gateway team has not confirmed. Needs: their p99 broken down by caller.
Обратите внимание: у открытого вопроса тоже есть владелец. Вопрос без владельца исчезает так же надёжно, как правка без владельца.
Внешний отчёт: тот же инцидент, другой документ
Публичный отчёт для клиентов — не сокращённая версия внутреннего постмортема, а отдельный жанр с другим читателем и другим решением. Клиент решает: продолжать ли полагаться на ваш сервис и нужно ли ему что-то сделать со своей стороны.
Как обычно выглядит:
Уважаемые клиенты! Приносим извинения за возможные неудобства. В работе сервиса
наблюдался кратковременный технический сбой. Наши специалисты оперативно устранили
проблему. Мы постоянно работаем над повышением качества и надёжности сервиса.
Здесь нет ни одного факта: ни времени, ни масштаба, ни того, что делать клиенту со своими незавершёнными заказами. Такой текст выполняет функцию «мы отреагировали» и ровно поэтому не работает: читатель уже знает, что был сбой, — он открыл страницу ради того, чего не знает. Про тон и формулировки в интерфейсных сообщениях — микрокопия.
Переписано:
Оформление заказов было недоступно 28 минут: с 20:23 до 20:51 МСК 17 марта.
41% попыток оформления в этом окне завершались ошибкой.
Что это значит для вас. Если вы получили ошибку при оплате, заказ не был создан
и деньги не списывались. Проверить статус: раздел «Заказы» → фильтр «17 марта».
Списания в статусе «hold» снимаются автоматически до 19 марта; если к 19 марта
средства не вернулись, напишите в поддержку с номером попытки.
Что произошло. Изменение конфигурации увеличило нагрузку на пул соединений
к базе данных сервиса оформления. Пул исчерпался, часть запросов не обслуживалась.
Изменение откачено в 20:47, полное восстановление в 20:51.
Что мы меняем. К 24 марта — оповещение при заполнении пула выше 80%.
К 31 марта — автоматическая проверка в сборке, блокирующая изменения конфигурации,
превышающие ёмкость пула.
Правила жанра, если сводить их к списку:
- Времена, длительность, доля затронутых — обязательно и в начале.
- Раздел «что делать вам» идёт раньше раздела «что произошло»: у клиента практический вопрос, а не любопытство.
- Механизм объясняется без внутренних имён сервисов и без имён людей, но без вранья: «технический сбой» — вранье умолчанием.
- Сроки правок — публичное обязательство. Не пишите дат, которых не выдержите: сорванная дата в публичном отчёте дороже, чем её отсутствие.
- Ни при каких обстоятельствах — ни одной фамилии.
Разговор с руководством об инциденте — ещё один отдельный жанр со своим форматом; он разобран в главе «Работа вверх».
Как пишется на практике: от инцидента до опубликованного текста
Постмортем ломается не на написании, а на организации написания: черновик пишет комитет, ревью текста смешивается с ревью инцидента, и через две недели документ согласовывают до состояния, в котором он никого не задевает и ничего не сообщает.
скриншоты, значения метрик D->>F: Сырьё в течение 24 часов F->>A: Назначен один автор
(не комитет) A->>A: Черновик: хронология из сырья,
факторы, влияние в числах A->>F: Черновик за сутки до встречи F->>T: Рассылка: читают заранее,
комментарии в документе T->>F: Встреча 60 минут:
вопросы «что вы видели» F->>A: Правки по содержанию A->>T: Ревью текста отдельным проходом T->>A: Правки по формулировкам A->>O: Публикация, правки в трекер
с владельцем и датой O->>T: Статус правок на планировании
Четыре решения, которые определяют качество текста:
- Один автор. Черновик, написанный вдвоём, получается в полтора раза длиннее и вдвое осторожнее. Соавторы дают материал, пишет один.
- Фасилитатор — не участник инцидента. Он же следит за формулировками на встрече: вопрос «почему ты так сделал» переформулируется в «что ты видел в этот момент». Техника ведения обсуждения — фасилитация.
- Ревью содержания и ревью текста — разные проходы. Смешивать нельзя: обсуждение запятых на встрече про факторы гарантированно съедает время, а замечания к сути, пришедшие на этапе вычитки, ломают структуру. Как читать чужой документ и как принимать правки — глава «Ревью текста».
- Сроки. Черновик — 2–3 рабочих дня, встреча — до 5, публикация — до 10. Позже хронология уже реконструируется, а не вспоминается.
Хороший приём для черновика: пишите его в репозитории сервиса, а не в вики. Тогда постмортем проходит через тот же процесс ревью, что и код, замечания видны построчно, а ссылка на него живёт рядом с кодом, который меняли по его итогам (см. совместную работу в git).
Почему постмортемы мертвеют — и что с этим делают структурно
Постмортем — документ о прошлом, и в этом его особенность: он не устаревает по содержанию. Событие 17 марта останется событием 17 марта. Мертвеет он иначе, через потерю связи с настоящим, и это происходит по четырём механизмам сразу.
Механизм 1: документ невидим. Через полгода дежурный не знает, что этот постмортем
существует, и заново проходит тот же путь. Лечится не призывом «читайте постмортемы»,
а тем, что документ привязан к местам, где его ищут: класс отказа из словаря
(не свободный текст) в шапке, ссылка в раннбуке того сервиса, ссылка в описании алерта,
который в этом инциденте срабатывал, комментарий в коде рядом с местом правки
(// см. PM-2026-03: пул исчерпывается при fan-out > 8). Строка в шаблоне алерта
«прошлые инциденты этого класса» стоит один PR и работает лучше любых напоминаний.
Механизм 2: ссылки протухают. Дашборд удалён, тикет перенесён в другой трекер, сервис переименован. Через год документ формально существует, но половина ссылок ведёт в никуда, и перепроверить ничего нельзя. Лечится тем, что числа и запросы вставляются в текст, а не только ссылаются: PromQL-запрос текстом, значение метрики текстом, скриншот приложен, а не «см. дашборд». Ссылка — дополнение к данным, а не замена им.
Механизм 3: правки уходят в песок. Пункты заведены, потом квартал переприоритизирован, и никто не помнит, что там было. Лечится тем, что срок жизни есть не у документа, а у пунктов: у каждой правки владелец-человек и дата, статус пунктов автоматически собирается из трекера и виден на регулярном обзоре, а закрытие через «не будем делать» требует явной записи с датой и подписью. Механику приоритизации правок и метрики программы разборов см. в SRE-главе.
Механизм 4: одиночные документы вместо картины. Пятнадцать постмортемов за год, каждый честный, — и ни одного вывода, потому что никто не смотрел на них вместе. Лечится машиночитаемой шапкой с фиксированным словарём классов отказа и квартальным агрегатом: три класса, съевших больше всего бюджета, — и есть настоящий план на квартал. Без словаря агрегат невозможен: свободный текст в поле «причина» не группируется.
Общая механика устаревания документации — близость к коду, генерация, владелец, срок жизни, удаление как штатная операция — разбирается в главе «Почему документация устаревает». У постмортема есть своя особенность, которую стоит проговорить прямо: сам текст неизменяем (как и ADR). Найденную позже ошибку в фактах исправляют не переписыванием, а датированным дополнением: «2026-04-02, дополнение: последующий анализ показал, что ретраи вносили не 12%, а 60% нагрузки на шлюз». Переписанная задним числом хронология превращает документ из свидетельства в художественный текст.
Часть постмортемов пишут ради процесса — и это надо уметь видеть
Честная часть. В любой достаточно большой организации некоторая доля разборов существует не ради правок, а ради того, чтобы разбор состоялся. Это не всегда чей-то злой умысел: требование может идти от регулятора, от контракта с клиентом, от политики страховщика, от аудита. Проблема начинается, когда процессный документ маскируется под аналитический — тогда команда тратит время как на настоящее расследование, а результат никого не меняет.
Признаки, по которым это распознаётся:
- Шаблон из четырнадцати обязательных полей, из которых восемь заполняются фразой «не применимо». Форма растёт от требований согласующих, а не от вопросов, на которые нужно ответить.
- Дедлайн важнее содержания: «постмортем должен быть в течение 24 часов» — и он появляется через 23 часа, написанный уставшим дежурным сразу после смены.
- Все пункты плана — P3 и все формулируются глаголами «рассмотреть», «проанализировать», «усилить».
- Список согласующих длиннее списка участников.
- Ни один документ не переоткрывался после публикации: ни ссылок из тикетов, ни упоминаний в других разборах.
- Ключевой вопрос на встрече — «кто подпишет», а не «что мы меняем».
Три теста, которые дают ответ за десять минут:
- Тест удаления. Удалите документ. Кто заметит и через сколько? Если ответ «никто» — вы писали для процесса.
- Тест поиска. Посмотрите в вики или гите, кто открывал документы этого типа за последние 90 дней и по какому пути пришёл. Обычно результат отрезвляет.
- Тест правки. Возьмите три последних постмортема и найдите в трекере или в истории коммитов изменения, которые из них вышли. Ноль — жанр выродился.
Что с этим делать практически:
- Разделить слои. Обязательная форма для аудита — отдельный артефакт, желательно генерируемый из машиночитаемой шапки и трекера. Рабочий разбор — короткий документ для инженеров. Не пытайтесь одним текстом обслужить регулятора и дежурного: получится плохо для обоих.
- Автоматизировать процессный слой. Всё, что можно собрать из трекера, CI и системы оповещения, должно собираться скриптом. Человек пишет только то, что нельзя сгенерировать: факторы и наблюдения.
- Договориться о пороге. Разбор по каждому мелкому событию гарантированно превращается в ритуал: качество расследования падает пропорционально их числу. Порог — предмет явного соглашения, а не привычки.
- Не воевать с формой в одиночку. Если требование внешнее, спорить бессмысленно; задача — сделать его дешёвым, а рабочий разбор — настоящим.
И обратная честность: иногда «документ ради процесса» — правильный ответ. Если контракт требует уведомления в течение четырёх часов, это уведомление нужно написать и не рассуждать о его читателе. Просто не называйте это постмортемом и не тратьте на него время, отведённое на расследование.
Типичные ошибки
- «Root cause» в единственном числе. Одна причина — почти всегда та, на которой автор устал искать дальше.
- Хронология, написанная задним числом. Слова «ошибочно», «зря», «очевидно» внутри хронологии — маркер послезнания.
- Человек в подлежащем. Даже вежливая формулировка с человеком в подлежащем закрывает расследование.
- Пассив как маскировка. «Была допущена ошибка» не обвиняет никого и не сообщает ничего.
- Влияние в минутах вместо единиц читателя. Из минут не следует решение о приоритете.
- Правки без владельца-человека. «Команда» — не владелец.
- План из одних безопасных пунктов. Сто процентов выполнения, ноль изменений в системе.
- Документ, живущий только в вики. Не привязан к раннбуку, алерту и коду — через полгода невидим.
- Ссылка вместо числа. Дашборд удалят, число останется.
- Смешение постмортема с разговором о человеке. Испортит оба.
- Переписывание документа задним числом. Дополняйте датированной вставкой, не редактируйте историю.
- Оценки вместо механизмов. «Мониторинг был недостаточным» — не фактор, а вздох.
Мини-итог
- Постмортем существует ради правок, которые кто-то должен приоритизировать. Главный адресат — тот, кто даёт на них время; под него пишется резюме и раздел влияния.
- Обвинение попадает в текст через синтаксис: человек в подлежащем, глаголы недостатка, модальность долженствования, оценки внутри фактов. Лекарство — не пассив, а смена подлежащего на механизм.
- Хронология описывает две ленты: что происходило в системе и что было в поле зрения человека. Формат строки — время, наблюдаемое, источник. Половина хронологии генерируется.
- Резюме — пять строк с числами: масштаб, цена, механизм, чего не хватило, чтобы увидеть, правки P0 с владельцами. По нему принимается решение.
- Факторы записываются как «устроено так → защита не сработала → стало возможно», сортируются по силе правки, а не по хронологии.
- Правка проверяема, если её выполнение видно в диффе, CI, конфиге или на дашборде. Всё остальное — пожелание.
- Внешний отчёт — отдельный жанр: сначала «что делать вам», потом «что произошло», без имён и без вранья умолчанием.
- Постмортемы не устаревают, а становятся невидимыми. Структурные лекарства: словарь классов отказа, ссылки из раннбука, алерта и кода, числа в тексте вместо ссылок, срок жизни у правок, квартальный агрегат по классам.
- Часть разборов пишется ради процесса. Распознаётся тестами удаления, поиска и правки; лечится разделением слоёв и автоматизацией процессного слоя.
Источники
- Google SRE Book, «Postmortem Culture: Learning from Failure»: https://sre.google/sre-book/postmortem-culture/
- Пример постмортема из Google SRE Book — полезен как образец формы: https://sre.google/sre-book/example-postmortem/
- Etsy, Debriefing Facilitation Guide — как вести разбор и какими словами спрашивать: https://extfiles.etsy.com/DebriefingFacilitationGuide.pdf
- John Allspaw, «Blameless PostMortems and a Just Culture»: https://www.etsy.com/codeascraft/blameless-postmortems/
- Howie: The Post-Incident Guide — подробное руководство по расследованию и его записи: https://www.jeli.io/howie/welcome
- Richard Cook, «How Complex Systems Fail» — восемнадцать тезисов, объясняющих, почему «человеческая ошибка» не бывает объяснением: https://how.complexsystems.fail/
- Sidney Dekker, «The Field Guide to Understanding “Human Error”» — источник теста подстановки и разбора послезнания.
- Learning From Incidents in Software: https://www.learningfromincidents.io/
- The VOID — открытая база отчётов об инцидентах, полезна как материал для сравнения формулировок: https://www.thevoid.community/
- Коллекция публичных постмортемов (danluu/post-mortems): https://github.com/danluu/post-mortems
- GitLab, разбор потери данных 31 января 2017 — образец честного публичного отчёта: https://about.gitlab.com/blog/2017/02/10/postmortem-of-database-outage-of-january-31/
- Cloudflare, «Details of the Cloudflare outage on July 2, 2019» — образец внешнего технического отчёта: https://blog.cloudflare.com/details-of-the-cloudflare-outage-on-july-2-2019/
- Amazon, «Summary of the Amazon S3 Service Disruption», февраль 2017: https://aws.amazon.com/message/41926/
Что дальше
Постмортем и RFC — документы про решения и события: их читают в конкретный момент и ради конкретного действия. Дальше начинаются документы другого рода — те, которые читает пользователь вашей системы, и первый из них человек видит раньше всего остального. У README есть тридцать секунд, чтобы объяснить, что это, кому нужно и как запустить; всё, что не поместилось в эти тридцать секунд, работать не будет.