Files
orchestrator/docs/architecture/adr/adr-0007-executable-self-deploy.md

4.7 KiB
Raw Blame History

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.