7.1 KiB
adr-0010: Post-deploy мониторинг прода + реакция на деградацию
- Статус: proposed (design) — реализация в ветке
feature/ORCH-021-post-deploy-rollback - Дата: 2026-06-07
- Задача: ORCH-021
- Метка:
arch:major-change(новая под-компонента + новый reserved-agent job-kind) - Детальный ADR:
docs/work-items/ORCH-021/06-adr/ADR-001-post-deploy-monitor.md
Контекст
Конвейер заканчивается на deploy → done: check_deploy_status видит
deploy_status: SUCCESS → terminal-sync (Plane → Done, release merge-lease), и
оркестратор забывает про прод. «Успех» сегодня = health-check в момент рестарта
(~60с окно в orchestrator-deploy-hook.sh). Класс инцидентов «зелёный деплой, красный
прод» (прецедент ET-8): деградация проявляется через минуты под боевым трафиком,
health отвечает 200 ok, фича сломана. Для self-hosting опасно вдвойне — сломанный
прод-орк (8500) обслуживает ВСЕ проекты из общего инстанса.
Решение
Продлить ответственность конвейера ЗА done: после терминального перехода для
применимого репо армится пост-деплой наблюдение окна post_deploy_window_s (дефолт
~15 мин) с интервалом post_deploy_interval_s; деградация фиксируется по
детерминированным порогам, при подтверждении выполняется реакция.
Механизм — reserved-agent job post-deploy-monitor (калька deploy-finalizer,
ORCH-36), НЕ отдельная стадия и НЕ daemon-поток:
- Арм: в
stage_engine.advance_stage, в блокеnext_stage == "done", приpost_deploy.post_deploy_applies(repo)→post_deploy.arm_monitor(...)(sentinelarmed= идемпотентность, первый job черезenqueue_job(available_at_delay_s=...)). - Тик:
launcher.launch_jobперехватываетagent == "post-deploy-monitor"ДО_spawn→stage_engine.run_post_deploy_monitor(job): один опрос сигналов, append в персистентныйseries, классификация; HEALTHY и окно не истекло → перепостановка с задержкой; иначе → реакция + артефакт +mark_done. - Чистая логика — новый leaf-модуль
src/post_deploy.py(never-raise, по образцуself_deploy.py/staging_verdict.py):post_deploy_applies,probe_signals(опрос/health+ доля 5xx на/status,/queue),classify(HEALTHY|DEGRADED — главный предмет юнит-тестов),decide_action(NONE|ROLLBACK|ALERT_ONLY с учётом self-hosting), sentinel-state хелперы,write_post_deploy_log.
Сигналы и пороги (детерминированно, AC-3…AC-6): DEGRADED ⇔ ≥ post_deploy_fail_threshold ПОСЛЕДОВАТЕЛЬНЫХ провалов health ИЛИ доля 5xx на окне > post_deploy_5xx_threshold. Одиночный глюк < порога → HEALTHY (нет ложных откатов).
Реакция (BR-4/BR-5):
- Self-hosting (
orchestrator) — ВСЕГДАALERT_ONLY: громкий Telegram + Plane, запрос ручного approve отката. Тик НИКОГДА не откатывает/рестартит прод-контейнер (структурный инвариант). Откат прод-орка, если оператор решит, — только detached host-процесс (self_deploy.initiate_deploy), вне тика (MVP). - Не-self +
post_deploy_auto_rollback=True: хук--rollbackс прод-env; exit0 → ROLLBACK_OK,1/2 → ROLLBACK_FAILED+ громкий алерт. - Дефолт (
auto_rollback=False) →ALERT_ONLY.
Артефакт 16-post-deploy-log.md (новый) с YAML-frontmatter (post_deploy_status,
action_taken, window_s, checks_total/failed) — машиночитаемо для петли уроков
ORCH-8; best-effort. Наблюдаемость — блок post_deploy в GET /queue (образец
reconcile.status()).
Альтернативы
- Daemon-watchdog (как reconciler) — отклонён: per-task серия опросов в памяти не restart-safe (а деплой орка = рестарт); restart-safe-вариант требует тех же sentinel, reserved-agent проще и уже имеет проверенную jobs+sentinel машинерию.
- Отдельная пост-deploy стадия + QG — отклонён: меняет
STAGE_TRANSITIONS/QG_CHECKS, ломает семантику терминальногоdone; наблюдение принципиально ПОСЛЕdone. - Авто-rollback прод-орка из тика — отклонён (self-hosting safety): групповой риск; контейнер не откатит себя надёжно. Self → alert + ручной approve (как ORCH-54).
- Колонка в
tasks— отклонён: миграция на проде; sentinel-файлы restart-safe (как ORCH-36/53/58).
Последствия
- Класс «зелёный деплой, красный прод» закрыт измеримыми порогами; деградация = сигнал для ORCH-8.
- Реестры (
STAGE_TRANSITIONS/QG_CHECKS), контрактcheck_deploy_status, terminal-sync, merge-gate, exit-code-контракт хука, схема БД — не меняются. - Дефолты безопасны: kill-switch on, auto-rollback off, self только alert.
- Ограничение: монитор self бежит внутри наблюдаемого прода — полностью wedged контейнер = пропущенный тик/алерт (known MVP gap; внешний watchdog — follow-up).
- Self-hosting: тик не рестартит/не роняет прод-контейнер; kill-switch
post_deploy_monitor_enabledобязателен; поэтапный раскат черезpost_deploy_repos.
Связи
adr-0007-executable-self-deploy (ORCH-36 — sentinel/detached-host/finalizer образец,
map_exit_code_to_status), adr-0007-reconciler (ORCH-53 — daemon/status() образец,
отклонён как основной механизм), adr-0006 (merge-gate — условность/флаги раската),
adr-0003 (staging-gate — образец условности), adr-0008 (provenance — .deploy-prev-image/
хук-откат). Прецедент ET-8. Будущее: ORCH-8 (петля уроков), ORCH-54 (полный авто).