12 KiB
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-stagingORCH-113 на релевантные пути; атомарныйreap_running_jobrowcount-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 |