---
work_item: ORCH-090
stage: analysis
author_agent: analyst
status: ready-for-review
created_at: 2026-06-09
model_used: claude-opus-4-8
---

# 03 — Критерии приёмки (Acceptance Criteria): ORCH-090 — Механизм отмены задачи: статус STOP в Plane

Work Item: **ORCH-090** · Repo: **orchestrator** · Стадия: analysis

Формат: каждый критерий имеет **PASS** (что должно быть истинно для приёмки) и **FAIL**
(что считается провалом). Любой машинный/ручной reviewer проверяет их буквально по файлам
репозитория.

---

## AC-1 — STOP останавливает активного агента

**Условие:** задача с running-job'ом переведена в Plane-статус STOP.
- **PASS:** активному процессу агента послан SIGTERM через существующий каскад
  (`launcher._watchdog`: SIGTERM → grace → SIGKILL); по grace процесс завершён; `agent_runs`/`jobs`
  отражают завершение. Тест демонстрирует вызов остановки по `jobs.pid`.
- **FAIL:** процесс агента продолжает работать после STOP, либо kill реализован новым «грязным»
  механизмом мимо graceful-каскада, либо STOP падает с исключением.

---

## AC-2 — Все job'ы задачи отменены без авто-requeue

**Условие:** у задачи есть job'ы в `queued` и/или `running`; пришёл STOP.
- **PASS:** все job'ы задачи переведены в терминальный отменённый исход; `claim_next_job` их не
  выбирает; `_finalize_permanent`/`job_reaper` не возвращают их в `queued` (ретраи исчерпаны).
  Тест: после STOP claim не возвращает job задачи, reaper не requeue'ит.
- **FAIL:** хотя бы один job задачи остаётся claimable/возвращается в `queued` после STOP, либо
  происходит авто-requeue.

---

## AC-3 — Таймеры/мониторы сняты, отменённая задача не реконсилируется

**Условие:** задача отменена через STOP.
- **PASS:** связанные таймеры/мониторы (post-deploy monitor, brd-review clock, defer'ы) не активны
  для задачи; `reconciler` (`_is_terminal_state`, терминал-скип `done`/`cancelled`) и `job_reaper`
  не трогают/не «оживляют» отменённую задачу. Тест: reconciler F-1 пропускает отменённую задачу.
- **FAIL:** монитор/таймер срабатывает по отменённой задаче, либо reconciler/reaper её
  релончит/реанимирует.

---

## AC-4 — Полный сброс: ветка/worktree удалены/архивированы, прогресс сброшен, docs сохранены

**Условие:** задача отменена через STOP.
- **PASS:** рабочий worktree удалён (`remove_worktree`, never-raise), рабочая ветка удалена/
  заархивирована; `main` не тронут (force-push в `main` отсутствует); прогресс задачи в БД приведён
  к durable-состоянию «отменена» (повторный запуск возможен только с нуля); docs-артефакты
  (`docs/work-items/ORCH-090/01..17`) **сохранены/забэкаплены**, не удалены.
- **FAIL:** worktree/ветка остаются как «живой» прогресс, либо тронут `main`, либо docs-артефакты
  удалены, либо задача способна продолжиться «с середины».

---

## AC-5 — Единственный вход к запуску — To Analyse; дыра релонча закрыта

**Условие:** существующая задача (с веткой/прогрессом) вручную переведена в промежуточный рабочий
статус (Architecture/Development/Review/Testing/Deploying/Awaiting Deploy/Monitoring).
- **PASS:** агент соответствующей стадии **не** запускается (нет `enqueue_job` стадийного агента по
  факту ручной смены рабочего статуса). Запуск пайплайна происходит ТОЛЬКО при статусе «To Analyse»
  (`start_pipeline`). Тест: перевод в Development не порождает job; перевод в To Analyse порождает
  старт с нуля.
- **FAIL:** ручной перевод в любой промежуточный рабочий статус релончит агента текущей стадии
  (текущее дырявое поведение `handle_status_start`).

---

## AC-6 — Идемпотентность STOP

**Условие:** STOP приходит на задачу, которая уже отменена / `done` / не существует.
- **PASS:** обработчик — no-op: нет повторного kill, нет повторного удаления ветки, нет ошибок, нет
  Telegram-спама дублями. Тест: повторный STOP не меняет состояние и не бросает.
- **FAIL:** повторный STOP бросает исключение, повторно убивает/чистит, либо генерирует
  дубль-уведомления.

---

## AC-7 — Безопасное прерывание merge/deploy (self-hosting safety)

**Условие:** STOP приходит во время merge/deploy задачи.
- **PASS:** `main` не остаётся в half-merged состоянии; прод-контейнер не рестартится/не роняется
  обработчиком STOP; force-push в `main` отсутствует. Если необратимый шаг уже запущен — он не
  «разрывается» с порчей (исход зафиксирован честно, затем применена отмена). Тест/обоснование
  демонстрирует fail-safe точку прерывания.
- **FAIL:** после STOP `main` в неконсистентном состоянии, прод перезапущен/упал по вине STOP, либо
  выполнен force-push в `main`.

---

## AC-8 — Kill-switch и нулевая регрессия

**Условие:** флаг `stop_status_enabled=False`.
- **PASS:** STOP-обработка не активна, дыра релонча в поведении не меняется относительно текущего
  кода; `STAGE_TRANSITIONS` / `QG_CHECKS` / `check_*` не изменены; полный `pytest tests/` зелёный;
  enduro-trails не затронут. При `True` — STOP работает по AC-1…AC-7.
- **FAIL:** при выключенном флаге поведение отличается от текущего; изменены exit-гейты/реестр QG;
  регресс существующих тестов.

---

## AC-9 — Аддитивность БД и restart-safe

**Условие:** изменения схемы БД и поведение после рестарта.
- **PASS:** все миграции аддитивны и идемпотентны (`CREATE TABLE IF NOT EXISTS`/`_ensure_column`);
  после рестарта контейнера отменённая задача остаётся отменённой и не релончится. Тест: повторная
  инициализация БД не падает; отменённая задача durable.
- **FAIL:** деструктивная/неидемпотентная миграция, изменение существующих таблиц-контрактов, либо
  «оживание» отменённой задачи после рестарта.

---

## AC-10 — Наблюдаемость STOP

**Условие:** STOP применён к задаче.
- **PASS:** факт отмены залогирован; отправлен Telegram-алерт с кликабельным номером задачи;
  Plane-коммент (best-effort); live-карточка обновлена (never-raise); `GET /queue` несёт read-only
  блок отмены. Тест: блок присутствует в ответе `GET /queue`.
- **FAIL:** STOP не оставляет следов в логе/уведомлениях, либо `GET /queue` падает/не отражает
  отмену.

---

## Сводная матрица AC ↔ FR/BR

| AC | Покрывает |
|----|-----------|
| AC-1 | BR-1 / FR-2 |
| AC-2 | BR-1 / FR-3 |
| AC-3 | BR-1 / FR-4 / NFR-4 |
| AC-4 | BR-2 / FR-5 |
| AC-5 | BR-3, BR-4 / FR-6 |
| AC-6 | BR-5 / FR-1 |
| AC-7 | BR-6 / FR-7 / NFR-3 |
| AC-8 | NFR-1 / FR-6 |
| AC-9 | NFR-2, NFR-4 / FR-3, FR-5 |
| AC-10 | BR-8 / FR-8 |
