work_item: ORCH-068
description: >
  Регрессионные и модульные тесты на устранение livelock reconciler F-2
  (спам _note_unblock для синхронизированной done-задачи) и связанного бага
  кэша статусов. Все тесты офлайн: Plane API / Telegram / dispatch мокаются.
  Целевые модули: src/reconciler.py, src/plane_sync.py.

tests:
  # ---------- P0: основной баг (livelock / спам) ----------
  - id: TC-01
    type: unit
    description: >
      Синхронизированная done-задача (Plane=Done, БД=done, нет активных job):
      один тик F-2 -> _note_unblock НЕ вызван, send_telegram НЕ вызван,
      unblocked_total не изменился, 0 jobs. (AC-1, AC-7)
    module: tests/test_reconciler_plane.py
    expected: PASS

  - id: TC-02
    type: unit
    description: >
      Терминал «схлопнут» с approved по UUID: issue в Done с тем же UUID, что и
      approved-набор, НЕ заходит ни в одну ветку in_progress/approved/rejected
      (silence). Проверка проектно-независимого исключения терминалов. (AC-2)
    module: tests/test_reconciler_plane.py
    expected: PASS

  - id: TC-03
    type: unit
    description: >
      Cancelled терминал также исключён из actionable-выборки -> тик = silence,
      0 нотификаций. (AC-2)
    module: tests/test_reconciler_plane.py
    expected: PASS

  - id: TC-04
    type: unit
    description: >
      _note_unblock не вызывается после no-op dispatch: handle_verdict не сдвинул
      стадию (задача уже в целевом состоянии) -> 0 нотификаций. (AC-3)
    module: tests/test_reconciler_plane.py
    expected: PASS

  - id: TC-05
    type: unit
    description: >
      Дедуп: два последовательных тика по одной синхронизированной задаче без
      изменения состояния -> суммарно 0 повторных уведомлений. (AC-4)
    module: tests/test_reconciler_plane.py
    expected: PASS

  - id: TC-06
    type: unit
    description: >
      Нет регресса: Plane=Approved, локальная стадия не продвинута, grace выдержан,
      нет активных job -> handle_verdict доигран, задача продвинута, _note_unblock
      вызван РОВНО один раз. (AC-5)
    module: tests/test_reconciler_plane.py
    expected: PASS

  - id: TC-07
    type: unit
    description: >
      Нет регресса для in_progress (task is None -> старт пайплайна, 1 unblock) и
      rejected (task существует -> откат, 1 unblock), оба только при реальном
      изменении состояния. (AC-6)
    module: tests/test_reconciler_plane.py
    expected: PASS

  - id: TC-08
    type: unit
    description: >
      never-raise: list_issues_by_state / get_project_states / _dispatch /
      send_telegram бросают исключение -> тик не падает, ошибка изолирована и
      залогирована, прочие issues обработаны. (AC-8)
    module: tests/test_reconciler_plane.py
    expected: PASS

  - id: TC-09
    type: unit
    description: >
      Kill-switch: reconcile_enabled=False -> F-2 не выполняется;
      reconcile_plane_enabled=False -> F-2 не выполняется, F-1 не затронут. (AC-9)
    module: tests/test_reconciler_plane.py
    expected: PASS

  - id: TC-10
    type: integration
    description: >
      End-to-end F-2 на двух проектах (enduro И orchestrator): задача в Done на
      каждом -> тик reconcile_plane_once = 0 нотификаций / 0 jobs на обоих,
      независимо от алиасинга статусов проекта. Главный регресс-тест бага. (AC-1, AC-2)
    module: tests/test_reconciler_plane.py
    expected: PASS

  # ---------- P1: связанный баг кэша статусов ----------
  - id: TC-11
    type: unit
    description: >
      Устаревший _STATES_CACHE обновляется без рестарта: после появления нового
      статуса срабатывает выбранный механизм (TTL/flush) -> следующий
      get_project_states содержит новый статус. (AC-12)
    module: tests/test_plane_states_cache.py
    expected: PASS

  - id: TC-12
    type: unit
    description: >
      Совместимость по умолчанию: при дефолтных настройках get_project_states не
      регрессирует — enduro отдаёт свои UUID, fallback на _DEFAULT_STATES при
      недоступности API сохранён. (AC-13)
    module: tests/test_plane_states_cache.py
    expected: PASS

  # ---------- P0: общий прогон ----------
  - id: TC-13
    type: integration
    description: >
      Полный набор pytest tests/ -q зелёный (нет регресса в reconciler/plane/qg/
      stage_engine). (AC-15)
    module: tests/
    expected: PASS
