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

123 lines
8.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Критерии приёмки — ORCH-065
Work Item ID: ORCH-065
Формат: каждый критерий имеет явное условие PASS/FAIL. Все критерии должны быть
PASS для прохождения review/testing.
## A. Job-reaper (Проблема A)
### AC-1 — реап мёртвого running-job без рестарта
- PASS: при наличии строки `jobs` в статусе `running`, чей процесс/исполнитель
достоверно мёртв (pid не существует ИЛИ `agent_runs.exit_code` записан, а job всё
ещё `running`) и условие устойчивости (FR-1.3) выполнено, фоновый reaper переводит
строку в корректный статус (`done`/`queued`/`failed`) **без перезапуска процесса**.
- FAIL: строка остаётся `running` после `reaper_dead_ticks` тиков / превышения
`reaper_max_running_s`.
### AC-2 — разблокировка очереди при concurrency=1
- PASS: после реапа зомби-строки `count_running_jobs()` снижается, и следующий
queued-job успешно claim'ится воркером.
- FAIL: очередь остаётся заблокированной зомби-строкой.
### AC-3 — анти-ложноположительность (живой долгий агент не реапится)
- PASS: `running`-job с ЖИВЫМ процессом в пределах его `agent_timeout` НЕ помечается
зомби (ни по одному тику, ни в пределах `reaper_max_running_s`, если потолок
больше таймаута).
- FAIL: живой агент помечен `failed`/`queued` reaper'ом.
### AC-4 — корректный исход по результату
- PASS: при `agent_runs.exit_code == 0` reaper доводит до успешного завершения без
дублирования уже выполненного stage-advance (идемпотентно); при неуспехе и
`attempts < max_attempts``queued`; при исчерпании → `failed` + Telegram.
- FAIL: успешный исход помечен `failed`; либо дублируется stage-переход; либо
исчерпанный бюджет молча зацикливается на `queued`.
### AC-5 — restart-safe совместимость
- PASS: одновременная работа стартового `requeue_running_jobs()` и периодического
reaper не приводит к двойной обработке одной строки (атомарный UPDATE с guard
`status='running'`).
- FAIL: одна строка обработана дважды / гонка приводит к рассинхрону статуса.
## B. Stale/dead merge-lease reclaim (Проблема B)
### AC-6 — реклейм lease мёртвого держателя
- PASS: lease `.merge-lease-<repo>.json`, чей `pid` не существует, проактивно
освобождается на старте И периодическим потоком (не дожидаясь TTL и не дожидаясь
чужого `acquire`).
- FAIL: lease мёртвого держателя остаётся до истечения `merge_lock_timeout_s` или
до следующего чужого `acquire`.
### AC-7 — реклейм по TTL сохранён
- PASS: lease старше `merge_lock_timeout_s` освобождается (существующий контракт не
сломан), с `logger.warning`.
- FAIL: просроченный lease не освобождается.
### AC-8 — не трогать живой lease
- PASS: lease с ЖИВЫМ держателем (pid жив) и возрастом `< merge_lock_timeout_s` НЕ
освобождается (защита легитимного merge).
- FAIL: освобождён lease живого держателя → возможен параллельный конфликтный merge.
### AC-9 — условность и never-raise
- PASS: реклейм реален только для `merge_gate_repos`/self-hosting; для прочих репо
— no-op; любая ошибка реклейма логируется и не валит поток (never-raise).
- FAIL: реклейм выполняется для не-self-hosting репо; либо ошибка пробрасывается
наружу/роняет поток.
## C. Идемпотентная финализация merge (Проблема C)
### AC-10 — докатывание незавершённого merge
- PASS: сценарий «rebase+re-test зелёные, merge не состоялся, процесс умер»
восстанавливается автоматически (job → `queued` reaper'ом / reconciler доигрывает),
и merge доводится без повторного ненужного прогона дорогих шагов.
- FAIL: задача остаётся в полу-выполненном состоянии, требует ручного merge.
### AC-11 — идемпотентность при уже слитом PR
- PASS: повторный вызов финализации при уже слитом PR — no-op (определяется по
состоянию PR/`main`), без ошибки и без второго merge.
- FAIL: второй merge / ошибка при уже слитом PR.
## D. Инварианты и безопасность self-hosting
### AC-12 — прод-контейнер не трогается
- PASS: ни reaper, ни lease-reclaim не рестартят/не роняют прод-контейнер и не
инициируют git-push в `main`.
- FAIL: любая из новых веток кода рестартит self / пушит main.
### AC-13 — контракты неизменны
- PASS: `STAGE_TRANSITIONS`, реестр `QG_CHECKS`, сигнатуры/поведение `check_*`,
БАГ-8 откат, exit-коды deploy-хука — без изменений; новых QG checks/стадий нет.
- FAIL: затронут любой из перечисленных контрактов.
### AC-14 — kill-switches
- PASS: `reaper_enabled=false` → reaper не работает (строго прежнее поведение);
`lease_reclaim_enabled=false` → проактивный реклейм отключён (остаётся лишь
прежний ленивый TTL-реклейм в `acquire`).
- FAIL: флаг `false` не отключает соответствующий механизм.
## E. Наблюдаемость
### AC-15 — блок reaper в /queue
- PASS: `GET /queue` содержит блок `reaper` (enabled, interval, last_run_ts,
reaped_total, last_reaped, lease_reclaimed_total).
- FAIL: блок отсутствует/не обновляется.
### AC-16 — логи и алерты
- PASS: каждый reap и lease-reclaim → `logger.warning` с идентификаторами;
reap→`failed` и lease-reclaim → Telegram.
- FAIL: реап/реклейм происходят молча.
## F. Документация (gate reviewer)
### AC-17 — golden-source обновлён в этом же PR
- PASS: обновлены `docs/architecture/README.md` (раздел про reaper + lease-reclaim),
`CHANGELOG.md`, `.env.example` (новые `ORCH_*` флаги); заведён
`06-adr/ADR-001-*.md`.
- FAIL: код изменён, документация — нет (reviewer → REQUEST_CHANGES).
## G. Тесты
### AC-18 — регресс-тесты зелёные
- PASS: новые unit/integration тесты (см. 04-test-plan.yaml) проходят; существующий
`pytest tests/ -q` зелёный (нет регресса merge_gate / queue / reconciler).
- FAIL: любой тест из плана красный или сломан существующий тест.