12 KiB
12 KiB
ТЗ — 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-frontmatter14-deploy-log.md(worktree → origin/main fallback → not found).check_staging_status:580— условный (реален только для self-hostingorchestrator).is_self_hosting_repo()(:511) — детектор self-репо.
- Откаты/диспетчеризация (
src/stage_engine.py):_handle_qg_failure_rollbacks:585— веткаdeployer+check_deploy_statusFAILED → откат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).
- deployer-агент конфиг:
- Хост-хук (
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(envORCH_DEPLOY_REQUIRE_MANUAL_APPROVE). - Прод-параметры хука:
DEPLOY_SSH_USER,DEPLOY_SSH_HOST,DEPLOY_HOOK_SCRIPT(уже есть в INFRA-карте) + прод-overrideTARGET_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.