152 lines
14 KiB
Markdown
152 lines
14 KiB
Markdown
# 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`.
|