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

# 03 — Критерии приёмки (Acceptance Criteria): ORCH-113 — BUG: job-reaper не должен повторно запускать финализацию `deploy-staging`, пока жив исходный finalizer

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

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

---

## AC-1 — Нет второго прогона edge-гейтов при живом finalizer'е

**Условие:** job на `deploy-staging` с `exit_code=0`, `finished_age_s >= reaper_finalize_grace_s`, но
исходный monitor/finalizer ещё **жив** (сигнал живости присутствует).
- **PASS:** reaper **не** вызывает `_gate_driven_advance`/`advance_stage` для этого job; второй прогон
  security / merge-gate / локального re-test / coverage / image-freshness **не** запускается; reaper
  логирует defer.
- **FAIL:** reaper запускает повторный `advance_stage` / любой edge-под-гейт, пока finalizer жив.

---

## AC-2 — Идемпотентность и строгое владение состоянием

**Условие:** монитор финализирует `deploy-staging` и параллельно срабатывает reaper-тик для того же
job/stage.
- **PASS:** тяжёлый прогон edge-гейтов (merge-gate / локальный re-test) исполняется **ровно один раз**
  для пары `(job, stage)`; актор без владения состоянием не выполняет побочных шагов (мерж/re-test/
  rollback).
- **FAIL:** второй локальный re-test/merge-gate запускается для того же job/stage без владения
  состоянием (двойное исполнение edge-гейтов).

---

## AC-3 — Мёртвый finalizer по-прежнему добивается

**Условие:** monitor/finalizer на `deploy-staging` реально **умер** посреди финализации (сигнал
живости отсутствует/протух), job завис в `running`.
- **PASS:** reaper за ограниченное время добивает job по существующему контракту (retry в пределах
  бюджета, иначе `failed` + Telegram; Tier-3 backstop как предохранитель); reaper для `deploy-staging`
  **не** превращён в no-op.
- **FAIL:** мёртвый finalizer на `deploy-staging` не добивается reaper'ом (зомби-job блокирует очередь).

---

## AC-4 — Нет ложного отката и расхождения состояния после успешного deploy

**Условие:** сценарий инцидента ORCH-111 — долгая (> grace) финализация `deploy-staging` при зелёном
`staging_status: SUCCESS`, deploy/finalizer параллельно доходит до `deploy_status: SUCCESS` / merge PR.
- **PASS:** задача **не** откатывается `deploy-staging → development` параллельной reaper-веткой;
  developer-retry **не** инкрементируется ложно; у задачи единственное консистентное
  терминальное/стадийное состояние (сходимость, не расхождение).
- **FAIL:** задача откатана `deploy-staging → development` и/или начислен ложный developer-retry, в то
  время как deploy фактически успешен; ветки состояния расходятся.

---

## AC-5 — Инварианты и контракт reaper сохранены

**Условие:** аудит диффа и поведения при выключенном kill-switch.
- **PASS:** `STAGE_TRANSITIONS` / `QG_CHECKS` / каждый `check_*` / machine-verdict ключи / схема
  существующих таблиц — **байт-в-байт**; БД-правки только аддитивные (`_ensure_column` /
  `CREATE TABLE IF NOT EXISTS`); reaper остаётся never-raise per unit; выключенный флаг → прежнее
  поведение; правки не рестартят прод и не пушат `main`; сквозной инвариант
  `reaper_max_running_s > Σ gate-work + grace` (ORCH-065/109/110) сохранён.
- **FAIL:** изменены `STAGE_TRANSITIONS`/`QG_CHECKS`/семантика `check_*`/machine-verdict ключи или
  схема существующих таблиц; reaper может бросить исключение из тика; флаг `False` меняет поведение;
  нарушен сквозной бюджетный инвариант.

---

## AC-6 — Обязательный регресс-тест и зелёный полный прогон

**Условие:** запуск тест-сюита репозитория.
- **PASS:** добавлен регресс-тест инцидента ORCH-111 (TC-05 в `04-test-plan.yaml`), **красный** на
  коде до фикса и **зелёный** после; полный `pytest tests/ -q` зелёный.
- **FAIL:** регресс-теста нет, либо он зелёный и до фикса (не воспроизводит баг), либо полный регресс
  `tests/` красный.

---

## Сводная матрица AC ↔ FR/BR
| AC | Покрывает |
|----|-----------|
| AC-1 | BR-1 / BR-3 / FR-1 |
| AC-2 | BR-2 / FR-2 |
| AC-3 | BR-4 / FR-4 |
| AC-4 | BR-5 / FR-5 |
| AC-5 | NFR-1 / NFR-2 / NFR-3 / NFR-6 / FR-3 |
| AC-6 | BR-1…BR-5 (регресс-доказательство) |
