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

104 lines
8.1 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.
# 03 — Критерии приёмки (Acceptance Criteria): ORCH-088 — Serial gate
Work Item: **ORCH-088** · Repo: **orchestrator** · Стадия: analysis
Формат: каждый критерий — чёткое условие **PASS/FAIL**. Критерий считается выполненным, если
описанная проверка даёт указанный результат. Нумерация AC-1…AC-6 соответствует BR; AC-7…AC-11 —
производные/защитные.
> Скоп — FR-1…FR-5 (serial e2e). Merge-очередь / pre-merge rebase / фазы A/B/C — вне приёмки.
---
## AC-1 — Gate закрыт при активной задаче
**Условие:** в репо `R` есть задача `A` со `stage != 'done'`. В очередь поступает новая задача `B`
того же репо.
- **PASS:** analyst-агент задачи `B` НЕ запускается; ветка `B` НЕ создаётся; `B` остаётся в ожидании
(`jobs.status='queued'` / не стартована). `GET /queue` показывает `B` как ожидающую.
- **FAIL:** analyst `B` стартовал, или ветка `B` создана, пока `A` не `done`.
## AC-2 — Автостарт следующей по достижении `done`
**Условие:** активная задача `A` репо `R` достигла `stage = 'done'` (после прод-деплоя). В очереди
ждёт `B`.
- **PASS:** `B` стартует анализ **автоматически** (без ручного действия) — claim analyst-job `B`
происходит на ближайшем цикле планировщика; ветка `B` создаётся в этот момент.
- **FAIL:** `B` не стартует после `A.stage='done'`, либо для старта требуется ручное вмешательство.
## AC-3 — Restart-safe (состояние в БД)
**Условие:** активна `A` (`stage<done`), `B` ждёт; оркестратор перезапускается.
- **PASS:** после рестарта gate по-прежнему закрыт (`B` не стартовала, `A` определяется из БД);
после `A.stage='done'` `B` стартует. Freeze (если был выставлен) сохраняется после рестарта.
- **FAIL:** после рестарта `B` стартовала при `A.stage<done`, или freeze «потерян».
## AC-4 — Per-repo параллелизм
**Условие:** активна задача в `orchestrator` (`stage<done`); в `enduro-trails` поступает новая задача.
- **PASS:** задача `enduro-trails` стартует анализ независимо (gate orchestrator её не держит) и
наоборот; gate/freeze одного репо не влияет на другой.
- **FAIL:** задача другого репо заблокирована состоянием gate/freeze чужого репо.
## AC-5 — Rollback-freeze + алерт
**Условие:** задача `A` репо `R` достигла `done`; во время post-deploy мониторинга вынесен вердикт
`DEGRADED` (self → `ALERT_ONLY`; non-self+auto_rollback → `ROLLBACK`).
- **PASS:** для `R` выставлен durable freeze (в БД); отправлен Telegram-алерт о заморозке; следующая
задача репо НЕ стартует, пока freeze не снят **вручную**; `GET /queue` показывает `frozen: true`.
После ручного снятия freeze следующая задача стартует.
- **FAIL:** следующая задача стартовала при активном freeze; либо freeze снялся автоматически; либо
алерт не отправлен.
## AC-6 — Нет stale-base (ветка от свежего `main`)
**Условие:** задачи `A` затем `B` одного репо проходят serial. `A` влита в `main` к моменту своего
`done`.
- **PASS:** ветка `B` срезана от `main`, **содержащего код `A`**: проверка
`git merge-base --is-ancestor <validated_sha задачи A> <branch B>` (или равноценная: HEAD `A` в
`main` — предок базы `B`) истинна. Branch `B` не создан раньше `A.stage='done'`.
- **FAIL:** база `B` не содержит коммитов `A` (ветка срезана до завершения `A`).
## AC-7 — Kill-switch / нулевая регрессия
**Условие:** `serial_gate_enabled = False` (или репо вне `serial_gate_repos`).
- **PASS:** claim и старт ведут себя строго как до ORCH-088 (gate инертен); тесты прежнего поведения
зелёные; enduro не затронут.
- **FAIL:** при выключенном флаге поведение отличается от исходного.
## AC-8 — never-raise / fail-open для claim
**Условие:** при вычислении gate происходит ошибка БД/логики в горячем пути claim.
- **PASS:** ошибка перехвачена и залогирована; claim НЕ падает; для claim — поведение fail-open
(очередь всех проектов не заклинивает). Конвейер enduro продолжает работать.
- **FAIL:** ошибка gate роняет claim/воркер или заклинивает очередь.
## AC-9 — fail-closed для freeze
**Условие:** при определении состояния freeze возникает сомнение/ошибка (например, не удалось
достоверно прочитать признак).
- **PASS:** в отношении freeze применяется консервативное (безопасное для прода) поведение — не
стартовать следующую при невозможности подтвердить отсутствие freeze (зафиксировать в ADR/коде).
- **FAIL:** при сомнении gate открывается и стартует следующую задачу.
## AC-10 — Наблюдаемость `GET /queue`
**Условие:** запрос `GET /queue` при активной задаче и/или freeze.
- **PASS:** ответ содержит аддитивный блок `serial_gate` с: `enabled`, областью, per-repo
`active_task`, списком `waiting`, `frozen`. Существующие ключи `/queue` не изменены.
- **FAIL:** блок отсутствует/ломает существующий контракт, либо данные не отражают реальное состояние.
## AC-11 — Инварианты неизменны
**Условие:** проверка контрактов после внедрения.
- **PASS:** `STAGE_TRANSITIONS`, реестр `QG_CHECKS`, `check_*`, exit-коды deploy-хука, merge-gate,
merge-verify, image-freshness, post-deploy контракт — без изменений; миграции БД аддитивны и
идемпотентны; прод-контейнер не рестартится механизмом gate.
- **FAIL:** изменён любой перечисленный контракт, либо миграция не идемпотентна.
---
## Сводная матрица AC ↔ FR/BR
| AC | FR | BR | Тип проверки |
|----|----|----|--------------|
| AC-1 | FR-1 | BR-1 | unit (claim/gate) + integration |
| AC-2 | FR-1/2 | BR-2 | integration |
| AC-3 | FR-4 | BR-5 | integration (restart) |
| AC-4 | FR-3 | BR-4 | unit + integration |
| AC-5 | FR-5 | BR-6/7 | integration |
| AC-6 | FR-1 | BR-3 | integration (git base) |
| AC-7 | — | BR-8 | unit |
| AC-8 | — | NFR-1 | unit |
| AC-9 | FR-5 | NFR-1 | unit |
| AC-10 | — | BR-9 | unit (snapshot) |
| AC-11 | — | NFR-5 | unit (контракты) |