- add src/git_worktree.py: ensure/remove/get_worktree_path - config: worktrees_dir=/repos/_wt - launcher: agent runs in per-branch worktree; task-file + commit/push in worktree; no shared checkout - qg/checks: read artifacts + run make test from worktree (branch arg, backward-compatible) - webhooks/plane: pass branch into QG dispatch; review fallback from worktree - webhooks/gitea: keep read-only branch --contains in main clone (documented) - tests: test_git_worktree.py (isolation) + update test_launcher write-task-file - docs: ARCHITECTURE worktree section + BUGFIXES_2026-06-02_ORCH2 Preserves B-1/B-2/S-1/S-5 fixes (paths now point at worktree).
Multi-Agent Orchestrator
FastAPI-сервис для оркестрации мульти-агентного пайплайна разработки. Принимает webhooks от Plane и Gitea, управляет жизненным циклом задач через Quality Gates, запускает Claude CLI агентов на каждой стадии.
Архитектура
Plane (task mgmt) ──webhook──┐
├──► Orchestrator (FastAPI) ──► Quality Gates ──► Agent Launcher
Gitea (git events) ─webhook──┘ │ │
▼ ▼
SQLite DB Claude CLI
(events, tasks, (analyst, architect,
agent_runs) developer, reviewer, tester)
Стадии пайплайна
created → analysis → architecture → development → review → testing → deploy → done
↑ │
└─── REQUEST_CHANGES ─┘ (max 3 retries)
| Стадия | Агент | Quality Gate (выход) | Триггер перехода |
|---|---|---|---|
| created | — | — | Plane webhook (work_item.created) |
| analysis | analyst | Файлы BRD/TRZ/AC/TestPlan | Push docs/ |
| architecture | architect | ADR или infra-requirements | Push docs/ |
| development | developer | check_tests_local (орк сам гоняет make test) |
Auto-advance после developer |
| review | reviewer | check_reviewer_verdict (verdict: во frontmatter 12-review.md) |
Auto-advance после reviewer |
| testing | tester | Test report с PASS | Auto-advance после tester |
| deploy | deployer | — | SSH deploy-hook |
| done | — | — | — |
API Endpoints
| Method | Path | Описание |
|---|---|---|
| GET | /health |
Health check |
| GET | /status |
Активные задачи (stage != done) |
| POST | /webhook/plane |
Plane webhook receiver |
| POST | /webhook/gitea |
Gitea webhook receiver |
Структура проекта
src/
├── main.py # FastAPI app, lifespan (orphan recovery)
├── config.py # Pydantic settings (env vars)
├── db.py # SQLite: init, get_db, update_task_stage
├── stages.py # State machine (transitions, agents, QG)
├── notifications.py # Уведомления (логирование)
├── plane_sync.py # Синхронизация статусов с Plane API
├── agents/
│ └── launcher.py # AgentLauncher: launch, monitor, watchdog, auto-advance
├── webhooks/
│ ├── plane.py # Plane webhook handler
│ └── gitea.py # Gitea webhook handler (push, PR, CI status)
└── qg/
└── checks.py # Quality Gate checks (filesystem + Gitea API)
data/
├── orchestrator.db # SQLite database
└── runs/ # Agent output logs ({run_id}.log)
docs/
├── ARCHITECTURE.md # Подробная архитектура
├── LESSONS_ET006.md # Lessons learned из ET-006
├── BUGFIXES_2026-05-21.md # Багфиксы
└── SETUP_WEBHOOKS.md # Настройка webhooks
docker-compose.yml # Deployment config
Dockerfile # Python 3.12 + Docker CLI + tini
Запуск
Docker (production)
docker compose up -d --build
Dev
pip install -r requirements.txt
uvicorn src.main:app --reload --port 8500
Конфигурация
Все переменные с префиксом ORCH_:
| Переменная | Описание | Default |
|---|---|---|
ORCH_PLANE_API_URL |
Plane API URL | http://localhost:8091 |
ORCH_PLANE_API_TOKEN |
Plane API token | — |
ORCH_PLANE_WEBHOOK_SECRET |
Webhook secret | — |
ORCH_PLANE_WORKSPACE_SLUG |
Workspace slug | — |
ORCH_PLANE_PROJECT_ID |
Project UUID | — |
ORCH_GITEA_URL |
Gitea URL | http://localhost:3000 |
ORCH_GITEA_TOKEN |
Gitea API token | — |
ORCH_GITEA_WEBHOOK_SECRET |
Gitea webhook secret | — |
ORCH_GITEA_OWNER |
Gitea repo owner | admin |
ORCH_DEFAULT_REPO |
Default repository | enduro-trails |
ORCH_CLAUDE_BIN |
Путь к Claude CLI | /opt/claude-code/bin/claude.exe |
ORCH_REPOS_DIR |
Repos dir (container) | /repos |
ORCH_HOST_REPOS_DIR |
Repos dir (host) | /home/slin/repos |
ORCH_DB_PATH |
SQLite path | /app/data/orchestrator.db |
Ключевые механизмы
Auto-advance
После успешного завершения агента (exit_code=0), _try_advance_stage() проверяет QG и автоматически продвигает задачу + запускает следующего агента.
Review bounce
При REQUEST_CHANGES от reviewer задача откатывается в development, developer перезапускается (до 3 попыток). При исчерпании — эскалация.
Orphan recovery (M-1)
При старте контейнера каждый run с finished_at IS NULL старше 35 минут помечается exit_code=-1, логируется per-run warning и отправляется Telegram-уведомление «нужна ручная проверка/перезапуск» (не молча).
Запись task-файлов (B-1)
Task-файлы .task-*.md пишутся прямой записью в смонтированный volume /repos/<repo>/ (без docker). При ошибке записи — RuntimeError (не молчит). В .gitignore проекта.
Логи агентов (B-2)
stdout/stderr агента перенаправляются СРАЗУ в /app/data/runs/{id}.log на уровне ОС (без PIPE). monitor-поток делает proc.wait() → реальный exit_code, нет зомби.
Watchdog
Каждый агент имеет timeout 30 минут. При превышении — SIGKILL + запись exit_code=-9.
Event routing
Gitea events роутятся по типу:
push→ проверка файлов, advance architecture/developmentpull_request*(wildcard) → review approved/rejected, PR mergestatus→ (legacy) Gitea CI; С-1: больше не authoritative,failureлогируется на debug и не блокирует/не алертит (QG развития = локальныйcheck_tests_local)
Тесты
pytest tests/ -v
Известные ограничения
- Single-task / shared
/reposcheckout — одновременно безопасно обрабатывается одна задача: все агенты иcheck_tests_localделаютgit checkoutв одном/repos/<repo>→ гонки при параллельных задачах. Исправление — git worktree per task (S-4, отдельно). - Plane sync — маппинг issue ID может быть некорректным (P3, в работе)
- In-process daemon-потоки — агенты живут в потоках uvicorn; при рестарте ловит orphan-recovery. Целевое — очередь задач (F-2b)
- Gitea CI не настроен — тесты гоняет сам оркестратор локально
- Tester timeout — e2e тесты с Playwright могут занимать >25 мин на тяжёлых фичах
- No retry on API errors — httpx вызовы к Gitea/Plane без retry logic