Проблема релизного дня редко звучит технически чисто. На панели красный блок, кто-то говорит «бюджет почти закончился», другая команда просит не задерживать изменение, а on-call не может объяснить, какой пользовательский путь пострадал. Если принять решение только по цвету, можно остановить безопасное исправление или выпустить изменение в момент, когда полезнее сначала разобраться с надёжностью. Цена — не только риск для пользователя. Команда привыкает считать SLO отчётностью, потому что число не связывается с действием и ответственностью.
Обратная ошибка — превратить budget в автоматический запрет. Формула сама не знает, является ли изменение обратимым, закрывает ли оно security-уязвимость, относится ли к тому же пути и подтверждены ли входные данные. Без policy владелец узнаёт о решении уже после того, как CI или чей-то скрипт сделал необратимое действие. Цена — скрытые полномочия и плохая диагностика: красный график объясняет «что-то не так», но не показывает причину, границу или следующий безопасный шаг.
Error budget нужен для вопроса, а не для победы в споре
Google SRE Book в главе 2017 года описывает error budget как способ обсудить допустимый риск между разработкой и надёжностью. В Example Error Budget Policy Google SRE Workbook от 19 февраля 2018 года отдельно сказано, что policy не является наказанием за missed SLO. Практический смысл для небольшой команды: заранее договориться, какое evidence нужно перед решением и какие обратимые действия допустимы. Тогда цифра не заканчивает разговор; она запускает один и тот же маршрут для релиза, reliability-задачи и разбора расхождения.
Это особенно важно, когда SLI — proxy. Низкая доля good событий может относиться к одному backend-ответу, но не объяснять весь пользовательский путь. Высокая доля может скрывать ошибку после точки измерения. Поэтому петля решения содержит два разных перехода: сначала проверить, что сигнал соответствует договору, затем искать причину в разрешённых данных. Нельзя перепрыгнуть из одного synthetic процента к выводу «был инцидент» или «нужно заблокировать production». Эти утверждения требуют других фактов и других владельцев.
| Шаг | Что должен принести owner | Допустимое действие | Чего не делает шаг |
|---|---|---|---|
| Сигнал | версия SLI-contract, scope, окно, target и time of observation | открыть разбор | не объявляет incident автоматически |
| Проверка формулы | eligible/good definitions, exclusions и источник | остановить неверный расчёт | не доказывает причину деградации |
| Контекст | диагностические данные разрешённой среды и known changes | сформировать гипотезу | не подменяет продуктовый impact |
| Решение | owner, policy, обратимость и evidence | сузить rollout, исправить, отложить или продолжить с контролем | не выдаёт CI-право учебному fixture |
| Повторная проверка | та же формула и критерий после действия | подтвердить или пересмотреть гипотезу | не обещает отсутствие следующих сбоев |
Один сигнал не объясняет причину
SLI отвечает на заранее узкий вопрос: выполняется ли выбранная мера в выбранной границе. Он не обязан хранить корневую причину. Когда сигнал отклоняется, следующей задачей становится диагностика: изменение версии, зависимость, класс ответов, очередь, лимит, данные или сценарий клиента. Набор диагностических сигналов зависит от архитектуры и доступа. Нельзя заранее объявить, что trace, log или dashboard всегда дадут ответ. Но можно заранее назначить, кто проверяет scope и кто подтверждает, что данные относятся к одному и тому же периоду.
В Google SRE Workbook 2018 о SLO alerting подчёркнута разница между alerting metric и данными, которые помогают расследовать причину. Этот вывод не позволяет сказать «любая красная точка требует page». Он учит не смешивать роль меры и роль объяснения. Для одних путей нужен срочный response, для других — ticket, review или временное ограничение rollout. Сначала должна быть policy с владельцем и уровнями действий, а затем выбранные thresholds. Без этого alert просто переносит спор из чата в notification channel.
Policy должна быть короткой и исполнимой людьми
Минимальная policy помещается в несколько строк: какие SLO относятся к релизу, кто владелец решения, какие данные обязательны, что считается обратимым действием, какие исключения требуют отдельного одобрения и когда договор пересматривают. Важно указать не только «при exhausted budget остановить изменения», но и что именно означает exhausted по версии формулы, какая проверка защищает от ложного сигнала и кто может разрешить security fix. Иначе правило будет жить только в памяти того, кто однажды настроил дашборд.
Synthetic fixture оставляет полномочие у владельца
Здесь fixture специально не играет роль release gate. Он возвращает `proposal`, но всегда сохраняет `releaseAuthority=not-granted`. В хорошей synthetic ветке остаётся четыре условные единицы бюджета, поэтому proposal — review before change. В другой ветке условный budget exhausted, но это всё равно не incident и не команда остановить реальную выкладку. Fixture не видит code diff, security context, CI result, feature flag, owner approval или production traffic; выдавать ему полномочие было бы ошибкой модели.
import { runSloFixture } from './upgrade-2023-10.mjs';
const report = runSloFixture();
if (!Object.values(report.assertions).every(Boolean)) throw new Error('fixture failed');
console.log(report.samples.valid.decision.releaseAuthority); // not-granted
console.log(report.samples.valid.calculation.observed); // not-observed
// Полный synthetic вход и отрицательные ветки находятся в этом же модуле.
// Нет чтения проекта, monitoring, CI, сети, real SLI, incident, burn rate или availability.
node web/scripts/upgrade-2023-10.mjs --verify-fixture
# PASS подтверждает только согласованность synthetic договора и его отрицательных веток.
Запуск создаёт фиксированные JS-объекты в памяти и завершается. Он не читает проект, не вызывает monitoring, CI, сеть, HTTP, SDK или часы. У него нет реальных SLI, availability, incident, burn rate, event stream либо dashboard. Даже отрицательная ветка `synthetic-reliability-work-first` описывает только ожидаемую форму учебной развилки. PASS проверяет, что она не перепутана с разрешением на release, а не то, что какой-либо сервис достиг цели.
Маршрут: симптом → причина → проверка → действие
- Симптом. Релизная команда видит красный budget-показатель, но не может связать его с конкретным путём, окном и версией SLI-contract.
- Причина. Сигнал, формула, диагностические данные и policy развивались отдельно; график получил вес решения, но не получил owner и границы полномочий.
- Проверка формулы. Сверьте scope, good/eligible events, exclusions, окно, target и источник. Если версия правила неизвестна, остановите интерпретацию, а не релиз по умолчанию.
- Проверка контекста. В разрешённой среде соберите минимальные данные для одной гипотезы и отделите их от synthetic fixture. Не называйте correlation или событие доказанными, пока источник не подтверждён.
- Действие. Owner выбирает обратимый шаг согласно policy: сузить exposure, исправить причину, отложить non-urgent change или продолжить с явным контролем. Выбор фиксируется вместе с evidence.
- Повтор. После действия примените ту же версию формулы и проверьте известный критерий. При расхождении пересматривайте гипотезу, а не подгоняйте denominator.
План обратного действия должен предшествовать спору
Слова «если что, откатим» не являются policy. До изменения нужно назвать, что именно меняется: код, конфигурация, правило обработки или ограничение exposure. Затем — какую версию вернуть, кто это сделает, что будет считаться подтверждением и какие потребители затронуты. Если действие нельзя обратить, policy должна сказать это прямо и потребовать иной уровень review. Error budget полезен тем, что превращает такое обсуждение в ожидаемую часть работы, а не в реакцию на громкий график.
Учебный rollback нарочно скучный: он возвращает пять полей synthetic договора и говорит, что monitoring, CI и сеть не затронуты. Он не может остановить deploy или удалить записи, потому что ничего такого не создавал. В реальной системе это ограничение не повод делать вид, что rollback существует. Это повод вынести операционный план в отдельный runbook с теми системами, где у команды действительно есть права и наблюдение.
Ограничения и следующий шаг
Пакет не показывает production incident, доступность, SLI, burn rate, error budget, алерт, CI run, релиз, пользователя или стоимость. Он не читает проект и не обращается к monitoring, CI, сети, HTTP, SDK, clock или dashboard. Все имена, события, количества и состояния имеют synthetic marker и существуют только в памяти Node. Google-источники задают исторические определения и примеры policy, но не предоставляют автоматический gate и не дают этому fixture права оценивать реальный риск.
Следующий шаг для команды — сделать одну реальную decision record до следующего спорного изменения. В ней должны быть SLI-contract version, owner, scope, источник evidence, окно, target, policy branch, обратимое действие и повторная проверка. Если не хватает хотя бы одной строки, не скрывайте пробел новой визуализацией. Сначала назначьте владельца и сузьте вопрос. Тогда SLO перестанет быть декорацией и станет способом честно выбрать следующий инженерный шаг.
Историческая граница октября 2023
К октябрю 2023 уже были доступны Google SRE Book 2017 и Google SRE Workbook 2018 с примерами SLO document, error budget policy и SLO alerting. Статья опирается на эти документы, не добавляя поздние платформенные практики и не имитируя чужую production-историю. Автор уровня M6 здесь связывает измерение с owner, evidence и обратимостью, но не выдаёт учебную модель за статистику своей системы.
Проверяемые источники
- Google SRE Book: Service Level Objectives, copyright 2017 — Первичный материал Google SRE: определяет SLI как количественную меру, SLO как целевое значение или диапазон и связывает error budget с решением о риске. Он не задаёт порог, окно, формулу или владельца для конкретного проекта.
- Google SRE Workbook: Example SLO Document, 19.02.2018 — Официальный пример документа с датой 19.02.2018: в нём есть scope, SLI, SLO и четырёхнедельное rolling window. Это пример формы, а не обязательное окно для любого сервиса.
- Google SRE Workbook: Example Error Budget Policy, 19.02.2018 — Официальный пример policy: расход бюджета служит правилом приоритизации и не должен быть наказанием. Он не разрешает автоматически блокировать или выпускать чужие изменения.
- Google SRE Workbook: Alerting on SLOs, copyright 2018 — Официальная глава о том, что alert должен относиться к действенной угрозе бюджету; отдельно разбираются ограничения low-traffic систем. Она не подтверждает реальный burn rate, alert или incident этого учебного пакета.