From f9fdce784429ea56fdac02bb38f29ebcaddb5467 Mon Sep 17 00:00:00 2001 From: Stream Date: Wed, 3 Jun 2026 22:40:02 +0300 Subject: [PATCH] auto-sync: 2026-06-03 22:40:01 --- .../DEV_TASK_TASKMD_DESCRIPTION.md | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 tasks/orchestrator/DEV_TASK_TASKMD_DESCRIPTION.md diff --git a/tasks/orchestrator/DEV_TASK_TASKMD_DESCRIPTION.md b/tasks/orchestrator/DEV_TASK_TASKMD_DESCRIPTION.md new file mode 100644 index 0000000..6ef2181 --- /dev/null +++ b/tasks/orchestrator/DEV_TASK_TASKMD_DESCRIPTION.md @@ -0,0 +1,67 @@ +# 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-версия) — отчитайся ДО мержа, не выдумывай. Один исполнитель.