Files
orchestrator/docs/work-items/ORCH-114/03-acceptance-criteria.md
claude-bot a685e0cbc9
All checks were successful
CI / test (push) Successful in 1m6s
analyst(ET): auto-commit from analyst run_id=708
2026-06-15 15:57:22 +03:00

12 KiB
Raw Blame History

work_item, stage, author_agent, status, created_at, model_used, escalate
work_item stage author_agent status created_at model_used escalate
ORCH-114 analysis analyst ready-for-review 2026-06-15 claude-opus-4-8 full-cycle

03 — Критерии приёмки (Acceptance Criteria): ORCH-114 — Ownership-lease для side-effectful переходов + умное восстановление при старте

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

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


AC-1 — Обязательный регресс: нет двойного эффекта при конкурентном входе в переход

Условие: два актора одновременно входят в advance_stage(deploy-staging) для одной задачи (живой монитор-финализатор + второй путь: reaper / reconciler F-1 / webhook). Тест-двойники для merge_pr / coverage-ratchet / image-rebuild / deploy-init считают число вызовов.

  • PASS: side-effectful шаги (merge_pr, ratchet baseline, image-rebuild, инициация прод-деплоя, enqueue следующего агента) выполняются ровно один раз; персистится ровно один согласованный исход стадии; второй актор получает «lost-race»/defer и не выполняет побочных эффектов. Тест красный до фикса, зелёный после (воспроизводит класс инцидента ORCH-111).
  • FAIL: любой side-effectful шаг вызван дважды; либо два противоречивых исхода (один откатил на development, другой довёл до done); либо тест не воспроизводит проблему до фикса.

AC-2 — Compare-and-swap на запись стадии

Условие: CAS-вариант записи стадии вызывается двумя писателями с одинаковым ожидаемым предусловием; первый применяется, второй приходит со «устаревшим» ожиданием.

  • PASS: первый writer применяет переход (rowcount=1); второй получает «lost-race» (rowcount=0), стадия не мутируется повторно; при выключенном kill-switch CAS вырождается в прежний безусловный update_task_stage (байт-в-байт).
  • FAIL: второй writer перезатирает стадию; либо CAS меняет семантику записи при выключенном флаге.

AC-3 — Жизненный цикл владения: acquire / release / реклейм

Условие: актор начинает side-effectful финализацию.

  • PASS: владение захватывается на границе финализации и освобождается в try/finally — в т.ч. при исключении и при откате (rollback); durable-запись владения видна другому актору; после release владение реклеймится/свободно.
  • FAIL: владение не освобождается при исключении/откате (lease «течёт» и клинит задачу); либо не захватывается на границе.

AC-4 — Reaper откладывает реклейм при живом владении (все пути, не только Tier-2/deploy-staging)

Условие: durable-владение активно (живой финализатор), reaper делает тик.

  • PASS: reaper defer (лог + счётчик, без повторного advance_stage) пока владение живо и в пределах бюджета; область defer обобщена за пределы Tier-2/deploy-staging ORCH-113 на релевантные пути; атомарный reap_running_job rowcount-guard сохранён.
  • FAIL: reaper повторно исполняет финализацию при живом владельце; либо defer ограничен только прежней узкой областью, оставляя кросс-путь открытым.

AC-5 — Reaper добивает мёртвое/устаревшее владение в ограниченное время

Условие: владелец провально мёртв/завис (lease устарел), финализация не прогрессирует.

  • PASS: reaper реклеймит задачу в пределах Tier-3 backstop reaper_max_running_s (маркер владения backstop не обходит); задача не остаётся навсегда заклиненной; сквозной инвариант reaper_max_running_s > Σ(deploy-staging gate-work) + grace сохранён.
  • FAIL: мёртвое владение блокирует задачу бессрочно; либо нарушен бюджетный инвариант ORCH-065/ 109/110/113.

AC-6 — Умное восстановление при рестарте процесса

Условие: процесс убит в середине финализации deploy-staging/deploy (in-memory состояние потеряно); процесс перезапущен (requeue_running_jobs + цикл).

  • PASS: восстановление через durable-владение/эпоху + авторитетные факты (SHA-in-main ORCH-071/073, маркер INITIATED) детерминированно сходится к единственному согласованному исходу: незавершённое дорешается, уже применённый необратимый шаг (мерж/ratchet/прод-деплой) не применяется повторно.
  • FAIL: после рестарта переход исполняется заново с двойным необратимым эффектом; либо возникает противоречие rollback↔done; либо задача застревает нетерминальной с удержанным lease.

AC-7 — Reconciler F-1 пропускает переход при активном lease

Условие: lease перехода активен; reconciler F-1 сканирует задачу.

  • PASS: F-1 defer/skip (silent, наблюдаемо), не вызывает advance_stage, по образцу skip-guard'ов escalated/Blocked/task-deps; fail-safe: неопределённость lease → консервативный skip.
  • FAIL: F-1 продвигает стадию параллельно живому владельцу.

AC-8 — Webhook-путь пропускает переход при активном lease

Условие: lease перехода активен; приходит Plane-webhook (Approved / Confirm Deploy) на ту же задачу.

  • PASS: webhook-путь продвижения defer, не дублирует переход/финализацию при живом владельце; поздний легитимный сигнал не теряется (повторно отработает после release или станет идемпотентным no-op).
  • FAIL: webhook повторно входит в переход параллельно владельцу и даёт двойной эффект.

AC-9 — Kill-switch off → поведение байт-в-байт прежнее

Условие: новый kill-switch выключен.

  • PASS: lease не пишется/не читается; CAS вырождается в прежний безусловный update_task_stage; reaper/reconciler/webhook/startup ведут себя как до ORCH-114; существующий pytest tests/ зелёный без правок ожиданий; enduro не затронут.
  • FAIL: при выключенном флаге наблюдается любое отличие от до-ORCH-114 поведения.

AC-10 — never-raise + fail-open (hot-path) / fail-closed (prod-safety)

Условие: механизм владения сталкивается с ошибкой (БД-сбой/повреждённая запись lease/исключение).

  • PASS: ни одна публичная функция владения не роняет конвейер; горячий путь claim/guard — fail-open (общая очередь всех проектов не клинится); решения, критичные для необратимости/прода — fail-closed; на ошибке — WARNING + безопасный дефолт.
  • FAIL: ошибка механизма роняет claim/конвейер; либо hot-path заклинивает очередь; либо prod-критичное решение фейлит «открыто».

AC-11 — Инварианты конвейера не тронуты

Условие: аудит диффа против src/stages.py, src/qg/checks.py, схемы БД.

  • PASS: STAGE_TRANSITIONS / реестр QG_CHECKS / семантика и имена check_* / машинные вердикт-ключи (verdict:/result:/deploy_status:/staging_status:/security_status:/ coverage_status:) — байт-в-байт; любое новое хранилище аддитивно/идемпотентно (CREATE TABLE IF NOT EXISTS / _ensure_column), схемы существующих таблиц неизменны.
  • FAIL: изменены состав/порядок стадий, реестр/семантика гейтов, вердикт-ключи или существующие столбцы/индексы.

AC-12 — Наблюдаемость

Условие: GET /queue при включённом флаге.

  • PASS: присутствует аддитивный read-only блок владения (держатели/возраст/defer-счётчики/реклеймы); существующие ключи /queue не сломаны; форсированный/устаревший реклейм даёт Telegram-алерт с кликабельным номером.
  • FAIL: блок отсутствует/ломает существующий вывод; реклейм происходит молча без наблюдаемости.

AC-13 — Self-hosting безопасность

Условие: аудит механизма владения на побочные действия.

  • PASS: механизм никогда не рестартит прод-контейнер orchestrator, не пушит/force-push в main, не трогает detached deploy-процесс; деплой орка по-прежнему только через staging-гейт (8501) и Confirm Deploy.
  • FAIL: механизм владения инициирует рестарт прода/мутацию main/вмешательство в detached-деплой.

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

AC Покрывает Тип проверки
AC-1 BR-1, BR-6, BR-8 / FR-1, FR-2 integration (regression, red→green)
AC-2 BR-2 / FR-2 unit
AC-3 BR-1 / FR-1 unit
AC-4 BR-3 / FR-3 integration
AC-5 BR-3, NFR-6 / FR-3 unit/integration
AC-6 BR-4, BR-6, NFR-4, NFR-7 / FR-1…FR-4 integration (restart-recovery)
AC-7 BR-5 / FR-5 unit/integration
AC-8 BR-5 / FR-5 unit/integration
AC-9 BR-9, NFR-8 / FR-7 regression (kill-switch off)
AC-10 NFR-1 / FR-7 unit
AC-11 NFR-3 / FR-6 (negative) structural audit
AC-12 BR-7 / FR-6 unit/integration
AC-13 NFR-5 / FR-1 structural audit