# 01 — BRD (бизнес-требования): ORCH-076 — ORCH-52c: протокол handoff + frontmatter-контракт (writer/валидатор/схема) Work Item: **ORCH-076** · Repo: **orchestrator** · Стадия: analysis ## 1. Бизнес-контекст и проблема Это **слой 2 эпика ORCH-52** (стандартизация документного конвейера). Слой 1 (ORCH-52b / ORCH-075) уже в `main`: создан **описательный** стандарт `docs/_standards/PIPELINE_DOCS.md` + копируемые скелеты `docs/_templates/*`. Стандарт честно фиксирует карту «стадия → агент → документ → гейт → frontmatter machine-key», но прямо помечен как слой описательный: «Машинная проверка соответствия шаблонам/frontmatter — отдельная задача ORCH-52c». Установленные факты (проверено в репо на ветке задачи): - **`src/frontmatter.py` = ТОЛЬКО reader.** Единственная функция `read_frontmatter_value(path, key) -> str | None` (single-key, ~2.6 KB). В docstring модуля прямой коммент: *«merging into a single parser is a follow-up task»* — это и есть ORCH-52c. Контракт reader — **never raises** (любая ошибка → `None` + `logger.debug`). - **Протокол вердиктов размазан по отдельным парсерам с дублированной ~10-строчной YAML-frontmatter-логикой:** - `src/qg/checks.py::check_reviewer_verdict` — читает `verdict:` из `12-review.md`; - `src/qg/checks.py::_parse_tests_verdict` — читает `result:`/`verdict:`/`status:` из `13-test-report.md` (три равноранговых поля, ORCH-047); - `src/qg/checks.py::_parse_deploy_status` — читает `deploy_status:` из `14-deploy-log.md`; - `src/qg/checks.py::_parse_staging_status` — читает `staging_status:` из `15-staging-log.md`; - `src/security_gate.py::parse_security_status` — читает `security_status:` из `17-security-report.md`; - `src/post_deploy.py` — пишет/читает `post_deploy_status:` в `16-post-deploy-log.md`; - `src/review_parse.py` — defensive-извлечение прозы (`_strip_frontmatter`). Каждый парсер заново реализует `content.startswith("---")` → `split("---", 2)` → `yaml.safe_load`. Единого контракта нет → риск рассинхрона (разная обработка ошибок, разный набор токенов, разный регистр). - **Нет формальной спеки handoff:** нигде не зафиксировано «что КАЖДАЯ стадия ОБЯЗАНА оставить на выходе» (полный список артефактов + обязательные frontmatter-ключи) как единый контракт передачи между стадиями. **Боль/риск:** без единого контракта чтения вердиктов и без обязательной схемы frontmatter каждая правка одного парсера может разойтись с остальными; новый агентский документ легко написать с неверным ключом/регистром (гейт упадёт ложно), а отсутствие машинной проверки схемы оставляет соблюдение стандарта на ручную дисциплину reviewer'а. **⚠️ Self-hosting.** Задача меняет КОД, читающий вердикты НА ГЕЙТАХ (review/staging/security/ tester/deploy) в инструменте, который сейчас обслуживает прод (enduro-trails) из общего инстанса. Любой регресс чтения вердикта = остановка конвейера всех проектов. Поэтому рефакторинг обязан быть строго обратно совместимым и fail-safe. ## 2. Объём (scope) ### В объёме - **Спека handoff** в `docs/_standards/` (рядом с `PIPELINE_DOCS.md`): формальный контракт «стадия → обязательный выход» (какие документы + какие frontmatter-ключи обязательны на выходе каждой стадии), согласованный с манифестом ORCH-52b. - **Расширение `src/frontmatter.py`:** к существующему reader добавить **writer** (запись YAML-frontmatter) и **валидатор** обязательной схемы. Обязательная схема: `work_item`, `stage`, `author_agent`, `status`, `created_at`, `model_used`. - **Единый контракт вердиктов в одном месте** (док + единый frontmatter-API): гейты (reviewer→`verdict:`, tester→`result:`, deployer→`deploy_status:`, staging→`staging_status:`, security→`security_status:`) читают СТАНДАРТНЫЕ поля через единый frontmatter-API, а не через разрознённые ad-hoc парсеры. - Обновление документации (CLAUDE.md, architecture/README, ADR — глобальный и per-work-item, CHANGELOG). ### Вне объёма - **Правка промптов агентов** (`.openclaw/agents/*.md`), чтобы те эмитили новую полную схему — это **ORCH-52d** (слой 3). - **Ретро-фит старых документов** (дописывание новой схемы в уже существующие work-items). - Изменение `STAGE_TRANSITIONS` и **состава** `QG_CHECKS` (какие гейты существуют). - Изменение **семантики** вердиктов (какое значение → какой переход) — только КАК они читаются. - Включение hard-fail валидации схемы по умолчанию (дефолт — warning; hard-fail только под явно включённым kill-switch). ## 3. Заинтересованные стороны - **Заказчик / Owner** — Слава (homenet542): подтверждает BRD (ручной гейт остаётся ручным). - **Самообслуживаемый инструмент (self-hosting)** — оркестратор правит сам себя; задача — первый боевой тест `autoDeploy` (см. примечание ниже). - **Затрагиваемые роли конвейера** — reviewer / tester / deployer / security-гейт (их вердикты теперь читаются через единый API); architect/analyst (новая обязательная схема для будущих документов, фактическое внедрение — ORCH-52d). - **Другие проекты (enduro-trails)** — НЕ должны почувствовать изменений (нулевая регрессия). ## 4. Бизнес-требования (BR) - **BR-1** — `src/frontmatter.py` предоставляет полный набор операций над YAML-frontmatter: **reader** (сохранён без изменения контракта), **writer** (сериализация frontmatter в документ), **валидатор** (проверка обязательной схемы). - **BR-2** — Обязательная схема frontmatter определена и проверяема: поля `work_item`, `stage`, `author_agent`, `status`, `created_at`, `model_used`. - **BR-3** — Создана формальная спека handoff в `docs/_standards/`, согласованная с `PIPELINE_DOCS.md`: для каждой стадии указано, какие документы и какие frontmatter-ключи она обязана оставить на выходе. - **BR-4** — Контракт вердиктов сведён в ОДНО место; все пять гейтов-вердиктов (review/staging/security/tester/deploy) читают стандартные поля через единый frontmatter-API, а не через разрознённые парсеры. - **BR-5** — Семантика вердиктов неизменна: то же значение → тот же переход/откат, что и сейчас (включая трёх-полевой контракт tester'а ORCH-047 и токен-логику BLOCKED/FAILED). ## 5. Нефункциональные требования (NFR) - **NFR-1 (обратная совместимость, критично self-hosting)** — Существующие документы-вердикты БЕЗ новой полной схемы ПРОДОЛЖАЮТ читаться гейтами (fallback на текущее поведение). Старый `12/13/14/15/17`-док без `work_item/stage/...` парсится по вердикт-ключу как раньше. - **NFR-2 (never-raise / fail-safe)** — Ошибка writer'а или валидатора НЕ роняет конвейер (тот же контракт, что у reader: любая ошибка → лог + безопасное значение, исключение наружу не выходит). - **NFR-3 (валидатор не self-block)** — Валидатор обязательной схемы НЕ является hard-fail на гейте по умолчанию (иначе сама ORCH-52c заблокировала бы себя на собственном деплое, т.к. её документы и документы соседей ещё без полной схемы). Дефолт — warning/лог; жёсткость — под kill-switch (флаг). - **NFR-4 (нулевая регрессия для enduro)** — Поведение для не-self-hosting репозиториев и всех существующих гейтов остаётся 1:1; полный регресс `tests/` зелёный. - **NFR-5 (обратимость)** — Поведенческие изменения (если есть, напр. строгая валидация) закрываются kill-switch с дефолтом, эквивалентным прежнему поведению. ## 6. Допущения и ограничения - Frontmatter везде в каноне — ведущий YAML-блок между `---` … `---` (как в `qg/checks.py` и `frontmatter.py`). - Источник истины о поведении гейтов остаётся КОД (`src/stages.py`, `src/qg/checks.py`, `src/stage_engine.py`); спека/манифест документируют, а не управляют (правило ORCH-075). - `model_used` в схеме — это модель, которой документ создан; фактический источник значения для агентских доков — резолв `resolve_agent_model` (ORCH-41); проставление в реальные документы агентами — ORCH-52d, вне scope. - `pyyaml` уже зависимость проекта (используется во всех существующих парсерах). - Реализационные решения (одна функция-парсер vs класс, точная сигнатура writer/валидатора, имя модуля контракта вердиктов) — прерогатива архитектора (06-adr), здесь не предрешаются. ## 7. Критерии успеха Задача успешна, если: `src/frontmatter.py` несёт reader+writer+валидатор обязательной схемы; спека handoff создана и согласована с `PIPELINE_DOCS.md`; все пять гейтов-вердиктов читают через единый frontmatter-API; старые доки-вердикты продолжают проходить гейты (анти-регресс); ошибка writer/валидатора не роняет конвейер, hard-fail валидации под kill-switch (дефолт — warning); `STAGE_TRANSITIONS` и состав `QG_CHECKS` не изменены, семантика вердиктов неизменна; документация обновлена; **сама ORCH-52c проходит свои гейты** (включая первый боевой `autoDeploy`). Детальные PASS/FAIL — `03-acceptance-criteria.md`. ## 8. Риски - **Регресс чтения вердикта на гейте** → остановка конвейера всех проектов (главный риск self-hosting). Митигация — строгая обратная совместимость + полный регресс тестов гейтов. - **Самоблокировка валидатором** на собственном деплое (документы без полной схемы). Митигация — NFR-3 (валидатор не hard-fail по умолчанию). - **Расхождение спеки handoff с фактом кода** → «лживый» стандарт. Митигация — согласование с `PIPELINE_DOCS.md` и явная пометка «источник истины — код». - **Первый боевой `autoDeploy`** — авто-подтверждение прод-деплоя орка (см. примечание). Детали митигации/наблюдения — задача архитектора (`10-tech-risks.md`). > **Примечание (АВТО-ДЕПЛОЙ).** На этой задаче выставлен лейбл `autoDeploy` (ORCH-089): орк > САМ подтверждает прод-деплой после зелёного staging + всех тех-гейтов. BRD-гейт остаётся > ручным (Слава подтверждает BRD). Это первый боевой тест `autoDeploy`.