6.8 KiB
DEV TASK: orchestrator — check_tests_passed пропускает BLOCKED/FAILED отчёты (substring "PASS")
Репо: slin@82.22.50.71:/home/slin/repos/orchestrator (пароль motoZ@yaz2010).
Push в main запрещён → только PR в Gitea. Gitea токен: docker exec orchestrator printenv ORCH_GITEA_TOKEN.
Одна ветка fix/tests-machine-verdict от актуального main, один PR. НЕ мержить сам.
Baseline pytest на проде: 277 passed + 9 failed (9 = off-limits HMAC/401, НЕ чинить).
КОНТЕКСТ / БАГ (подтверждён на ET-013, 2026-06-04)
Стадия testing → deploy гейтится функцией check_tests_passed (src/qg/checks.py:139).
Сейчас она делает наивный substring-поиск:
if "PASS" in content or "All tests passed" in content:
return True, "Test report indicates PASS"
content — это весь docs/work-items/<WI>/13-test-report.md.
Что пошло не так на ET-013
Тестер ЯВНО выставил машинный вердикт в YAML-frontmatter:
status: blocked
verdict: BLOCKED
(причина: провален P1-критерий AC-19 — на проде нет hillshade z9-тайлов).
НО в теле отчёта полно слова PASS («23 passed», «✅ PASS (часть AC-18)», «All checks
passed»). Substring "PASS" нашёлся → гейт вернул True → задача с вердиктом BLOCKED
уехала в deploy и доползла до Done. Недоделанная фича попала на прод.
Корень
check_tests_passed не читает машинный вердикт тестера, а ищет подстроку. Это зеркальная
проблема той, что уже ПОЧИНЕНА в check_reviewer_verdict (S-5, читает verdict: из
frontmatter) и check_deploy_status (читает deploy_status:). check_tests_passed
забыли привести к тому же контракту.
ШАГ 0 — ПОДТВЕРДИТЬ ПО КОДУ
- Открой
check_tests_passed(checks.py:139) иcheck_reviewer_verdict(checks.py:211) — последняя уже читает frontmatterverdict:правильно, используй её как ЭТАЛОН структуры. - Посмотри, какие значения вердикта реально пишет тестер. На ET-013:
verdict: BLOCKED,status: blocked. Проверь ещё 1-2 прошлых отчёта (git show origin/main:docs/work-items/ ET-012/13-test-report.md, ET-011) — какой вердикт у УСПЕШНЫХ (вероятноPASS/PASSED/GREEN/APPROVED— зафиксируй ТОЧНЫЕ значения, чтобы не сломать прошедшие задачи). - Зафиксируй verbatim в отчёте: какие значения = успех, какие = блок.
ЧТО СДЕЛАТЬ
Привести check_tests_passed к машинному контракту, как check_reviewer_verdict:
- Читать ТОЛЬКО
verdict:(и при необходимостиstatus:) из YAML-frontmatter13-test-report.md. НЕ искать подстроку в теле. - Успех (return True) ТОЛЬКО при явном положительном вердикте. По образцам определи
множество положительных значений — как минимум
PASS/PASSED(нормализуй.upper().strip()). Если у успешных прошлых отчётов вердикт иной (напр.GREEN,APPROVED) — включи и его, но ОБОСНУЙ по реальным образцам, не выдумывай. - Любой иной вердикт (
BLOCKED,FAILED,REQUEST_CHANGES, пустой, нет frontmatter) → return False с понятной причиной (напр.Test verdict: BLOCKED). - Файла нет → False «Test report not found» (как сейчас).
- Невалидный YAML → False с причиной (как в check_reviewer_verdict).
- Никогда не падать.
ВАЖНО — обратная совместимость
- Если у УЖЕ ПРОШЕДШИХ успешных задач (ET-011, ET-012, ET-014) в отчётах НЕТ frontmatter-
вердикта (старый формат) — реши аккуратно: либо считать отсутствие вердикта блоком (строго,
но может сломать тесты), либо оставить узкий fallback. ПРЕДПОЧТИТЕЛЬНО строгий машинный
контракт; если это ломает существующие pytest-фикстуры — почини фикстуры под новый контракт
(добавь им
verdict: PASS), а не ослабляй проверку. Опиши решение в отчёте.
НЕ ТРОГАТЬ
check_reviewer_verdict,check_deploy_status(эталоны, уже верные), merge-gate gitea.py, PLANE_STATES, set_issue_done, launcher deployer-guard, HMAC, queue, usage_comment/Plane- комменты, cost_usd, формат трекера/Итого, миграции, stages.py mapping. Толькоcheck_tests_passed+ его тесты (+ при необходимости фикстуры тест-отчётов).
ТЕСТЫ (обязательно)
verdict: PASS(или подтверждённое успешное значение) в frontmatter → True.verdict: BLOCKED+ тело со словом «PASS» (кейс ET-013!) → False (главный кейс).verdict: FAILED→ False.- Тело содержит «23 passed», но frontmatter
verdict: BLOCKED→ False (substring больше не обманывает). - Нет frontmatter / нет вердикта → False.
- Невалидный YAML → False, не исключение.
- Файла нет → False «not found».
- Полный pytest зелёный кроме тех же 9 off-limits.
СДАЧА
- Ветка
fix/tests-machine-verdict, один PR. НЕ мержить — на ревью Стрим. - Отчёт:
tasks/orchestrator/reports/dev-2026-06-04-tests-verdict-fix.md— commit, PR-номер, вывод pytest, какие значения вердикта = успех (по реальным образцам ET-011/012/014), до/после поведения на кейсе ET-013, как решена обратная совместимость. - Перенос на прод: scp нет →
base64 | ssh 'base64 -d'или docker cp. - Сообщить: PR-номер, pytest, краткое описание.