65 lines
4.7 KiB
Markdown
65 lines
4.7 KiB
Markdown
# ADR-0007: Исполняемый самодеплой стадии `deploy` (Вариант B, ORCH-36)
|
||
|
||
## Статус
|
||
Accepted (design) — реализация в ветке `feature/ORCH-036`.
|
||
|
||
## Контекст
|
||
Стадия `deploy` была «бумажной»: deployer-агент писал `deploy_status:` в
|
||
`14-deploy-log.md`, гейт `check_deploy_status` парсил вердикт и двигал
|
||
`deploy → done`. Реального деплоя не было. ORCH-36 делает стадию исполняемой для
|
||
self-hosting (`orchestrator`), сохраняя прежний ssh-путь для остальных репо.
|
||
|
||
Три ограничения формируют дизайн (детально — `docs/work-items/ORCH-036/06-adr/ADR-001`):
|
||
1. **Self-restart**: рестарт прод-контейнера 8500 убивает in-container процесс →
|
||
рестарт делает ВНЕШНИЙ host-процесс.
|
||
2. **Status-only verdict model**: approve = смена статуса Plane на `Approved`
|
||
(комментарии не управляют конвейером).
|
||
3. **Гонка гейта**: вердикт нельзя читать до завершения асинхронного хука.
|
||
|
||
## Решение
|
||
Для self-hosting стадия `deploy` исполняется в три фазы детерминированным кодом
|
||
(без LLM в критическом пути self-restart):
|
||
|
||
- **Фаза A (вход в `deploy`)** — для self + `deploy_require_manual_approve=true`
|
||
вместо запуска прод-deployer выставляется approval-pending статус Plane + запрос
|
||
approve (Plane-коммент + Telegram). Перехват в `advance_stage` на ребре
|
||
`deploy-staging → deploy` (после `check_staging_status` и merge-gate).
|
||
- **Фаза B (Plane → Approved)** — `advance_stage(deploy, finished_agent=None)`
|
||
запускает **detached host-процесс** (ssh + setsid → `orchestrator-deploy-hook.sh`
|
||
с прод-параметрами и build-once retag) и ставит **детерминированный finalizer-job**
|
||
с задержкой; маркер `initiated` — идемпотентность. Возврат БЕЗ advance.
|
||
- **Фаза C (finalizer)** — после рестарта новый контейнер дочитывает sentinel
|
||
`result` (exit-code хука), маппит `0→SUCCESS / иначе→FAILED`, пишет
|
||
`14-deploy-log.md`, вызывает `advance_stage(deploy, finished_agent="deployer")`
|
||
→ существующие контракты: `SUCCESS → done`, `FAILED → откат БАГ-8 на development`.
|
||
|
||
### Ключевые инварианты (НЕ меняются)
|
||
`STAGE_TRANSITIONS`, реестр QG, `check_deploy_status` / `_parse_deploy_status`
|
||
(frontmatter only), откат БАГ-8, terminal-sync `deploy → done`, merge-gate (ORCH-43),
|
||
exit-code-контракт хука (0/1/2).
|
||
|
||
### Новое (сквозное)
|
||
- **Детерминированный job-kind** `deploy-finalizer` в очереди (reserved-agent, не
|
||
LLM): read-result | defer | map+write+advance. Зеркалит детерминизм merge-gate.
|
||
- **Approve-флаг** `deploy_require_manual_approve` (дефолт `true`; полный авто —
|
||
отдельная задача после набора метрик доверия, ORCH-54).
|
||
- **Build-once**: опциональный `SOURCE_IMAGE` retag в хуке (обратно совместимо).
|
||
- **Restart-safe состояние** деплоя — sentinel-файлы под
|
||
`<repos_dir>/.deploy-state-<repo>/<wi>/` (как merge-lease), БЕЗ миграции БД.
|
||
|
||
### Условность
|
||
Вся логика — только для `is_self_hosting_repo(repo)` (как ORCH-35). Прочие репо
|
||
деплоятся прежним синхронным ssh-путём агентом.
|
||
|
||
## Последствия
|
||
- `deploy_status: SUCCESS` доказан реальным health-ok; критический путь self-restart
|
||
детерминирован.
|
||
- Вводится новая под-компонента (finalizer job-handler) → изменение помечено
|
||
`arch:major-change`.
|
||
- Approve вписан в status-only модель: restart-safe, аудируемо, идемпотентно.
|
||
- На старте — обязательный ручной approve; молчаливых деплоев нет (Plane+Telegram).
|
||
|
||
## Связанные ADR
|
||
`adr-0003` (staging-gate), `adr-0006` (merge-gate), `adr-0005` (run-as-host-uid).
|
||
Детальный per-work-item: `docs/work-items/ORCH-036/06-adr/ADR-001-executable-self-deploy.md`.
|