diff --git a/docs/work-items/ORCH-076/12-review.md b/docs/work-items/ORCH-076/12-review.md new file mode 100644 index 0000000..73c30ac --- /dev/null +++ b/docs/work-items/ORCH-076/12-review.md @@ -0,0 +1,93 @@ +--- +type: review +work_item_id: ORCH-076 +verdict: APPROVED +version: 1 +--- + +# Review ORCH-076 — ORCH-52c: единый frontmatter-контракт + спека handoff + +## Summary + +Изменение реализует слой 2 эпика ORCH-52: `src/frontmatter.py` превращён из single-key +reader'а в полный машинный контракт (reader + writer + валидатор схемы + единый парс-примитив), +а дублированное чтение YAML-frontmatter в пяти вердикт-парсерах сведено к одной точке +(`parse_frontmatter`). Дополнительно создана формальная спека handoff +(`docs/_standards/HANDOFF_PROTOCOL.md`). + +Реализация **полностью соответствует ТЗ и ADR-001/adr-0020**: унифицирован только МЕХАНИЗМ +парсинга (D2), семантика вердиктов, token-логика, приоритет негативного токена, fallback +`worktree→origin/main` и трёх-полевой контракт tester (ORCH-047) сохранены 1:1. Валидатор +warning-only по умолчанию, hard-fail только под kill-switch `frontmatter_validation_strict` +(дефолт `False`) — критично для self-hosting (задача не self-block'ится). Весь модуль +never-raise. `STAGE_TRANSITIONS` и состав `QG_CHECKS` не тронуты (подтверждено TC-16). + +Проверка по осям: +- **Соответствие ТЗ:** FR-1…FR-6 реализованы (writer, валидатор, полночтение, единый контракт + вердиктов, BC старых доков, спека handoff). API/БД не тронуты (TRZ §4–§5). ✓ +- **Соответствие AC:** AC-1…AC-7 выполнены (см. ниже). ✓ +- **Соответствие ADR:** D1–D5 реализованы как спроектировано (функции в leaf-модуле, + unify-механизм-не-семантику, warning-only validator, спека handoff, без API/БД). ✓ +- **Качество кода:** docstrings на всех публичных функциях; never-raise контракт выдержан + (broad-except + лог + безопасный возврат); leaf-модуль без проектных импортов (cycle-free). +- **Тесты:** содержательные, покрывают writer/round-trip/валидатор/strict/never-raise/reader + (`test_frontmatter.py`), семантику пяти гейтов + BC + origin/main fallback + (`test_qg_verdicts.py`), security-гейт (`test_security_gate.py`), инварианты реестра + (`test_stages_invariants.py`). Полный регресс **1212 passed**. + +Проверка AC: +- **AC-1** (reader+writer+валидатор, unit-tested): ✓ `read_frontmatter_value` (BC), + `render/write_frontmatter`, `validate_schema` с 6 полями `REQUIRED_FIELDS`; TC-01…TC-07. +- **AC-2** (спека handoff в `docs/_standards/`, согласована): ✓ покрывает все стадии + `created`→`done`, набор документов/ключей/гейтов 1:1 с `PIPELINE_DOCS.md` §2–§3; + `PIPELINE_DOCS.md` обновлён ссылкой + отметкой реализации (§5–§6). +- **AC-3** (единый контракт вердиктов): ✓ все 5 (`check_reviewer_verdict`, + `_parse_tests_verdict`, `_parse_deploy_status`, `_parse_staging_status`, + `parse_security_status`) делегируют `parse_frontmatter`; ad-hoc блоки удалены. +- **AC-4** (BC старых доков + регресс зелёный): ✓ TC-13/TC-14 для старых доков без схемы; + 1212 tests green. +- **AC-5** (never-raise + warning-only + kill-switch): ✓ TC-05 (битый ввод), `maybe_warn_schema` + инертен при дефолте, `frontmatter_validation_strict` в `config.py`. +- **AC-6** (`STAGE_TRANSITIONS`/`QG_CHECKS` неизменны, семантика 1:1): ✓ TC-16; вердикт-логика + не тронута. +- **AC-7** (документация): ✓ см. раздел «Документация». + +## Findings + +### P0 — Blocker +- Нет. + +### P1 — Must fix +- Нет. + +### P2 — Should fix +- Нет. + +### P3 — Nice-to-have +- [ ] `_parse_tests_verdict` (`src/qg/checks.py`): для редкого случая «валидный YAML, но не + mapping» во frontmatter старая ветка возвращала reason `"Malformed YAML frontmatter in test + report (not a mapping)"`, новая реализация маршрутизирует этот ввод в путь пустых данных → + reason `"No machine-readable verdict/status/result in test report frontmatter"`. + **Boolean-вердикт идентичен (`False` в обоих случаях) → семантика и STAGE_TRANSITIONS не + затронуты (AC-6 соблюдён).** Расхождение только в reason-строке (лог/коммент). ADR D2 заявляет + «reason-строки 1:1» — здесь незначительное отклонение в крайне редком кейсе. Можно при желании + добавить явную ветку для паритета, но это не обязательно. +- [ ] `parse_security_status` (`src/security_gate.py`) не вызывает `maybe_warn_schema`, тогда как + 4 из 5 вердикт-парсеров его вызывают. Поскольку warning инертен (не влияет на вердикт), это + чисто косметическая несогласованность наблюдаемости. Для единообразия можно добавить вызов. + +## Документация + +Обновлено в том же PR (golden source синхронен с кодом, правило CLAUDE.md №2/№6): +- `CLAUDE.md` — блок про единый frontmatter-контракт в «Конвенциях». +- `docs/architecture/README.md` — «Канон гейтов» (единый контракт), компонент frontmatter, + ссылки на спеку handoff и adr-0020. +- `docs/_standards/HANDOFF_PROTOCOL.md` — **создан** (спека handoff, все стадии, обязательная + схема `REQUIRED_FIELDS`). +- `docs/_standards/PIPELINE_DOCS.md` — обновлён (слой 2 реализован, §5–§6 + ссылки). +- `CHANGELOG.md` — детальная запись `[Unreleased]`. +- ADR: per-work-item `docs/work-items/ORCH-076/06-adr/ADR-001-frontmatter-contract.md` + + сквозной `docs/architecture/adr/adr-0020-frontmatter-contract.md`; индекс + `docs/architecture/adr/README.md` обновлён (adr-0018/0019/0020, max=0020). + +Документация полная и согласованная — претензий нет.