work_item: ORCH-089
title: "Авто-режим по лейблам: autoApprove (авто-BRD) + autoDeploy (авто-деплой)"
description: >
  План тестов авто-прохода двух человеческих гейтов по лейблам Plane.
  Фокус юнит-тестов — чистая логика src/labels.py (never-raise, fail-safe) и
  врезки в stage_engine (autoApprove в _handle_analysis_approved_flow,
  autoDeploy в _handle_self_deploy_phase_a). Сеть Plane — мокается.
  Инвариант: STAGE_TRANSITIONS/QG_CHECKS/тех-гейты не трогаются.

tests:
  # --- src/labels.py: чистая логика авто-режима (never-raise, fail-safe) -----
  - id: TC-01
    type: unit
    description: "has_label возвращает True, когда лейбл присутствует на issue (мок Plane labels)"
    module: tests/test_labels.py
    expected: PASS

  - id: TC-02
    type: unit
    description: "has_label возвращает False, когда лейбла нет на issue"
    module: tests/test_labels.py
    expected: PASS

  - id: TC-03
    type: unit
    description: "has_label при ошибке Plane API / таймауте → fail-safe (нет авто, never-raise)"
    module: tests/test_labels.py
    expected: PASS

  - id: TC-04
    type: unit
    description: "Сопоставление имени лейбла нормализовано (регистр/пробелы); неоднозначность → нет авто"
    module: tests/test_labels.py
    expected: PASS

  - id: TC-05
    type: unit
    description: "auto_approve_applies/auto_deploy_applies: scope CSV + self-hosting; пустой scope по дефолту"
    module: tests/test_labels.py
    expected: PASS

  - id: TC-06
    type: unit
    description: "auto_label_enabled=False → has_label/applies дают 'нет авто' без сетевых вызовов"
    module: tests/test_labels.py
    expected: PASS

  # --- plane_sync: чтение лейблов + сеттер Approved ---------------------------
  - id: TC-07
    type: unit
    description: "fetch_issue_labels парсит поле labels issue и резолвит uuid→имя по карте проекта (мок httpx)"
    module: tests/test_plane_sync_labels.py
    expected: PASS

  - id: TC-08
    type: unit
    description: "Карта лейблов проекта кэшируется с TTL (повтор в окне TTL не делает второй GET)"
    module: tests/test_plane_sync_labels.py
    expected: PASS

  - id: TC-09
    type: unit
    description: "set_issue_approved PATCHит issue в Approved-UUID (get_project_states['approved']); never-raise при ошибке"
    module: tests/test_plane_sync_labels.py
    expected: PASS

  # --- autoApprove: врезка в _handle_analysis_approved_flow ------------------
  - id: TC-10
    type: unit
    description: "autoApprove + артефакты готовы → авто-advance analysis→architecture, Approved выставлен, клок brd_review_ended закрыт"
    module: tests/test_auto_approve_brd.py
    expected: PASS

  - id: TC-11
    type: unit
    description: "Без лейбла autoApprove → прежнее поведение: In Review, return без advance (ждёт человека)"
    module: tests/test_auto_approve_brd.py
    expected: PASS

  - id: TC-12
    type: unit
    description: "autoApprove, но артефактов нет (check_analysis_complete FAIL) → НЕ advance (AC-5 для BRD)"
    module: tests/test_auto_approve_brd.py
    expected: PASS

  - id: TC-13
    type: unit
    description: "autoApprove идёт через тот же advance-путь, что ручной Approved (нет дублирования логики; идемпотентно при повторе)"
    module: tests/test_auto_approve_brd.py
    expected: PASS

  - id: TC-14
    type: unit
    description: "autoApprove: авто-проход логируется + Telegram/карточка/Plane-коммент вызваны (прозрачность AC-7)"
    module: tests/test_auto_approve_brd.py
    expected: PASS

  # --- autoDeploy: врезка в _handle_self_deploy_phase_a ----------------------
  - id: TC-15
    type: unit
    description: "autoDeploy + Phase A advance на deploy → автоматически вызывается _handle_self_deploy_phase_b (initiate_deploy)"
    module: tests/test_auto_deploy.py
    expected: PASS

  - id: TC-16
    type: unit
    description: "Без лейбла autoDeploy → прежнее поведение: Awaiting Deploy, ждёт ручного Confirm Deploy"
    module: tests/test_auto_deploy.py
    expected: PASS

  - id: TC-17
    type: unit
    description: "autoDeploy идемпотентен: маркер INITIATED уже стоит → повторный авто-триггер = no-op"
    module: tests/test_auto_deploy.py
    expected: PASS

  - id: TC-18
    type: unit
    description: "autoDeploy не-self репо / вне scope → no-op (Phase A/B существуют только для self-hosting)"
    module: tests/test_auto_deploy.py
    expected: PASS

  - id: TC-19
    type: unit
    description: "autoDeploy: авто-проход логируется + Telegram + Plane-коммент (прозрачность AC-7)"
    module: tests/test_auto_deploy.py
    expected: PASS

  # --- независимость лейблов + kill-switch -----------------------------------
  - id: TC-20
    type: unit
    description: "Только autoApprove (без autoDeploy): BRD авто, деплой ждёт человека (AC-9)"
    module: tests/test_auto_label_combinations.py
    expected: PASS

  - id: TC-21
    type: unit
    description: "Только autoDeploy (без autoApprove): BRD ждёт человека, деплой авто (AC-9)"
    module: tests/test_auto_label_combinations.py
    expected: PASS

  - id: TC-22
    type: unit
    description: "auto_label_enabled=False → оба гейта ручные при наличии обоих лейблов (kill-switch AC-8)"
    module: tests/test_auto_label_combinations.py
    expected: PASS

  # --- интеграция: сквозной авто-проход на ребрах конвейера ------------------
  - id: TC-23
    type: integration
    description: "Оба лейбла + все тех-гейты зелёные → задача проходит analysis→deploy без ручных кликов (AC-3)"
    module: tests/test_auto_labels_integration.py
    expected: PASS

  - id: TC-24
    type: integration
    description: "autoDeploy + красный staging/merge-gate → Phase A не достигнут, Phase B не инициирован (AC-5)"
    module: tests/test_auto_labels_integration.py
    expected: PASS

  # --- инварианты / регрессия ------------------------------------------------
  - id: TC-25
    type: integration
    description: "Регресс: задача без лейблов проходит оба гейта ровно как до ORCH-089 (AC-4)"
    module: tests/test_auto_labels_integration.py
    expected: PASS

  - id: TC-26
    type: unit
    description: "Инвариант: STAGE_TRANSITIONS и реестр QG_CHECKS не изменены ORCH-089 (snapshot-сверка)"
    module: tests/test_auto_labels_invariants.py
    expected: PASS
