# ADR-0018: Авто-режим по лейблам — autoApprove / autoDeploy (ORCH-089)

## Статус
Accepted (реализация — ORCH-089)

## Контекст
Конвейер имеет два **человеческих** гейта, тормозящих пакетный автономный прогон
(эпик ORCH-088, «10–20 задач за ночь»):
1. **BRD** (`analysis`): ждёт ручного Plane-статуса `Approved` → advance на `architecture`.
2. **Прод-деплой** (`deploy`): Phase A ставит `Awaiting Deploy` и ждёт ручного
   `Confirm Deploy` (ORCH-059) → Phase B (`initiate_deploy`).

Для доверенных задач оба клика избыточны. Нужно снять **только эти два человеческих
решения**, выборочно/декларативно (лейбл Plane на задаче), не ослабляя ни одной
технической проверки.

## Решение
Аддитивно, по образцу условных под-гейтов (ORCH-035/043/058/059/088): leaf-модуль чистой
логики `src/labels.py` (never-raise) + точечные врезки + флаги. `STAGE_TRANSITIONS`, реестр
`QG_CHECKS`, все `check_*`, схема БД — **не трогаются**.

- **`autoApprove`** (лейбл задачи) → в `_handle_analysis_approved_flow` (ветка `files_ok`)
  после `In Review`+коммента: `set_issue_approved` (индикация) + лог/Telegram/Plane-коммент +
  `advance_stage(..., finished_agent=None)` — тот же путь, что человеческий Approved
  (`approved-via-status` → `analysis → architecture` + `mark_brd_review_ended`). Без
  дублирования переходной логики.
- **`autoDeploy`** (лейбл задачи) → в `_handle_self_deploy_phase_a` сразу после advance на
  `deploy` + `clear_state`: лог/Telegram/Plane-коммент + `_handle_self_deploy_phase_b(...)`
  (idempotency-маркер `INITIATED`, `Deploying`, finalizer). Пропускаются лишь
  индикативно-человеческие шаги (`Awaiting Deploy` + «ask-human»).
- **Чтение лейблов** — `plane_sync.fetch_issue_labels` + `get_project_labels` (TTL-кэш,
  образец `get_project_states`); сопоставление по нормализованному имени; источник истины —
  Plane API (не payload). Новый сеттер `set_issue_approved` (ключ `approved` уже в states).
- **Флаги:** `auto_label_enabled` (kill-switch), `auto_approve_label`/`auto_deploy_label`
  (имена), `auto_label_repos` (CSV; **пусто → self-hosting only**), `auto_label_states_ttl_s`.
  `applies(repo)` (локальный) проверяется ПЕРВЫМ; `has_label` (сеть) — только если
  `applies==True` → при выключенном флаге нулевой сетевой оверхед.

## Критические инварианты
- **Авто-режим снимает ТОЛЬКО человеческое решение**, не ослабляя ни один тех-гейт
  (CI / staging / security / merge-gate / image-freshness / merge-verify / regression-guard /
  post-deploy). autoDeploy живёт в точке, где все под-гейты ребра `deploy-staging → deploy`
  уже зелёные → структурно «никогда не деплоит сломанное».
- **Fail-safe (never auto):** любая ошибка/недоступность Plane/неоднозначность имени →
  «нет авто» → ручной гейт (согласовано с fail-closed-практикой ORCH-059). never-raise.
- **Нулевая регрессия:** без лейблов / `auto_label_enabled=False` / репо вне scope →
  поведение 1:1 как до ORCH-089 (enduro не затронут).
- **Идемпотентность:** autoApprove — advance применяется один раз (поздний Approved/F-2
  видят уже `architecture`); autoDeploy — маркер `INITIATED`.

## Последствия
**+** минимальная поверхность, единый источник истины перехода, декларативно/обратимо,
независимые лейблы, безопасный дефолт. **−** Approved-статус транзиентен (durable-аудит —
лог/Telegram/коммент); 1–2 GET к Plane на гейт применимого репо (TTL-кэш карты лейблов);
требуется однократно создать лейблы в Plane-проекте ORCH (инфра-предусловие; их отсутствие =
fail-safe ручной режим).

Детально: `docs/work-items/ORCH-089/06-adr/ADR-001-auto-label-gates.md`,
`07-infra-requirements.md`, `10-tech-risks.md`.
