# Acceptance Criteria — ORCH-067

Work Item: **ORCH-067**
Каждый критерий формулирует чёткое условие PASS/FAIL. Привязка к тестам — в `04-test-plan.yaml`.

---

## Группа A — Bump по умолчанию (Требование 1)

### AC-1 — дефолт tracker_mode = bump
- **PASS:** `Settings().tracker_mode == "bump"` без выставленного env `ORCH_TRACKER_MODE`.
- **FAIL:** дефолт остался `"edit"` или иное.

### AC-2 — bump-поведение: одна карточка падает вниз
- **PASS:** при втором (и последующем) вызове `update_task_tracker` для задачи с уже
  сохранённым `tracker_message_id` вызывается `delete_telegram(old_id)` (best-effort),
  затем `send_telegram(...)` с `disable_notification=True`, затем `set_tracker_message_id`
  на новый id. В чате остаётся ровно одна карточка на задачу.
- **FAIL:** карточка редактируется на месте при дефолте; либо появляются дубли; либо новая
  карточка отправляется со звуком (`disable_notification` не True).

### AC-3 — bump fail-safe: транзиентный фейл send не обнуляет указатель
- **PASS:** если `send_telegram` вернул `None` (нет креды/транзиентный фейл),
  `tracker_message_id` НЕ перезаписывается в `None` и дубликат в рамках вызова не создаётся.
- **FAIL:** указатель обнулён или создан второй card-месседж в одном вызове.

### AC-4 — режим edit остаётся доступен через env
- **PASS:** при `ORCH_TRACKER_MODE=edit` поведение прежнее (editMessageText, fallback на
  новый месседж только при EDIT_GONE).
- **FAIL:** edit-режим сломан/недоступен.

---

## Группа B — Статус-строка карточки по модели ORCH-066 (Требование 2)

### AC-5 — статус-строка присутствует в карточке
- **PASS:** `render_task_tracker(task_id)` содержит явную строку текущего Plane-статуса
  (напр. `📍 <status>`) в шапке/верхней части карточки.
- **FAIL:** статус-строки нет.

### AC-6 — корректный маппинг stage → Plane-статус
- **PASS:** для всех stage-выводимых состояний строка статуса соответствует таблице ТЗ §2.2:
  `created→To Analyse`, `analysis→Analysis`, `architecture→Architecture`,
  `development→Development`, `review→Code-Review`, `testing→Testing`,
  `deploy→Awaiting Deploy`, `done→Done`.
- **FAIL:** хотя бы один stage маппится на неверное имя/внутренний ярлык.

### AC-7 — In Review (ожидание согласования BRD) как полноценный статус
- **PASS:** при `stage == "analysis"`, `brd_review_started_at` задан и
  `brd_review_ended_at` пуст — статус-строка явно отражает `⏸️ In Review` с пометкой
  «ожидание согласования BRD»; при этом существующая строка «Подтверждение BRD …» с ⏸️/⏳
  сохранена. Работает без сетевых вызовов.
- **FAIL:** In Review теряется/не показан как статус, либо строка «Подтверждение BRD» исчезла.

### AC-8 — Awaiting Deploy и Needs Input отражены
- **PASS:** состояние ожидания Confirm Deploy показывается как
  `⏸️ Awaiting Deploy — ожидание Confirm Deploy`; состояние вопросов аналитика — как
  `❓ Needs Input — нужны уточнения`.
- **FAIL:** любое из этих состояний не отражено в статус-строке.

### AC-9 — рендер карточки никогда не падает
- **PASS:** при любой ошибке построения статуса (битые данные, недоступный источник)
  `render_task_tracker` возвращает корректную карточку (деградация на stage-маппинг или
  fallback-строку), исключение наружу не выходит.
- **FAIL:** `render_task_tracker` бросает исключение.

---

## Группа C — Кликабельный номер в карточке (Требование 3)

### AC-10 — номер задачи в карточке — гиперссылка
- **PASS:** при наличии `plane_web_url` (не loopback), `plane_workspace_slug`, `project_id`
  (резолв по repo) и `plane_issue_id` карточка содержит
  `<a href="https://<base>/<ws>/projects/<pid>/issues/<issue_id>/">ORCH-NNN</a>`.
- **FAIL:** номер выводится сырым текстом при наличии всех данных, либо URL собран неверно.

### AC-11 — fail-safe ссылки в карточке
- **PASS:** при отсутствии любого из (web_base/не-loopback, workspace, project_id,
  plane_issue_id) карточка показывает номер БЕЗ ссылки (`html.escape(work_item_id)`) и не
  падает.
- **FAIL:** падение, пустая ссылка `<a href="">`, либо битый `<a>` тег.

---

## Группа D — Кликабельный номер во всех уведомлениях (Требование 4)

### AC-12 — единый хелпер ссылки
- **PASS:** существует `plane_issue_link(...)`, возвращающий HTML-ссылку при достаточных
  данных и `html.escape(work_item_id)` при недостаточных; никогда не бросает.
- **FAIL:** хелпера нет, либо он падает на неполных данных.

### AC-13 — хелпер применён во всех уведомлениях с work_item_id
- **PASS:** во всех точках `send_telegram`/`notify_*` из ТЗ §3.3, где упоминается
  `work_item_id` (`notify_approve_requested`, `notify_error`, alert'ы stage_engine,
  launcher, merge_gate, job_reaper, security_gate, reconciler, main), номер задачи
  кликабелен (при наличии данных) и ведёт на ту же страницу Plane.
- **FAIL:** хотя бы одна такая точка выводит номер сырым текстом при наличии данных.

### AC-14 — HTML-экранирование пользовательского текста
- **PASS:** title/причины/сообщения с потенциальным HTML (`<`, `>`, `&`) экранируются
  `html.escape`; разметка `<a>` остаётся валидной; сообщение проходит `parse_mode=HTML`.
- **FAIL:** неэкранированный текст ломает разметку (тест с title, содержащим `<b>`/`&`,
  обнаруживает поломку).

---

## Группа E — Нерегресс и качество

### AC-15 — инварианты транспорта/нотификаций сохранены
- **PASS:** `send_telegram`/`edit_telegram`/`delete_telegram` не изменены по сигнатуре/
  семантике; карточка тихая (`disable_notification=True`); инвариант «одна карточка на
  задачу» соблюдён; `STAGE_TRANSITIONS`/QG/схема БД не тронуты.
- **FAIL:** изменён транспорт, карточка пингует, появились дубли, тронута схема БД/QG.

### AC-16 — нет регресса для enduro-trails
- **PASS:** существующие тесты нотификаций (`test_notify_approve_links.py`,
  `test_notify_done_regression.py` и др.) проходят; поведение карточки для не-ORCH проектов
  без новых Plane-статусов деградирует корректно (alias-fallback, без ссылки при нехватке
  данных).
- **FAIL:** падение существующих тестов или сломанная карточка для enduro.

### AC-17 — весь набор тестов зелёный
- **PASS:** `pytest tests/ -q` зелёный.
- **FAIL:** любой упавший тест.

### AC-18 — документация обновлена в том же PR
- **PASS:** обновлены `CLAUDE.md` (раздел нотификаций/tracker), `CHANGELOG.md`,
  создан ADR per-work-item.
- **FAIL:** функционал изменён, документация — нет (reviewer → REQUEST_CHANGES).
