Files
orchestrator/docs/architecture/README.md
claude-bot ad1589084b
All checks were successful
CI / test (push) Successful in 14s
architect(ET): auto-commit from architect run_id=183
2026-06-06 17:16:00 +00:00

12 KiB
Raw Blame History

Архитектура Orchestrator

Обзор

Мульти-агентный оркестратор разработки. Принимает webhooks от Plane (управление задачами) и Gitea (git-события), ведёт задачи по конвейеру стадий через Quality Gates, на каждой стадии запускает Claude CLI агента. Поддерживает несколько проектов (multi-repo) и self-hosting (дорабатывает сам себя).

Компоненты

  • Webhook Receivers (src/webhooks/plane.py, gitea.py) — приём событий, HMAC-проверка, дедупликация (_dedup.py). Роуты: POST /webhook/plane, POST /webhook/gitea.
  • State Machine (src/stages.py) — STAGE_TRANSITIONS: переходы, агент и QG каждой стадии. Хелперы: get_next_stage, get_agent_for_stage, get_qg_for_stage, get_previous_stage.
  • Stage Engine (src/stage_engine.py) — исполнение переходов, диспетчеризация QG (_run_qg), откаты, синхронизация с Plane.
  • Review/Test Parsers (src/review_parse.py, ORCH-046) — defensive-извлечение дословного must-fix текста из артефактов для встраивания в task_desc заворота: extract_review_findings (P0/P1 из 12-review.md), extract_test_failures (фрагмент тела 13-test-report.md). Контракт «never raise»: любая ошибка → "".
  • Quality Gates (src/qg/checks.py) — проверки выхода со стадии, реестр QG_CHECKS.
  • Agent Launcher (src/agents/launcher.py) — запуск Claude CLI агентов в изолированном git worktree, мониторинг, auto-advance.
  • Queue (src/queue_worker.py, ORCH-1) — персистентная очередь задач (SQLite jobs), atomic claim, max_concurrency, ретраи, restart-safe.
  • Project Registry (src/projects.py, ORCH-6) — Plane project id → repo + prefix; фильтрация вебхуков по проекту.
  • Plane Sync (src/plane_sync.py) — синхронизация статусов/комментариев в Plane.

Конвейер и Quality Gates

created → analysis → architecture → development → review → testing → deploy-staging → deploy → done
                          ↑                          │
                          └──── REQUEST_CHANGES ──────┘  (откат на development, max 3 retries)
Стадия Агент (выход) Quality Gate Артефакт
created analyst
analysis architect check_analysis_approved 01-brd / 02-trz / 03-acceptance-criteria / 04-test-plan.yaml
architecture developer check_architecture_done 06-adr/
development reviewer check_ci_green код + PR
review tester check_reviewer_verdict 12-review.md (verdict:)
testing deployer check_tests_passed 13-test-report.md
deploy-staging deployer check_staging_status 15-staging-log.md (staging_status:)
deploy check_deploy_status 14-deploy-log.md (deploy_status:)
done

Реестр QG (QG_CHECKS): check_analysis_approved, check_analysis_complete, check_architecture_done, check_ci_green, check_review_approved, check_tests_passed, check_reviewer_verdict, check_tests_local, check_deploy_status, check_staging_status, check_branch_mergeable (ORCH-043).

Канон гейтов: машинные вердикты читаются ТОЛЬКО из YAML-frontmatter, никогда из прозы. Лог-файлы мержатся в origin/main отдельным PR; гейт читает из origin/main.

Условный staging-гейт (ORCH-35)

check_staging_status реален только для self-hosting (is_self_hosting_repo(repo)orchestrator); для остальных проектов → no-op (True, "Staging gate N/A"). Для orchestrator парсит staging_status: из 15-staging-log.md; FAILED → откат на development. Подробнее: ADR-0003.

Merge-gate: догон main + re-test + сериализация слияний (ORCH-043)

Детерминированный под-гейт (check_branch_mergeable, без LLM) на ребре deploy-staging → deploy: исполняется ПОСЛЕ check_staging_status и ДО запуска deployer'а, который вливает PR в main (deployer мержит в начале стадии deploy). Стадии (STAGE_TRANSITIONS) НЕ меняются — это «под-гейт» ребра, а не отдельная стадия (триггер — то же событие «staging-deployer завершился»).

Назначение: ветка валидируется относительно того main, из которого создана; параллельная задача могла уйти вперёд → семантический конфликт слияния (зелёная ветка ломает обновлённый main). Merge-gate гарантирует проверку против актуального origin/main перед слиянием:

  • Догон: ветка отстаёт (⇔ origin/main не предок HEAD) → rebase origin/main в worktree + push --force-with-lease (ТОЛЬКО ветка задачи; main — никогда). Текстовый конфликт → rebase --abort → откат на development.
  • Re-test: python -m pytest (merge_retest_target, дефолт tests/) в worktree догнанной ветки, тайм-аут merge_retest_timeout_s. Красный/тайм-аут → откат на development.
  • Сериализация (merge-lock): файловый merge-lease на репо (<repos_dir>/.merge-lease-<repo>.json), живёт от гейта до фактического merge. Acquire неблокирующий (anti-deadlock при max_concurrency=1): busy → defer (повторная постановка deployer'а на deploy-staging с задержкой через available_at), а не откат. Release — на PR-merged вебхуке / deploy→done / откате / по возрасту (crash-реклейм). Restart-safe; без изменения схемы БД.
  • Условность (как ORCH-35): реален для orchestrator; прочие репо — no-op. Флаги merge_gate_enabled / merge_gate_repos — поэтапный раскат. Контракт never-raise.

Подробнее: adr-0006, детально — docs/work-items/ORCH-043/06-adr/ADR-001-merge-gate.md.

Откаты

  • Reviewer REQUEST_CHANGES → откат на development + retry (MAX_DEVELOPER_RETRIES = 3).
  • Tester check_tests_passed FAIL → откат на development + retry.
  • Deploy / deploy-staging FAILED → откат на development.
  • Merge-gate FAIL (конфликт rebase / красный re-test, ORCH-043) → откат на development + retry; merge-lock busydefer (не откат, dev-retry не тратится).
  • get_previous_stage использует порядок ключей STAGE_TRANSITIONS.

Обогащение task_desc при заворотах (ORCH-046)

При откате на development task_desc (попадает в .task-dev.md developer-агента) несёт дословный must-fix текст, а не только ссылку — чтобы агент видел суть претензий сразу и не повторял ту же ошибку:

  • reviewer REQUEST_CHANGES → дословные пункты P0/P1 из секции ## Findings файла 12-review.md (extract_review_findings);
  • tester check_tests_passed FAILreason гейта + фрагмент тела 13-test-report.md (приоритет: ## Вывод pytest → FAIL-строки ## Результаты## Итог; extract_test_failures).

Ссылка на полный файл-артефакт сохраняется всегда («Полный контекст»). Парсеры src/review_parse.py — defensive (never-raise); при отсутствующем/битом артефакте task_desc graceful-фоллбэк на прежнюю ссылку-строку, последовательность отката и retry-счётчик не меняются (ADR docs/work-items/ORCH-046/06-adr/ADR-001-embed-findings-in-task-desc.md).

Plane Sync: единый status-коммент агентов (ORCH-016)

Все агенты (analyst / architect / developer / reviewer / tester / deployer) пишут финальный коммент через один хелпер usage.build_status_comment(...) (ADR docs/work-items/ORCH-016/06-adr/ADR-001-unified-status-comment.md). Формат HTML, разделители <br>:

{ICON} {RoleName} — {описание стадии}
[Verdict|Status: VALUE]                  # reviewer/tester/deployer, из YAML-frontmatter артефакта
[Длительность: 4m 12s]                   # явный duration_s от launcher, либо fallback из agent_runs
<b>Документы:</b><ul><li><a href="…">label</a></li>…</ul>
[<sub>8.5M in / 45.8k out · $7.29</sub>] # тех-хвост usage; опускается при нулях
  • Длительность считается launcher'ом (_monitor_agent) и пробрасывается в _post_usage_comments; для analyst (коммент строится в stage_engine) используется DB-фоллбэк usage.get_agent_duration(task_id, agent).
  • Vердикт-парсерsrc/frontmatter.read_frontmatter_value(...) (defensive, никогда не raise). Машинные ключи: reviewer → verdict: (12-review.md); testing-гейт check_tests_passed (13-test-report.md) → любое из трёх равноправных: result: (канон промпта тестера), verdict:, status: (ORCH-047, ADR-001); deployer → deploy_status: (14-deploy-log.md), staging_status: (15-staging-log.md). Negative-токен в любом поле авторитетен (перебивает positive).
  • Формат коммента не меняет реестр гейтов и стадий; коммент — отображение, не управление.

База данных (SQLite)

  • events — входящие вебхуки (дедуп)
  • tasks — задачи и их стадии
  • agent_runs — запуски агентов (run_id, usage, cost)
  • jobs — очередь задач (ORCH-1)

Изоляция (git worktree, ORCH-2)

Каждая задача исполняется в отдельном git worktree, ветки не пересекаются. Репозитории проектов разделены под /repos/<project>.

API

Method Path Описание
GET /health health check
GET /status активные задачи (stage != done)
GET /queue очередь: counts + max_concurrency + последние jobs
POST /webhook/plane Plane webhook
POST /webhook/gitea Gitea webhook (push, PR, CI status)

Деплой и эксплуатация

Топология, контейнеры, порты, env-карта, self-hosting риски — docs/operations/INFRA.md. Деплой-хук — DEPLOY_HOOK.md. Staging — STAGING.md.

ADR

Сквозные архитектурные решения — adr/. Per-work-item решения — docs/work-items/<id>/06-adr/.

Детали реализации

Схема БД, потоки данных, resilience-слой, детали Dockerfile — internals.md.


Актуально на 2026-06-06. Обновлять при изменении src/stages.py, src/qg/checks.py, src/main.py. ORCH-043: merge-gate — design (см. adr-0006), реализация в ветке feature/ORCH-043.