Files
orchestrator/docs/work-items/ORCH-071/02-trz.md

11 KiB
Raw Blame History

ТЗ — ORCH-071: Верификация merge-в-main как условие done

Документ фиксирует ТРЕБОВАНИЯ к изменениям (WHAT). Конкретный дизайн (HOW: новый leaf-модуль vs расширение существующего, где разместить шаг merge, формат sentinel'ов) — за архитектором (ADR 06-adr/). ТЗ задаёт инварианты, точки врезки и контракты, которые дизайн обязан удовлетворить.

0. Резюме root cause (вход для дизайна)

Для self-hosting (orchestrator) стадия deploy идёт детерминированным путём _handle_self_deploy_phase_b → initiate_deploy → run_deploy_finalizer, который не содержит шага merge PR в main (merge делает только LLM-deployer, не запускаемый на self-hosting). done достигается по deploy_status: SUCCESS без верификации main. Требуется: (A) выполнить/докатить merge в main детерминированно до перехода в done; (B) верифицировать факт merge ПОСЛЕ деплоя; (C) запретить done без подтверждённого merge.

1. Задействованные модули src/

Модуль Роль в фиксе Характер изменения
src/stage_engine.py run_deploy_finalizer (Phase C), терминал-блок next_stage == "done", _handle_self_deploy_phase_b Врезка шага merge-в-main + пост-merge верификация; блокировка перехода в done при неподтверждённом merge.
src/merge_gate.py Уже содержит pr_already_merged (ORCH-065, read-only guard) Добавить детерминированный merge-актор для self-hosting (выполнить merge PR через Gitea API) + helper верификации «SHA предок origin/main». Опора на существующие pid_alive/reclaim_stale_lease.
src/self_deploy.py Sentinel-state Phase A/B/C Возможный новый sentinel-маркер merged (restart-safe), если дизайн выносит merge в отдельный переживающий рестарт шаг (G3).
src/qg/checks.py Реестр QG_CHECKS, check_deploy_status Возможный новый под-чек верификации merge (например check_merged_to_main) ЛИБО усиление условия перехода deploy→done. check_deploy_status НЕ менять по контракту парсинга.
src/config.py Флаги Новый kill-switch (напр. merge_verify_enabled / merge_verify_repos), таймауты merge/verify. Дефолт — область self-hosting (как ORCH-35/43/58).
.openclaw/agents/deployer.md Промпт deployer'а (non-self merge) Уточнить: для self-hosting merge выполняет детерминированный код; non-self путь без изменений.
src/main.py (/queue) Наблюдаемость Опционально: блок/счётчики верификации merge (merge_verified_total, not_merged_alerts_total).

2. Функциональные требования

FR-1 (G3) — Детерминированный merge-в-main для self-hosting

  • Для self-hosting репо merge PR ветки в main ДОЛЖЕН выполняться детерминированным кодом (не LLM-агентом), т.к. deployer-агент на self-hosting deploy не запускается.
  • Merge выполняется через Gitea PR-merge API (как сегодня делает агент), НИКОГДА не force-push / не прямой push в main (INV-4).
  • ПЕРЕД merge консультироваться merge_gate.pr_already_merged(repo, branch) — уже слит → no-op (INV-5, переиспользовать ORCH-065).
  • G3 — порядок относительно рестарта: merge ДОЛЖЕН быть завершён и подтверждён ДО рестарта прод-контейнера, ЛИБО вынесен в шаг, переживающий рестарт (паттерн requeue_running_jobs/finalizer-defer): если процесс умер во время Phase B, шаг merge докатывается после рестарта (re-drive finalizer'а или отдельный merge-job). Дизайн выбирает один из двух вариантов; выбранный обязан быть restart-safe (sentinel/jobs, без миграции БД — §4).

FR-2 (G1) — Пост-деплой верификация merge

  • ПОСЛЕ деплоя (в Phase C / финализации, ДО фиксации done) выполнить детерминированную верификацию: задеплоенный commit (validated SHA) — предок origin/main (git merge-base --is-ancestor <sha> origin/main) ИЛИ PR.merged == true (Gitea API).
  • Верификация never-raise (INV-1): любая ошибка git/HTTP → трактуется как «не подтверждено» → alert, НЕ падение.
  • При неподтверждённой верификации — alert «deploy succeeded but not merged» (Telegram + Plane-коммент) и задача НЕ переходит в done (FR-3).

FR-3 (G2) — done только при подтверждённом merge

  • Переход deploy → done для self-hosting ДОЛЖЕН быть обусловлен подтверждённым merge (verify из FR-2 зелёный). Наличие deploy_status: SUCCESS + post-deploy HEALTHYнедостаточно.
  • При SUCCESS-маркере деплоя, но неподтверждённом merge: задача удерживается (не done), Plane-статус — не терминальный (например текущий Deploying/Awaiting или Blocked по решению дизайна), шлётся alert. Конвейер НЕ откатывается на development автоматически из-за not-merged (это инфраструктурный, не код-дефект) — реакция = alert + ручное вмешательство (согласовать с дизайном; по умолчанию ALERT-only, как ORCH-021 self-hosting).

FR-4 (G4) — Диагностический runbook

  • В docs/operations/ добавить runbook с 4 проверками из постмортема (метод однозначной локализации фантома):
    1. Gitea API: список PR + флаги merged.
    2. md5 прод-файлов vs git show origin/main:<file>.
    3. git merge-base ветки vs main.
    4. Таймлайн деплой-логов.
  • Включить готовые команды (copy-paste) и критерий «фантом подтверждён».

FR-5 — Условность раската (как ORCH-35/43/58)

  • Новая логика merge+verify реальна для self-hosting (is_self_hosting_repo / merge_verify_repos); прочие репо — поведение БЕЗ изменений (non-self merge остаётся за агентом deployer).
  • Kill-switch (env, дефолт true) → false восстанавливает строго прежнее поведение.

3. Изменения API

  • Внешний HTTP API сервиса (/health, /status, /queue, /webhook/*) — без новых endpoint'ов. Допустимо обогащение ответа GET /queue блоком наблюдаемости merge-verify (счётчики), по образцу блоков reaper/post_deploy.
  • Gitea API (исходящие вызовы): новый детерминированный вызов POST /repos/{owner}/{repo}/pulls/{index}/merge (merge-актор, FR-1) + чтение GET /repos/{owner}/{repo}/pulls?... (уже используется в pr_already_merged). Через существующий httpx-клиент и settings.gitea_*.

4. Изменения схемы БД

  • НЕТ. Schema-changes запрещены (не-цель). Restart-safe состояние нового шага merge — через sentinel-файлы (.deploy-state-<repo>/<wi>/, как ORCH-036) и/или существующую очередь jobs (finalizer-defer). Колонка jobs.pid (ORCH-065) уже есть, при необходимости переиспользуется.

5. Требования к новым QG checks

  • Допускается ввести детерминированный под-чек верификации merge (напр. check_merged_to_main), регистрируемый в QG_CHECKS, ЛИБО встроить верификацию как условие в логику перехода deploy→done без нового чека — на усмотрение дизайна. В любом случае:
    • Контракт check_deploy_status / _parse_deploy_status (читает только deploy_status: frontmatter) НЕ меняется.
    • STAGE_TRANSITIONS НЕ меняется (verify — это условие/под-гейт ребра/финализации, не новая стадия).
    • Вердикт (если артефакт) — строго YAML-frontmatter (канон гейтов), never проза.

6. Артефакты, создаваемые/обновляемые по pipeline

  • 14-deploy-log.md — существующий; дизайн может добавить поле статуса merge (напр. merged_to_main: true|false) во frontmatter (машиночитаемо), не ломая deploy_status:.
  • Новый runbook в docs/operations/ (FR-4).
  • Обязательно (CLAUDE.md §2): обновить docs/architecture/README.md (раздел Phase B / merge-gate / executable self-deploy — описать новый merge+verify шаг), CHANGELOG.md, при сквозном решении — ADR (docs/work-items/ORCH-071/06-adr/ADR-001-*.md и/или global docs/architecture/adr/).

7. Совместимость / регресс

  • Happy-path не-self репо (enduro-trails): merge остаётся за агентом deployer → поведение без изменений.
  • Happy-path self-hosting: при штатном merge задача done ставится как раньше (после добавления verify, который зелёный).
  • Все существующие контракты неизменны: STAGE_TRANSITIONS, реестр QG_CHECKS (кроме возможного нового under-чека), check_deploy_status, БАГ-8, terminal-sync, merge-gate (ORCH-043), Confirm Deploy (ORCH-059), exit-коды хука (0/1/2), схема БД.