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