8 lines
18 KiB
JSON
8 lines
18 KiB
JSON
{
|
||
"index": 149,
|
||
"slug": "editorial-2023-11-mechanism-postmortem",
|
||
"title": "Postmortem без заднего знания: как связать факт, решение и действие",
|
||
"excerpt": "После сбоя команда легко принимает позднюю гипотезу за причину. Разбираем временную границу знания, контракт записей и проверяемый профилактический шаг.",
|
||
"contentHtml": "<p>После сбоя в чате появляется короткое объяснение: «релиз сломал обработку, поэтому инженер откатил его». В одной фразе смешаны событие, причина, решение и оценка. Но в момент отката команда могла не знать, был ли виноват релиз. Она могла видеть только рост ошибок и доступный способ остановить поток.</p>\n<p>Цена ошибки — не неточная формулировка. Команда ставит защиту вокруг самого заметного элемента истории. Она добавляет проверку к релизу, хотя сбой мог возникнуть из-за данных, лимита или внешней зависимости. Следующий разбор повторяет ту же подмену. Postmortem становится рассказом задним числом, а не инструментом изменения системы.</p>\n<p>Рабочая модель разделяет три записи: наблюдаемый факт, решение с доступной в тот момент информацией и будущую проверку гипотезы. Время ограничивает вывод. Поздний лог может объяснить событие, но не доказывает, что этот лог был доступен оператору при выборе. Так документ сохраняет неизвестное и показывает, какое действие нужно проверить.</p>\n<h2>Граница между фактом и объяснением</h2>\n<p>Факт описывает то, что можно привязать к источнику: время, сигнал, значение поля, изменение состояния. Он не обязан содержать причину. Запись «в 10:03 доля ответов 5xx превысила порог» сильнее записи «сервис упал из-за релиза», если связь с релизом ещё не проверена.</p>\n<p>Решение описывает действие и снимок доступных фактов. Его нельзя оценивать полным набором данных, который появился позже. Иначе документ наказывает человека за информацию, которой у него не было, и скрывает вопрос к системе: почему нужный сигнал, инструкция или безопасный способ остановки не были доступны раньше.</p>\n<p>Эксперимент переводит гипотезу в проверяемую работу. Он должен назвать один риск, способ проверки, критерий успеха и обратный путь. Фраза «добавить больше мониторинга» не даёт критерия. Фраза «для этого маршрута появляется alert при трёх последовательных ошибках, а дежурный подтверждает его в тестовом окружении» уже задаёт проверку формы. Она всё ещё не доказывает эффект в production.</p>\n<table><caption>Как разобрать спорную фразу postmortem</caption><thead><tr><th scope=\"col\">Слой</th><th scope=\"col\">Что записать</th><th scope=\"col\">Что не утверждать</th></tr></thead><tbody><tr><td>Факт</td><td>Время, наблюдение и ссылка на лог, метрику или change.</td><td>«Это точно причина» без проверки связи.</td></tr><tr><td>Решение</td><td>Действие и факты, доступные до него.</td><td>Оценку через поздние данные.</td></tr><tr><td>Гипотеза</td><td>Какой механизм нужно проверить.</td><td>Причину, если она пока только предполагается.</td></tr><tr><td>Эксперимент</td><td>Критерий, владелец роли и rollback.</td><td>Обещание предотвратить любой повтор.</td></tr></tbody></table>\n<h2>Механизм: время ограничивает допустимый вывод</h2>\n<p>У каждой записи есть <code>occurredAt</code>. У решения есть <code>availableFactIds</code>. В список попадают только факты, которые уже существовали до решения. Это простое правило удерживает границу знания. Новая запись может изменить гипотезу о причине, но не меняет набор данных, на котором приняли исходное решение.</p>\n<p>Рассмотрим учебный пример. Он не читает реальные логи и не описывает настоящий инцидент. В нём зафиксированы три факта, решение остановить проверку изменения и эксперимент с обратным путём.</p>\n<pre><code>{\n \"facts\": [\n {\"id\": \"f-01\", \"at\": \"10:00\", \"text\": \"доля ответов 5xx выросла\", \"source\": \"metric-card-01\"},\n {\"id\": \"f-02\", \"at\": \"10:03\", \"text\": \"изменена версия конфигурации\", \"source\": \"change-02\"}\n ],\n \"decision\": {\n \"at\": \"10:05\",\n \"action\": \"остановить продвижение\",\n \"availableFactIds\": [\"f-01\", \"f-02\"]\n },\n \"experiment\": {\n \"hypothesis\": \"явная проверка версии сократит время обнаружения\",\n \"successCriterion\": \"проверка видна в тестовом сценарии\",\n \"rollback\": \"удалить проверку и вернуть прежнюю конфигурацию\"\n }\n}</code></pre>\n<p>Код показывает форму, а не результат. В реальном документе <code>source</code> должен указывать разрешённый артефакт, который команда действительно может открыть. Время должно использовать одну часовую зону. Если источник недоступен, это нужно записать как ограничение, а не заменить догадкой.</p>\n<p>Модель допускает, что причиной окажется не изменение версии. Например, поздняя проверка покажет исчерпанный лимит внешнего сервиса. Тогда факты и исходное решение остаются полезными. Меняется гипотеза и, возможно, эксперимент. Нельзя переписать факт так, чтобы он заранее подтверждал новую версию.</p>\n<figure><img src=\"/assets/editorial/2023/postmortem-2023-decision-record.svg\" alt=\"Схема связывает факты с решением, а решение — с ограниченным профилактическим экспериментом; ветка с именем виновника перечёркнута\" loading=\"lazy\" /><figcaption>Учебная схема границ postmortem: факты входят в решение только через доступную временную последовательность, а профилактика получает критерий и rollback. Рисунок не показывает настоящий инцидент.</figcaption></figure>\n<h2>Симптом → причина → проверка → действие</h2>\n<table><caption>Диагностическая матрица для разбора</caption><thead><tr><th scope=\"col\">Симптом</th><th scope=\"col\">Вероятная причина записи</th><th scope=\"col\">Проверка</th><th scope=\"col\">Действие</th></tr></thead><tbody><tr><td>В первом абзаце назван виновник.</td><td>Имя человека используется как объяснение состояния.</td><td>Убрать имя и спросить, какое условие системы нужно изменить.</td><td>Записать владельца будущего действия отдельно от причины.</td></tr><tr><td>Решение выглядит очевидным после чтения всей timeline.</td><td>К решению добавили факты, появившиеся позже.</td><td>Сравнить время решения с каждым <code>availableFactId</code>.</td><td>Оставить только предшествующие факты и сохранить unknown.</td></tr><tr><td>Action item звучит как «добавить мониторинг».</td><td>Гипотеза не имеет измеримого критерия.</td><td>Спросить, какой артефакт должен измениться и как увидеть проход.</td><td>Указать сигнал, порог, владельца роли и rollback.</td></tr><tr><td>После исправления обещают отсутствие повторов.</td><td>Учебная проверка выдана за production-результат.</td><td>Найти источник эффекта и период наблюдения.</td><td>Сузить вывод до «проверяет форму» или собрать реальные данные.</td></tr></tbody></table>\n<h2>Как писать решение без поиска виноватого</h2>\n<p>Отсутствие поиска виноватого не отменяет ответственности. В документе должны быть владельцы действий, сроки и правила эскалации. Но роль владельца отвечает на вопрос «кто доведёт изменение», а не на вопрос «почему система оказалась в таком состоянии». Для второго вопроса нужны условия: доступный сигнал, версия инструкции, права, лимит, автоматическая защита или отсутствие безопасной остановки.</p>\n<p>Полезно отделить две оценки. Первая: было ли действие разумным при доступной информации? Вторая: какие условия сделали такой выбор вероятным? Первая требует воспроизвести границу знания. Вторая ведёт к изменению интерфейса, runbook, алерта или архитектуры. Поздняя причина может помочь второй оценке, но не должна подменять первую.</p>\n<p>Отрицательный путь важен не меньше положительного. Если источник не открывается, поле остаётся неизвестным. Если rollback нельзя выполнить безопасно, эксперимент не готов. Если критерий нельзя проверить без production-доступа, нужно сначала спроектировать безопасную проверку или признать границу. Документ не должен заполнять пробелы уверенным тоном.</p>\n<h2>Порядок действий</h2>\n<ol><li>Запишите наблюдаемый симптом с временем, системой и доступным источником.</li><li>Отделите факт от слов «вызвал», «из-за», «виноват» и «предотвратит». Эти слова требуют отдельного доказательства.</li><li>Соберите решение как снимок: действие, время и полный список фактов, известных до выбора.</li><li>Проверьте временной порядок и единую часовую зону. Удалите из контекста решения все поздние записи.</li><li>Сформулируйте одну гипотезу о защите. Не превращайте список идей в план без критерия.</li><li>Добавьте бинарный или наблюдаемый критерий, владельца роли, границы доступа и rollback.</li><li>Проверьте учебную форму отдельно от production-эффекта. Успешная проверка JSON или документа не доказывает снижение числа инцидентов.</li><li>Закройте разбор только после того, как читатель, не участвовавший в инциденте, сможет восстановить факт, решение и следующий проверяемый шаг.</li></ol>\n<h2>Ограничения</h2>\n<p>Эта модель не заменяет incident command, расследование безопасности, юридическую оценку или правила хранения персональных данных. В security-контуре источники и доступы требуют отдельной политики. В распределённой системе часы могут расходиться, а источник может измениться после события. Тогда нужно хранить версию артефакта, часовой пояс и допустимый уровень точности.</p>\n<p>Три слоя не доказывают причинность. Они только не дают написать вывод шире доступных данных. Причинную связь проверяют отдельными методами: воспроизведением, сравнением изменений, экспериментом или анализом данных. Если эти методы недоступны, корректная формулировка — «причина не подтверждена».</p>\n<p>Учебный JSON выше фиксирует структуру и отрицательный путь. Он не запускается на настоящей инфраструктуре, не читает метрики и не измеряет влияние. Не переносите его идентификаторы, время и критерий в production без адаптации к своим источникам, ролям и процедурам отката.</p>\n<h2>Проверяемый критерий готовности</h2>\n<p>Postmortem готов к техническому review, если независимый читатель может открыть источник каждого факта, увидеть, что решение ссылается только на предшествующую информацию, и проверить один профилактический эксперимент по его критерию. Если хотя бы один пункт не выполняется, статус должен быть «не готов», а следующий шаг — устранение конкретного пробела: источник, временная граница, критерий или rollback.</p>\n<h2>Проверяемые источники</h2>\n<ul><li><a href=\"https://sre.google/sre-book/postmortem-culture/\" target=\"_blank\" rel=\"noopener noreferrer\">Google SRE Book: Postmortem Culture: Learning from Failure</a> — официальный материал о документировании инцидента, contributing causes и follow-up; он описывает практику Google и не доказывает эффект этой модели для любой команды.</li><li><a href=\"https://sre.google/sre-book/example-postmortem/\" target=\"_blank\" rel=\"noopener noreferrer\">Google SRE Book: Example Postmortem</a> — официальный учебный пример с timeline и action items; он показывает форму документа, а не данные конкретного инцидента.</li><li><a href=\"https://csrc.nist.gov/pubs/sp/800/61/r2/final\" target=\"_blank\" rel=\"noopener noreferrer\">NIST SP 800-61 Revision 2: Computer Security Incident Handling Guide</a> — официальное руководство для security incident response и lessons learned; его область не распространяется автоматически на любой эксплуатационный разбор.</li></ul>"
|
||
}
|