6.4 KiB
6.4 KiB
Dev Report: orchestrator — 4 правки наблюдаемости + вторая дверь баг-8
Дата: 2026-06-04 Статус: DONE
Задача
Одна ветка fix/observability-and-merge-gate, один PR. 4 правки:
- КРИТ: merge-вебхук при
current_stage=="deploy"НЕ ставит done (gated by deployer verdict). - КРИТ: токены — показывать полный вход (input + cache_read + cache_creation), хранить cache_creation.
- deploy→done success → Plane в терминальный Done.
- Все агенты прикладывают ссылку на свой артефакт в финиш-коммент.
Результат — сдача
- PR: #20 — admin/orchestrator#20 (open, НЕ смержен)
- Ветка:
fix/observability-and-merge-gate(от актуального main2629dff) - 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 на deploysrc/db.py— миграция cache_creation_tokenssrc/usage.py— парсинг/формат/summary/artifact_linkssrc/plane_sync.py— set_issue_donesrc/stage_engine.py— терминальный Plane Done на deploy→donesrc/agents/launcher.py— контекст ссылок + _open_pr_numbertests/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=0in_total == input_tokens, формат45.2k inбез скобки — обратная совместимость сохранена.
Не сделано (по ТЗ)
- PR НЕ смержен — оставлен на ревью Стрим (PR #20, open).
- PLANE_STATES маппинг, HMAC, gitea_public_url конфиг, conftest.py, status-only verdict-модель — не тронуты.