Files

10 KiB
Raw Permalink Blame History

verdict, work_item, stage, author_agent, status, created_at, model_used, type, work_item_id, version
verdict work_item stage author_agent status created_at model_used type work_item_id version
APPROVED ORCH-027 review reviewer approved 2026-06-10 claude-opus-4-8 review ORCH-027 2

Review ORCH-027 — Code coverage как гейт

Summary

Дисциплинированная реализация детерминированного coverage-гейта строго по образцу security/merge/image-freshness под-гейтов. Соответствие ТЗ/ADR — полное; код качественный, тесты содержательны (test_coverage_gate.py — 30 тестов; полный регресс tests/ -q зелёный: 1466 passed); документация обновлена исчерпывающе.

Единственный прежний блокер закрыт. Ревизия v1 выносила P1 за повреждённую (дословно продублированную) запись ORCH-095 в CHANGELOG.md — коммит 75c33ab docs(changelog): repair duplicated ORCH-095 entry body устранил дубль: тело bullet ORCH-095 теперь присутствует ровно один раз (git revert occurrences on line 16: 1), артефакт чужой задачи восстановлен. Новых P0/P1 не выявлено.

Проверено: 4 оси (ТЗ / ADR / качество кода / документация) + трассировка маркеров + полный прогон тест-сьюта.

Findings

P0 — Blocker

  • (нет)

P1 — Must fix

  • (нет) — прежний P1 (дубль записи ORCH-095 в CHANGELOG) исправлен коммитом 75c33ab.

P2 — Should fix

  • Несоответствие формулировки ADR-001 D7 фактическому артефакту: 6-польная схема 52c не эмитится. ADR-001-coverage-gate.md D7 утверждает: «Артефакт несёт аддитивно обязательную 6-польную схему 52c, не трогая coverage_status:». Фактически и генератор (coverage_gate.render_coverage_report), и скелет docs/_templates/18-coverage-report.md эмитят только coverage_status/work_item + coverage-поля; отсутствуют 5 из 6 полей схемы 52c (stage/author_agent/status/created_at/model_used). Почему не блокер: (а) TRZ §6 формулирует это условно («Если отчёт несёт обязательную 6-польную схему 52c — добавить её аддитивно»), (б) валидация схемы warning-only по умолчанию (frontmatter_validation_strict=False), (в) гейт-генерируемые артефакты (прецедент 17-security-report.md) исторически несут лишь свой machine-key — эпик 52c (ORCH-077) скоупил схему на 6 агент-промптов, не на машинные отчёты. Машинный вердикт читается из coverage_status: корректно, контракт не нарушен. Действие (на усмотрение, не блокирует приёмку): привести формулировку D7 к факту (отчёт несёт coverage_status: + coverage-поля, без полной 52c-схемы) ЛИБО добавить 5 полей в генератор+шаблон.

Документация

Статус: обновлена исчерпывающе (golden source синхронизирован в том же PR, AC-10 PASS):

  • docs/architecture/README.md — реестр QG_CHECKS дополнен check_coverage_gate (ORCH-027); добавлен раздел «Coverage-гейт: защита от деградации покрытия» (точка/порядок, измерение, чистая функция, baseline+ratchet, условность/fail-open, артефакт/наблюдаемость).
  • docs/_standards/PIPELINE_DOCS.md — диапазон доков …18-coverage-report.md; строка карты стадия→агент→документ→гейт→machine-key + строка таблицы вердикт-парсеров (coverage_status:check_coverage_gate).
  • docs/_templates/18-coverage-report.md — скелет с frontmatter зарегистрирован.
  • docs/work-items/ORCH-027/06-adr/ADR-001-coverage-gate.md (D1…D8) + сквозной docs/architecture/adr/adr-0029-coverage-gate.md.
  • CHANGELOG.md — детальная корректная запись ORCH-027; повреждение соседней записи ORCH-095 устранено (v1-P1 закрыт).
  • CLAUDE.md — паспортный блок «Гейт покрытия тестами (ORCH-027)» добавлен.
  • .env.example / src/config.py — флаги ORCH_COVERAGE_* задокументированы.
  • Маркеры ORCH-027 проставлены в коде/доках (AC-10).

src/ изменён → документация обновлена в том же PR: да (P0-условие выполнено). Обзорные доки (ORCH-079): PR не закрывает ни один пункт README.md «Известные ограничения» (coverage-деградация там не значилась) → обновление витрины не требуется, finding отсутствует.

Оси проверки (детально)

1. Соответствие ТЗ (02-trz / 03-acceptance) — PASS. AC-1 измерение инструментально (measure_coveragepytest --cov=srctotals.percent_covered, pytest-cov==5.0.0 в requirements.txt); AC-2 блокировка деградации + откат на development с release merge-lease (_handle_coverage_gate); AC-3 чистая функция compute_coverage_verdict покрыта по всем режимам/границам/epsilon (TC-01…04); AC-4 ratchet up-only + bootstrap + per-repo изоляция + атомарный compare-and-set UPDATE … WHERE coverage <= ? (db.ratchet_coverage_baseline); AC-5 kill-switch/scope + applies(repo) ПЕРВЫМ (дорогой прогон только при applies==True) — регресс зелёный, enduro не затронут; AC-6 fail-open дефолт / fail-closed по флагу; AC-7 never-raise

  • leaf (не импортирует stage_engine) + AST-проверка отсутствия деплой/force-push токенов; AC-8 контракты STAGE_TRANSITIONS/check_*/вердикт-ключи байт-в-байт, таблица coverage_baseline аддитивна; AC-9 вердикт только из frontmatter (parse_coverage_status через frontmatter.parse_frontmatter) + GET /queue блок coverage + Telegram с кликабельным номером.

2. Соответствие ADR (ADR-001 D1…D8 / adr-0029) — PASS (с P2-оговоркой по тексту D7). Порядок под-гейтов security → merge → coverage → image-freshness реализован ровно как в D1 (врезка _handle_coverage_gate между merge-handling и ORCH-058 freshness в advance_stage); coverage ПОСЛЕ merge-gate (догнанный HEAD) и merge_gate.release_merge_lease при FAIL — соответствует D1/TR-2 (зеркало image-freshness rollback, в отличие от security — тот до захвата lease). Ratchet в choke-point _handle_merge_verify (ребро deploy→done, D5), БД-таблица coverage_baseline (D4), машинный вердикт/парсинг (D7), override POST /coverage/baseline (D8). Глобальные ADR (INV-4 merge только через Gitea API; не трогать main/прод) не нарушены — leaf только мерит/читает/пишет/решает.

3. Качество кода — PASS. Docstrings на всех публичных функциях; never-raise контракт выдержан последовательно (все внешние границы обёрнуты, исключение не всплывает в advance_stage); единый frontmatter-контракт переиспользован (нет дублирования парс-логики); тесты содержательные (режимы/границы/epsilon, ratchet up-only + bootstrap + per-repo изоляция, fail-open/closed, never-raise, write/read-back отчёта, self-hosting AST-инвариант, интеграция в advance_stage с откатом+release lease). Фикс sys.executable вместо bare python (коммит 8cd7c20) корректен — pytest-cov живёт в интерпретаторе орка. Нет утечек/security-дыр; измерение offline. Замечание (не finding): синхронный pytest --cov в hot-path advance_stage (тайм-аут coverage_run_timeout_s=900) наследует established-паттерн merge-gate re-test/security-gate — нового класса риска не вводит.

4. Документация — см. раздел «Документация» выше (P0-условие выполнено; обзорные доки N/A).

Трассировка маркеров (TRACEABILITY). Правки рядом с маркерами ORCH-022/ORCH-043/ORCH-058 в advance_stage — аддитивная врезка между merge-gate и image-freshness; инварианты соседних под-гейтов не сломаны (release-lease зеркалит image-freshness rollback, merge через Gitea API не тронут). Врезка в _handle_merge_verify (ORCH-071/073) — never-raise best-effort ratchet, SHA-in-main choke-point не изменён. Чужие артефакты не повреждены (восстановлена запись ORCH-095).