# DEV TASK: Analyst Plane Sync Integration **Статус:** ✅ Done **Проект:** multi-agent **Приоритет:** High **Зависит от:** DEV_TASK_ANALYST_IN_ORCHESTRATOR **Завершено:** 2026-05-31 --- ## Контекст Существующие агенты (`architect`, `developer`, `reviewer`, `tester`) уже интегрированы с Plane через: - `plane_sync.py` (state update, comments) - Автоматический запуск через Plane webhook в `plane.py` - Автоматический запрос `:approved:` и продвижение стадий **Analyst** — единственный агент, который: - Был запущен "вручную" (через `launcher.py` напрямую) - Записал документы локально, но **не синхронизировался с Plane** - Не запросил `:approved:` у стейкхолдера - Не обновил статус тикета В результате ET-005 (Спутниковая карта) аналитик отработал, создал BRD/ТЗ/AC/Test Plan, но ничего не появилось в Plane, и Слава не получил запрос на согласование. --- ## Цель Сделать Analyst **полностью интегрированным агентом** в конвейере Plane → Orchestrator, как architect/developer/reviewer/tester. После этой задачи: - Analyst автоматически запускается при переводе тикета в Analysis - Analyst пишет комментарии в Plane при старте, запросе approve, завершении - Analyst автоматически коммитит документы в feature-ветку - Analyst запрашивает `:approved:` у стейкхолдера через комментарий в Plane - Слава видит BRD и может согласовать без дополнительной коммуникации --- ## Задачи ### 1. Зарегистрировать Analyst в Orchestrator launcher **Файл:** `src/agents/launcher.py` **Что сделать:** - Убедиться, что конфиг для `"analyst"` присутствует (аналогично architect/developer) - Добавить `task_id` в вызов `launch("analyst", repo, task_desc, task_id=task_id)` - Убедиться, что env-переменные для Analyst (HOME, GIT_*) настроены корректно **Проверка:** ```bash docker exec orchestrator python -c " from src.agents.launcher import launcher print('analyst' in launcher.agent_configs) " ``` ### 2. Подключить Analyst к Plane webhook routing **Файл:** `src/webhooks/plane.py` **Что сделать:** - В `handle_work_item_created` / `handle_work_item_updated`: - Если issue переведён в Analysis (или создан со стадией Analysis) → вызвать `launcher.launch("analyst", repo, task_desc, task_id=task_id)` - Автоматически создать комментарий в Plane: "Analyst запущен. BRD в работе..." - Сохранить `plane_issue_id` в таблицу `tasks` **Пример:** ```python if new_stage == "analysis": run_id = launcher.launch("analyst", repo, task_desc, task_id=task_id) plane_sync.post_comment(plane_issue_id, "Analyst запущен (run_id={}). BRD/ТЗ/AC в работе.".format(run_id)) ``` ### 3. Добавить Plane sync при запуске Analyst **Файл:** `src/agents/launcher.py` (или `plane.py`) **Что сделать:** - При старте Analyst автоматически создать комментарий в Plane: > "Analyst начал работу над BRD. Ожидайте результатов (8-15 мин)." ### 4. Добавить автоматический запрос `:approved:` после завершения Analyst **Файл:** `src/webhooks/plane.py` + `plane_sync.py` **Что сделать:** - После успешного завершения Analyst (exit_code=0) и наличия BRD/ТЗ/AC: - Автоматически создать комментарий в Plane: > "BRD/ТЗ/AC/TestPlan готовы. Прошу review и реакцию `:approved:` на подзадаче Анализ." - Обновить статус подзадачи Analysis → `in_review` ### 5. Автоматическое продвижение после `:approved:` **Файл:** `src/webhooks/plane.py` **Что сделать:** - При получении комментария с `:approved:` на тикет в стадии Analysis: - Проверить QG `check_analysis_approved` - Если проходит → `advance_stage(task_id, "analysis", "architecture")` - Запустить Architect: `launcher.launch("architect", repo, task_desc, task_id=task_id)` ### 6. Автоматический коммит документов Analyst'а в Gitea **Файл:** `src/agents/launcher.py` (env для Analyst) **Что сделать:** - Убедиться, что Analyst имеет доступ к git (HOME, GIT_AUTHOR_NAME/EMAIL) - Analyst должен автоматически коммитить документы в feature-ветку `docs/work-items//` - После коммита создать комментарий в Plane: "Документы закоммичены в ``." ### 7. Обновить документацию **Файлы:** - `tasks/multi-agent/BRD.md` — добавить описание Analyst + Plane sync - `tasks/multi-agent/STATUS.md` — отметить интеграцию Analyst - `tasks/multi-agent/DEV_TASK_ANALYST_IN_ORCHESTRATOR.md` — связать с этой задачей --- ## Файлы для изменения | Файл | Изменения | Приоритет | |------|-----------|-----------| | `src/agents/launcher.py` | Регистрация analyst + env + git commit | High | | `src/webhooks/plane.py` | Роутинг Analysis → analyst, post_comment на старте/approve | High | | `src/plane_sync.py` | (возможно) расширить для analyst | Medium | | `src/qg/checks.py` | Убедиться, что `check_analysis_approved` существует | Medium | | `tasks/multi-agent/BRD.md` | Документация Analyst + Plane sync | Low | | `tasks/multi-agent/STATUS.md` | Обновить статус | Low | --- ## Ограничения - НЕ ломать существующий цикл (architect → developer → reviewer → tester) - Analyst НЕ пишет код (только документы) - Analyst всегда запрашивает `:approved:` перед закрытием Analysis - Все комментарии в Plane должны быть на русском (если Слава пишет на русском) --- ## Порядок выполнения 1. `launcher.py` (регистрация analyst + env) 2. `plane.py` (роутинг + post_comment) 3. QG + auto-advance после approve 4. Документация 5. Smoke test: создать тестовый тикет → Analyst запускается → пишет комментарий → запрашивает approve → Слава ставит `:approved:` → architecture --- ## Результат После выполнения этой задачи: - **Analyst полностью интегрирован** в конвейер Plane → Orchestrator - Создание тикета с переводом в Analysis → Analyst автоматически: - Запускается - Пишет комментарий в Plane ("Analyst начал работу...") - Коммитит документы в Gitea - Запрашивает `:approved:` через комментарий - Слава видит BRD в Plane и может согласовать без дополнительной коммуникации - **Все агенты** (architect, developer, reviewer, tester, analyst) работают по единому протоколу --- ## Команды проверки после деплоя ```bash # 1. Analyst в configs docker exec orchestrator python -c " from src.agents.launcher import launcher print('analyst config:', launcher.agent_configs.get('analyst')) " # 2. Smoke: создать тестовый тикет в Analysis → проверить комментарий docker exec orchestrator python -c " import sqlite3 conn = sqlite3.connect('/app/data/orchestrator.db') conn.row_factory = sqlite3.Row r = conn.execute('SELECT * FROM agent_runs WHERE agent=\"analyst\" ORDER BY id DESC LIMIT 1').fetchone() print(dict(r)) " ```