docs: update README, add ARCHITECTURE.md with full system documentation

This commit is contained in:
Dev Agent
2026-05-22 14:09:24 +03:00
parent 0ad56e1f0a
commit 267bc58fb2
2 changed files with 302 additions and 31 deletions

133
README.md
View File

@@ -1,70 +1,141 @@
# Multi-Agent Orchestrator
FastAPI-сервис для оркестрации мульти-агентного пайплайна разработки.
FastAPI-сервис для оркестрации мульти-агентного пайплайна разработки. Принимает webhooks от Plane и Gitea, управляет жизненным циклом задач через Quality Gates, запускает Claude CLI агентов на каждой стадии.
## Что делает
## Архитектура
- Принимает webhooks от **Plane** (task management) и **Gitea** (git events)
- Проверяет Quality Gates перед переходом между стадиями
- Запускает **Claude CLI** агентов (analyst, architect, developer, reviewer, tester)
- Ведёт журнал событий в SQLite
```
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 | CI green | Gitea status event |
| review | reviewer | PR approved (no stale) | Gitea review event |
| testing | tester | Test report с PASS | Auto-advance после tester |
| deploy | — | — | PR merge |
| done | — | — | — |
## API Endpoints
| Method | Path | Описание |
|--------|------|----------|
| GET | `/health` | Health check |
| GET | `/status` | Активные задачи |
| GET | `/status` | Активные задачи (stage != done) |
| POST | `/webhook/plane` | Plane webhook receiver |
| POST | `/webhook/gitea` | Gitea webhook receiver |
## Настройка
## Структура проекта
```bash
cp .env.example .env
# Заполнить токены в .env
```
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)
## Запуск
### Docker (production)
```bash
docker compose up -d --build
```
## Запуск (dev)
### Dev
```bash
pip install -r requirements.txt
uvicorn src.main:app --reload --port 8500
```
## Тесты
## Конфигурация
```bash
pip install pytest
pytest tests/ -v
```
## Переменные окружения
Все переменные с префиксом `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_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_CLAUDE_BIN` | Путь к Claude CLI | `/usr/bin/claude` |
| `ORCH_REPOS_DIR` | Директория с репозиториями | `/home/slin/repos` |
| `ORCH_DB_PATH` | Путь к SQLite БД | `/app/data/orchestrator.db` |
| `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
При старте контейнера все runs с `finished_at IS NULL` старше 35 минут помечаются как failed (exit_code=-1).
### Watchdog
Каждый агент имеет timeout 30 минут. При превышении — SIGKILL + запись exit_code=-9.
### Event routing
Gitea events роутятся по типу:
- `push` → проверка файлов, advance architecture/development
- `pull_request*` (wildcard) → review approved/rejected, PR merge
- `status` → CI green/failure
## Тесты
```bash
pytest tests/ -v
```
Plane webhook ──┐
├──► Orchestrator ──► Quality Gates ──► Agent Launcher ──► Claude CLI
Gitea webhook ──┘ │
SQLite (events, tasks, agent_runs)
```
## Известные ограничения
1. **Single-task** — одновременно обрабатывается одна задача на репозиторий (нет параллелизма)
2. **Plane sync** — маппинг issue ID может быть некорректным (P3, в работе)
3. **Tester timeout** — e2e тесты с Playwright могут занимать >25 мин на тяжёлых фичах
4. **No retry on API errors** — httpx вызовы к Gitea/Plane без retry logic

200
docs/ARCHITECTURE.md Normal file
View File

@@ -0,0 +1,200 @@
# Архитектура Orchestrator
## Обзор
Orchestrator — event-driven FastAPI сервис, который управляет жизненным циклом задач разработки через мульти-агентный пайплайн. Каждая задача проходит через фиксированные стадии, на каждой из которых работает специализированный Claude CLI агент.
## Компоненты
### 1. Webhook Receivers
#### Plane Webhook (`src/webhooks/plane.py`)
- Принимает `work_item.created` — создаёт задачу в DB, запускает analyst
- Принимает `work_item.updated` — синхронизация статусов
#### Gitea Webhook (`src/webhooks/gitea.py`)
- **push** — проверяет наличие артефактов (docs/, src/), продвигает стадию
- **pull_request\*** (wildcard) — обрабатывает review approved/rejected, PR merge
- **status** — CI green/failure, продвигает development → review
### 2. State Machine (`src/stages.py`)
Линейный пайплайн с одним возможным откатом (review → development):
```
STAGE_TRANSITIONS = {
created: → analysis (agent: None)
analysis: → architecture (agent: architect, QG: check_analysis_complete)
architecture: → development (agent: developer, QG: check_architecture_done)
development: → review (agent: reviewer, QG: check_ci_green)
review: → testing (agent: tester, QG: check_review_approved)
testing: → deploy (agent: None, QG: check_tests_passed)
deploy: → done (agent: None, QG: None)
}
```
### 3. Quality Gates (`src/qg/checks.py`)
| Check | Метод проверки |
|-------|---------------|
| check_analysis_complete | Filesystem: 4 файла в docs/work-items/{id}/ |
| check_architecture_done | Filesystem: ADR dir или infra-requirements.md |
| check_ci_green | Gitea API: GET /commits/{branch}/status |
| check_review_approved | Gitea API: GET /pulls/{n}/reviews (skip stale) |
| check_tests_passed | Filesystem: test-report.md содержит "PASS" |
### 4. Agent Launcher (`src/agents/launcher.py`)
Запускает Claude CLI как subprocess:
```bash
claude.exe --print --system-prompt --allowedTools Read,Write,Edit,Bash
```
Каждый запуск:
1. Записывает run в DB (agent_runs)
2. Запускает subprocess с stdout → `/app/data/runs/{id}.log`
3. Стартует **watchdog thread** (timeout 30 мин → SIGKILL)
4. Стартует **monitor thread** (ждёт завершения → git commit/push → auto-advance)
### 5. Auto-advance (`launcher._try_advance_stage`)
После успешного завершения агента:
1. Определяет текущую стадию задачи
2. Проверяет QG для выхода из стадии
3. Если QG пройден — продвигает стадию
4. Запускает следующего агента (если определён)
Исключение: `check_review_approved` — обрабатывается через PR webhook, не через auto-advance.
### 6. Review Bounce
При REQUEST_CHANGES:
1. Считает количество developer runs для задачи
2. Если < MAX_DEV_RETRIES (3) — откатывает в development, перезапускает developer
3. Если >= MAX_DEV_RETRIES — эскалация (логирование + уведомление)
## Database Schema
```sql
-- Задачи
CREATE TABLE tasks (
id INTEGER PRIMARY KEY,
work_item_id TEXT, -- Plane issue identifier (e.g. "ET-006")
plane_issue_id TEXT, -- Plane UUID
repo TEXT,
branch TEXT,
stage TEXT DEFAULT 'created',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Запуски агентов
CREATE TABLE agent_runs (
id INTEGER PRIMARY KEY,
task_id INTEGER REFERENCES tasks(id),
agent TEXT, -- analyst/architect/developer/reviewer/tester
started_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
finished_at TIMESTAMP,
exit_code INTEGER,
output_path TEXT -- /app/data/runs/{id}.log
);
-- Сырые события
CREATE TABLE events (
id INTEGER PRIMARY KEY,
source TEXT, -- plane/gitea
event_type TEXT,
payload TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```
## Deployment
### Docker Compose
```yaml
services:
orchestrator:
build: .
container_name: orchestrator
restart: unless-stopped
network_mode: host
volumes:
- ./data:/app/data # SQLite + logs
- /home/slin/repos:/repos # Git repositories
- /var/run/docker.sock:/var/run/docker.sock # Docker CLI
- claude-code:/opt/claude-code:ro # Claude CLI binary
- /home/slin/.claude:/home/slin/.claude # Claude config
env_file: .env
group_add: ["999"] # docker group
```
### Dockerfile
- Base: python:3.12-slim
- Docker CLI (sibling containers)
- **tini** как PID 1 (proper zombie reaping)
- `git config --global safe.directory '*'`
- ENTRYPOINT: tini → uvicorn
## Потоки данных
### Happy path (ET-006 пример)
```
1. Plane webhook: work_item.created → task created, analyst launched
2. Analyst: пишет BRD/TRZ/AC/TestPlan → git push docs/
3. Gitea push webhook: docs/ detected → QG check_analysis_complete → PASS
4. Auto-advance: analysis → architecture, architect launched
5. Architect: пишет ADR, infra-requirements → git push docs/
6. Gitea push webhook: ADR detected → QG check_architecture_done → PASS
7. Auto-advance: architecture → development, developer launched
8. Developer: пишет код src/ + tests/ → git push, creates PR
9. Gitea status webhook: CI green → QG check_ci_green → PASS
10. Auto-advance: development → review, reviewer launched
11. Reviewer: оставляет review (APPROVED или REQUEST_CHANGES)
12. Gitea PR webhook: review event → QG check_review_approved → PASS
13. Advance: review → testing, tester launched
14. Tester: прогоняет тесты, пишет test-report.md → git push
15. Auto-advance: testing → deploy (QG check_tests_passed → PASS)
16. PR merge → Gitea PR webhook: action=closed, merged=true → done
```
### Review bounce path
```
11. Reviewer: REQUEST_CHANGES
12. Gitea PR webhook: review_state=REQUEST_CHANGES, stage=review
13. Rollback: review → development, developer relaunched (attempt N/3)
14. Developer: фиксит замечания → git push
15. CI green → development → review, reviewer relaunched
16. Reviewer: APPROVED → continue happy path
```
## Resilience
| Механизм | Описание |
|----------|----------|
| Orphan recovery | При старте: runs без finished_at старше 35 мин → exit_code=-1 |
| Watchdog | Каждый агент: timeout 30 мин → SIGKILL + exit_code=-9 |
| tini | PID 1 reaper — zombie processes невозможны |
| safe.directory | git операции работают в любой директории |
| Stale review skip | check_review_approved игнорирует stale reviews |
| Max retries | Developer: max 3 попытки, затем эскалация |
## Агенты
Каждый агент — Claude CLI с:
- **System prompt**: `.openclaw/agents/{role}.md` (в репозитории)
- **Task file**: `.task-{suffix}.md` (генерируется orchestrator)
- **Tools**: Read, Write, Edit, Bash
- **Output**: `--print` mode (весь вывод в stdout после завершения)
| Агент | Артефакты | Время (типичное) |
|-------|-----------|-------------------|
| analyst | BRD, TRZ, AC, TestPlan | 5-10 мин |
| architect | ADR, infra-requirements, tech-risks | 5-10 мин |
| developer | src/, tests/, PR | 15-30 мин |
| reviewer | review report, PR review | 3-5 мин |
| tester | test-report.md, e2e results | 10-25 мин |