Files
wiki/tasks/multi-agent/ORCHESTRATOR_DOCS.md
2026-06-01 20:10:01 +03:00

338 lines
16 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.
# Документация: Orchestrator Multi-Agent Pipeline
## Статус: 2026-06-01 (актуально)
---
## Архитектура
```
Plane (Work Items) → Webhook → Orchestrator → Claude CLI agents → Gitea → Deploy
```
**Orchestrator** — Python FastAPI приложение в Docker на mva154 (port 8500).
Слушает webhooks от Plane и Gitea, управляет жизненным циклом задач.
---
## Конвейер (Pipeline)
```
created → analysis → architecture → development → review → testing → deploy → done
```
| Stage | Agent | QG (вход) | Что делает |
|-------|-------|-----------|------------|
| analysis | analyst | — | BRD, ТЗ, AC, Test Plan |
| architecture | architect | check_analysis_approved (`:approved:` от Славы) | ADR, архитектурные решения |
| development | developer | check_architecture_done (файлы ADR есть) | Код + тесты + PR |
| review | reviewer | check_ci_green (Gitea CI status) | Code review → 12-review.md |
| testing | tester | check_reviewer_verdict (APPROVED в 12-review.md) | Прогон тестов → 13-test-report.md |
| deploy | deployer | check_tests_passed (PASS в 13-test-report.md) | Merge PR → tag → deploy → smoke |
| done | — | — | Задача завершена |
---
## Агенты
### Конфигурация (AGENT_CONFIGS)
| Agent | Task file | System prompt | Model |
|-------|-----------|---------------|-------|
| analyst | `.task.md` | `.openclaw/agents/analyst.md` | claude-sonnet-4-6 |
| architect | `.task-arch.md` | `.openclaw/agents/architect.md` | **claude-opus-4-7** |
| developer | `.task-dev.md` | `.openclaw/agents/developer.md` | claude-sonnet-4-6 |
| reviewer | `.task-review.md` | `.openclaw/agents/reviewer.md` | **claude-opus-4-7** |
| tester | `.task-test.md` | `.openclaw/agents/tester.md` | claude-sonnet-4-6 |
| deployer | `.task-deploy.md` | `.openclaw/agents/deployer.md` | claude-sonnet-4-6 |
### Deployer (добавлен 2026-06-01)
**Функции:**
1. Merge PR через Gitea API
2. Создать semver tag (patch increment)
3. Deploy (git pull main на сервере)
4. Healthcheck (до 60 сек, 12 попыток)
5. Smoke test (ключевые endpoints)
6. Rollback к предыдущему тегу при fail
7. Записать `14-deploy-log.md` + обновить `CHANGELOG.md`
**Запрещено:** менять код, force push, деплоить без merge.
---
## Quality Gates
| QG | Функция | Что проверяет |
|----|---------|---------------|
| QG-0 | Валидация при создании Issue | title 5-80 chars, description ≥2 предложений |
| check_analysis_approved | `:approved:` в комментарии Plane от стейкхолдера | Человеческое подтверждение ТЗ |
| check_architecture_done | Наличие ADR файлов в `docs/work-items/<id>/06-adr/` | Архитектура задокументирована |
| check_ci_green | Gitea commit status API | CI pipeline зелёный |
| check_reviewer_verdict | Парсинг `12-review.md` → APPROVED/REQUEST_CHANGES | Код прошёл ревью |
| check_tests_passed | Парсинг `13-test-report.md` → PASS/FAIL | Тесты пройдены |
---
## Plane Integration (полная)
### Статусы Issue
| Статус | ID | Когда | Что значит для Славы |
|--------|-----|-------|---------------------|
| **Backlog** | `113b24f6...` | Создан, ещё не взят | Ничего не происходит |
| **Todo** | `2c7d3df3...` | Прошёл QG-0, ждёт запуска | Скоро начнётся |
| **In Progress** | `b873d9eb...` | Агент работает | Система работает, ждать |
| **Needs Input** | `babf08a3...` | Analyst задал вопросы | **Слава, ответь в комментарии** |
| **In Review** | `38fb1f64...` | ТЗ готово, ждёт approve | **Слава, прочитай и `:approved:` / `:rejected:`** |
| **Blocked** | `6c4543f9...` | Ошибка / retry исчерпаны | **Нужно ручное вмешательство** |
| **Done** | `381a2833...` | Всё задеплоено | Готово |
| **Cancelled** | `b1cae7f9...` | Отменена | — |
### Переходы статусов
```
Backlog → [QG-0 pass] → In Progress (analyst запущен)
In Progress → [analyst questions] → Needs Input
Needs Input → [Слава ответил] → In Progress (analyst перезапущен)
In Progress → [analyst done] → In Review (ждёт :approved:)
In Review → [:approved:] → In Progress (architect запущен)
In Review → [:rejected:] → In Progress (analyst перезапущен с причиной)
In Progress → [все этапы до done] → Done
In Progress → [3 retry исчерпаны / deploy fail] → Blocked
```
### Комментарии в Plane
Orchestrator автоматически пишет комментарии при:
- Каждом переходе stage (с ссылками на branch и PR)
- QG failure (что не прошло и почему)
- Запуске агента
- Вопросах analyst'а (текст вопросов)
- Ошибках (deploy fail, retry exhausted)
- Завершении задачи
### Ссылки в комментариях
При переходах stage комментарий содержит:
- 📂 Branch: ссылка на ветку в Gitea
- 🔗 PR: ссылка на Pull Request (если есть, на этапах review/testing/deploy)
### Webhook events
| Event | Действие |
|-------|----------|
| `work_item.created` / `issue.created` | QG-0 → create branch → init docs → launch analyst |
| `comment.created` / `issue_comment.created` | Проверка `:approved:` / `:rejected:` / ответ на вопросы |
### QG-0: Валидация при создании Issue
При создании Issue в Plane, orchestrator проверяет:
- Title: 5-80 символов
- Description: ≥2 предложений
Если не проходит → Issue переходит в **Blocked** + комментарий с описанием что исправить.
---
## Механизмы автономности
### Auto-advance
После завершения агента (exit 0), `_monitor_agent` вызывает `_try_advance_stage`:
1. Определяет текущий stage задачи
2. Проверяет QG следующего stage
3. Если QG green → advance stage → launch next agent
4. Если QG red → stop (ждёт внешнего события)
### Auto-PR
После developer push, `_ensure_pr()` автоматически создаёт PR в Gitea.
### Auto-init
При создании Issue в Plane → webhook → QG-0 → branch → docs → analyst.
Слава просто создаёт Issue — всё остальное автоматически.
### Retry (developer)
При `REQUEST_CHANGES` от reviewer'а — developer перезапускается (до 3 раз).
### Retry (tester fail)
При FAIL тестов — developer перезапускается для фикса (до 3 раз).
После 3 неудач → Issue переходит в **Blocked**.
### Analyst questions
Analyst может создать `01-questions.md` → Issue переходит в **Needs Input**.
Слава отвечает комментарием → analyst перезапускается с ответами (до 3 раундов).
### Notifications
Telegram уведомления на каждом переходе stage + при ошибках.
---
## Сценарии работы
### 🟢 Позитивный (happy path)
1. Слава создаёт Issue в Plane: "Добавить фильтр по высоте"
2. QG-0 ✓ → branch `feature/ET-012-filter-altitude` → analyst запущен
3. Analyst пишет BRD/ТЗ/AC/TestPlan → Issue → **In Review**
4. Слава читает, пишет `:approved:` → Issue → **In Progress**
5. Architect → ADR → auto-advance
6. Developer → код + тесты → PR → auto-advance
7. Reviewer → APPROVED → auto-advance
8. Tester → PASS → auto-advance
9. Deployer → merge → tag → deploy → smoke ✓ → Issue → **Done**
10. Telegram: "🎉 ET-012: задача завершена!"
### 🟡 Analyst задаёт вопросы
1. Analyst не понимает требования → создаёт `01-questions.md`
2. Issue → **Needs Input** + Telegram: "❓ ET-012: Analyst задаёт вопросы"
3. Слава отвечает комментарием в Plane
4. Orchestrator ловит комментарий → Issue → **In Progress** → analyst перезапущен
5. Analyst учитывает ответы → пишет ТЗ → Issue → **In Review**
6. (Максимум 3 раунда вопросов, потом → **Blocked**)
### 🟡 Слава отклоняет ТЗ
1. Issue в **In Review**, Слава пишет `:rejected: Не учтены мобильные устройства`
2. Issue → **In Progress** → analyst перезапущен с причиной отклонения
3. Analyst исправляет → Issue → **In Review** (повторно)
### 🔴 Tester находит баги
1. Tester прогоняет тесты → FAIL в `13-test-report.md`
2. Issue остаётся **In Progress** → developer перезапущен для фикса
3. Developer фиксит → reviewer → tester (повторно)
4. Если 3 попытки developer'а не помогли → Issue → **Blocked**
5. Telegram: "🚨 ET-012: Tests still failing after 3 retries"
### 🔴 Deploy fail
1. Deployer мержит PR, деплоит, smoke test FAIL
2. Deployer откатывает к предыдущему тегу
3. Issue → **Blocked**
4. Telegram: "🚨 ET-012: Deploy failed! Rolled back."
### 🔴 Architect conflict
1. Architect находит конфликт с ТЗ → создаёт `10-conflict.md`
2. Issue → **In Progress** → analyst перезапущен с описанием конфликта
3. Analyst пересматривает ТЗ → Issue → **In Review** (повторно)
---
## Файловая структура
```
/home/slin/repos/orchestrator/
├── src/
│ ├── main.py # FastAPI app
│ ├── config.py # Settings (env vars)
│ ├── db.py # SQLite (tasks, agent_runs, events)
│ ├── stages.py # STAGE_TRANSITIONS
│ ├── notifications.py # Telegram notifications
│ ├── plane_sync.py # Plane API (states, comments, links)
│ ├── agents/
│ │ ├── launcher.py # AgentLauncher (launch, monitor, retry, advance)
│ │ └── __init__.py
│ ├── webhooks/
│ │ ├── gitea.py # Push, PR, CI status handlers
│ │ ├── plane.py # work_item.created, comment handlers
│ │ └── __init__.py
│ └── qg/
│ ├── checks.py # QG check functions
│ └── __init__.py
├── docker-compose.yml
├── Dockerfile
└── requirements.txt
```
---
## Инфраструктура
- **Host:** mva154 (82.22.50.71)
- **Container:** `orchestrator` (port 8500)
- **Gitea:** localhost:3000 (в docker network)
- **Plane:** localhost:8091 (в docker network)
- **Repos:** `/home/slin/repos/orchestrator`, `/repos/enduro-trails` (в контейнере)
- **DB:** SQLite (`/app/data/orchestrator.db`)
- **Logs:** `/app/data/logs/` (per-agent run logs)
---
## Единственная точка ручного вмешательства
**`:approved:` после analyst'а** — Слава подтверждает ТЗ в Plane.
Всё остальное — полностью автономно:
- auto-init при создании Issue
- architect запускается автоматически после approve
- developer → после architecture done
- reviewer → после CI green
- tester → после review approved
- deployer → после tests passed
- done → после deploy success
- retry при ошибках (до 3 раз)
- rollback при deploy fail
---
## Автономный деплой
Deployer выполняет деплой через SSH на хост:
```bash
ssh slin@127.0.0.1 "bash /home/slin/bin/enduro-deploy-hook.sh"
```
Hook (`/home/slin/bin/enduro-deploy-hook.sh`) делает:
1. `git pull origin main` в репо проекта
2. `docker compose up -d app` — перезапуск app контейнера
3. Опционально: `docker compose --profile batch run --rm gps-collector` (флаг `--run-gps-collector`)
4. Логирует всё в `/var/log/enduro-trails/deploy-hook.log`
SSH ключ orchestrator'а: `/home/slin/.orchestrator-ssh/id_ed25519` (смонтирован в контейнер как `/root/.ssh/`)
---
## Расхождения с Proposal v1
Полная таблица: `tasks/multi-agent/PROPOSAL_VS_REALITY.md`
Ключевые отличия от идеала:
- Designer не реализован (skip для не-UI задач)
- QG упрощены (проверка файлов, не lint-скрипты)
- Один environment (test), нет prod
- Нет budget tracking
- Architect и Reviewer на Opus, остальные на Sonnet (proposal: все на Sonnet)
- Нет Plane подзадач (7 subtasks) — один Issue, этапы в orchestrator DB
---
## Changelog
| Дата | Изменение |
|------|-----------|
| 2026-05-31 | Fix: `_monitor_agent` PIPE streaming (race condition) |
| 2026-05-31 | Fix: `check_reviewer_verdict` вместо `check_review_approved` |
| 2026-05-31 | Add: `_ensure_pr` (auto-PR after developer push) |
| 2026-05-31 | Add: REQUEST_CHANGES retry logic (3 attempts) |
| 2026-06-01 | Add: **deployer agent** (merge → tag → deploy → smoke → rollback) |
| 2026-06-01 | Remove: `_auto_merge_pr` hardcode from `_try_advance_stage` |
| 2026-06-01 | Add: **Plane states** — Needs Input, In Review, Blocked |
| 2026-06-01 | Add: **Analyst questions flow** (01-questions.md → Needs Input → relaunch) |
| 2026-06-01 | Add: **:rejected: handler** с причиной + relaunch |
| 2026-06-01 | Add: **Tester FAIL → developer retry** (до 3 раз → Blocked) |
| 2026-06-01 | Add: **Deploy FAIL → Blocked** + rollback |
| 2026-06-01 | Add: **Architect conflict** (10-conflict.md → rollback to analysis) |
| 2026-06-01 | Add: **QG-0** валидация при создании Issue |
| 2026-06-01 | Add: **Ссылки в комментариях** (branch + PR URLs) |
| 2026-06-01 | Add: **Max 3 question rounds** для analyst |
| 2026-06-01 | Fix: **Analyst prompt** — добавлена явная инструкция использовать Write tool (артефакты на диск, не в stdout) |
| 2026-06-01 | Fix: **Analyst model** — возвращён на Sonnet (был переключён на Opus, расходовал лимиты Max 5x) |
| 2026-06-01 | Add: **Startup timeout 120s** — если Claude CLI не выдаёт output за 120 сек → kill + Telegram уведомление |
| 2026-06-01 | Fix: **Plane comment webhook**`handle_comment` теперь читает поле `issue` (Plane шлёт именно его, не `work_item_id`/`issue_id`) + `comment_stripped` вместо `comment_html` |
| 2026-06-01 | Add: **SSH deploy hook** — deployer использует SSH для вызова `/home/slin/bin/enduro-deploy-hook.sh` на хосте |
| 2026-06-01 | Add: **openssh-client** в Dockerfile orchestrator, SSH ключ смонтирован с хоста (`/home/slin/.orchestrator-ssh/`) |
| 2026-06-01 | Fix: **Plane comment webhook**`handle_comment` читает поле `issue` (Plane шлёт именно его) + `comment_stripped` |
| 2026-06-01 | Fix: **ET-008 GPS-треки** — pipeline завершён, v0.0.1 задеплоен, gps-collector запущен |