6.7 KiB
BRD — ORCH-047: check_tests_passed должен читать поле result: из тест-отчёта
1. Контекст и проблема
Quality Gate check_tests_passed (src/qg/checks.py, функция-парсер _parse_tests_verdict) гейтит переход testing → deploy-staging. Он читает машиночитаемый вердикт из YAML-frontmatter артефакта 13-test-report.md.
Дефект (обнаружен дев-агентом в ходе ORCH-17, подтверждён 05.06.2026):
парсер читает ТОЛЬКО поля verdict: и status:. Однако промпт тестер-агента (.openclaw/agents/tester.md, строки 51–56 и 78–80) предписывает эмитить машиночитаемое поле result: PASS|FAIL — и НЕ упоминает ни verdict:, ни status:.
В результате тестер, честно следующий своей инструкции (реальный отчёт ORCH-017: result: PASS, без verdict:/status:), упирается в ветку «ни verdict, ни status не заданы» → гейт возвращает False с причиной "No machine-readable verdict/status in test report frontmatter" → задача откатывается testing → development.
Последствие: ЛЮБАЯ задача, где тестер пишет result: PASS (то есть строго по своей инструкции), застревает в бесконечной петле testing ↔ development до исчерпания MAX_DEVELOPER_RETRIES. Именно это крутило ORCH-17. ORCH-016 прошёл раньше лишь потому, что его отчёт избыточно нёс И verdict:, И result:.
Корень: рассинхрон контракта. Гейт (потребитель) и промпт тестера (производитель) описывают разные имена машиночитаемого поля.
2. Бизнес-цель
Привести контракт гейта check_tests_passed в соответствие с тем, что тестер-агенту реально велено эмитить, чтобы корректные тест-отчёты (result: PASS) проходили гейт, а отрицательные (result: FAIL) — надёжно откатывали задачу. Устранить ложноотрицательные срабатывания, ломающие конвейер всех проектов.
3. Заинтересованные стороны
- Owner / Стрим, Слава — выявили дефект при разборе ORCH-17 (05.06).
- Все проекты общего прод-инстанса (orchestrator self-hosting + enduro-trails) — потребители shared quality-gate. Это SHARED-изменение, влияет на всех.
- Тестер-агент — производитель
13-test-report.md.
4. Объём работ (scope)
В объёме
_parse_tests_verdictчитаетresult:как первоклассное машиночитаемое поле НАРАВНЕ сverdict:иstatus:.- Семантика приоритетов сохраняется и распространяется на все три поля:
- negative-токен в ЛЮБОМ из трёх (
result/verdict/status) → FAIL и авторитетен (перебивает positive в другом поле); - при отсутствии negative — positive-токен в ЛЮБОМ из трёх → PASS;
- ни одно из трёх полей не задано → FAIL (нет машиночитаемого вердикта);
- заданы, но не распознаны → FAIL.
- negative-токен в ЛЮБОМ из трёх (
- Обратная совместимость: отчёты, несущие только
verdict:/status:(стиль enduro-trails ET-001…ET-014, ORCH-016), продолжают работать ровно как раньше. - ADR на изменение семантики shared testing-гейта (правило 2 CLAUDE.md — обязательно для сквозного изменения).
- Обновление документации:
docs/architecture/README.md(строка про машинные ключи вердикт-парсера),CHANGELOG.md.
Вне объёма
- Изменение промпта тестера (
.openclaw/agents/tester.md). Контракт приводится со стороны гейта к тому, что тестеру УЖЕ велено эмитить; промпт не трогаем. - Изменение других гейтов (
check_reviewer_verdict,check_deploy_status,check_staging_status) — у них свои поля (verdict:,deploy_status:,staging_status:), они вне этого дефекта. - Изменения ORCH-017 (про ссылки) — это отдельный work item.
5. Ограничения и риски
- SHARED quality-gate, общий прод-инстанс. Изменение затрагивает enduro-trails наравне с orchestrator. Регресс недопустим: набор положительных/отрицательных токенов и поведение для старого формата (
verdict:/status:) должны остаться неизменными. - Self-hosting. Орк правит сам себя; деплой проходит через обязательную стадию
deploy-staging(8501). Прод-контейнерorchestrator(8500) не ронять. - Изменение читает только frontmatter, никогда не прозу (канон гейтов из
docs/architecture/README.md). - Парсер не должен бросать исключения ни при каком вводе (битый YAML, пустой файл, frontmatter-не-mapping) → всегда
(False, reason).
6. Эталонный код
Дев-агент уже написал референс-реализацию в ветке feature/ORCH-017 (src/qg/checks.py + tests/test_qg.py, 23 теста). Его допустимо использовать как ориентир, но оформить чисто через данный work item с собственным ADR.
7. Критерий успеха
Тест-отчёт с одним лишь result: PASS проходит гейт check_tests_passed; с result: FAIL — нет. Старый формат (verdict:/status:) не регрессирует. Все pytest зелёные. ADR заведён.