work_item: ORCH-061
title: "BUG: deploy-staging петля — откат на development (self-deploy)"
description: >
  План тестов на устранение зацикливания deploy-staging -> development для
  self-hosting orchestrator. Покрывает обе подтверждённые причины: (1) ложный
  FAILED check_staging_status из-за заведомо инфраструктурных C9a/C9b в sandbox;
  (2) трактовку "no changes to commit" на action-стадии как недовыполнения.
  Тесты outcome-ориентированы и не предписывают механизм: часть кейсов помечена
  как mechanism-dependent (а=sandbox-инфра честно, б=толерантность/отвязка) —
  финальный набор подтверждает архитектор в ADR; реализуются тесты под выбранный
  механизм. Инвариант страховки (реальный регресс откатывает) и условность
  self-hosting проверяются ВСЕГДА.
tests:
  # --- Главный сценарий: нет петли ----------------------------------------
  - id: TC-01
    type: unit
    description: >
      Корректный self-deploy: при staging_status SUCCESS и пройденном merge/freshness
      sub-gate advance_stage(deploy-staging, finished_agent=deployer) продвигает к
      deploy (Phase A approval-pending), НЕ откатывает на development. (AC-1)
    module: tests/test_stage_engine.py
    expected: PASS

  - id: TC-02
    type: unit
    description: >
      Регресс-страховка ORCH-35: реальный провал реальной pipeline-проверки ->
      staging_status FAILED -> advance_stage откатывает deploy-staging -> development
      + set_issue_blocked. (AC-3)
    module: tests/test_stage_engine.py
    expected: PASS

  # --- Причина №1: ложный инфраструктурный FAIL ---------------------------
  - id: TC-03
    type: unit
    description: >
      Классификация проверок staging_check: проверки, заведомо зависящие от
      sandbox-инфраструктуры (C9a/C9b), отличимы (метка/категория) от реальных
      pipeline-проверок. Чистая логика классификации/вердикта тестируется без
      live staging/docker. (AC-2, mechanism-dependent: вариант б)
    module: tests/test_staging_check_b6.py
    expected: PASS

  - id: TC-04
    type: unit
    description: >
      Вердикт-логика: все реальные проверки PASS, падают ТОЛЬКО известные
      sandbox-инфра проверки (C9a/C9b) -> итог не-FAILED (нет ложного отката).
      (AC-2)
    module: tests/test_qg_checks.py
    expected: PASS

  - id: TC-05
    type: unit
    description: >
      Вердикт-логика: падает хотя бы одна РЕАЛЬНАЯ pipeline-проверка (помимо инфра)
      -> итог FAILED (страховка не ослаблена, fail-closed). (AC-3)
    module: tests/test_qg_checks.py
    expected: PASS

  # --- Причина №2: no changes на action-стадии ----------------------------
  - id: TC-06
    type: unit
    description: >
      На action-стадии (deploy-staging/deploy) для self-deploy отсутствие
      git-изменений ("no changes to commit") НЕ приводит к откату/недопродвижению;
      продвижение определяется exit + вердиктом, а не наличием коммита. (AC-4)
    module: tests/test_launcher.py
    expected: PASS

  - id: TC-07
    type: unit
    description: >
      На code-стадии (development) отсутствие изменений всё ещё обрабатывается
      прежним образом (нет ложного "успеха" там, где код должен был измениться) —
      изменение FR-3 не протекает на не-action стадии. (AC-4, regression-guard)
    module: tests/test_launcher.py
    expected: PASS

  # --- Условность self-hosting --------------------------------------------
  - id: TC-08
    type: unit
    description: >
      Для не-self-hosting репо check_staging_status остаётся (True, "Staging gate
      N/A …") и новое поведение НЕ активируется; поведение этих репо неизменно.
      (AC-6, FR-5)
    module: tests/test_qg.py
    expected: PASS

  # --- Kill-switch / обратная совместимость -------------------------------
  - id: TC-09
    type: unit
    description: >
      При выключенном флаге нового поведения (FR-6) система ведёт себя 1:1 как до
      ORCH-061: инфра-FAIL снова приводит к FAILED/откату. Дефолт флага безопасен.
      (AC-7)
    module: tests/test_config.py
    expected: PASS

  # --- БАГ-8: реальный провал прод-деплоя ----------------------------------
  - id: TC-10
    type: unit
    description: >
      deploy_status FAILED (exit-code хука != 0) -> откат deploy -> development +
      set_issue_blocked + release merge-lease + clear deploy-state (БАГ-8 не сломан).
      (AC-5)
    module: tests/test_deploy_rollback.py
    expected: PASS

  # --- Контракты / реестр / never-raise -----------------------------------
  - id: TC-11
    type: unit
    description: >
      Снапшот реестра QG_CHECKS и STAGE_TRANSITIONS не изменён неожиданно;
      frontmatter-контракты staging_status/deploy_status (SUCCESS|FAILED, только
      YAML) сохранены. (AC-8)
    module: tests/test_qg_registry_snapshot.py
    expected: PASS

  - id: TC-12
    type: unit
    description: >
      never-raise: новая логика staging-вердикта/advance при внутренней ошибке
      (io/парсинг/docker/ssh) возвращает безопасный детерминированный вердикт и не
      пробрасывает исключение в advance_stage. (AC-10)
    module: tests/test_stage_engine.py
    expected: PASS

  # --- Интеграционный сквозной сценарий ------------------------------------
  - id: TC-13
    type: integration
    description: >
      Сквозной self-deploy на тестовой БД: задача deploy-staging при здоровом
      стенде с инфра-only недочётами проходит deploy-staging -> deploy (Phase A) ->
      (approve) -> deploy финализация SUCCESS -> done, БЕЗ единого отката на
      development в логе переходов. (AC-1, AC-4)
    module: tests/test_stage_engine.py
    expected: PASS

  - id: TC-14
    type: integration
    description: >
      Наблюдаемость: при срабатывании нового поведения (игнор инфра-FAIL /
      ожидаемые no-changes) присутствует явная лог-строка/диагностика, отличающая
      "честно зелёный" от "зелёного с допущением". (AC-11)
    module: tests/test_stage_engine.py
    expected: PASS
