Files
wiki/tasks/orchestrator/reports/dev-2026-06-03-orch-m6-plane-sequence.md
2026-06-03 10:10:01 +03:00

4.7 KiB
Raw Blame History

Dev Report: M-6 — work_item_id из Plane sequence_id

Дата: 2026-06-03 Статус: DONE (запушено, PR #8 открыт; НЕ мержено — мерж за Стримом после живой проверки)

Задача

Источник правды для номера work_item_id — Plane sequence_id, маппить в <prefix>-NNN. Fallback на get_next_work_item_id (DB-инкремент) если Plane недоступен (автономность > точность). Бонус: убрать хардкод ET- в find_issue_id.

Разведка (живой GET к Plane) — КЛЮЧЕВОЕ

  • Endpoint одиночного issue: {PLANE_BASE}/workspaces/{ws}/projects/{pid}/issues/{uuid}/trailing slash ОБЯЗАТЕЛЕН: без него 301 redirect (не JSON).
  • Успешный GET (issue 64e98247-..., seq=5) → 200, sequence_idtop-level int (5), поле называется именно sequence_id. Формат helper-шаблона из ТЗ совпал 1:1.
  • GET по f9009756-... (ET-010) → 404 с {"error": ...} JSON → .get("sequence_id") = None → helper вернёт None. Этот issue реально отсутствует в Plane — живая иллюстрация рассинхрона, ради которого делается M-6.
  • Списочный endpoint /issues/ → 200, results[] с sequence_id (int) на каждом issue.
  • Вывод: шаблон helper-а из ТЗ корректен, использован как есть (trailing slash уже был).

Сделано

  • Разведка живым GET — формат подтверждён
  • plane_sync.py: fetch_issue_sequence_id(issue_id, project_id) -> int|None (timeout=10, try/except, не кидает)
  • webhooks/plane.py handle_work_item_created: seq→f"{prefix}-{seq:03d}", None→fallback DB + logger.warning
  • plane_sync.py find_issue_id: убран хардкод ET-, матч по sequence_id из суффикса work_item_id (rsplit("-",1)), обобщён на любой префикс
  • tests/test_m6_sequence.py — 7 тестов
  • 2 коммита (Conventional Commits), push, проверка remote, PR #8

Изменённые файлы

  • src/plane_sync.py — +helper fetch_issue_sequence_id; find_issue_id без ET-хардкода (матч по числу из суффикса)
  • src/webhooks/plane.py — work_item_id из Plane seq + fallback на get_next_work_item_id
  • tests/test_m6_sequence.py — новый, 7 тестов

Результат

  • Новые тесты: 7 passed (helper int/None×2/missing-field; created→ORCH-007 по seq=7; created→fallback ORCH-099 при seq=None; find_issue_id ORCH-005 по seq=5; ET-002 по seq=2).
  • Полный прогон в контейнере (IMG=orchestrator-orchestrator): 158 passed, 9 failed — 9 = pre-existing 401/signature в test_webhooks.py (baseline 151 + 7 новых = 158). M-6 не трогает HMAC; 9 не починены и не сломаны (как требует ТЗ).
  • Fallback-путь: при seq=None task всё равно создаётся (тест test_created_falls_back_to_db_when_plane_down это assert-ит) → автономность сохранена.

Git

  • Ветка feature/ORCH-M6-plane-sequence из свежего main (be27f50).
  • Коммиты:
    • 1d978ca feat(webhook): derive work_item_id from Plane sequence_id (M-6)
    • c431a3d fix(plane_sync): drop hardcoded ET- prefix in find_issue_id (M-6)
  • git log origin/main..origin/feature/ORCH-M6-plane-sequenceоба коммита присутствуют на remote (грабля ORCH-7 проверена).
  • PR #8: admin/orchestrator#8 (head→base = feature→main).
  • Токен: рабочий из env контейнера (ORCH_GITEA_TOKEN=c81227...), совпал с embedded в origin URL.

Проблемы и решения

  • Remote-only репо (нет локального доступа) → редактировал через Python-скрипты по SSH; heredoc с Python мангал shell → решил через cat > file (base64-free, через stdin).
  • Коммит-сплит: оба изменения в plane_sync.py → разнёс git add -p (printf "y\nn\n") — feature-хелпер в коммит 1, find_issue_id-фикс в коммит 2.

Ограничения соблюдены

Не трогал: nginx/openclaw.json/.env/deploy-хук/is_active/ORCH-1..7/stage_engine/STAGE_TRANSITIONS/HMAC/очередь. get_next_work_item_id оставлен как fallback. НЕ деплоил, НЕ мержил.