Files

12 KiB
Raw Permalink Blame History

ТЗ — ORCH-36: Исполняемый самодеплой (стадия deploy дёргает хост-хук, Вариант B)

Work Item: ORCH-036 Stage: analysis Автор: analyst Дата: 2026-06-06

Документ фиксирует ТРЕБОВАНИЯ к изменениям (что и где). Конкретный механизм (ssh vs docker.sock vs detached nohup/systemd-run; механизм approve) выбирает архитектор в ADR (06-adr/). ТЗ задаёт границы и контракты, не реализацию.

1. Текущее устройство (as-is, разведано в коде)

  • Стадии (src/stages.py): … testing → deploy-staging → deploy → done.
    • deploy-staging: agent=deployer, qg=check_staging_status (запускается deployer при выходе из deploy-staging, входе в deploy).
    • deploy: agent=None, qg=check_deploy_status (агент НЕ запускается при выходе из deploy).
    • Вывод: реальную работу стадии deploy делает deployer-агент, запущенный на переходе deploy-staging → deploy. Он пишет 14-deploy-log.md. Когда он завершается, advance_stage с current_stage=deploy прогоняет check_deploy_status и двигает deploy → done.
  • QG (src/qg/checks.py):
    • check_deploy_status:464_parse_deploy_status:406 читает ТОЛЬКО deploy_status: из YAML-frontmatter 14-deploy-log.md (worktree → origin/main fallback → not found).
    • check_staging_status:580 — условный (реален только для self-hosting orchestrator).
    • is_self_hosting_repo() (:511) — детектор self-репо.
  • Откаты/диспетчеризация (src/stage_engine.py):
    • _handle_qg_failure_rollbacks:585 — ветка deployer + check_deploy_status FAILED → откат deploy → development, set_issue_blocked, release merge-lease, Plane+Telegram.
    • Terminal-sync deploy → done (:281) → set_issue_done, release merge-lease.
    • merge-gate (ORCH-43) на ребре deploy-staging → deployНЕ трогать.
  • Launcher (src/agents/launcher.py):
    • deployer-агент конфиг: .task-deploy.md / .openclaw/agents/deployer.md (:180).
    • Пост-обработка: commit+push артефактов в worktree (:506-558).
    • exit_code != 0 && agent == deployer → откат deploy → development (:560-581).
  • Хост-хук (scripts/orchestrator-deploy-hook.sh, ORCH-34) — ГОТОВ: --deploy/--rollback, параметризован env, дефолты STAGING; health 10×6с; авто-rollback; exit 0/1/2.
  • Agent (deployer.md): на стадии deploy сейчас пишет «бумажный» вердикт; в промпте маркер «Real docker/SSH deploys are handled by scripts/orchestrator-deploy-hook.sh (ORCH-36)».
  • Топология (docs/operations/INFRA.md): prod=8500 (.env), staging=8501 (.env.staging, profile staging). Контейнер под uid 1000, доступ к docker.sock через gid 999.

2. Изменения по модулям (to-be)

2.1 scripts/orchestrator-deploy-hook.sh (донастройка прод-режима)

  • Хук уже параметризован; требуется обеспечить корректный прод-профиль вызова: TARGET_SERVICE=orchestrator, TARGET_PORT=8500, TARGET_IMAGE=orchestrator-orchestrator, COMPOSE_PROFILE (для прод-сервиса — пустой/дефолтный, т.к. prod стартует без profile).
  • Build-once (BR-6): деплой должен использовать образ, прошедший staging (перетег staging-образа → прод-тег + docker compose up -d --no-build), а НЕ пересобирать. Если текущий хук всегда --no-build и тянет git pull — уточнить в ADR, как гарантируется идентичность артефакта staging↔prod (retag staging image, либо общий build-once шаг).
  • PREV_IMAGE_FILE для прод — отдельный путь (например .deploy-prev-image без -staging), чтобы не путать снапшоты prod/staging.
  • Поведение --rollback, health-loop, exit-code (0=ok, 1=rolled back, 2=rollback тоже упал) — НЕ менять контракт.

2.2 Approve-гейт (новое; место — на дизайне)

  • Ввести флаг конфигурации DEPLOY_REQUIRE_MANUAL_APPROVE (bool, дефолт true).
  • При true: перед вызовом прод-хука (после зелёного deploy-staging) конвейер ОСТАНАВЛИВАЕТСЯ и ждёт явного «go» Владельца. Без «go» прод-хук НЕ вызывается.
  • Механизм approve (выбрать ОДИН в ADR): Plane-коммент-триггер (по образцу :approved: в check_analysis_approved) / Telegram-кнопка / signal-файл. Требование к механизму: рестарт-safe (переживает перезапуск инстанса), идемпотентный, аудируемый.
  • При false (вне этой задачи): approve-шаг пропускается — НЕ реализовывать выключение здесь, только заложить ветку по флагу.

2.3 Триггер реального деплоя из стадии deploy

  • На стадии deploy (для self-репо orchestrator) вместо/в дополнение к записи вердикта агентом — ИНИЦИИРОВАТЬ внешний detached-процесс (host-хук), который выполнит build-once+restart+health ПОСЛЕ выхода агента (BR-2: агент не рестартит сам себя).
  • Маршрут вызова (на дизайне): ssh на хост (DEPLOY_SSH_USER/DEPLOY_HOOK_SCRIPT) ИЛИ detached через docker.sock/nohup/systemd-run. Требование: процесс хука переживает выход агента и завершение его сессии.
  • Для не-self репо (enduro-trails): деплой по ssh на их хост (как раньше) — поведение не ломать.

2.4 Маппинг результата хука → deploy_status

  • deploy_status: SUCCESS пишется в 14-deploy-log.md ТОЛЬКО при exit-code хука = 0 (health-ok).
  • exit-code ≠ 0 (1 = rolled back; 2 = rollback тоже упал) → deploy_status: FAILED.
  • Контракт _parse_deploy_status НЕ меняется (читает deploy_status: SUCCESS|FAILED из frontmatter). Меняется только КТО и КОГДА пишет этот вердикт — на основе реального исхода.
  • Гонка чтения гейта: т.к. self-рестарт асинхронный (detached), гейт check_deploy_status не должен прочитать вердикт ДО завершения хука. Механизм синхронизации (post-factum запись лога/мердж в main / отложенный гейт) — спроектировать в ADR так, чтобы гейт читал РЕАЛЬНЫЙ итог. Контракт чтения из worktree→origin/main (_deploy_log_from_main) можно переиспользовать.

2.5 Уведомления (BR-5)

  • На промоут (старт прод-деплоя + успех) и на откат → plane_add_comment(work_item_id, …) + send_telegram(…). Переиспользовать существующие хелперы (src/notifications.py, src/plane_sync.py). Никаких «молчаливых» деплоев.

2.6 Конфигурация (src/config.py / .env.example / .env.staging.example)

  • Новый: deploy_require_manual_approve: bool = True (env ORCH_DEPLOY_REQUIRE_MANUAL_APPROVE).
  • Прод-параметры хука: DEPLOY_SSH_USER, DEPLOY_SSH_HOST, DEPLOY_HOOK_SCRIPT (уже есть в INFRA-карте) + прод-override TARGET_SERVICE/PORT/IMAGE. Прописать дескрипторы в .env.example (значения — только на хосте, не коммитить).
  • Условность по репо: реальный прод-деплой — только для self-hosting (is_self_hosting_repo), как ORCH-35; прочие репо идут прежним ssh-путём.

2.7 Документация (BR-10, golden source)

  • .openclaw/agents/deployer.md — раздел «Stage: deploy»: переписать с «бумажного SUCCESS» на «стадия ВЫЗЫВАЕТ хук»; зафиксировать запрет синхронного рестарта 8500 и detached-путь self.
  • docs/operations/INFRA.md — процедура прод-деплоя орка через хук + approve.
  • docs/operations/DEPLOY_HOOK.md — обновить, если затронут контракт хука.
  • CHANGELOG.md — запись о включении исполняемого деплоя (manual-approve).
  • ADR в docs/work-items/ORCH-036/06-adr/ADR-NNN-*.md (создаёт архитектор).

3. API

  • Изменений публичного HTTP API (/health, /status, /queue, /webhook/*) не требуется.
  • Если approve реализуется через Plane-коммент — переиспользуется существующий webhook-путь (POST /webhook/plane), новый endpoint не вводится. Если через signal-файл/Telegram — внешний по отношению к HTTP API механизм. Решение — ADR.

4. Схема БД

  • Изменения схемы не требуются для базового сценария (вердикт — в 14-deploy-log.md; approve-состояние желательно хранить рестарт-safe — допустимо через jobs/task_content или signal-файл, без новой таблицы). Если архитектор сочтёт нужным поле статуса approve — обосновать в ADR; по умолчанию — без миграции.

5. Требования к Quality Gates

  • check_deploy_status и _parse_deploy_status — контракт чтения НЕ менять (frontmatter only).
  • Откат deploy → development при deploy_status: FAILED (stage_engine БАГ-8) — сохранить.
  • Terminal-sync deploy → done и release merge-lease — сохранить.
  • merge-gate (check_branch_mergeable) на ребре deploy-staging → deploy — не затрагивать.
  • check_staging_status остаётся обязательным предусловием (BR-7).

6. Артефакты pipeline

  • Создаётся/обновляется: docs/work-items/ORCH-036/14-deploy-log.md (с РЕАЛЬНЫМ deploy_status).
  • Обновляются по pipeline: 06-adr/ADR-NNN-*.md, 12-review.md, 13-test-report.md, 15-staging-log.md (последующими агентами).

7. Нефункциональные требования

  • Безопасность self-deploy: рестарт 8500 — только внешним рубильником; орк не может необратимо убить себя.
  • Идемпотентность хука и approve-механизма; рестарт-safe approve-состояние.
  • MTTR < 60с при авто-rollback (health-loop хука 10×6с уже укладывается).
  • Отладка только на staging-цели хука; реальный прод — лишь после approve.