Files
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

10 KiB
Raw Permalink Blame History

01 — Business Requirements Document (BRD)

Work Item: ORCH-043 Тема: Безопасная параллель в одном репо: merge-gate + auto-rebase + re-test Проект: orchestrator (self-hosting) Автор: Analyst Дата: 2026-06-06


1. Контекст и проблема

Оркестратор ведёт несколько work item параллельно, каждый в своём изолированном git worktree / ветке (feature/ORCH-NNN-slug, ORCH-2/S-4). Все ветки одного проекта исходят из общего origin/main и в конце конвейера вливаются обратно в main.

Текущий конвейер валидирует ветку относительно того состояния main, из которого она была создана, а не относительно main на момент слияния:

  • check_ci_green (стадия development) — CI зелёный на ветке (Gitea commit status ветки).
  • check_tests_passed (стадия testing) — вердикт тестировщика по коду ветки.
  • На стадии deploy ветка вливается в main (слияние выполняет deployer-агент, см. src/webhooks/gitea.py — комментарий про «deployer merges the PR at the START of its run»).

Между «ветка проверена» и «ветка влита» main мог уйти вперёд из-за слияния другой параллельной задачи. Возникает семантический (логический) конфликт слияния: git сливает ветки без текстового конфликта, но объединённый код main сломан — тесты, которые были зелёными на ветке, на обновлённом main падают.

Почему это критично именно здесь (self-hosting)

Проект ORCH правит инструмент, который СЕЙЧАС работает в проде и обслуживает другие проекты (enduro-trails) из одного инстанса с общей БД и общей очередью (см. CLAUDE.md, docs/operations/INFRA.md). Сломанный main оркестратора = встал конвейер ВСЕХ проектов. Две параллельные ORCH-задачи, каждая «зелёная» по отдельности, при последовательном слиянии способны положить прод.

Сценарий-иллюстрация

  1. Задачи A и B ответвлены от main@C0.
  2. A проходит конвейер, вливается → main@C1.
  3. B тестировалась против C0; её CI зелёный относительно C0. Git-слияние B в C1 проходит без текстового конфликта, но C1 содержит изменения A, ломающие B.
  4. main становится красным. Конвейер всех проектов деградирует.

2. Цель

Гарантировать, что ветка вливается в main только если она проверена против актуального origin/main. Перед слиянием ветка автоматически догоняет main (auto-rebase) и повторно тестируется (re-test); зелёный результат на актуальном main — обязательное условие слияния (merge-gate). Слияния в main одного репозитория сериализуются, чтобы окно гонки не воспроизводилось между двумя гейтами.

3. Заинтересованные стороны

  • Owner / разработчики — не хотят красный main и ручные разборы конфликтов.
  • Все проекты на инстансе — зависят от живого прод-оркестратора.
  • Агенты конвейера — получают детерминированный гейт вместо ручной координации.

4. Объём (Scope)

В объёме

  1. Merge-gate — детерминированный гейт перед слиянием в main: пропускает слияние только если ветка не отстаёт от origin/main И повторная проверка зелёная.
  2. Auto-rebase — если ветка отстаёт от origin/main, автоматически догнать main (rebase/merge ветки на актуальный origin/main) в worktree и запушить результат.
  3. Re-test — после auto-rebase повторно прогнать тест-набор на догнанной ветке; зелёный результат — условие прохода гейта.
  4. Сериализация слияний — в пределах одного репозитория одновременно «догон+слияние» выполняет только одна задача (merge-lock), иначе гонка воспроизводится.
  5. Откаты при неуспехе — текстовый конфликт rebase ИЛИ красный re-test → возврат задачи на development (по образцу существующих откатов) с понятным комментарием.
  6. Конфигурируемость — пороги/тайм-ауты re-test и поведение гейта вынесены в settings.

Вне объёма

  • Изменение логики стадий analysis / architecture / review.
  • Замена самого механизма слияния PR в Gitea (UI/настройки репозитория).
  • Реальные прод-деплои (остаются за scripts/orchestrator-deploy-hook.sh).
  • Кросс-репозиторная сериализация (гейт защищает main каждого репо отдельно).

5. Бизнес-требования (BR)

ID Требование
BR-1 Перед слиянием ветки в main оркестратор обязан проверить, что ветка содержит последний origin/main (не отстаёт).
BR-2 Если ветка отстаёт — оркестратор автоматически догоняет её до origin/main без участия человека (auto-rebase).
BR-3 После догона тест-набор повторно прогоняется; слияние разрешено только при зелёном результате (re-test).
BR-4 Текстовый конфликт при auto-rebase или красный re-test НЕ приводит к слиянию: задача откатывается на development для ручного фикса.
BR-5 В пределах одного репозитория «догон+проверка+слияние» сериализуются: две задачи не могут одновременно пройти merge-gate и влиться.
BR-6 Гейт детерминированный (Python/гит-команды + код тестов), а не доверие LLM-агенту.
BR-7 Гейт обязателен минимум для self-hosting репозитория orchestrator; применим к любому репо с параллельными задачами.
BR-8 Все события гейта (догон, re-test, проход/откат) логируются и отражаются комментарием в Plane, без рассинхрона стадий.

6. Критерии успеха

  • Воспроизводимый ранее сценарий «две зелёные ветки ломают main» более не приводит к красному main: вторая ветка либо догоняется и проходит re-test, либо откатывается.
  • Прод-контейнер orchestrator не перезапускается и не падает в рамках задачи.
  • Реестр гейтов и стадий остаётся консистентным (snapshot-тесты обновлены осознанно).

7. Риски и ограничения

  • Гонка между двумя гейтами — снимается merge-lock (BR-5); без него фикс неполон.
  • Долгий re-test — нужен тайм-аут и понятный откат, а не вис задачи.
  • Force-push догнанной ветки — допустим только --force-with-lease и только по own-ветке задачи; никогда по main.
  • Self-hosting — любые изменения не должны ронять/рестартить прод-оркестратор; обязательная страховка стадией deploy-staging (порт 8501) сохраняется.
  • Окончательное место встройки в конвейер (новая стадия / гейт существующего перехода / шаг перед слиянием) — решение архитектора (ADR), BRD фиксирует требуемое поведение.

8. Связанные артефакты

  • 02-trz.md — техническое задание (модули, гейт, конфиг, точки встройки).
  • 03-acceptance-criteria.md — критерии приёмки PASS/FAIL.
  • 04-test-plan.yaml — план тестов.
  • Контекст кода: src/qg/checks.py, src/stage_engine.py, src/git_worktree.py, src/agents/launcher.py, src/webhooks/gitea.py, src/stages.py, src/config.py.