Files
orchestrator/docs/work-items/ORCH-090/03-acceptance-criteria.md

9.2 KiB
Raw Blame History

work_item, stage, author_agent, status, created_at, model_used
work_item stage author_agent status created_at model_used
ORCH-090 analysis analyst ready-for-review 2026-06-09 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