139 lines
8.5 KiB
Markdown
139 lines
8.5 KiB
Markdown
---
|
||
work_item: ORCH-027
|
||
stage: analysis
|
||
author_agent: analyst
|
||
status: ready-for-review
|
||
created_at: 2026-06-10
|
||
model_used: claude-opus-4-8
|
||
---
|
||
|
||
# 03 — Критерии приёмки (Acceptance Criteria): ORCH-027 — Code coverage как гейт
|
||
|
||
Work Item: **ORCH-027** · Repo: **orchestrator** · Стадия: analysis
|
||
|
||
Формат: каждый критерий имеет **PASS** (что должно быть истинно для приёмки) и **FAIL**
|
||
(что считается провалом). Любой машинный/ручной reviewer проверяет их буквально по файлам
|
||
репозитория.
|
||
|
||
---
|
||
|
||
## AC-1 — Покрытие измеряется инструментально
|
||
|
||
**Условие:** на применимом репозитории конвейер измеряет покрытие тестами исполнением сьюта под
|
||
coverage-инструментацией перед слиянием в `main`.
|
||
- **PASS:** в коде есть путь, который запускает `pytest` под coverage в изолированном worktree и
|
||
извлекает числовую метрику line coverage (`%`); coverage-зависимость добавлена в `requirements.txt`.
|
||
- **FAIL:** покрытие не измеряется инструментально, метрика берётся из прозы/вердикта LLM, либо
|
||
зависимость не объявлена.
|
||
|
||
---
|
||
|
||
## AC-2 — Гейт блокирует деградацию
|
||
|
||
**Условие:** покрытие ниже политики не пропускается дальше к деплою.
|
||
- **PASS:** при измеренном покрытии ниже порога/базовой линии (с учётом epsilon) гейт даёт FAIL и
|
||
инициирует штатный откат на `development` (инкремент developer-retry), задача не достигает `done`.
|
||
- **FAIL:** задача с упавшим покрытием проходит гейт и продвигается к деплою/`done`.
|
||
|
||
---
|
||
|
||
## AC-3 — Чистая функция решения
|
||
|
||
**Условие:** вердикт — детерминированная чистая функция от (measured, baseline, floor, policy, epsilon).
|
||
- **PASS:** `compute_coverage_verdict(...)` покрыта unit-тестами для всех режимов
|
||
(`absolute`/`baseline`/`both`), границ (равно порогу), epsilon-допуска; без участия LLM.
|
||
- **FAIL:** решение принимает LLM, либо логика недетерминирована/не покрыта тестами границ.
|
||
|
||
---
|
||
|
||
## AC-4 — Режим базовой линии (ratchet)
|
||
|
||
**Условие:** поддержан режим «не ниже предыдущего» с обновлением базовой линии вверх при слиянии.
|
||
- **PASS:** базовая линия персистентна per-repo; при слиянии обновляется значением смёрженного
|
||
покрытия только если оно ≥ текущей; bootstrap инициализирует её фактическим покрытием `main`;
|
||
обновление атомарно/сериализовано относительно параллельных слияний.
|
||
- **FAIL:** базовая линия не хранится / откатывается вниз / обновляется неатомарно (гонка двух
|
||
слияний теряет/занижает значение).
|
||
|
||
---
|
||
|
||
## AC-5 — Условность и нулевая регрессия
|
||
|
||
**Условие:** вне области / при выключенном флаге — поведение конвейера 1:1 как до ORCH-027.
|
||
- **PASS:** при `coverage_gate_enabled=False` или repo ∉ `coverage_gate_repos` гейт — no-op
|
||
(`(True, "...N/A")`); существующая тестовая база (`pytest tests/`) зелёная; enduro-trails не
|
||
затронут; `applies(repo)` проверяется до дорогого прогона.
|
||
- **FAIL:** гейт срабатывает вне области, либо выключенный флаг меняет поведение, либо есть
|
||
регресс существующих тестов.
|
||
|
||
---
|
||
|
||
## AC-6 — Fail-open по умолчанию при ошибке инструмента
|
||
|
||
**Условие:** сбой/недоступность coverage-инструмента не заклинивает автономный конвейер.
|
||
- **PASS:** при ошибке измерения и `coverage_tool_fail_closed=False` гейт даёт PASS + WARNING-лог
|
||
(observability-строка); флаг `=True` переключает в fail-closed (FAIL). Поведение покрыто тестом.
|
||
- **FAIL:** ошибка инструмента по умолчанию заворачивает задачу (петля rework) либо роняет
|
||
`advance_stage`.
|
||
|
||
---
|
||
|
||
## AC-7 — never-raise / self-hosting безопасность
|
||
|
||
**Условие:** ядро гейта не роняет конвейер и не трогает прод/`main`.
|
||
- **PASS:** `src/coverage_gate.py` — leaf (не импортирует `stage_engine`); любое исключение
|
||
перехвачено и не всплывает в `advance_stage`; код не вызывает деплой-хук, не перезапускает
|
||
прод-контейнер, не пушит/форс-пушит в `main`/`master`.
|
||
- **FAIL:** исключение из гейта всплывает в `advance_stage`; гейт трогает прод-контейнер или `main`.
|
||
|
||
---
|
||
|
||
## AC-8 — Совместимость контрактов
|
||
|
||
**Условие:** существующие машинные контракты не изменены.
|
||
- **PASS:** `STAGE_TRANSITIONS`, семантика существующих `check_*`, machine-verdict ключи
|
||
(`verdict:`/`result:`/`deploy_status:`/`staging_status:`/`security_status:`) — байт-в-байт
|
||
прежние; любая новая БД-сущность аддитивна (без миграции существующих таблиц).
|
||
- **FAIL:** изменена семантика/имя существующего гейта или вердикт-ключа; миграция ломает
|
||
существующую схему.
|
||
|
||
---
|
||
|
||
## AC-9 — Машинный вердикт покрытия и наблюдаемость
|
||
|
||
**Условие:** результат измерения прозрачен и машинно читаем.
|
||
- **PASS:** при FAIL — Telegram-алерт с кликабельным номером задачи, измеренным покрытием,
|
||
порогом/базовой линией и дельтой; `GET /queue` несёт read-only блок `coverage`; артефакт-отчёт
|
||
с machine-readable вердиктом (`coverage_status: PASS|FAIL`) записан и читается обратно из того
|
||
же файла через `src/frontmatter.py`.
|
||
- **FAIL:** результат не виден в `GET /queue`/Telegram, либо вердикт парсится из прозы, а не из
|
||
frontmatter, либо имя ключа не зафиксировано (регистр).
|
||
|
||
---
|
||
|
||
## AC-10 — Документация обновлена (golden source)
|
||
|
||
**Условие:** документация синхронизирована с изменением в том же PR.
|
||
- **PASS:** если введён артефакт-отчёт — он зарегистрирован в `docs/_standards/PIPELINE_DOCS.md`
|
||
и `docs/_templates/`; обновлены `docs/architecture/README.md` (описание гейта/флагов) и
|
||
`CHANGELOG.md`; новые/изменённые инварианты несут маркер `ORCH-027`.
|
||
- **FAIL:** функционал введён без обновления обзорной/стандартной документации (reviewer →
|
||
REQUEST_CHANGES, ORCH-079).
|
||
|
||
---
|
||
|
||
## Сводная матрица AC ↔ FR/BR
|
||
|
||
| AC | Покрывает |
|
||
|----|-----------|
|
||
| AC-1 | BR-1 / FR-1 |
|
||
| AC-2 | BR-2 / FR-2, FR-3 |
|
||
| AC-3 | BR-2 / FR-2 / NFR-6 |
|
||
| AC-4 | BR-3 / FR-4 |
|
||
| AC-5 | BR-4 / FR-5 / NFR-5 |
|
||
| AC-6 | NFR-2 / FR-6 |
|
||
| AC-7 | NFR-1 / NFR-3 |
|
||
| AC-8 | NFR-5 / FR-6 (§6 ТЗ) |
|
||
| AC-9 | BR-5 / FR-7 / §6 ТЗ |
|
||
| AC-10 | Правила агентов §2/§6 (CLAUDE.md) |
|