DarkRiDDeR11 мин

Postmortem без поиска виноватого: собрать факты до объяснения

НадёжностьКомандная работа

После сбоя команда часто помнит одно: кто нажал кнопку и какой фрагмент лога тревожил. Встреча быстро превращается в поиск автора неверного действия. Цена не только в конфликте. Из документа исчезают условия, при которых решение казалось разумным, и следующий дежурный получает не проверяемый маршрут, а мораль из прошлого случая.

Практическая проблема не решается заменой слова «виноват» на «бескорыстно». Нужна другая форма записи. Сначала фиксируем факт с источником и временем. Затем отдельно записываем решение, доступные в тот момент факты и обратимость. После этого формулируем профилактический эксперимент с критерием проверки. Такое разложение не доказывает причину и не оправдывает любое действие; оно делает границу неизвестного видимой и оставляет материал для следующей проверки.

Что считать фактом, а что — объяснением

Факт в ретроспективе — узкое утверждение, которое можно связать с артефактом: отметкой времени, снимком состояния, версией конфигурации, сообщением runbook или разрешённой записью наблюдения. «В 10:03 была зафиксирована версия» — факт, если рядом есть ссылка на его источник. «Версия сломала маршрут» — уже объяснение. Вторую фразу нельзя прятать в timeline: у неё могут быть альтернативы, а источника в одной строке обычно недостаточно.

Три записи, которые нельзя склеивать
Тип записиВопросМинимальные поляНедопустимый вывод
Фактчто зафиксировано и где?время, формулировка, evidence referenceкто виноват и почему это произошло
Решение в моментекакое действие выбрали при известных данных?время, действие, доступные факты, оценка неизвестначто решение было ошибкой без контекста
Профилактический экспериментчто хотим проверить до следующего изменения?гипотеза, метод, критерий, rollbackчто эффект уже получен
Action itemкто и когда доведёт работу?владелец роли, срок, ссылка на проверкучто задача устраняет все риски
Учебная timeline: три synthetic факта идут раньше synthetic решения, за ним расположен обратимый профилактический эксперимент. Стрелки показывают порядок records, а не причину, вину или эффект настоящего инцидента.
Timeline отделяет наблюдаемые поля от решения в моменте и будущего эксперимента. Это учебная схема fixed synthetic records, не лог, alert, trace, incident report или выгрузка production-системы.

Сначала сужаем карточку факта

Начните с одной строки: когда и какой артефакт был доступен. Не добавляйте в неё оценку человека, пересказ диалога и гипотезу о механизме. Если источник нельзя назвать из-за доступа или чувствительности, укажите тип источника и статус «не проверено», а не заполняйте пробел правдоподобным текстом. Важна не литературная полнота, а возможность через неделю отличить сохранённое свидетельство от воспоминания участника.

В учебной модели ниже есть три fixed synthetic fact records. У каждого заранее задан `occurredAt`, `statement` и `evidenceRef`, а поле `inference` жёстко равно `not-a-cause-claim`. Это не способ хранить настоящий инцидент и не пример корректного schema для вашей базы. Он нужен, чтобы на ревью заметить подмену: когда в поле факта появляется причина, фамилия, чужая деталь или обещание эффекта, модель отклоняет запись. Отрицательная ветка полезнее красивой timeline: она показывает, что именно нельзя честно вывести.

Решение нужно читать во времени

Следующая запись отвечает не на вопрос «кто ошибся», а на вопрос «какой выбор был сделан с теми данными, которые уже были». Для решения полезны действие, timestamp и список fact IDs. Этот список не доказывает правильность действия. Он показывает границу информации: какие записи могли повлиять на выбор, а какие появились позже. После инцидента у нас больше контекста, поэтому задним числом легко назвать очевидным то, чего в моменте никто ещё не видел.

Если решение было необратимым, не смягчайте это словом «оперативное». Напишите, что именно нельзя быстро вернуть, кто владеет точкой возврата и какой сигнал подтверждает остановку. Если действие обратимо, всё равно нужен критерий: «вернуть конфигурацию до версии X» недостаточно без способа проверить, что новая ветка больше не применяется. Google в своём примере postmortem показывает timeline и action items; это хороший ориентир формы, но не разрешение приписывать своей системе чужой результат или срок.

Профилактика — это эксперимент, а не приговор

После разбора хочется написать «добавить проверку, чтобы такого больше не было». Такая задача слишком широка. Она не называет, что проверяем, на каком входе, какой результат будет достаточным и как остановиться, если изменение ухудшит ситуацию. Вместо этого формулируйте эксперимент: гипотеза, минимальный метод, критерий успеха, владелец роли и обратимый rollback. До прогона это намерение проверить, а не доказательство, что инцидент больше не повторится.

Например, можно проверить только наличие reversible checkpoint в одном runbook. Успехом будет не «система стала надёжнее», а «перед действием перечислены точка возврата, владелец и наблюдаемый критерий остановки». Если checkpoint не помещается в карточку, он ещё не готов к автоматизации. Такое ограничение намеренно скромное: оно не измеряет availability, не читает настоящие alerts и не делает вывод о влиянии на пользователей.

Прогоните маленький контракт до встречи

Код создаёт фиксированный synthetic набор в памяти и проверяет двадцать одну assertion. Он принимает только полный набор известных top-level полей, три exact fact records, одно decision record с полным набором известных фактов и один experiment record с rollback. Отдельные отрицательные ветки отклоняют лишнее поле, неполный evidence reference, чужой текст факта, решение с частью фактов, именованного виновника, утверждение root cause, обещание реального эффекта и experiment без точки возврата. PASS означает только то, что учебный контракт не перепутал типы записей.

import {
  assembleSyntheticPostmortem,
  runPostmortemFixture,
  syntheticIncidentRecords,
} from './upgrade-2023-11.mjs';

const card = assembleSyntheticPostmortem(syntheticIncidentRecords);
if (!card.accepted) throw new Error(card.reason);

const report = runPostmortemFixture();
if (!Object.values(report.assertions).every(Boolean)) throw new Error('fixture failed');

console.log(card.evidence.permittedConclusion);
// record-boundaries-present-in-fixed-synthetic-model

// Только fixed synthetic records в памяти. Нет I/O, сети, CI,
// logs, traces, alerts, users или production runtime.

node web/scripts/upgrade-2023-11.mjs --verify-fixture

# PASS не читает и не отправляет реальные incident data, logs, traces, alerts, users, CI или сеть.
# Он не устанавливает виновника, причину или эффект настоящего изменения.

В результате корректная формулировка звучит так: «в fixed synthetic модели три факта были доступны до решения; experiment имеет rollback и критерий». Некорректная: «мы нашли виновника» или «проверка уже предотвратила следующий сбой». Разница важна для редактора документа: первая фраза оставляет следующий шаг, вторая закрывает вопрос без evidence.

Маршрут: симптом → причина → проверка → действие

  1. Симптом. Черновик содержит имена людей и оценки, но не показывает, какие записи были доступны до действия.
  2. Причина. Факт, решение и профилактика лежат в одной хронологической строке, поэтому позднее знание маскируется под знание в моменте.
  3. Проверка. Для каждого предложения поставьте метку: факт с источником, решение с набором доступных фактов или проверяемый experiment. Строку без метки вынесите в вопрос.
  4. Действие. Оставьте timeline из фактов; привяжите решение к fact IDs; превратите профилактику в маленькую гипотезу с критерием и rollback.
  5. Проверка вывода. На ревью спросите, есть ли в документе утверждение о причине, человеке или эффекте, которое не имеет отдельного evidence. Если есть — смените статус на «не проверено».
  6. Следующий шаг. Выберите один action item и заранее договоритесь, какой артефакт подтвердит его результат в разрешённой среде.

Когда остановиться и как откатить

Остановите редактуру, если команда начинает спорить о мотивах, а не о данных в моменте. Это не запрет на ответственность: последствия действия и владелец следующей проверки остаются в документе. Просто мотивацию нельзя подменять evidence. Вернитесь к последнему факту с источником, зафиксируйте открытый вопрос и договоритесь, кто может добавить разрешённый артефакт. Не пытайтесь закрыть пробел реконструкцией из памяти одного участника.

Rollback этого fixture узкий: `rollbackSyntheticPostmortem()` возвращает snapshot synthetic records и помечает `externalIO=no-system-change`. Он не отменяет rollout, не удаляет реальные данные, не выключает alert, не меняет CI и не исправляет production runtime. В реальном разборе rollback должен быть отдельным операционным планом с системой, владельцем, границей воздействия и наблюдаемым критерием завершения. Учебная функция лишь не позволяет назвать имитацию операционным действием.

Ограничения и следующий шаг

Пакет не содержит настоящего incident data, logs, traces, alerts, users, CI, сетевых запросов или production runtime. Времена, факт-карточки, действие и experiment полностью synthetic. Он не устанавливает виновника, root cause, impact, доступность, пользовательский эффект или результат изменения. Наличие структуры не делает разбор законченным: настоящая команда должна отдельно проверить доступ, privacy, retention, юридические границы, правила disclosure и способ связывать evidence с источником.

Следующий шаг — взять один завершённый, разрешённый для обучения случай и сначала заполнить только колонки «факт» и «источник». Лишь потом добавить решения в моменте и один обратимый experiment. Если до встречи неизвестно, где лежит evidence, это уже результат: не пишите причину, пока не определите владельца и допустимый способ проверки. Так короткая ретроспектива становится техническим документом, а не стенограммой поиска виноватого.

Историческая граница ноября 2023

К ноябрю 2023 были доступны Google SRE Book с разделом о blameless postmortems и примером timeline/action items, NIST SP 800-61 Rev. 2 с post-incident lessons learned, а также CISA playbooks 2021 для федерального cybersecurity response. Здесь из них взята дисциплина документировать факт, review и follow-up. Материал не утверждает, что подход Google или требования американского security-контура автоматически подходят любой команде, и не называет их доказательством конкретного эффекта.

Проверяемые источники

  • Google SRE Book: Postmortem Culture: Learning from Failure, 2017 — официальная публикация Google, доступная до ноября 2023. Она описывает опыт и практику Google: документирование инцидента, разбор contributing causes, review и action items. Это не универсальное доказательство эффекта для другой команды.
  • Google SRE Book: Example Postmortem, 2017 — официальный учебный пример с timeline, impact, action items и lessons learned. Он показывает форму артефакта, но не является данными этого fixture или причиной какого-либо чужого сбоя.
  • NIST SP 800-61 Revision 2: Computer Security Incident Handling Guide, август 2012 — официальное руководство по обработке компьютерных security-инцидентов, включая phase post-incident lessons learned. Его область — incident response в security, а не готовый шаблон для любого продуктового или эксплуатационного разбора.
  • CISA: Federal Government Cybersecurity Incident and Vulnerability Response Playbooks, ноябрь 2021 — официальный федеральный playbook США, опубликованный до ноября 2023. Он относится к FCEB cybersecurity response; статья не переносит его обязательства, сроки или полномочия в иной контур.