work_item: ORCH-071
title: "Верификация merge-в-main как условие done (фантомный merge)"
notes: >
  Тесты детерминированные, без LLM. Gitea/PR-состояние и git-операции мокаются
  (monkeypatch httpx / subprocess / merge_gate helpers). Цель — закрыть AC-1..AC-11.
  Все новые функции верификации/merge соблюдают never-raise.

tests:
  # --- FR-2 / G1 / AC-1: пост-деплой верификация merge ---
  - id: TC-01
    type: unit
    description: "verify_merged_to_main возвращает True, когда deployed SHA — предок origin/main (git merge-base --is-ancestor rc=0)"
    module: tests/test_merge_verify.py
    expected: PASS
  - id: TC-02
    type: unit
    description: "verify_merged_to_main возвращает True, когда PR.merged==true (Gitea mock), даже если git-проверка недоступна"
    module: tests/test_merge_verify.py
    expected: PASS
  - id: TC-03
    type: unit
    description: "verify_merged_to_main возвращает False, когда SHA не предок origin/main И PR.merged==false (фантом)"
    module: tests/test_merge_verify.py
    expected: PASS
  - id: TC-04
    type: unit
    description: "never-raise (AC-7): ошибка git/HTTP в verify -> False (не подтверждено), исключение не пробрасывается"
    module: tests/test_merge_verify.py
    expected: PASS

  # --- FR-3 / G2 / AC-2: done только при подтверждённом merge ---
  - id: TC-05
    type: integration
    description: "Phase C finalizer: deploy_status=SUCCESS но PR open -> задача НЕ переходит в done, шлётся alert 'deploy succeeded but not merged'"
    module: tests/test_deploy_finalizer_merge_gate.py
    expected: PASS
  - id: TC-06
    type: integration
    description: "Phase C finalizer: deploy_status=SUCCESS и merge подтверждён -> задача переходит в done (happy-path, AC-4)"
    module: tests/test_deploy_finalizer_merge_gate.py
    expected: PASS

  # --- FR-1 / AC-9: детерминированный merge-актор + идемпотентность ---
  - id: TC-07
    type: unit
    description: "merge-актор self-hosting вызывает Gitea POST /pulls/{index}/merge, когда PR не слит; никакого push/force-push в main"
    module: tests/test_merge_actor.py
    expected: PASS
  - id: TC-08
    type: unit
    description: "идемпотентность (AC-9): pr_already_merged==True -> merge-актор no-op (нет второго merge, нет ошибки Gitea)"
    module: tests/test_merge_actor.py
    expected: PASS
  - id: TC-09
    type: unit
    description: "merge-актор never-raise: ошибка Gitea API -> (False, reason), исключение не пробрасывается"
    module: tests/test_merge_actor.py
    expected: PASS

  # --- FR-1 G3 / AC-3: merge переживает рестарт ---
  - id: TC-10
    type: integration
    description: "smoke (AC-3): симуляция смерти процесса во время Phase B -> re-drive finalizer/merge-job докатывает merge после 'рестарта', main получает commit, verify зелёная -> done"
    module: tests/test_deploy_restart_merge_recovery.py
    expected: PASS

  # --- FR-5 / AC-10: условность раската ---
  - id: TC-11
    type: unit
    description: "AC-4b: для non-self репо (enduro-trails) новая merge/verify-логика = no-op (merge остаётся за агентом deployer)"
    module: tests/test_merge_verify.py
    expected: PASS
  - id: TC-12
    type: unit
    description: "AC-10: kill-switch выключен -> строго прежнее поведение (verify/merge не выполняются)"
    module: tests/test_merge_verify.py
    expected: PASS

  # --- INV-2 / AC-8: self-hosting safety ---
  - id: TC-13
    type: unit
    description: "AC-8: путь merge/verify не вызывает рестарт прод-контейнера и не делает прямой/force push в main (проверка отсутствия соответствующих вызовов)"
    module: tests/test_merge_actor.py
    expected: PASS

  # --- INV-3 / AC-11: ручной approve сохранён ---
  - id: TC-14
    type: integration
    description: "AC-11: Phase B запускается только при confirm_deploy=True ('Confirm Deploy'); merge/verify не вводят авто-деплой (обычный Approved -> no-op)"
    module: tests/test_deploy_finalizer_merge_gate.py
    expected: PASS

  # --- Регресс существующих контрактов ---
  - id: TC-15
    type: unit
    description: "регресс: check_deploy_status / _parse_deploy_status неизменны (читают только deploy_status: frontmatter)"
    module: tests/test_qg_checks.py
    expected: PASS
  - id: TC-16
    type: unit
    description: "регресс: STAGE_TRANSITIONS и реестр QG_CHECKS не сломаны (deploy->done ребро на месте)"
    module: tests/test_stages.py
    expected: PASS
