auto-sync: 2026-06-05 14:20:01

This commit is contained in:
Stream
2026-06-05 14:20:01 +03:00
parent f47eb43011
commit b59f0224e2
2 changed files with 117 additions and 0 deletions

View File

@@ -413,6 +413,20 @@ Dev (session orch9_docs_canon) отработал, я проверила не с
- Архив доставки: `temp/orch_docs_canon.tgz` → slin `/tmp/orch_docs_canon.tgz`
- Отчёт Dev: `tasks/orchestrator/reports/dev-2026-06-05-orch9-docs-canon.md`
### ЗАПУСК САМОДОРАБОТКИ — ревью готовности (05.06, Слава: «Старт», таска ORCH-16):
- **БЛОКЕР 1 УСТРАНЁН:** прод-образ отставал (checks.py без is_self_hosting_repo). Ребилд из main `5ecd1c4` (ОК Славы). Постпроверка: checks.py=main `3f9fe07`, is_self_hosting_repo(enduro)=False/(orchestrator)=True, staging-gate enduro=пропуск, 6 ET-задач на месте, 319 passed. Прод синхронен. (Тесты НЕ в образе — Dockerfile COPY только src/+data/, гонять из /repos/orchestrator или CI.)
- **БЛОКЕР 2 = ORCH-10 (в работе):** plane_sync.py хардкодит PLANE_STATES = UUID СТАТУСОВ ТОЛЬКО ENDURO. ORCH-проект имел 5 базовых статусов, нет стадийных. Слава: «сделать в ORCH такую же статусную модель как в ET, недостающие добавить».
- **СДЕЛАЛА:** создала 9 недостающих статусов в ORCH-проекте через Plane API (Architecture/Development/Review/Testing/Approved/Rejected/Needs Input/In Review/Blocked) — теперь 14 шт, идентично ET по составу. UUID НОВЫЕ (свои у ORCH).
- **Dev запущен** (orch10_states, session 305f824d): ТЗ `DEV_TASK_ORCH10_PER_PROJECT_STATES.md` — динамический резолвинг статусов по project_id (get_project_states + кэш + fallback _DEFAULT_STATES). КРИТИЧНО: webhook-сравнение in_progress резолвить по проекту (иначе ORCH-задача не стартует). Ветка feature/ORCH-10-per-project-states.
- Полные карты UUID обоих проектов — в ТЗ (сняты с прода). ORCH-16 ОСТАЛАСЬ в Backlog (мой PATCH state упал 400 — и хорошо, конвейер НЕ запущен). В описание ORCH-16 дописаны ответы на 2 вопроса (текст+ссылка+1-строка вердикт; один коммент на агента).
- **ПОРЯДОК:** ORCH-10 (Dev) → ребилд прода → проверка резолвинга лично → ТОГДА ORCH-16 Backlog→In Progress (старт конвейера).
- ORCH-16 = «Единообразные коммент-артефакты в Plane» id `2b80c58c-2a83-4ab0-aa69-b7f5d2f8c345`, мелкая, наполнена. Первая самодоработка-прогрев.
### КЛЮЧЕВЫЕ PLANE state-id (оба проекта):
- **ORCH** in_progress `e331bfb3-e17e-4699-ba48-4abb89c21b7b`, backlog `2d5d42ff-...`, done `3738cd3c-...`. Стадийные: architecture `795cc32f`, development `f5ed4705`, review `2026f3d9`, testing `81c5cd78`, approved `63f2c8fe`, rejected `4c769e90`, needs_input `99978b3f`, in_review `c52e99b9`, blocked `505f01a6`.
- **ET** in_progress `b873d9eb-...` (остальные — в ТЗ ORCH-10 и plane_sync.py PLANE_STATES).
- ORCH-проект plane_id `8da6aa25-a60e-44d6-a1e2-d8ae59aa7d6a`, ET plane_id `7a79f0a9-5278-49cd-9007-9a338f238f9c`.
### ФАКТЫ ОРКА (золотой источник, для будущих сессий):
- НЕТ Makefile, НЕТ budget.yaml (в отличие от enduro). Тесты: `pytest tests/ -q` (из .gitea/workflows/ci.yml). CI = Gitea Actions.
- Прод 8500, staging 8501 (изолированная БД ./data/staging, profile staging, только sandbox-проект). External: https://openclaw.mva154.duckdns.org/orchestrator/. Webhook: .../orchestrator/webhook/gitea (+ /webhook/plane).

View File

@@ -0,0 +1,103 @@
# DEV TASK — ORCH-10: per-project резолвинг Plane-статусов
**Проект:** orchestrator | **Сервер:** slin@82.22.50.71 (pw motoZ@yaz2010) | **Репо:** /home/slin/repos/orchestrator
**Ветка:** `feature/ORCH-10-per-project-states` из свежего origin/main (`git fetch && git checkout main && git pull --ff-only && git checkout -b feature/ORCH-10-per-project-states`).
**PR push в main ЗАПРЕЩЁН, НЕ мержить.** Коммит в ветку + PR в Gitea.
## ПРОБЛЕМА (корень)
`src/plane_sync.py` хардкодит `PLANE_STATES` — UUID статусов ТОЛЬКО enduro-проекта (`7a79f0a9`). В коде уже стоит `TODO(ORCH-10): these UUIDs are PER-PROJECT ... do NOT hardcode globally`. При онбординге orchestrator-проекта (`8da6aa25`) синхронизация статусов на доске ломается: орк пытается выставить ET-шный UUID в ORCH-проект → статус не найден.
**Статусы в обоих проектах УЖЕ созданы и идентичны по составу (14 шт), но UUID разные.** Нужен резолвинг по project_id.
## ГОТОВЫЕ ДАННЫЕ (не выдумывай — это снято с прода Стрим)
### enduro-trails (project_id `7a79f0a9-5278-49cd-9007-9a338f238f9c`):
```
backlog 113b24f6-cce8-4be9-9a22-a359b9cf0122
todo 2c7d3df3-9eb9-419b-92b7-d7d560bcdd10
in_progress b873d9eb-993c-48cd-97ac-99a9b1623967
architecture 3020bbb7-6122-4663-930c-0315ba8dfa3d
development 9920609b-f140-4e46-ab95-89acda8412c8
review ba0d802c-5218-41d4-ab43-978b0ea123ed
testing 7855d807-b1bf-42ef-8dae-6cde0df92d02
approved a519a341-dada-4a91-8910-7604f82b79c5
rejected ba958f3c-5db5-461d-8f82-89425e413b97
done 381a2833-3c4e-4be5-bd0f-be84cb946ad8
cancelled b1cae7f9-961d-4889-a179-f3acea697d17
needs_input babf08a3-ff4d-41f3-a821-5491aa29a8ac
in_review 38fb1f64-aa1e-48a3-92e0-0b109679046b
blocked 6c4543f9-ac47-4ef7-ae0f-070020dc9920
```
### orchestrator (project_id `8da6aa25-a60e-44d6-a1e2-d8ae59aa7d6a`):
```
backlog 2d5d42ff-e94d-4209-a664-8020c28c2a95
todo b5d3f512-4870-460f-bf6b-4ea560f00a6f
in_progress e331bfb3-e17e-4699-ba48-4abb89c21b7b
architecture 795cc32f-5f5a-4244-be7b-9acffc92c7c0
development f5ed4705-5029-470d-89a9-54c3f0d211ee
review 2026f3d9-0f43-4054-ab5f-3f9bae3308b8
testing 81c5cd78-2993-4f2c-9e8c-2f52db3e5623
approved 63f2c8fe-dcda-4ace-952f-dd88bd0118ff
rejected 4c769e90-bf80-4a52-b97a-e1c84904bfc3
done 3738cd3c-7610-4907-ba5e-26b9a248d9c0
cancelled 59d1d210-8e3a-4a83-930a-cbc5dbf6ad85
needs_input 99978b3f-72fe-46e3-8b9b-25ba02899fa0
in_review c52e99b9-31ae-4b31-be3f-9773eea7a747
blocked 505f01a6-a12f-4121-aaa7-9c5dd009acc4
```
## РЕШЕНИЕ (архитектура — согласовано)
**Динамический резолвинг статусов по project_id через Plane API + кэш**, с fallback на статический дефолт (текущие ET-значения = safe default).
### R1. Функция резолвинга
В `src/plane_sync.py` ввести:
```python
def get_project_states(project_id: str) -> dict[str, str]:
"""Резолвит {логическое_имя -> state_id} для конкретного project_id.
Источник правды — Plane API GET /projects/<id>/states/.
Маппит Plane-имена статусов (по полю name) на логические ключи
(backlog/todo/in_progress/architecture/development/review/testing/
approved/rejected/done/cancelled/needs_input/in_review).
Кэшируется per project_id (модульный dict, lazy). Если API недоступен —
fallback на статический _DEFAULT_STATES (текущие ET-значения).
"""
```
- Маппинг Plane-name → логический ключ: `{"Backlog":"backlog","Todo":"todo","In Progress":"in_progress","Architecture":"architecture","Development":"development","Review":"review","Testing":"testing","Approved":"approved","Rejected":"rejected","Done":"done","Cancelled":"cancelled","Needs Input":"needs_input","In Review":"in_review","Blocked":"blocked"}`.
- Кэш: `_STATES_CACHE: dict[str, dict[str,str]]` per project_id. Функция `reload_project_states(project_id=None)` для сброса (по аналогии с `reload_projects`).
- `_DEFAULT_STATES` = текущий `PLANE_STATES` dict (ET-значения) — fallback при сбое API.
### R2. Заменить хардкод-обращения PLANE_STATES[...] на резолвинг по проекту
Во ВСЕХ местах, где сейчас `PLANE_STATES["..."]` используется для записи статуса в КОНКРЕТНУЮ задачу — резолвить по project_id этой задачи. Точки (из грепа):
- `STAGE_TO_STATE` (строки 128-137) — сейчас статический dict на PLANE_STATES. Сделать функцией `stage_to_state(stage, project_id)` ИЛИ резолвить внутри `update_issue_state`/`set_issue_stage_state`.
- `update_issue_state` (285), `set_issue_stage_state` (362), `_set_issue_state_direct` (377) — уже принимают `project_id`; использовать его для резолвинга.
- `set_issue_needs_input`(333), `set_issue_in_review`(338), `set_issue_blocked`(343), `set_issue_done`(354), `set_issue_in_progress`(359) — резолвить по project_id.
- `STAGE_VISIBILITY_STATE`(117) + использование в `set_issue_stage_state`(371-374).
### R3. Webhook-сравнения (src/webhooks/plane.py 140-152)
`if new_state == PLANE_STATES["in_progress"]` / approved / rejected — это СРАВНЕНИЕ входящего state с известными. Тут project_id известен из payload (`data.project` или резолв через registry по plane_project_id). Резолвить ожидаемые state-id ПО ПРОЕКТУ задачи:
- `in_progress` старт пайплайна, `approved`/`rejected` — вердикт-переходы.
- ⚠️ КРИТИЧНО: сравнение должно работать для ОБОИХ проектов. Сейчас сравнивает только с ET-UUID → для ORCH-задачи переход в In Progress (ORCH-UUID `e331bfb3`) НЕ распознаётся как старт! Это БЛОКЕР запуска ORCH-задач. Резолвить expected in_progress по project_id входящей задачи.
### R4. project_id — откуда брать
В реестре `src/projects.py` есть `get_project_by_repo`/`get_project_by_plane_id`. project_id Plane = `ProjectConfig.plane_project_id`. Задача знает свой repo (tasks.repo) → резолв project_id через registry. Если в функции уже передаётся project_id — использовать его; если нет — резолвить через repo задачи.
## ⛔ OFF-LIMITS / ГРАБЛИ
- НЕ менять QG-логику (`src/qg/checks.py`), очередь, launcher.
- НЕ ломать enduro: при project_id=enduro резолвинг ДОЛЖЕН давать те же UUID, что сейчас (тесты это проверят).
- НЕ создавать/удалять статусы в Plane (они УЖЕ созданы Стрим — только читать через API).
- PLANE_STATES оставить как `_DEFAULT_STATES` (fallback) — НЕ удалять, на него опираются тесты и аварийный режим.
- Кэш не должен протухать в пределах процесса, но `reload_project_states` для тестов/ручного сброса.
- Plane API base — тот же, что использует существующий код (`PLANE_BASE`, `WORKSPACE`, токен) — переиспользовать, не хардкодить URL.
- Санитайзер SSH-heredoc: `$(...)` экранировать. Запуск Python в проде: base64→docker cp→exec.
## ПРОВЕРКА (пруф в отчёт)
1. `pytest tests/ -q` — все проходят (был 319; не ронять, добавить тесты на резолвинг).
2. Новый тест: `get_project_states(ET)` даёт ET-UUID; `get_project_states(ORCH)` даёт ORCH-UUID (значения из таблиц выше).
3. Новый тест: webhook in_progress распознаётся для ОБОИХ проектов (ORCH `e331bfb3` И ET `b873d9eb` → старт).
4. Fallback: при недоступном API `get_project_states` возвращает `_DEFAULT_STATES`.
5. `git diff --name-status origin/main..ветка` — затронуты только plane_sync.py, webhooks/plane.py (+ возможно stage_engine.py), tests/. НЕ qg/checks.py, НЕ launcher, НЕ queue.
6. Ручная проверка на проде НЕ требуется от тебя — Стрим проверит лично после ребилда.
## РЕЗУЛЬТАТ
Отчёт → `tasks/orchestrator/reports/dev-2026-06-05-orch10-states.md`. Коммит: `fix(plane): resolve issue states per-project instead of hardcoded enduro UUIDs (ORCH-10)`. Верни: список файлов diff, новые тесты, результат pytest, номер PR, краткое описание подхода к резолвингу/кэшу.