# DEV TASK — description не доходит до analyst + name=untitled (баг ввода конвейера) **Проект:** orchestrator | **Сервер:** slin@82.22.50.71 | **Репо:** /home/slin/repos/orchestrator | **Контейнер:** orchestrator (8500) **Ветка:** `fix/taskmd-description` из свежего main (`git checkout main && git pull && git checkout -b fix/taskmd-description`). main = `2d392b6` (PR #12, status-only). НЕ трогать фиксы PR #11/#12. ⚠️ **ГРАБЛЯ push (ORCH-7):** после push `git log origin/main..origin/fix/taskmd-description` ДОЛЖЕН показать коммиты ДО отчёта «PR готов». ℹ️ Токен Gitea: `docker exec orchestrator printenv ORCH_GITEA_TOKEN`. ## Симптом (вскрыт на проде, run 61 ET-011) Analyst получил `.task.md` 101 байт без описания → его BRD/заключение: «business request не содержит бизнес-целей, проблемы, scope...» (`Title: untitled`, `Description: TBD`). При этом в логах `start_pipeline: pulled description from Plane API (445 chars)` — **описание дотянуто, но не передано агенту.** ## Баг A (главный) — description теряется по дороге в .task.md `src/webhooks/plane.py`, `start_pipeline`, **строка ~512**: ```python task_desc = f"Work item: {work_item_id}\nRepo: {repo}\nBranch: {branch}\nStage: analysis\nTitle: {name}" ``` `description` (дотянутый на ~401) НЕ добавлен в `task_desc`. **Фикс:** добавить описание в task_desc, напр.: ```python task_desc = ( f"Work item: {work_item_id}\nRepo: {repo}\nBranch: {branch}\n" f"Stage: analysis\nTitle: {name}\n\nDescription:\n{description}" ) ``` Проверь, что `description` в этой точке — это финальная переменная после дотяжки из Plane API (стр. ~397-401), а не payload-версия. `.task.md` для analyst должен содержать тело задачи. ## Баг B — name=untitled (не тянется из Plane на issue.updated) `start_pipeline` стр. ~376: `name = data.get("name", "untitled")`. На `issue.updated` Plane шлёт только изменённые поля → name пуст → `untitled` (отсюда slug ветки `feature/ET-011-untitled` и Title untitled). Это тот же класс бага, что был с description (PR #11), но для name фикс не сделан. **Фикс:** если `name` пуст/«untitled»/слишком короткий — дотянуть его из Plane API тем же issue-detail запросом, что и description. Идеально: **одним GET** issue-detail вернуть И name, И description (не два запроса). Посмотри `fetch_issue_description` в `src/plane_sync.py` — он уже делает GET issue-detail; добавь рядом `fetch_issue_name(issue_id, project_id)` ИЛИ расширь до `fetch_issue_fields(...)` возвращающего `(name, description)`, и используй в start_pipeline. НЕ дублируй GET без нужды. - ⚠️ name используется для slug ветки (стр. ~459) — если name дотянулся ПОСЛЕ создания slug, перенеси дотяжку name ВЫШЕ построения slug/branch. Иначе ветка останется untitled. - Если name честно пуст и в Plane (edge) → оставить fallback `untitled`, не падать. ## Баг C — коммент analyst: устаревший «жду :approved:» + нет ссылок на документы После готовности артефактов analyst пишет в Plane коммент «BRD/ТЗ готовы. Жду :approved:» — устарело (комментный approve выпилен в PR #12, теперь только статусы). Найди этот коммент (`grep -rn ':approved:\|BRD\|жду\|Готов' src/` — вероятно в stage_engine или check_analysis_complete, где analyst переводит в In Review). **Фиксы:** 1. **Текст коммента — под статусную модель:** > `✅ BRD/ТЗ/AC готовы. Для продвижения переведите задачу в статус Approved. Для отклонения — напишите причину комментом и переведите в Rejected.` (НЕ «In Progress», НЕ «:approved:» — подтверждено Славой: одобрение = статус Approved.) 2. **Ссылки на документы в комменте.** analyst коммитит артефакты в `docs/work-items//` (00-business-request.md, 01-brd.md, 02-trz.md, 03-acceptance-criteria.md, 04-test-plan.yaml, 04b-ui-test-cases.md). Добавь в коммент прямые ссылки на них в Gitea: - База URL: `{GITEA_ROOT_URL}/{owner}/{repo}/src/branch/{branch}/docs/work-items/{work_item_id}/`. GITEA_ROOT_URL = `https://git.mva154.duckdns.org/` (возьми из env/конфига, НЕ хардкодь если есть переменная; owner=admin, repo=enduro-trails — резолвь из get_project_by_repo / remote). - Перечисли только реально созданные файлы (проверь `git diff --name-only` или список файлов в worktree), не выдумывай несуществующие. - Формат коммента — HTML (`comment_html`), ссылки кликабельные ``. - ⚠️ Если коммент формируется в обобщённом месте для всех стадий — правь только analyst-ветку (готовность артефактов → In Review), не ломай комменты других агентов. ## Ограничения - 🚫 НЕ трогай: nginx/openclaw.json/.env/deploy-хук/HMAC/verify_plane_signature/очередь(queue_worker/jobs кроме чтения+enqueue)/webhook URL в БД Plane/per-agent authorship/PLANE_STATES UUID/M-6 derive/uniqueness-guard/fetch_issue_description(переиспользуй, не ломай)/status-only-verdict логику(PR#12)/conftest.py. - Conventional Commits, отдельные коммиты: `fix(pipeline): pass issue description to analyst task file`, `fix(pipeline): fetch issue name from Plane API on status-trigger start`, `feat(plane): analyst comment asks for Approved status + links docs`. ## Тесты (контейнер) `IMG=$(docker inspect orchestrator --format '{{.Config.Image}}'); docker run --rm -v /home/slin/repos/orchestrator:/code -w /code --entrypoint python3 $IMG -m pytest tests/ -q` Новые: - `test_taskdesc_includes_description`: start_pipeline с description (мок дотяжки) → enqueue_job получил task_desc, содержащий тело description (не только Title). - `test_name_fetched_when_payload_empty`: issue.updated без name → дотянут из Plane API (мок) → slug/Title не «untitled». (если name в API тоже пуст → fallback untitled, ветка валидна). Baseline: **204 passed + 9 pre-existing failed** (test_webhooks signature/401) — не ломать pre-existing. ## Проверка (ассистент — боевым прогоном) | # | Что | Критерий | |---|-----|----------| | 1 | .task.md содержит тело | analyst получает description (не 101 байт, не TBD) | | 2 | name дотянут | ветка/Title = реальное имя задачи, не untitled | | 3 | analyst-заключение | BRD по реальному ТЗ, не «business request пуст» | | 3b | коммент analyst | текст просит «Approved» (не :approved:, не In Progress) + кликабельные ссылки на доки | | 4 | тесты | baseline не сломан + новые passed | | 5 | git | PR в main, remote содержит коммиты | ## Отчёт - НЕ деплоить, НЕ мержить (мерж — ассистент после живой проверки + боевого прогона). - В отчёте: точные строки правок, как дотягиваешь name (один GET или два, переиспользовал ли fetch_issue_description), куда вставил description в task_desc, вывод релевантных тестов. Если что-то разошлось с ТЗ (напр. description в этой точке всё же payload-версия) — отчитайся ДО мержа, не выдумывай. Один исполнитель.