{ "index": 148, "slug": "editorial-2023-11-field-postmortem", "title": "Полевой разбор сбоя: как отделить факт от догадки и довести проверку до действия", "excerpt": "Практический маршрут для разбора сбоя: восстановить доступные факты, проверить решение в его контексте и выбрать одну обратимую защиту с явным критерием готовности.", "contentHtml": "

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

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

Сначала восстановите наблюдаемое

Начните с симптома, а не с объяснения. Запишите, что увидел пользователь или оператор: запросы стали получать ошибку, очередь перестала уменьшаться, запись появилась дважды, откат не изменил состояние. Добавьте время, область воздействия и способ обнаружения. Если значение неизвестно, напишите «не установлено». Такая строка полезнее числа, которое никто не может подтвердить.

У каждого факта должен быть источник. Это может быть метрика, лог, трасса, запись изменения, сообщение в канале или ручное наблюдение. Источник не делает утверждение автоматически истинным. Он позволяет другому читателю повторить проверку и увидеть границы данных. Сообщение в чате помогает восстановить порядок действий, но само по себе не доказывает техническую причину.

Отделяйте время события от времени знания. Сбой мог начаться в 10:02, а команда увидела его в 10:11. Решение в 10:12 нужно оценивать по сигналам, доступным в 10:12. Поздняя трасса или найденный после инцидента фрагмент конфигурации объясняют контекст расследования, но не меняют исходный набор данных.

Механизм: три разных записи

Разбор становится проверяемым, если в нём не смешиваются факты, решения и будущие проверки. Факт описывает наблюдаемое событие и ссылается на источник. Решение описывает действие и перечисляет факты, которые были доступны перед ним. Эксперимент проверяет гипотезу после события и имеет ограниченный масштаб, критерий остановки и возврат.

Unknown — не дырка, которую нужно срочно закрыть догадкой. Это отдельное состояние. Для него укажите вопрос, владелец которого может найти ответ, допустимый источник и срок повторной проверки. Если источник потерян, честный вывод звучит как «причина не установлена». Тогда улучшайте хранение или наблюдаемость, а не переписывайте прошлое.

Такой порядок не отменяет технический анализ. Он не запрещает говорить о root cause. Он требует пометить причинную связь как гипотезу, пока её не поддерживают данные. Иногда один инцидент имеет несколько contributing causes: дефект, слабый сигнал и неясный runbook. Сведение всего к одной причине убирает условия, при которых защита не сработала.

Учебный пример: решение при неполном сигнале

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

type Fact = {\n  id: string\n  observedAt: string\n  source: string\n  statement: string\n}\n\ntype Decision = {\n  action: 'pause-change' | 'rollback' | 'continue-observing'\n  basedOn: string[]\n  decidedAt: string\n}\n\ntype Experiment = {\n  hypothesis: string\n  scope: string\n  criterion: string\n  rollback: string\n}

В этом фрагменте структура важнее названий полей. basedOn может ссылаться только на факты, известные до decidedAt. Эксперимент не должен обещать «исключить все повторы». Его критерий должен отвечать на вопрос: что именно проверяем, когда остановимся и какое действие выполним при отрицательном результате.

Например, гипотеза может звучать так: «В runbook не указан порог, при котором нужно остановить изменение». Ограниченная проверка — дать документ инженеру, который не участвовал в событии, и попросить назвать действие при заданном сигнале. Критерий — он находит порог, владельца решения и ссылку на возврат без устного пояснения. Если не находит, это результат проверки формы документа, а не доказательство, что runbook вызвал настоящий сбой.

\"Цикл
Учебный цикл связывает факт, решение, неизвестность и ограниченную проверку. Иллюстрация не показывает реальный incident workflow, трафик или подтверждённый production-эффект.

Симптом → причина → проверка → действие

Симптом → причина → проверка → действие
СимптомПричинаПроверкаДействие
В разборе есть имя, но нет защитыПерсональная оценка заменила описание условия отказаПопросить назвать сигнал, границу управления и отказавшую защитуПереписать вывод как проверяемое системное условие
Хронология противоречит логамПозднее знание смешали с исходным контекстомСверить время события, время знания и источник каждой строкиРазделить timeline и историю расследования
Все версии выглядят правдоподобноГипотезы записали как фактыУ каждого утверждения найти evidence reference или пометить unknownОставить competing hypotheses и назначить различающую проверку
После разбора появился длинный backlogКоманда обещает исправить всё сразуДля каждой задачи проверить scope, criterion и rollbackВыбрать один риск и один обратимый эксперимент
Тест зелёный, а повтор не обнаруживаетсяПроверяли форму, но не сигнал и отрицательный путьСымитировать отказ, тайм-аут, повтор и отсутствие данныхДобавить наблюдаемый сигнал или признать, что тест ограничен формой

Проверьте решение в его моменте

Выберите одно действие из хронологии. Запишите, что было известно до него, какие варианты были доступны и чем они отличались по риску. Не спрашивайте сначала «почему инженер так сделал». Спросите: какой сигнал он видел, какие права имел, какой срок был у решения, какой путь возврата существовал. Ответ может выявить плохой выбор. Но он также может показать, что нужный dashboard отсутствовал, runbook был неоднозначен, а безопасный откат требовал доступа, которого у смены не было.

Оценка должна включать отрицательный путь. Если выбран rollback, что происходит, когда он не меняет метрику? Если выбран pause, кто решает, когда возобновить работу? Если система получила двойной запрос, можно ли повторить операцию без двойной записи? Если ответа нет, документ описывает намерение, а не управляемый механизм.

Не называйте действие обратимым только потому, что можно переключить флаг. Возврат маршрута не удаляет уже созданную запись, не отзывает отправленное сообщение и не отменяет внешний платёж. Для состояния нужны отдельные правила сверки и компенсации. Если их нет, сузьте эксперимент до read-only-пути или оставьте изменение в режиме наблюдения.

Сделайте одну профилактическую проверку

После хронологии легко составить десять улучшений: новый alert, обязательный review, запрет ручных изменений, переработка сервиса. Длинный список создаёт иллюзию движения. Выберите один риск, который можно проверить за короткий цикл. Укажите гипотезу, scope, owner роли, criterion, дату review и rollback. Если результат нельзя увидеть без новых предположений, эксперимент слишком широк.

Учебная проверка документа может быть достаточной первой ступенью. Дайте карточку с фактом, решением и неизвестностью независимому читателю. Попросите его ответить на три вопроса: что было известно, что сделали и что ещё только проверяют. Если он смешивает ответы, граница в документе не работает. Исправьте поля и повторите проверку. Это проверяет читаемость и полноту формы. Это не измеряет надёжность сервиса и не подтверждает предотвращение инцидента.

Техническая профилактика должна менять механизм. Если проблема связана с отсутствующим сигналом, добавьте измерение и проверьте его на отрицательном сценарии. OpenTelemetry разделяет telemetry signals на traces, metrics и logs; это удобная рамка для выбора наблюдаемого свидетельства, но сам факт наличия сигнала не доказывает, что он покрывает нужный вопрос. Сначала сформулируйте вопрос, затем выберите сигнал.

Порядок действий

  1. Опишите симптом, время, область воздействия и цену повторения. Не добавляйте причину в эту строку.
  2. Соберите факты с timestamp и ссылкой на источник. Разделите время события и время, когда команда узнала о нём.
  3. Выберите одно решение. Привяжите его только к фактам, доступным до решения, и перечислите реальные альтернативы.
  4. Вынесите поздние объяснения в hypotheses. Для каждой укажите подтверждающий или опровергающий источник.
  5. Отметьте unknown явно. Назначьте вопрос, владельца роли и безопасный способ проверки. Не заполняйте пробел именем человека.
  6. Проверьте отрицательный путь: отказ, тайм-аут, повтор, неполный ответ и неуспешный rollback.
  7. Выберите один обратимый эксперимент. Назовите scope, criterion, owner, дату review и точку остановки.
  8. Проведите проверку независимым читателем или автоматическим тестом формы. Запишите, что именно проверка не покрывает.
  9. Передайте результат в рабочий процесс с владельцем и сроком. Закройте задачу только по критерию, а не по факту обсуждения.

Ограничения

Разбор не восстанавливает удалённые логи и не превращает неполный сигнал в доказательство. При малом retention часть причин останется неизвестной. При sampling трасса может не содержать нужный запрос. При ручной хронологии порядок сообщений может быть неточным. Эти ограничения нужно показывать рядом с выводом.

Blameless-подход не означает отсутствие ответственности. Он запрещает подменять техническое объяснение обвинением. Если человек нарушил правило доступа или безопасности, это может потребовать отдельного процесса. В postmortem всё равно нужно описать, какая проверка или граница позволила нарушению пройти и как её можно сделать наблюдаемой.

Учебные структуры, synthetic-данные и локальные тесты имеют узкую область применимости. Они проверяют связи между полями и ветви отрицательного пути. Они не подтверждают impact, доступность, безопасность, финансовый ущерб, поведение пользователей или результат изменения в production. Такой результат нельзя приписывать команде без реальных данных и отдельной проверки.

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

Разбор готов к передаче, если независимый читатель может без устного контекста показать: симптом и цену ошибки; источник каждого факта; решение и набор доступных до него данных; неизвестный пробел; одну причинную гипотезу с проверкой; профилактическое действие с owner, criterion и rollback. Для необратимых эффектов отдельно написано, что возврат не покрывает.

Критерий готовности не звучит как «сбой больше не повторится». Он звучит проверяемо: «по этой записи читатель назовёт сигнал остановки и действие при его появлении» или «тест обнаружит двойной запрос до записи второго результата». Если условие не выполняется, разбор ещё не закончен. Сузьте вывод, соберите источник или оставьте неизвестность явно.

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

"}