Files
orchestrator/docs/work-items/ORCH-043/03-acceptance-criteria.md
claude-bot 77e7205ce8
All checks were successful
CI / test (push) Successful in 14s
analyst(ET): auto-commit from analyst run_id=182
2026-06-06 16:39:20 +00:00

106 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)
**Work Item:** ORCH-043 — merge-gate + auto-rebase + re-test
**Автор:** Analyst
Каждый критерий имеет однозначное условие PASS/FAIL. Все критерии должны быть PASS.
---
## AC-1 — Ветка актуальна: гейт пропускает без догона
- **Дано:** ветка содержит последний `origin/main` (не отстаёт).
- **Когда:** выполняется `check_branch_mergeable(repo, work_item_id, branch)`.
- **PASS:** возвращает `(True, ...)` с причиной «up-to-date», auto-rebase НЕ запускается,
ветка не пушится повторно.
- **FAIL:** возвращает `False`, либо выполняет ненужный rebase/push.
## AC-2 — Ветка отстаёт + чистый догон + зелёный re-test → проход
- **Дано:** ветка отстаёт от `origin/main`; rebase проходит без текстового конфликта;
тест-набор на догнанной ветке зелёный.
- **Когда:** выполняется merge-gate.
- **PASS:** ветка догнана до `origin/main`, запушена `--force-with-lease`, re-test зелёный,
гейт возвращает `(True, ...)`.
- **FAIL:** гейт возвращает `False` при чистом догоне и зелёном re-test, либо `main` тронут,
либо push выполнен НЕ через `--force-with-lease`.
## AC-3 — Текстовый конфликт rebase → откат на development, без слияния
- **Дано:** auto-rebase упирается в текстовый конфликт.
- **Когда:** выполняется merge-gate.
- **PASS:** rebase отменён (worktree чист), гейт возвращает `(False, "rebase conflict...")`,
задача переведена на `development`, в Plane — комментарий с причиной, слияния в `main` нет.
- **FAIL:** ветка осталась в конфликтном состоянии, или задача продвинулась к слиянию,
или `main` изменён.
## AC-4 — Красный re-test после догона → откат на development, без слияния
- **Дано:** rebase чистый, но тесты на догнанной ветке падают.
- **Когда:** выполняется merge-gate.
- **PASS:** гейт возвращает `(False, "re-test failed after rebase...")`, задача на
`development`, комментарий в Plane, слияния нет.
- **FAIL:** гейт вернул `True`, либо слияние произошло при красном re-test.
## AC-5 — Сериализация слияний (merge-lock)
- **Дано:** две задачи одного `repo` одновременно подходят к merge-gate.
- **Когда:** обе пытаются пройти гейт.
- **PASS:** «догон+re-test+слияние» выполняет одновременно только одна задача; вторая
ждёт освобождения lock (в пределах `merge_lock_timeout_s`), после чего повторно
сверяет «не отстаёт» и при необходимости догоняется. Воспроизводимый сценарий
«две зелёные ветки ломают main» НЕ приводит к красному `main`.
- **FAIL:** обе задачи параллельно проходят гейт и вливаются, воспроизводя гонку.
## AC-6 — Re-test тайм-аут управляем
- **Дано:** re-test превышает `settings.merge_retest_timeout_s`.
- **PASS:** прогон прерывается, гейт возвращает `(False, "re-test timeout...")`, задача
не виснет, идёт штатный откат.
- **FAIL:** задача висит дольше тайм-аута или падает с необработанным исключением.
## AC-7 — Никогда не push/merge в main напрямую из гейта
- **PASS:** код merge-gate не выполняет `git push ... main` и не форс-пушит `main`;
force-операции — только `--force-with-lease` по ветке задачи.
- **FAIL:** найден любой push/force-push в `main` из логики гейта.
## AC-8 — Изоляция в worktree
- **PASS:** все git-операции гейта идут в worktree ветки (`get_worktree_path` /
`ensure_worktree`), а не в общем `/repos/<repo>` clone.
- **FAIL:** rebase/тесты выполняются в общем clone, создавая S-4-гонку.
## AC-9 — Контракт never-raise
- **Дано:** недоступен git/сеть, бит worktree, отсутствует ветка и т.п.
- **PASS:** `check_branch_mergeable` и функции `merge_gate.py` возвращают `(False, "<reason>")`
(или безопасный фоллбэк), НИКОГДА не пробрасывают исключение в `advance_stage`.
- **FAIL:** любое необработанное исключение всплывает из гейта.
## AC-10 — Реестр QG и снапшоты консистентны
- **PASS:** `"check_branch_mergeable"` зарегистрирован в `QG_CHECKS` и callable;
`tests/test_qg_registry_snapshot.py` (`_EXPECTED_QGS`, при изменении стадий —
`_EXPECTED_TRANSITIONS`) обновлены и зелёные; порядок ключей `STAGE_TRANSITIONS`
сохранён (не сломан `get_previous_stage`).
- **FAIL:** дрейф реестра/стадий без обновления снапшотов; красные snapshot-тесты.
## AC-11 — Интеграция отката в stage_engine
- **PASS:** в `_handle_qg_failure_rollbacks` есть ветка merge-gate FAIL → `development`
с уведомлениями (Plane + Telegram) и учётом `MAX_DEVELOPER_RETRIES`; `_run_qg`
корректно диспетчеризует новый чек.
- **FAIL:** FAIL гейта не приводит к откату, или нет уведомления, или зацикливание заворотов.
## AC-12 — Условный no-op / выключение (если реализовано)
- **Дано:** `settings.merge_gate_enabled = False` (или репо вне `merge_gate_repos`).
- **PASS:** гейт возвращает `(True, "merge-gate disabled")`, конвейер работает как прежде.
- **FAIL:** гейт блокирует/ломает конвейер при выключенном флаге.
## AC-13 — Документация обновлена (golden source)
- **PASS:** обновлены `docs/architecture/README.md` (merge-gate/auto-rebase/re-test,
при изменении — таблицы стадий/реестра), `CHANGELOG.md`, `.env.example` (новые
`ORCH_*` настройки); создан ADR `06-adr/ADR-001-merge-gate.md`.
- **FAIL:** функционал изменён, документация/ADR/CHANGELOG не обновлены (Reviewer →
REQUEST_CHANGES).
## AC-14 — Безопасность self-hosting
- **PASS:** в рамках задачи прод-контейнер `orchestrator` (8500) не рестартился и не падал;
изменения не трогают `.env*`, `docker-compose.yml`, прод-инфраструктуру; страховка
стадией `deploy-staging` сохранена.
- **FAIL:** любой рестарт/падение прод-оркестратора или правка прод-инфры в рамках задачи.
## AC-15 — Зелёный регресс
- **PASS:** `pytest tests/ -q` зелёный целиком (новые тесты ORCH-043 + существующий набор).
- **FAIL:** любой упавший/сломанный существующий тест.