125 lines
12 KiB
Markdown
125 lines
12 KiB
Markdown
# 02 — ТЗ (TRZ): ORCH-076 — ORCH-52c: протокол handoff + frontmatter-контракт (writer/валидатор/схема)
|
||
|
||
Work Item: **ORCH-076** · Repo: **orchestrator** · Стадия: analysis
|
||
|
||
> ТЗ описывает **конкретные изменения к реализации**, выведенные из BRD и фактического кода.
|
||
> Архитектурное обоснование/решения (как именно структурировать модуль контракта вердиктов,
|
||
> точные сигнатуры) — задача архитектора (06-adr).
|
||
|
||
## 1. Сводка изменения
|
||
|
||
ORCH-52c превращает `src/frontmatter.py` из single-key reader в полный frontmatter-контракт
|
||
(**reader + writer + валидатор обязательной схемы**) и сводит **разрознённое чтение вердиктов**
|
||
гейтов к **единому frontmatter-API**, не меняя ни состав гейтов, ни семантику вердиктов.
|
||
Дополнительно создаётся **формальная спека handoff** в `docs/_standards/`, согласованная с
|
||
манифестом ORCH-52b (`PIPELINE_DOCS.md`). Всё строго обратно совместимо (старые доки читаются
|
||
как раньше), never-raise, валидатор не hard-fail по умолчанию (kill-switch).
|
||
|
||
## 2. Задействованные модули / пути
|
||
|
||
| Путь | Действие |
|
||
|------|----------|
|
||
| `src/frontmatter.py` | **изменить** — добавить writer + валидатор + чтение всего frontmatter (multi-key/dict); reader `read_frontmatter_value` сохранить (контракт неизменен) |
|
||
| `src/qg/checks.py` | **изменить** — `check_reviewer_verdict`, `_parse_tests_verdict`, `_parse_deploy_status`, `_parse_staging_status` перевести на чтение через единый frontmatter-API (поведение/токены/семантика 1:1) |
|
||
| `src/security_gate.py` | **изменить** — `parse_security_status` читает `security_status:` через единый API (семантика 1:1) |
|
||
| `src/post_deploy.py` | **изменить (по решению архитектора)** — чтение `post_deploy_status:` через единый API (информационный, не гейт) |
|
||
| `src/review_parse.py` | **возможно изменить** — `_strip_frontmatter` может использовать общий хелпер; контракт «never raise → ""» сохранить |
|
||
| `src/config.py` | **изменить** — добавить kill-switch строгой валидации (напр. `frontmatter_validation_strict: bool = False`) |
|
||
| `docs/_standards/HANDOFF_PROTOCOL.md` (имя — на усмотрение архитектора/стандарта) | **создать** — формальная спека handoff «стадия → обязательный выход» |
|
||
| `docs/_standards/PIPELINE_DOCS.md` | **изменить** — связать со спекой handoff, отметить что ORCH-52c реализовала машинный контракт |
|
||
| `tests/test_frontmatter.py` | **создать** — unit на reader/writer/валидатор/round-trip |
|
||
| `tests/` (гейты) | **изменить/создать** — анти-регресс тесты чтения вердиктов через новый API |
|
||
| `CLAUDE.md`, `docs/architecture/README.md`, `CHANGELOG.md`, ADR | **изменить/создать** — документация |
|
||
|
||
## 3. Функциональные требования
|
||
|
||
### FR-1 — Writer frontmatter (BR-1)
|
||
В `src/frontmatter.py` добавить функцию записи: принимает данные frontmatter (mapping
|
||
ключ→значение) и тело документа, возвращает/записывает строку с каноничным ведущим
|
||
YAML-блоком `---\n…\n---\n<body>`. Формат на 100% совместим с существующими парсерами
|
||
(`split("---", 2)` + `yaml.safe_load`). **never-raise** (NFR-2): ошибка сериализации/записи →
|
||
лог + безопасный результат, исключение наружу не выходит. Точная сигнатура (in-memory render
|
||
vs запись в файл, перезапись существующего frontmatter) — решение архитектора.
|
||
|
||
### FR-2 — Валидатор обязательной схемы (BR-2, NFR-3)
|
||
В `src/frontmatter.py` добавить валидатор, проверяющий наличие обязательных полей схемы:
|
||
`work_item`, `stage`, `author_agent`, `status`, `created_at`, `model_used`. Возвращает
|
||
структурированный результат (список отсутствующих/невалидных полей + признак валидности).
|
||
**Поведение по умолчанию — warning/лог, НЕ blocker** (NFR-3): отсутствие полей не роняет
|
||
конвейер и не заваливает гейт. Жёсткость (hard-fail) включается ТОЛЬКО kill-switch'ем
|
||
`frontmatter_validation_strict` (дефолт `False`). never-raise.
|
||
|
||
### FR-3 — Полночтение frontmatter / единый reader-API (BR-1, BR-4)
|
||
В `src/frontmatter.py` добавить чтение ВСЕГО frontmatter как mapping (а не только single-key),
|
||
поверх которого строится единый доступ к вердикт-полям. Существующий
|
||
`read_frontmatter_value(path, key)` сохраняется без изменения контракта (обратная
|
||
совместимость вызывающих — `notifications.build_status_comment` и т.п.). never-raise.
|
||
|
||
### FR-4 — Единый контракт чтения вердиктов (BR-4, BR-5, NFR-1)
|
||
Пять гейтов-вердиктов читают свои стандартные поля через единый frontmatter-API:
|
||
|
||
| Гейт / парсер | Документ | Стандартное поле | Семантика (НЕИЗМЕННА) |
|
||
|---------------|----------|------------------|------------------------|
|
||
| `check_reviewer_verdict` | `12-review.md` | `verdict:` | `APPROVED`→дальше; `REQUEST_CHANGES`→откат на development |
|
||
| `_parse_tests_verdict` | `13-test-report.md` | `result:` / `verdict:` / `status:` (3 равноранговых, ORCH-047) | `PASS`→дальше; `FAIL`/`BLOCKED`→откат; негативный токен авторитетен |
|
||
| `_parse_deploy_status` | `14-deploy-log.md` | `deploy_status:` | `SUCCESS`→done; `FAILED`→откат (БАГ-8) |
|
||
| `_parse_staging_status` | `15-staging-log.md` | `staging_status:` | `SUCCESS`→дальше; `FAILED`→откат (self-hosting; иначе N/A) |
|
||
| `parse_security_status` | `17-security-report.md` | `security_status:` | `PASS`→дальше; `FAIL`→откат |
|
||
|
||
Требование: **только механизм чтения** унифицируется (одна точка парсинга YAML-frontmatter);
|
||
наборы токенов (`_TESTS_NEGATIVE_TOKENS`/`_TESTS_POSITIVE_TOKENS`), приведение к верхнему
|
||
регистру, обработка «no frontmatter / bad YAML / missing key», fallback `worktree → origin/main`
|
||
для deploy/staging — сохраняются 1:1. Возврат каждого `check_*` — прежний `tuple[bool, str]`.
|
||
|
||
### FR-5 — Обратная совместимость старых доков (NFR-1, критично)
|
||
Документ-вердикт БЕЗ новых полей схемы (`work_item/stage/author_agent/status/created_at/
|
||
model_used`), но с вердикт-ключом (`verdict:`/`result:`/`deploy_status:`/…) ДОЛЖЕН читаться
|
||
гейтом ровно как сейчас. Новая схема — аддитивна; её отсутствие не влияет на чтение вердикта.
|
||
|
||
### FR-6 — Спека handoff (BR-3)
|
||
Создать в `docs/_standards/` формальную спеку «стадия → обязательный выход»: для каждой стадии
|
||
(`created`→`analysis`→`architecture`→`development`→`review`→`testing`→`deploy-staging`→`deploy`
|
||
→`done`) перечислить обязательные документы и обязательные frontmatter-ключи на выходе.
|
||
Согласовать с таблицей §2 `PIPELINE_DOCS.md` (тот же набор документов/ключей/гейтов), явно
|
||
указать «источник истины — код». Различать machine-verdict доки и информационные (как в
|
||
`PIPELINE_DOCS.md` §3).
|
||
|
||
## 4. Изменения API
|
||
|
||
Нет. HTTP-эндпоинты не добавляются/не меняются. (Опционально архитектор может предложить блок
|
||
наблюдаемости в `GET /queue` для счётчика валидации — НЕ требование данной задачи.)
|
||
|
||
## 5. Изменения схемы БД
|
||
|
||
Нет. Таблицы/миграции/индексы не затрагиваются. Контракт работает на файлах
|
||
(YAML-frontmatter) и in-memory.
|
||
|
||
## 6. Требования к новым/изменённым QG checks
|
||
|
||
- **Состав `QG_CHECKS` НЕ изменяется** (никаких новых/удалённых зарегистрированных гейтов) —
|
||
AC-6 / правило CLAUDE.md.
|
||
- Изменяется только **внутренняя реализация чтения вердикта** существующих `check_*`/`_parse_*`
|
||
(делегирование единому frontmatter-API). Сигнатуры и возвращаемые значения (`tuple[bool,str]`)
|
||
— неизменны.
|
||
- Новый kill-switch `frontmatter_validation_strict` (config) управляет жёсткостью валидатора
|
||
схемы; дефолт `False` (warning-only) → нулевая поведенческая регрессия.
|
||
|
||
## 7. Совместимость / регресс
|
||
|
||
- **Обратная совместимость (NFR-1):** старые доки-вердикты без новой схемы читаются как
|
||
раньше; контракт `read_frontmatter_value` неизменен; формат writer'а совместим с
|
||
существующими парсерами.
|
||
- **never-raise (NFR-2):** writer/валидатор/единый reader не выбрасывают исключений в
|
||
конвейер (паттерн текущего `frontmatter.py`).
|
||
- **kill-switch / обратимость (NFR-3, NFR-5):** `frontmatter_validation_strict=False` (дефолт)
|
||
→ валидация только логирует; `True` → строгий режим (на будущее). Поведение деградирует к
|
||
прежнему при дефолтном флаге.
|
||
- **Неизменность контрактов (AC-6):** `STAGE_TRANSITIONS`, состав `QG_CHECKS`, семантика
|
||
вердиктов, fallback `worktree→origin/main`, трёх-полевой контракт tester (ORCH-047),
|
||
токен-логика BLOCKED/FAILED — без изменений.
|
||
- **Нулевая регрессия enduro (NFR-4):** для не-self-hosting репо поведение 1:1; условные гейты
|
||
(ORCH-35/43/58) не затрагиваются по существу.
|
||
- **Полный регресс `tests/` зелёный** перед мержем.
|
||
- **self-hosting:** не перезапускать прод-контейнер вручную; деплой через штатный путь;
|
||
первый боевой `autoDeploy` (наблюдение — за стадией deploy).
|