11 KiB
11 KiB
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содержит frontmatterverdict: 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содержит frontmatterverdict: 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), артефакт-лог существует с frontmatterdeploy_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для этой задачи).
- issue переведён в
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.