# BRD — ORCH-021: Post-deploy мониторинг прода + авто-rollback при деградации Work Item: ORCH-021 Приоритет: высокий (★) Источник: предложение Стрим, одобрено Славой (2026-06-04) Стадия: analysis ## 1. Проблема (Why) Сейчас конвейер заканчивается на `deploy → done`: как только `check_deploy_status` видит `deploy_status: SUCCESS`, задача закрывается и оркестратор **забывает про прод**. «Успех» деплоя сегодня означает только то, что health-check в момент рестарта прошёл (10×6с в `scripts/orchestrator-deploy-hook.sh`) — узкое окно ~60 секунд. **Прямой урок ET-8:** деплой отрапортовал SUCCESS, а на проде фича не работала. Класс инцидентов — «зелёный деплой, красный прод»: - деградация проявляется через минуты, а не в первые 60с (прогрев кэшей, фоновые миграции, отложенные запросы, утечки, рост 5xx под реальным трафиком); - health-эндпоинт отвечает `200 ok`, но ключевая функциональность сломана; - регресс виден только под боевым трафиком, которого нет в момент рестарта. После закрытия задачи никакого пригляда за продом нет — деградацию замечает человек постфактум. Для self-hosting это особенно опасно: сломанный прод-орк (8500) обслуживает ВСЕ проекты (enduro-trails) из общего инстанса. ## 2. Цель (What) Продлить ответственность конвейера за прод **после** `deploy → done`: в течение заданного окна наблюдать ключевые сигналы здоровья прода и при доказанной деградации выполнить реакцию (откат на предыдущий образ или громкий алерт с запросом ручного отката). Закрыть класс «зелёный деплой, красный прод». Механизм частичного отката уже есть: `do_rollback()` и режим `--rollback` в `scripts/orchestrator-deploy-hook.sh` умеют вернуть предыдущий образ из `PREV_IMAGE_FILE` (`.deploy-prev-image-prod`), который сохраняется при каждом деплое. Задача — построить **наблюдение поверх** этого и привязать решение к измеримым порогам. ## 3. Заинтересованные стороны - **Owner (Слава)** — принимает риск авто-отката прода; получает алерты. - **Стрим** — инициатор; потребитель сигнала деградации для петли уроков (ORCH-8). - **Другие проекты (enduro-trails)** — косвенно: устойчивость общего инстанса. ## 4. Бизнес-требования | # | Требование | Приоритет | |---|------------|-----------| | BR-1 | После `deploy → done` прод наблюдается в течение конфигурируемого окна (дефолт ~15 мин), а не забывается. | Must | | BR-2 | Деградация определяется по **детерминированным измеримым сигналам**: периодический `/health` (HTTP 200 + `{"status":"ok"}`) и доля HTTP 5xx на ключевых эндпоинтах (`/status`, `/queue`). | Must | | BR-3 | Деградация фиксируется только по **порогам** (N последовательных провалов / окно), а не по разовому сетевому глюку — чтобы не было ложных откатов. | Must | | BR-4 | При подтверждённой деградации система выполняет реакцию: **авто-rollback** на `.deploy-prev-image-prod` (через существующий хук `--rollback`) **либо** громкий алерт с запросом ручного отката — в зависимости от политики репозитория. | Must | | BR-5 | **Self-hosting safety:** для самого `orchestrator` авто-откат прода = рестарт инструмента, обслуживающего все проекты. По умолчанию для self-hosting реакция — **алерт + ручной approve отката** (по образцу deploy Phase A/B), НЕ автоматический откат. Для не-self репозиториев допустим авто-откат. | Must | | BR-6 | Любой исход (наблюдение начато, деградация, откат, откат-провал, окно завершилось чисто) уведомляется в Telegram и комментарием в Plane; результат наблюдения фиксируется артефактом. | Must | | BR-7 | Мониторинг — **restart-safe**: рестарт оркестратора (в т.ч. сам деплой) не теряет и не задваивает наблюдение. Идемпотентность по образцу reconciler / deploy-finalizer. | Must | | BR-8 | Глобальный kill-switch (env-флаг) и список репозиториев, на которые распространяется фича (по образцу `merge_gate_enabled` / `image_freshness_enabled` / `self_deploy_repos`). Выключенный флаг = прежнее поведение (наблюдения нет). | Must | | BR-9 | Наблюдаемость: текущее состояние пост-деплой наблюдения отражается в `GET /queue` (по образцу блока `reconcile`). | Should | | BR-10 | Сигнал деградации пригоден для будущей петли уроков (ORCH-8): фиксируется в артефакте/логе в машиночитаемом виде. | Should | | BR-11 | Доменный smoke результата фичи (проверка, что конкретная фича реально работает) — желателен, но выносится в follow-up; MVP ограничивается health + 5xx. | Could | ## 5. Вне рамок (Out of scope) - Полноценная система метрик/APM (Prometheus, дашборды) — фича опирается на уже существующие HTTP-эндпоинты, не вводит сбор метрик. - Универсальный доменный smoke для произвольной фичи (BR-11 — follow-up). - Полностью автоматический откат прод-орка без участия человека (противоречит self-hosting safety; отдельная задача при наборе доверия, аналогично ORCH-54 для deploy). - Изменение момента вердикта `deploy_status` / контракта `check_deploy_status` (наблюдение происходит ПОСЛЕ `done`, не заменяет deploy-gate). ## 6. Связи - **ET-8** — прецедент «deploy SUCCESS, прод не работает». Обоснование задачи. - **ORCH-36** (`docs/architecture/adr/adr-0007-executable-self-deploy.md`) — Phase A/B/C исполняемого самодеплоя; пост-деплой наблюдение продлевает ответственность ЗА `done`, переиспользует sentinel-паттерн и detached-host-процесс для self-rollback. - **ORCH-53** (`src/reconciler.py`) — каноничный паттерн фонового daemon-потока (watchdog), запускаемого в `main.lifespan`; образец для пост-деплой наблюдателя. - **ORCH-58** — `.deploy-prev-image` и хук-механика отката, на которые опирается реакция. - **ORCH-8** — деградация прода = сигнал для петли уроков (BR-10). - **ORCH-12** — фича может оформиться как пост-deploy стадия ИЛИ как watchdog (решение архитектора, см. §7). ## 7. Открытые архитектурные вопросы (для архитектора, НЕ решаются в анализе) 1. **Где живёт наблюдение:** отдельная пост-deploy стадия конвейера vs фоновый watchdog-daemon (по образцу `reconciler`) vs reserved-agent job (по образцу `deploy-finalizer`). Анализ задаёт требования (BR-1, BR-7), выбор механизма — за архитектором. 2. **Механизм self-rollback для self-hosting:** откат прод-орка требует detached host-процесса (контейнер не может надёжно откатить себя, умирая) — переиспользовать ли `self_deploy.initiate_deploy` / хук `--rollback`. 3. Точные пороги и веса сигналов (BR-3) — анализ предлагает дефолты (см. AC), архитектор фиксирует реализацию.