# 03-Критерии приёмки — ORCH-026 **Work Item:** ORCH-026 · **Repo:** orchestrator · **Стадия:** analysis Каждый критерий — проверяемое условие PASS/FAIL. Маппинг на тесты — `04-test-plan.yaml`. --- ## Уровень A — Сериализация merge/деплоя внутри одного репо ### AC-A1 — Сериализация merge внутри репо - **PASS:** пока задача A применимого репо удерживает окно merge (merge-lease не освобождён / `main` ещё не обновлён), задача B того же репо НЕ доходит до фактического merge — она **defer**-ится (повторная постановка через `available_at`), а не мержится от устаревшего `main`. - **FAIL:** B мержится/деплоится, пока A не в `main`; или B откатывается на `development` вместо defer. ### AC-A2 — Proactive pre-merge rebase - **PASS:** перед merge ветка задачи **всегда** догоняется на свежий `origin/main` (вызывается rebase), даже когда текстового конфликта нет и ветка формально не «behind» по старой проверке; после rebase ветка содержит код предшественника (A). - **FAIL:** rebase запускается только при конфликте/`branch_is_behind_main`, и B мержится без кода A. ### AC-A3 — Кросс-репо параллелизм сохранён - **PASS:** задача в `orchestrator` и задача в `enduro-trails` доходят до merge/деплоя параллельно — сериализация одного репо не блокирует другой (lease/гейт строго per-repo). - **FAIL:** задача одного репо ждёт освобождения ресурса, удерживаемого задачей ДРУГОГО репо. ### AC-A4 — Restart-safe - **PASS:** после рестарта прод-контейнера состояние сериализации восстанавливается корректно; мёртвый держатель merge-lease проактивно реклеймится (ORCH-065), конвейер не встаёт навсегда. - **FAIL:** рестарт оставляет навсегда захваченный lease → конвейер всех проектов встаёт. ### AC-A5 — Self-hosting safety - **PASS:** прод-контейнер orchestrator НЕ рестартится/не падает вне штатного `Confirm Deploy` (ORCH-059); нет push/force-push в `main`; `STAGE_TRANSITIONS` и реестр `QG_CHECKS` не изменены. - **FAIL:** любой незапрошенный рестарт прода, прямой push в `main`, или изменение машины стадий. ### AC-A6 — Anti-deadlock / anti-livelock при defer - **PASS:** при занятой сериализации B defer-ится с задержкой и bounded бюджетом; исчерпание бюджета → эскалация (alert/Blocked), не бесконечный цикл и не откат. - **FAIL:** B уходит в вечный defer-цикл, либо немедленно откатывается на `development`. ### AC-A7 — Условность (не-self репо без регресса) - **PASS:** при выключенном kill-switch и для репо вне scope поведение конвейера 1:1 как до ORCH-026 (нулевая регрессия для enduro-trails). - **FAIL:** не-self репо меняет поведение merge/деплоя. --- ## Уровень B — Декларативные зависимости ### AC-B1 — Декларация зависимости - **PASS:** задача может объявить `blocked-by`/`depends-on` (через выбранный источник — Plane relations / БД / гибрid), и связь корректно считывается планировщиком. - **FAIL:** связь не считывается / теряется. ### AC-B2 — Гейт планировщика (B не стартует до A) - **PASS:** задача с незавершённым depends-on **не клеймится** воркером (не запускается агент, слот `max_concurrency` не занимается), пока все depends-on не достигли `done`; как только A становится `done` — B становится claimable. - **FAIL:** B запускается раньше завершения A; или занимает слот, простаивая. ### AC-B3 — Детект дедлоков (циклы) - **PASS:** циклическая зависимость (A→B→A и длиннее) детектируется детерминированно; задача(и) в цикле → `Blocked` + alert (Telegram/Plane) с указанием цикла; поток остальных задач не блокируется. - **FAIL:** цикл приводит к молчаливому вечному ожиданию или к падению воркера. ### AC-B4 — Видимость заблокированной задачи - **PASS:** заблокированная задача видна — Plane-статус `Blocked` и/или строка ожидания в Telegram-карточке (что/кого ждёт); инвариант «одна карточка на задачу» сохранён. - **FAIL:** заблокированная задача невидима наблюдателю. ### AC-B5 — Совместимость с reconciler/reaper - **PASS:** `reconciler` F-1 НЕ «разблокирует» задачу, заблокированную по зависимости (как уже делает для Blocked/Needs-Input, ORCH-060/068); reaper не реапит корректно ожидающую задачу. - **FAIL:** reconciler продвигает заблокированную задачу мимо её depends-on. --- ## Общие (оба уровня) ### AC-G1 — never-raise - **PASS:** любая ошибка (git/сеть/БД/Plane) в новой логике не пробрасывается в `advance_stage`/ воркер; деградирует консервативно (defer/skip/fail-closed), конвейер не падает. - **FAIL:** необработанное исключение роняет воркер/монитор-поток. ### AC-G2 — Kill-switch - **PASS:** глобальный kill-switch выключает фичу целиком → поведение 1:1 как до ORCH-026. - **FAIL:** при выключенном флаге поведение изменено. ### AC-G3 — Документация обновлена (golden source) - **PASS:** в ТОМ ЖЕ PR обновлены `docs/architecture/README.md`, `CLAUDE.md` (если изменилось поведение очереди), `CHANGELOG.md`, заведён ADR в `06-adr/`. Reviewer проверяет. - **FAIL:** код изменён, документация — нет (→ REQUEST_CHANGES). ### AC-G4 — Миграция БД безопасна (если применимо) - **PASS:** миграция только аддитивная (`CREATE TABLE IF NOT EXISTS`/`_ensure_column`), идемпотентна, безопасна на живой общей прод-БД; существующие данные enduro-trails не затронуты. - **FAIL:** деструктивная миграция / изменение существующих колонок. ### AC-G5 — Тесты зелёные - **PASS:** новые unit+integration тесты (`04-test-plan.yaml`) проходят; существующий `pytest tests/ -q` остаётся зелёным (нет регресса merge-gate/merge-verify/reconciler/reaper). - **FAIL:** красный pytest или регресс существующих тестов.