Files
wiki/tasks/orchestrator/reports/dev-2026-06-04-observability-fixes.md
2026-06-04 11:20:05 +03:00

86 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Dev Report: orchestrator — 4 правки наблюдаемости + вторая дверь баг-8
Дата: 2026-06-04
Статус: DONE
## Задача
Одна ветка `fix/observability-and-merge-gate`, один PR. 4 правки:
1. КРИТ: merge-вебхук при `current_stage=="deploy"` НЕ ставит done (gated by deployer verdict).
2. КРИТ: токены — показывать полный вход (input + cache_read + cache_creation), хранить cache_creation.
3. deploy→done success → Plane в терминальный Done.
4. Все агенты прикладывают ссылку на свой артефакт в финиш-коммент.
## Результат — сдача
- **PR: #20** — https://git.mva154.duckdns.org/admin/orchestrator/pulls/20 (open, НЕ смержен)
- **Ветка:** `fix/observability-and-merge-gate` (от актуального main `2629dff`)
- **Commit:** `61e26a8`
- **pytest (вся сюита):** `244 passed, 9 failed`
- Baseline был 227 passed + 10 failed. Добавлено **17 новых тестов** (227→244).
- 9 failed = подмножество off-limits HMAC/401 группы. 10-й off-limits тест
(`test_plane_webhook_generates_sequential_ids`) падает только в изоляции,
а в полной сюите проходит из-за порядка/состояния DB — это pre-existing
флак внутри off-limits группы, не связан с правками. Ни один НЕ off-limits
тест не падает.
## Что изменилось в каждой правке
### Правка 1 — `src/webhooks/gitea.py` (merge-gate, баг-8 вторая дверь)
В ветке `action=="closed" and pr.get("merged")` добавлен ранний `return` при
`current_stage == "deploy"` (только лог, без update_task_stage / advance_stage —
чтобы не было гонки). Для всех остальных стадий поведение merge→done сохранено.
deployer мержит PR в начале работы → merge-вебхук больше не фейк-завершает задачу;
done на deploy решает только `check_deploy_status` через `advance_stage`.
### Правка 2 — `src/usage.py` + `src/db.py` (полный вход токенов)
- `db.py`: idempotent миграция `_ensure_column(agent_runs, "cache_creation_tokens", "INTEGER")`.
- `parse_usage_from_text`: добавлен `cache_creation_tokens` из
`cache_creation_input_tokens`.
- `record_usage`: пишет новую колонку.
- Новый `fmt_in()`: `in_total = input + cache_read + cache_creation`,
`cached = cache_read + cache_creation`. Формат `8.5M in (8.4M cached)`;
при cached==0 — просто `45.2k in` (обратно совместимо).
- `usage_comment`: использует `fmt_in()`.
- `task_usage_summary`: `total_in = SUM(input+cache_read+cache_creation)`,
отдельно `total_cached`, per_agent теперь 5-кортежи; COALESCE(...,0) для NULL.
- `task_summary_comment`: показывает `<total_in> вход (<cached> cached) / <out> выход · <cost>`.
- `cost_usd` НЕ тронут.
### Правка 3 — `src/stage_engine.py` + `src/plane_sync.py` (Plane→Done)
- `plane_sync.py`: новый `set_issue_done()``_set_issue_state_direct(PLANE_STATES["done"])`
(маппинг PLANE_STATES НЕ менялся).
- `stage_engine.advance_stage`: в Advance-блоке при `next_stage == "done"` и наличии
work_item_id вызывается `set_issue_done(work_item_id)` (в try/except). Теперь
успешный deploy→done гарантированно доводит Plane до терминального Done
(раньше застревал на In Progress, т.к. merge-вебхук обходил флоу).
### Правка 4 — `src/usage.py` + `src/agents/launcher.py` (ссылки на артефакты)
- `usage.py`: `usage_comment` принимает опц. `repo/branch/work_item_id/pr_number`;
новая `artifact_links()` строит markdown-ссылки через `gitea_public_url`
(fallback gitea_url): reviewer→12-review.md, tester→13-test-report.md,
deployer→14-deploy-log.md, architect→06-adr/, developer→PR+branch.
Отсутствующий контекст/артефакт → ссылка пропускается, не падает. analyst не тронут.
- `launcher._post_usage_comments`: прокидывает repo/branch/work_item_id; для developer
резолвит номер открытого PR (`_open_pr_number`).
## Изменённые файлы
- `src/webhooks/gitea.py` — merge-gate на deploy
- `src/db.py` — миграция cache_creation_tokens
- `src/usage.py` — парсинг/формат/summary/artifact_links
- `src/plane_sync.py` — set_issue_done
- `src/stage_engine.py` — терминальный Plane Done на deploy→done
- `src/agents/launcher.py` — контекст ссылок + _open_pr_number
- `tests/test_usage.py` — +12 тестов (cache_creation, формат cached/без, summary, ссылки)
- `tests/test_webhooks.py` — +2 теста (merge на deploy→не done; merge не-deploy→done)
- `tests/test_stage_engine.py` — +2 теста (deploy→done форсит Plane Done; не-терминал не форсит)
## Проблемы и решения
- pytest нельзя запустить из репо напрямую (pycache принадлежит root, нет venv).
Решение: запуск внутри контейнера `orchestrator` из смонтированного `/repos/orchestrator`
с `PYTHONDONTWRITEBYTECODE=1 -p no:cacheprovider`.
- `.env.bak-*` файлы в репо untracked — НЕ добавлял в коммит (staged только 9 целевых файлов).
- Существующий тест `test_usage_comment_format` остался зелёным: при cache=0
`in_total == input_tokens`, формат `45.2k in` без скобки — обратная совместимость сохранена.
## Не сделано (по ТЗ)
- PR НЕ смержен — оставлен на ревью Стрим (PR #20, open).
- PLANE_STATES маппинг, HMAC, gitea_public_url конфиг, conftest.py, status-only verdict-модель — не тронуты.