89 lines
9.8 KiB
Markdown
89 lines
9.8 KiB
Markdown
# 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), архитектор
|
||
фиксирует реализацию.
|