work_item: ORCH-021
description: >
  Тест-план пост-деплой мониторинга прода + авто-rollback. Упор на детерминированную
  чистую логику классификации/решения (юнит, без сети/LLM) и на интеграцию
  армирования наблюдения после deploy->done. Сетевые опросы и хук-вызовы мокируются.
  Имена модулей/функций — целевые (src/post_deploy.py); архитектор уточняет точную
  сигнатуру, тесты адаптируются под ADR.

tests:
  # --- Классификация деградации (чистая логика, ядро) ---
  - id: TC-01
    type: unit
    description: "HEALTHY: серия опросов без провалов (< порога) -> вердикт HEALTHY"
    module: tests/test_post_deploy.py
    covers: [AC-3]
    expected: PASS

  - id: TC-02
    type: unit
    description: "DEGRADED: N последовательных провалов health (== fail_threshold) -> DEGRADED"
    module: tests/test_post_deploy.py
    covers: [AC-4]
    expected: PASS

  - id: TC-03
    type: unit
    description: "DEGRADED по 5xx: доля 5xx выше порога при health=200 -> DEGRADED"
    module: tests/test_post_deploy.py
    covers: [AC-5]
    expected: PASS

  - id: TC-04
    type: unit
    description: "Нет ложного срабатывания: одиночный провал (1 < threshold) + восстановление -> HEALTHY"
    module: tests/test_post_deploy.py
    covers: [AC-6]
    expected: PASS

  - id: TC-05
    type: unit
    description: "Пороги читаются из Settings (env ORCH_*), изменение порога меняет вердикт на тех же данных"
    module: tests/test_post_deploy.py
    covers: [AC-11]
    expected: PASS

  # --- Решение о реакции (чистая логика + self-hosting safety) ---
  - id: TC-06
    type: unit
    description: "Решение: не-self репо + auto_rollback=True + DEGRADED -> ROLLBACK"
    module: tests/test_post_deploy.py
    covers: [AC-7]
    expected: PASS

  - id: TC-07
    type: unit
    description: "Решение self-hosting: orchestrator + DEGRADED -> ALERT_ONLY (НИКОГДА не авто-rollback)"
    module: tests/test_post_deploy.py
    covers: [AC-8]
    expected: PASS

  - id: TC-08
    type: unit
    description: "Решение: HEALTHY -> NONE (реакции нет) для любого репо"
    module: tests/test_post_deploy.py
    covers: [AC-3]
    expected: PASS

  # --- Условность / kill-switch ---
  - id: TC-09
    type: unit
    description: "post_deploy_applies: пусто в repos -> True только для orchestrator, False для enduro-trails"
    module: tests/test_post_deploy.py
    covers: [AC-2]
    expected: PASS

  - id: TC-10
    type: unit
    description: "kill-switch: post_deploy_monitor_enabled=False -> applies()=False для всех; наблюдение не армится"
    module: tests/test_post_deploy.py
    covers: [AC-10]
    expected: PASS

  # --- Маппинг exit-code отката -> исход ---
  - id: TC-11
    type: unit
    description: "Откат exit 0 -> action_taken=ROLLBACK_OK"
    module: tests/test_post_deploy.py
    covers: [AC-7]
    expected: PASS

  - id: TC-12
    type: unit
    description: "Откат exit 1/2 (нет prev-образа / откат упал) -> ROLLBACK_FAILED + эскалация-алерт"
    module: tests/test_post_deploy.py
    covers: [AC-9]
    expected: PASS

  # --- Артефакт ---
  - id: TC-13
    type: unit
    description: "16-post-deploy-log.md пишется с валидным YAML-frontmatter (post_deploy_status/action_taken), парсится yaml.safe_load"
    module: tests/test_post_deploy.py
    covers: [AC-13]
    expected: PASS

  # --- never-raise ---
  - id: TC-14
    type: unit
    description: "Опрос при сетевой ошибке/таймауте -> консервативный результат (провал-как-down), исключение НЕ всплывает"
    module: tests/test_post_deploy.py
    covers: [AC-16]
    expected: PASS

  - id: TC-15
    type: unit
    description: "Ошибка записи артефакта (нет каталога/IO) -> логируется, функция возвращает False, не raise"
    module: tests/test_post_deploy.py
    covers: [AC-16, AC-13]
    expected: PASS

  # --- Интеграция: армирование после deploy->done ---
  - id: TC-16
    type: integration
    description: "advance_stage deploy->done для orchestrator армит наблюдение (sentinel/job создан); для enduro-trails — нет"
    module: tests/test_post_deploy_integration.py
    covers: [AC-1, AC-2]
    expected: PASS

  - id: TC-17
    type: integration
    description: "Идемпотентность: повторный арм той же задачи (двойной webhook) не создаёт второе наблюдение"
    module: tests/test_post_deploy_integration.py
    covers: [AC-15]
    expected: PASS

  - id: TC-18
    type: integration
    description: "Полный цикл DEGRADED -> для не-self вызывается откат (хук замокан), пишется лог, шлётся уведомление"
    module: tests/test_post_deploy_integration.py
    covers: [AC-7, AC-13, AC-17]
    expected: PASS

  - id: TC-19
    type: integration
    description: "Self-hosting DEGRADED: тик НЕ вызывает рестарт/откат прод-контейнера, формирует алерт+approve-запрос"
    module: tests/test_post_deploy_integration.py
    covers: [AC-8, AC-17]
    expected: PASS

  # --- Наблюдаемость и обратная совместимость ---
  - id: TC-20
    type: integration
    description: "GET /queue содержит блок post_deploy со снимком состояния"
    module: tests/test_post_deploy_integration.py
    covers: [AC-14]
    expected: PASS

  - id: TC-21
    type: integration
    description: "Регресс: существующие тесты deploy/staging/merge-gate/reconciler зелёные; STAGE_TRANSITIONS и QG_CHECKS не изменены"
    module: tests/test_stages.py
    covers: [AC-12]
    expected: PASS
