7.3 KiB
work_item, stage, author_agent, status, created_at, model_used
| work_item | stage | author_agent | status | created_at | model_used |
|---|---|---|---|---|---|
| ORCH-093 | analysis | analyst | ready-for-review | 2026-06-09 | claude-opus-4-8 |
03 — Критерии приёмки (Acceptance Criteria): ORCH-093 — ретрай транзиентных merge-ошибок Gitea + гард already-in-main
Work Item: ORCH-093 · Repo: orchestrator · Стадия: analysis
Формат: каждый критерий имеет PASS (что должно быть истинно для приёмки) и FAIL (что считается провалом). Reviewer/tester проверяет их буквально по файлам репозитория и тестам.
AC-1 — ретрай транзиента 405/5xx/таймаут → успешный мерж
Условие: merge_pr при транзиентной ошибке мержа повторяет POST …/merge с backoff и
доводит мерж до успеха в пределах бюджета.
- PASS: мок httpx даёт на
POST …/merge405дважды, затем200→merge_prвозвращает(True, …), выполнено ровно 3POST, ложногоFalseнет. Аналогично для5xxи таймаута/сетевой ошибки в первых попытках. - FAIL:
merge_prвозвращаетFalseна первом405/5xx/таймауте (one-shot), не делая повторныхPOST.
AC-2 — реальный конфликт / не-mergeable НЕ ретраится (быстрый честный HOLD)
Условие: merge_pr при реальном конфликте (409/422 с mergeable==False) или 403 не
зацикливается, а возвращает (False, …) быстро.
- PASS: мок httpx даёт
409наPOST …/mergeиGET /pulls/{n}сmergeable=False→merge_prвозвращает(False, …)без дополнительныхPOST(не более одной попытки мержа); reason различим как терминальный.403→ немедленный(False, …). - FAIL:
merge_prретраит реальный конфликт до исчерпания бюджета (вечный/долгий цикл), задерживая честный HOLD.
AC-3 — исчерпание ретраев → (False, …) + защита ORCH-071/081 как прежде
Условие: если транзиент не проходит за N попыток, merge_pr возвращает (False, …) с
понятным reason; защита «deploy succeeded but not merged» срабатывает как раньше.
- PASS: мок даёт
405на всехNпопытках →merge_prвозвращает(False, "merge failed after <N> attempts: HTTP 405")(или эквивалент); в_handle_merge_verifyнеподтверждённый SHA-in-main → HOLD + алерт (поведение ORCH-071/081 неизменно). Тест на не-merged HOLD остаётся зелёным. - FAIL: при исчерпании ретраев reason неинформативен; или защита HOLD не срабатывает / задача
ошибочно уходит в
done.
AC-4 — гард «ветка уже в main» → нет мусорного PR, задача доходит до done
Условие: если ветка уже полностью в main (нет коммитов origin/main..branch),
ensure_open_pr не создаёт PR и возвращает already-in-main; финализатор доводит до done.
- PASS: мок: открытого code-PR нет,
git rev-list --count origin/main..branch == 0→ensure_open_prвозвращает("already-in-main", …)и не делаетPOST …/pulls; в_handle_merge_verifyэтот статус пропускаетmerge_prиverify_merged_to_main(SHA-in-main) подтверждает мерж → задача доходит доdoneбез создания пустого PR. - FAIL:
ensure_open_prсоздаёт новый пустой PR на уже влитой ветке, либо статусalready-in-mainошибочно трактуется какfailed(ложный HOLD).
AC-5 — kill-switch / конфиг ретраев; дефолты задокументированы
Условие: ретрай-поведение конфигурируемо (число попыток, backoff, kill-switch); при выключении —
one-shot как сейчас; дефолты в .env.example.
- PASS: в
src/config.pyесть поляmerge_retry_enabled/merge_retry_max_attempts/merge_retry_backoff_base_s/merge_retry_backoff_max_sс разумными дефолтами (≈3 / 2 / 5);.env.exampleсодержит дескрипторыORCH_MERGE_RETRY_*; приmerge_retry_enabled=Falseтест подтверждает ровно одну попыткуPOST(one-shot). - FAIL: ретрай захардкожен (нет флагов/kill-switch), или
.env.exampleне обновлён, или при выключенном флаге поведение отличается от текущего one-shot.
AC-6 — never-raise сохранён; регресс зелёный; доки обновлены
Условие: контракт never-raise merge_pr/ensure_open_pr цел; полный регресс зелёный;
документация и CHANGELOG обновлены.
- PASS: при любой HTTP/parse/сетевой ошибке (в т.ч. внутри ретрай-цикла и git-проверки гарда)
функции возвращают безопасный кортеж, исключение не пробрасывается;
pytest tests/ -qзелёный; merge-gate-раздел доки (docs/architecture/README.md/CLAUDE.md) иCHANGELOG.mdописывают ретрай и гард already-in-main. - FAIL: исключение пробрасывается в
advance_stage; падает любой тест вtests/; доки/CHANGELOG не отражают изменение.
AC-7 — инварианты self-hosting / INV-4 не нарушены
Условие: изменение не вводит прямых push/force-push в main и не трогает
STAGE_TRANSITIONS/QG_CHECKS/схему БД.
- PASS: мерж по-прежнему идёт только через Gitea PR-merge API;
git diffне содержит правокSTAGE_TRANSITIONS/ составаQG_CHECKS/ схемы БД; никаких новых вызововgit push … main. - FAIL: появился прямой push в
main, либо измененыSTAGE_TRANSITIONS/QG_CHECKS/схема БД.
Сводная матрица AC ↔ FR/BR
| AC | Покрывает |
|---|---|
| AC-1 | BR-1 / FR-1, FR-2 |
| AC-2 | BR-2, BR-3 / FR-2 |
| AC-3 | BR-4 / FR-1 |
| AC-4 | BR-5 / FR-3, FR-4 |
| AC-5 | BR-6, BR-7 / FR-5 |
| AC-6 | NFR-1, NFR-6 / FR-1…FR-5 |
| AC-7 | NFR-2 / §6, §7 ТЗ |