Files
orchestrator/docs/work-items/ORCH-016/03-acceptance-criteria.md

11 KiB
Raw Blame History

Acceptance Criteria: Единообразные коммент-артефакты в Plane

Work Item ID: ORCH-016 Ревизия: 2 (по фидбэку стейкхолдера — все AC по агентам обновлены под строку длительности; добавлены AC-13 / AC-14)

Каждый AC сформулирован как чёткое условие PASS/FAIL. Проверяется автоматически (unit/integration) либо ручной верификацией в staging Plane (порт 8501).


AC-1. Архитектор пишет единообразный коммент

  • Given task завершила стадию architecture успешно, 06-adr/ содержит как минимум один ADR.
  • When _post_usage_comments(agent="architect", ...) вызывается.
  • Then в Plane появляется ровно один коммент со структурой:
    • первая строка: 📐 Architect — Завершил архитектурную проработку. См. ADR ниже.,
    • строка Длительность: <human> (формат — см. AC-13), значение соответствует фактическому времени работы архитектора (±1с),
    • блок «Документы:» с кликабельной ссылкой на …/src/branch/<branch>/docs/work-items/<wid>/06-adr/,
    • нет строки Verdict / Status.
  • And автор коммента — architect (PLANE_BOT_TOKENS["architect"], fallback на shared token).
  • PASS при выполнении всех пунктов; FAIL при отсутствии любого.

AC-2. Разработчик пишет единообразный коммент

  • Given task завершила стадию development, есть open PR.
  • When _post_usage_comments(agent="developer", ...) вызывается.
  • Then коммент в Plane:
    • 💻 Developer — Завершил разработку. См. PR / branch ниже.,
    • строка Длительность: <human>,
    • ссылки: Branch <branch>…/src/branch/<branch>, PR #<num>…/pulls/<num>,
    • нет строки Verdict.

AC-3. Ревьюер пишет коммент с вердиктом

  • Given 12-review.md содержит frontmatter verdict: APPROVE (или REQUEST_CHANGES).
  • When _post_usage_comments(agent="reviewer", ...) вызывается.
  • Then коммент:
    • 🔎 Reviewer — Завершил ревью изменений.,
    • строка Verdict: APPROVE (или REQUEST_CHANGES) — содержимое соответствует frontmatter,
    • строка Длительность: <human>,
    • ссылка Review…/12-review.md.
  • And если frontmatter не содержит verdict: или файл недоступен — строка Verdict: опускается, остальное (в т.ч. длительность) публикуется.

AC-4. Тестер пишет коммент с вердиктом

  • Given 13-test-report.md содержит frontmatter verdict: PASS (или FAIL).
  • When _post_usage_comments(agent="tester", ...) вызывается.
  • Then коммент:
    • 🧪 Tester — Завершил прогон тестов.,
    • строка Verdict: PASS (либо FAIL),
    • строка Длительность: <human>,
    • ссылка Test report…/13-test-report.md.

AC-5. Деплоер пишет коммент со статусом

  • Given task прошла стадию deploy (или deploy-staging), артефакт-лог существует с frontmatter deploy_status: SUCCESS (или staging_status: SUCCESS).
  • When _post_usage_comments(agent="deployer", ...) вызывается.
  • Then коммент:
    • 🚀 Deployer — Завершил деплой.,
    • строка Status: SUCCESS (или FAILED),
    • строка Длительность: <human>,
    • ссылка Deploy log…/14-deploy-log.md (и/или Staging log…/15-staging-log.md для staging-стадии).

AC-6. Аналитик не регрессирует

  • Given существующий поток PR #12/#13 (status-only verdict).
  • When аналитик завершает стадию analysis с готовыми 01..04.
  • Then в Plane:
    • issue переведён в In Review (не меняется),
    • коммент содержит то же человеческое описание (Approved/Rejected инструкции) и список ссылок BRD / ТЗ / AC / Test Plan — формат либо идентичен текущему, либо построен через тот же общий хелпер, что и остальные агенты, без потери смысла,
    • дополнительно к существующему содержимому в комменте присутствует строка Длительность: <human> — значение поднимается из agent_runs (последний завершённый run агента analyst для этой задачи).

AC-7. Один коммент на агента за стадию

  • Given агент успешно отработал стадию.
  • When наблюдаем ленту Plane.
  • Then для каждого агента (architect, developer, reviewer, tester, deployer) на стадию приходится ровно один status-коммент с артефактами. Дополнительные сервисные комменты (notify_stage_change, notify_qg_failure, notify_done) сохраняются — они не считаются status-комментом.

AC-8. Graceful fallback при отсутствии артефакта

  • Given артефакт (например, 12-review.md) ОТСУТСТВУЕТ в worktree на момент коммента (нестандартный сценарий).
  • When _post_usage_comments(agent="reviewer", ...) вызывается.
  • Then коммент всё равно публикуется: заголовок + описание, без ссылки на отсутствующий артефакт и без строки Verdict:. Исключения не пробрасываются.

AC-9. Кликабельность через gitea_public_url

  • Given в .env задан GITEA_PUBLIC_URL=https://git.mva154.duckdns.org, отличный от GITEA_URL.
  • When любой агент пишет status-коммент.
  • Then href всех артефакт-ссылок начинается с https://git.mva154.duckdns.org/ (а не с внутреннего gitea_url).
  • And при отсутствии gitea_public_url (пустая строка) — fallback на gitea_url (обратная совместимость).

AC-10. Существующие тесты зелёные

  • Given новый код влит в feature-ветку.
  • When запускается pytest tests/ -q.
  • Then все ранее существовавшие тесты проходят (нет регрессий status-only verdict, дедупа, set_issue_done).

AC-11. Quality Gates не меняются

  • Given изменения формата комментов.
  • When инспектируется src/qg/checks.py и src/stages.py.
  • Then реестр QG_CHECKS и STAGE_TRANSITIONS остаются идентичными версии до PR (diff в этих файлах = ∅).

AC-12. Документация обновлена

  • Given реализация добавлена в feature-ветку.
  • When reviewer проверяет PR.
  • Then в diff присутствуют обновления:
    • CHANGELOG.md (раздел Unreleased, описание изменения — включая «строку длительности агента в комментах»),
    • docs/architecture/README.md или docs/architecture/internals.md (упоминание единого формата status-комментов и строки длительности).
  • And при отсутствии обновлений документации reviewer ставит verdict: REQUEST_CHANGES (правило проекта).

AC-13. Формат строки длительности

  • Given утилитка fmt_duration(seconds: int) -> str в src/usage.py.
  • When ей передаются граничные значения.
  • Then возвращаемая строка соответствует таблице:
    • 0"0s"
    • 12"12s"
    • 59"59s"
    • 60"1m 00s"
    • 252"4m 12s"
    • 3599"59m 59s"
    • 3600"1h 00m"
    • 3780"1h 03m"
    • 10020"2h 47m"
  • And ввод None или отрицательное значение → функция возвращает пустую строку (или None), а вызывающая сторона строку Длительность: не печатает.
  • PASS при полном совпадении со всеми примерами таблицы.

AC-14. Длительность — graceful fallback

  • Given агент завершился, но _duration_s не пробрасывается явным параметром в коммент-хелпер (например, для аналитика).
  • When строится status-коммент.
  • Then хелпер запрашивает БД: последний agent_runs для (task_id, agent) с непустым finished_at, считает int((julianday(finished_at) - julianday(started_at)) * 86400) и подставляет в fmt_duration.
  • And при отсутствии подходящей строки agent_runs (или finished_at IS NULL, или результат < 0) — строка Длительность: опускается; остальные части коммента (заголовок, описание, вердикт, ссылки) публикуются без изменений.
  • And ошибка чтения БД не пробрасывает исключение наружу — логируется в logger.debug и трактуется как «значение неизвестно».

Финальный PASS задачи: все AC-1…AC-14 = PASS.