# 2026-06-08 — Дневник ## 🎯 ORCH-66 (статусная модель) доехала до прода САМА — историческое - ORCH-66 = новая статусная модель (Plane-статусы: To Analyse / Analysis / Code-Review / Awaiting Deploy / Deploy / Done + In Review для approve-pending). - **Прошла весь конвейер автономно**: analyst→architect→dev→reviewer→tester→staging→Phase A. CI зелёный, merge-gate пройден, staging пересобран (`bc2347ab`). - Стояла на `In Review` = approval-pending прода, ждала **Confirm Deploy** Славы. Символично: статусная модель первой пошла в прод сама. ## 🟢 ORCH-67 заведена — Telegram tracker багфикс+enhancement (seq=67, id=34a8440d-4024-41fa-bf6e-398937e23dee) ТЗ загружено в Plane как HTML (5458 симв.). Зависит от ORCH-66 (статусные имена) → запускать ПОСЛЕ прода ORCH-66. 4 требования: 1. **Bump заработал** — причина бага найдена и НЕ в коде: bump-логика (`delete + send + repoint`) корректна, но в проде `tracker_mode = "edit"` (дефолт `config.py:345`). Env `ORCH_TRACKER_MODE=bump` не выставлен → режим edit (карточка остаётся вверху). Фикс: включить bump + сделать дефолтом. 2. **Формат карточки со статусами как в Plane** — показывать Plane-статус этапа. 3. **Номер задачи (ORCH-NN) — гиперссылка** на страницу задачи в Plane, внутри карточки. 4. **Во ВСЕХ уведомлениях орка** номер задачи тоже кликабельный → ведёт в Plane. - Уточнение Славы (учтено в ТЗ): **ожидание согласования BRD = Plane-статус `In Review`** (⏸️ approve-pending между Analysis и Architecture). Отразить как полноценный статус, не только строкой «⏸️ Подтверждение BRD ⏳». ## 🔧 Технические факты по notifications.py / tracker (для будущих задач) - `update_task_tracker(task_id)` — два режима через `Settings.tracker_mode` (env `ORCH_TRACKER_MODE`), case-insensitive; всё кроме `"bump"` → `"edit"`. Оба держат инвариант «одна карточка на задачу». - **edit (DEFAULT):** первый вызов sendMessage (silent) + store message_id; далее editMessageText. - **bump (ORCH-042):** delete старого → send нового внизу → repoint message_id. - **`parse_mode: HTML` уже включён** в send/edit → гиперссылки `` делаются без изменения транспорта. - `render_task_tracker(task_id)` — stateless рендер из БД: строка `✅ · ↓/↑ · · ` на этап + строка `✅/⏸️ Подтверждение BRD · твоё время[ ⏳]` между Analysis/Architecture. - `send_telegram(text, disable_notification)` → возвращает message_id; `delete_telegram(message_id)`; есть список Telegram-ошибок «target уже отсутствует» (message_id_invalid и т.п.). ## 🔗 URL/env факты (env орка) - `ORCH_GITEA_PUBLIC_URL=https://git.mva154.duckdns.org` - **НЕТ публичного Plane-URL в env орка** — для гиперссылок нужен базовый URL `https://plane.mva154.duckdns.org`. Заложено в ТЗ ORCH-67 как новый конфиг. - project_id: **ORCH = `8da6aa25-a60e-44d6-a1e2-d8ae59aa7d6a`**, Sandbox = `8c5a3025-4f9d-4190-b79f-fa06276bb27e`. - `ORCH_PLANE_WEBHOOK_SECRET=e7d95e…8b16`. ## 🐛 ORCH-68 root-cause: livelock reconciler = РЕГРЕССИЯ от ORCH-66 (Слава угадал) - Слава: «это началось после внедрения 66ой» — подтверждено логами минута-в-минуту: - `22:17:04.019` рестарт после прод-деплоя ORCH-66 → `Reconciler started (interval=120s)` - `22:17:04.207` (через 0.2с) первый `ET-002 done разблокирована` — ДО 22:17 этого лога не было ever. - `22:18:33` `Task 52: deploy->done (self)` (ORCH-66 задеплоил себя). Спам каждые 120с, 191+ сообщений. - Механизм: ORCH-66 ввела новую статусную модель (имена Done/Monitoring after Deploy). Reconciler сверяет локальную стадию↔Plane-статус; новые имена сломали сравнение терминальных → ET-002 (done/Done = синхронизирована) каждый тик считается «потерян webhook» → `_note_unblock` вхолостую (no-op, токены НЕ тратятся, но спам + нарушает инвариант «fires only on actual state change»). - Чинить в `src/reconciler.py`: маппинг терминальных/пост-деплойных статусов привести к новой модели; done+Done не должен триггерить unblock. - Root-cause-блок дописан в Plane ORCH-68 (seq=68, id=70fd4d24-4241-4dd5-9245-11e629a3fc60), HTML 3603→5419. - ⚠️ Грабли: чуть не дописала root-cause в ЧУЖУЮ задачу seq=60 «Reconciler не должен трогать escalated» (тоже про reconciler) — поймала, откатила (вернула 549 симв.). **Plane seq≠work_item_id; искать issue по полному списку и сверять название, не по ключевому слову.** - ⚠️ Plane API: ручной urllib через двойной SSH+docker молчит/не отдаёт JSON. Рабочий путь — использовать модули орка `src/plane_sync.py` (`PLANE_BASE`, `WORKSPACE`, `PLANE_HEADERS`, httpx) внутри контейнера через файл-скрипт + `docker cp`. PATCH `description_html` работает (200). ## 🚀 ORCH-68 ЗАПУЩЕНА в работу (04:45 UTC) + архитектурный ответ - Слава: «68 срочно запускай. Правильно ли ориентироваться на статус Plane?» - **Ответ: ДА, ориентир на Plane корректен по дизайну.** Таблица `tasks` не имеет status-колонки (reconciler.py:201 «live Plane state is the source of truth»). F-2 обязан опрашивать Plane и реплеить пропущенные вебхуки — это сердце автономности. - **Баг — в МАППИНГЕ, не в идее:** `_reconcile_plane_project` тянет `list_issues_by_state(pid, [to_analyse, approved, rejected])`. ET-002 в Plane=`Done` — её не должно быть в выборке. На **enduro** `get_project_states` схлопывает статусы (reconciler.py:209-211) → `Done` алиасится под `approved` UUID → ветка «Approved but stage never advanced → replay verdict» → `_note_unblock` каждый тик. - **Ключевая находка:** у проекта **orchestrator** `Done`=group=`completed`, `Approved`=group=`started` (разные UUID, НЕ склеены). На enduro — склеены. ⚠️ Правильный фикс: использовать **`state.group == "completed"`** для терминала, а не голый UUID-маппинг. Заложено в ТЗ. - **Старт:** Plane-статус ORCH-68 → `To Analyse` (UUID `8acc6109-934e-4cd5-954b-7495672f520c`) = триггер конвейера. - **QG-0 завернул первый раз:** заголовок >80 симв. → задача ушла в `Blocked`. Укоротила до 60 симв («BUG: reconciler livelock — спам unblock done-задачи (ET-002)») → Backlog → To Analyse → пошла. **Урок: заголовок Plane-задачи для орка — <=80 символов (QG-0 hard check).** - **Сейчас:** task 53, ORCH-068, stage=analysis; **job 378 analyst running** (pid 3332), ветка `feature/ORCH-068-bug-reconciler-livelock-unbloc`. Аналитик получил полное ТЗ + root-cause + архитектурное уточнение. - ТЗ ORCH-68 в Plane: 5428→7007 симв (добавлен архитектурный блок). ## ✅ ORCH-68 BRD Approved (04:52 UTC) → analysis→architecture (архитектор run_id=347) - Аналитик выдал 4 артефакта (BRD/ТЗ/AC/test-plan) в `docs/work-items/ORCH-068/`. Проверила все — эталонная работа. - **Аналитик углубил мой root-cause:** разделил баг на 2 независимых дефекта: **D1** (терминалы не исключены из actionable-выборки) + **D2** (`_note_unblock` зовётся безусловно после no-op dispatch, нарушает свой docstring). D2 — мина, которую я пропустила. - **Захватил связанный баг кэша:** `_STATES_CACHE` живёт весь lifetime, `reload_project_states()` есть но не вызывается — именно из-за этого Слава рестартил орк после создания `Confirm Deploy`. Поймали заодно (G5/AC-12, secondary). - Plane-статусы переходов: To Analyse → Analysis (`cb834d55`) → In Review (`c52e99b9`, approve-pending BRD) → Approved (`63f2c8fe`) → Architecture (`795cc32f`). UUID approved для ORCH = `63f2c8fe-dcda-4ace-952f-dd88bd0118ff`. - Решение «state.group vs allowlist» правильно оставлено архитектору в ADR. ## ⚠️ QG-0 — правила заголовка/описания Plane-задач для орка (важно!) - **QG-0** = первый quality gate конвейера, функция `_qg0_errors(name, description)` в `src/webhooks/plane.py:366`. Проверяет **заголовок (name) и описание** до старта аналитика. - Три проверки: **Title ≥ 5**, **Title ≤ 80** (хардкод, без конфига), **Description ≥ 20** символов (`.strip()`). `len()` по Unicode-символам (кириллица = 1 символ, не байт). - **soft vs hard:** при `work_item.created` — soft (только warning, стр.362). При старте конвейера (`Status->In Progress`) — **hard** (стр.435-457): блокирует и кидает в `Blocked`. Вот почему создаётся ок, а при запуске заворачивает. - 🔑 **ПРАВИЛО: заголовок Plane-задачи для орка — короткий тайтл ≤ 80 символов, вся детализация — в description.** Не впихивать описание в заголовок (моя привычка — забываю). Дважды наступила 08.06 (ORCH-67/68). - ⚡ Возможный QoL-фикс (предложила Славе, ждёт решения): авто-обрезка заголовка до 80 («…») вместо блокировки, или вынести лимит 80 в конфиг. ## 📝 Грабли инструмента edit (зафиксировать) - `edit` требует строго: `path` + `edits` (массив), каждый элемент только `{oldText, newText}` — никаких лишних полей. `oldText` должен совпадать дословно (включая пробелы/переводы строк). Несколько фейлов за сессию из-за неверной формы аргументов и неточного oldText. - `image` (vibecode/claude-sonnet-4.6) падает с **403 Insufficient credits** — генерация картинок недоступна. ## Файлы, тронутые в сессии - `tasks/orchestrator/STATUS_MODEL_DEEP_ANALYSIS.md`, `STATUS_MODEL_PROPOSAL.md`, `status_workflow.html` - `/tmp/wi_tracker_desc.md` (ТЗ ORCH-67), `/tmp/wi1_desc.md` - `temp/DEV_TASK_ORCH-022_test_fix.md`