From 0663da6e4c699c0b56db13fc375d80ce8be7ff04 Mon Sep 17 00:00:00 2001 From: claude-bot Date: Fri, 5 Jun 2026 12:39:06 +0000 Subject: [PATCH] feat(plane): unified status-comment format with duration line (ORCH-016) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Все агенты (analyst..deployer) теперь пишут финальный коммент через единый хелпер usage.build_status_comment(...) — заголовок «{icon} {Role} — {описание}», опциональная строка Verdict/Status из YAML-frontmatter, строка «Длительность: 4m 12s» (явный duration_s от launcher, fallback из agent_runs для аналитика), HTML-блок Документы, тех-хвост tokens · cost. - Новые публичные функции в src/usage.py: build_status_comment, fmt_duration, get_agent_duration. usage_comment(...) → тонкая deprecated-обёртка (legacy тесты в tests/test_usage.py продолжают работать). artifact_links(...) переписан на HTML
  • (breaking change для внутреннего API, но единственный внешний клиент — _post_usage_comments — мигрирован). - Новый модуль src/frontmatter.py: defensive YAML reader, никогда не raise. - stage_engine._build_analyst_ready_comment(...) теперь тонкая обёртка над build_status_comment(agent="analyst", ...); task_id пробрасывается из _handle_analysis_approved_flow для DB-фоллбэка длительности (AC-14). - launcher._post_usage_comments(...) принимает duration_s, резолвит stage из tasks для deployer и worktree_root для AC-8 graceful skipping. Тесты (16 файлов, 56 новых тестовых функций, покрывают TC-01..TC-25): fmt_duration table, build_status_comment по всем агентам, DB-фоллбэк, authorship под per-agent ботами, дедуп-инвариант, regression на status-only verdict аналитика и финальный notify_done, snapshot QG_CHECKS + STAGE_TRANSITIONS. Документация: docs/architecture/README.md (раздел Plane Sync), CHANGELOG.md (Unreleased Added/Changed). Refs: ORCH-016 Co-Authored-By: Claude Opus 4.7 (1M context) --- CHANGELOG.md | 2 + docs/architecture/README.md | 15 + src/agents/launcher.py | 53 +- src/frontmatter.py | 75 +++ src/stage_engine.py | 79 ++- src/usage.py | 543 ++++++++++++++++-- tests/test_analyst_comment_regression.py | 126 ++++ tests/test_analyst_status_only_regression.py | 135 +++++ tests/test_fmt_duration.py | 68 +++ tests/test_notify_done_regression.py | 79 +++ tests/test_post_usage_comments_integration.py | 199 +++++++ tests/test_qg_registry_snapshot.py | 64 +++ tests/test_status_comment_authorship.py | 122 ++++ tests/test_status_comment_dedup_regression.py | 124 ++++ ...est_status_comment_duration_db_fallback.py | 145 +++++ tests/test_status_comment_format.py | 354 ++++++++++++ 16 files changed, 2071 insertions(+), 112 deletions(-) create mode 100644 src/frontmatter.py create mode 100644 tests/test_analyst_comment_regression.py create mode 100644 tests/test_analyst_status_only_regression.py create mode 100644 tests/test_fmt_duration.py create mode 100644 tests/test_notify_done_regression.py create mode 100644 tests/test_post_usage_comments_integration.py create mode 100644 tests/test_qg_registry_snapshot.py create mode 100644 tests/test_status_comment_authorship.py create mode 100644 tests/test_status_comment_dedup_regression.py create mode 100644 tests/test_status_comment_duration_db_fallback.py create mode 100644 tests/test_status_comment_format.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 09445c6..235e5f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ## [Unreleased] ### Added +- **Единый status-коммент агентов в Plane** (ORCH-016): `usage.build_status_comment(...)` — один хелпер для ВСЕХ ролей (analyst..deployer). HTML-формат: header `{icon} {Role} — {описание}`, опциональная строка `Verdict/Status: …` из YAML-frontmatter артефакта, **строка `Длительность: 4m 12s`** (явный `duration_s` от launcher, fallback из `agent_runs` для аналитика), `Документы:`, тех-хвост `tokens · cost`. Утилитки: `usage.fmt_duration`, `usage.get_agent_duration`, новый модуль `src/frontmatter.py` (defensive YAML reader). ADR `docs/work-items/ORCH-016/06-adr/ADR-001-unified-status-comment.md`. - **Документация по канону** (ORCH-9): `CLAUDE.md` (паспорт проекта), структура `docs/` (`architecture/` + `adr/`, `operations/`, `work-items/`, `history/`), `docs/operations/INFRA.md` (RUNBOOK с инфра-изоляцией и self-hosting рисками). - **ADR**: adr-0001 (multi-repo registry), adr-0002 (job queue), adr-0003 (условный staging-гейт). - **Стадия `deploy-staging`** (ORCH-35): промежуточный гейт между `testing` и `deploy`. QG `check_staging_status` (условный, только для self-hosting repo). PR #31. @@ -14,6 +15,7 @@ - **Реестр проектов** (ORCH-6): `src/projects.py`, фильтрация вебхуков по проекту. ### Changed +- **Status-коммент агентов теперь HTML и единообразен** (ORCH-016): `src/usage.usage_comment(...)` помечен deprecated и стал тонкой обёрткой над `build_status_comment`; `src/usage.artifact_links(...)` теперь возвращает `
  • ` HTML-фрагменты (раньше — markdown `[label](url)`); `stage_engine._build_analyst_ready_comment(...)` — тонкая обёртка, аналитик идёт через ту же ветку `build_status_comment(agent="analyst", ...)`. Реестр `QG_CHECKS` и `STAGE_TRANSITIONS` НЕ изменялись. - Цепочка стадий: `... testing → deploy-staging → deploy → done` (была без `deploy-staging`). ### Fixed diff --git a/docs/architecture/README.md b/docs/architecture/README.md index 62f7ad9..3eef0ce 100644 --- a/docs/architecture/README.md +++ b/docs/architecture/README.md @@ -46,6 +46,21 @@ created → analysis → architecture → development → review → testing → - Deploy / deploy-staging FAILED → откат на `development`. - `get_previous_stage` использует порядок ключей `STAGE_TRANSITIONS`. +### Plane Sync: единый status-коммент агентов (ORCH-016) +Все агенты (analyst / architect / developer / reviewer / tester / deployer) пишут финальный коммент через **один хелпер** `usage.build_status_comment(...)` (ADR `docs/work-items/ORCH-016/06-adr/ADR-001-unified-status-comment.md`). Формат HTML, разделители `
    `: + +``` +{ICON} {RoleName} — {описание стадии} +[Verdict|Status: VALUE] # reviewer/tester/deployer, из YAML-frontmatter артефакта +[Длительность: 4m 12s] # явный duration_s от launcher, либо fallback из agent_runs +Документы: +[8.5M in / 45.8k out · $7.29] # тех-хвост usage; опускается при нулях +``` + +- **Длительность** считается launcher'ом (`_monitor_agent`) и пробрасывается в `_post_usage_comments`; для analyst (коммент строится в `stage_engine`) используется DB-фоллбэк `usage.get_agent_duration(task_id, agent)`. +- **Vердикт-парсер** — `src/frontmatter.read_frontmatter_value(...)` (defensive, никогда не raise). Машинные ключи: `verdict:` (reviewer/tester), `deploy_status:` (14-deploy-log.md), `staging_status:` (15-staging-log.md). +- Формат коммента **не** меняет реестр гейтов и стадий; коммент — отображение, не управление. + ## База данных (SQLite) - `events` — входящие вебхуки (дедуп) - `tasks` — задачи и их стадии diff --git a/src/agents/launcher.py b/src/agents/launcher.py index b10d274..a7ff808 100644 --- a/src/agents/launcher.py +++ b/src/agents/launcher.py @@ -507,11 +507,15 @@ class AgentLauncher: from ..notifications import send_telegram send_telegram(f"\u26a0\ufe0f {_wid}: Agent {agent} failed (exit_code={exit_code}). Check logs: /app/data/runs/{run_id}.log") - # Feature 4: post the per-agent usage comment under that agent's bot, and - # — for the deployer finishing the task — the per-task usage summary. + # Feature 4 + ORCH-016: post the unified per-agent status comment under + # that agent's bot, threading the wall-clock duration we just measured + # straight through (ADR-001 §6: explicit param wins over DB fallback). + # The deployer finishing the task also posts the per-task usage summary. if exit_code == 0: try: - self._post_usage_comments(run_id, agent, repo, branch, _usage) + self._post_usage_comments( + run_id, agent, repo, branch, _usage, duration_s=_duration_s + ) except Exception as e: logger.warning(f"run_id={run_id}: usage comment failed: {e}") @@ -679,42 +683,67 @@ class AgentLauncher: logger.error(f"Auto-advance failed for run_id={run_id}: {e}") - def _post_usage_comments(self, run_id, agent, repo, branch, usage): - """Feature 4: post the per-agent usage comment (and Deployer summary). + def _post_usage_comments(self, run_id, agent, repo, branch, usage, duration_s=None): + """Feature 4 + ORCH-016: post the unified per-agent status comment. - Always (on success, with a work_item_id): a per-agent finish comment - with token/cost, authored by the finishing agent's Plane bot. + via ``usage.build_status_comment(...)``, authored by the finishing + agent's Plane bot. The comment carries: + * single-line header (icon + role + per-stage description), + * machine verdict line for reviewer / tester / deployer (when the + relevant frontmatter is present in the worktree), + * the agent's wall-clock duration (``duration_s`` is the measured + value in _monitor_agent; DB fallback is unused on this path), + * an HTML