Files
wiki/tasks/orchestrator/ORCHESTRATOR_DOCS.md
2026-06-03 23:50:01 +03:00

22 KiB
Raw Blame History

Документация: Orchestrator Multi-Agent Pipeline

Статус: 2026-06-03 (актуально)

Свежее (03.06.2026): переход на status-only verdict model (PR #12) — вердикт Славы теперь через смену статуса Issue (Approved/Rejected), а НЕ через коммент :approved:. Закрыты 4 бага входа/выхода analyst (PR #12#15). Конвейер впервые прошёл analysis→architecture через живой Approved. Подробности — в разделах «Переходы статусов» и Changelog.


Архитектура

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... Отменена

Переходы статусов (status-only verdict model, PR #12, 03.06.2026)

Ключевое изменение: вердикт Славы принимается только по смене статуса Issue в Plane (Approved / Rejected), не по комменту :approved:. Комменты теперь logged only, no pipeline action. Причина Rejected берётся из последнего коммента.

Backlog → [QG-0 pass] → In Progress (analyst запущен)
In Progress → [analyst questions] → Needs Input
Needs Input → [Слава ответил] → In Progress (analyst перезапущен)
In Progress → [analyst done] → In Review (BRD/ТЗ/AC готовы, ждёт статус Approved)
In Review → [Слава → статус Approved] → Architecture (architect запущен)   ← БАГ 4 фикс (PR #15)
In Review → [Слава → статус Rejected + причина комментом] → In Progress (analyst перезапущен)
Architecture → [architect done + QG] → Development → ... → Done
In Progress → [3 retry исчерпаны / deploy fail] → Blocked

Статусы-вердикты (новые):

  • Approved (a519a341...) — Слава одобрил ТЗ → конвейер двигается на следующую стадию (analysis→architecture).
  • Rejected — Слава отклонил → причина из коммента → analyst перезапуск.
  • Architecture (3020bbb7...) — рабочая стадия architect.
  • Без мелькания In Progress при advance: _try_advance_stage сразу PATCH-ит статус следующей стадии.

Комментарии в Plane

Orchestrator автоматически пишет комментарии при:

  • Каждом переходе stage (с ссылками на branch и PR)
  • QG failure (что не прошло и почему)
  • Запуске агента
  • Вопросах analyst'а (текст вопросов)
  • Ошибках (deploy fail, retry exhausted)
  • Завершении задачи

Ссылки в комментариях

При переходах stage / готовности analyst комментарий содержит кликабельные ссылки на доки (BRD/ТЗ/AC) + branch/PR.

ВАЖНО (PR #14, 03.06.2026): ссылки строятся от отдельного публичного URL gitea_public_url (env ORCH_GITEA_PUBLIC_URL, прод: https://git.mva154.duckdns.org), А НЕ от внутреннего gitea_url (localhost:3000, он для git clone/push). Без этого ссылки вели на localhost и не кликались из браузера. Fallback: если gitea_public_url пустой → используется gitea_url.

  • 📂 Branch: ссылка на ветку в Gitea (публичный URL)
  • 🔗 PR: ссылка на Pull Request (на этапах review/testing/deploy)
  • 📄 Доки: Business request / BRD / ТЗ / Acceptance Criteria (публичный URL, кликабельные)

Webhook events

Event Действие
work_item.created / issue.created QG-0 → create branch → init docs → launch analyst
issue.updated (смена статуса) Главный вердикт-путь (PR #12): Approved → advance, Rejected → rollback+relaunch, In Progress → start pipeline
comment.created / issue_comment.created Только лог (logged only, no pipeline action) — комменты БОЛЬШЕ НЕ двигают конвейер (было: :approved:/:rejected:). Причина 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 на хост:

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

🐛 Баги входа/выхода analyst — сессия 03.06.2026 (PR #12#15)

Цепочка из 4 багов, вскрытых при переходе на status-only verdict model и прогоне реальной задачи ET-011 (#6, task 29). Все подтверждены боевыми прогонами.

# PR Баг Корень Фикс
Баг 3 #12 Эхо-самоудар: собственный коммент/статус analyst сбивал стадию Коммент-вердикт (:approved:) ловился на собственных комментах бота status-only verdict model: вердикт только по смене статуса, комменты logged only
Баг A #13 description из Plane НЕ попадал в .task.md (пустышка 101 байт) Описание тянулось из API, но не писалось в файл задачи .task.md = 973 байта с полным ТЗ
Баг B #13 name не дотягивался → ветка untitled Имя Issue не читалось из API ветка feature/ET-011-popup-enduro-trails
Баг C #13 Устаревший коммент «Жду :approved:» + нет ссылок на доки Коммент analyst не обновлён под status-only коммент про Approved-статус + ссылки на 6 доков
#14 Ссылки в комменте вели на localhost:3000 — не кликались из браузера Ссылки строились от внутреннего gitea_url новое поле gitea_public_url (env ORCH_GITEA_PUBLIC_URL), fallback на gitea_url; git-операции не тронуты
Баг 4 #15 БЛОКЕР: ручной Approved из analysis НЕ двигал конвейер — task застревал в analysis, architect не запускался advance_stage(): ветка check_analysis_approved ВСЕГДА делала ранний return result → блок Advance недостижим. На webhook-пути (Approved, finished_agent=None) _handle_analysis_approved_flow выходил ничего не делая развёл ветку по agent: analyst(launcher)→flow+return (In Review+коммент), None(вердикт)→провал в Advance (update_task_stage+enqueue architect)

Итог: конвейер впервые прошёл analysis→architecture end-to-end через живой Approved Славы. architect запущен, создал ADR-014/ADR-015 + infra-requirements.


Changelog

Дата Изменение
2026-06-03 PR #15 Fix Баг 4: Approved-вердикт двигает analysis→architecture (развёд check_analysis_approved по finished_agent)
2026-06-03 PR #14 Add: gitea_public_url — внешний URL для кликабельных ссылок в комментах (git-операции на localhost не тронуты)
2026-06-03 PR #13 Fix Баги A/B/C: description.task.md, name→ветка (не untitled), коммент analyst под status-only + ссылки на доки
2026-06-03 PR #12 Add: status-only verdict model — вердикт по смене статуса (Approved/Rejected), комменты logged only (фикс Баг 3 эхо-самоудар)
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 webhookhandle_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 webhookhandle_comment читает поле issue (Plane шлёт именно его) + comment_stripped
2026-06-01 Fix: ET-008 GPS-треки — pipeline завершён, v0.0.1 задеплоен, gps-collector запущен