From b21e9d8898963b6d899d64cc80e8124faab80934 Mon Sep 17 00:00:00 2001 From: claude-bot Date: Tue, 9 Jun 2026 14:48:03 +0300 Subject: [PATCH] architect(ET): auto-commit from architect run_id=460 --- docs/architecture/README.md | 26 +++ docs/architecture/adr/README.md | 2 + .../adr/adr-0021-prompt-canon-anthropic.md | 84 +++++++ .../06-adr/ADR-001-anthropic-prompt-canon.md | 205 ++++++++++++++++++ docs/work-items/ORCH-077/10-tech-risks.md | 45 ++++ 5 files changed, 362 insertions(+) create mode 100644 docs/architecture/adr/adr-0021-prompt-canon-anthropic.md create mode 100644 docs/work-items/ORCH-077/06-adr/ADR-001-anthropic-prompt-canon.md create mode 100644 docs/work-items/ORCH-077/10-tech-risks.md diff --git a/docs/architecture/README.md b/docs/architecture/README.md index ebc6432..f3fbf1b 100644 --- a/docs/architecture/README.md +++ b/docs/architecture/README.md @@ -57,6 +57,32 @@ created → analysis → architecture → development → review → testing → детально — `docs/work-items/ORCH-075/06-adr/ADR-001-pipeline-docs-standard.md`, `docs/work-items/ORCH-076/06-adr/ADR-001-frontmatter-contract.md`. +#### Слой промптов: канон Anthropic + эмиссия схемы 52c (ORCH-077, 52d — замыкает эпик 52) +**Слой 3 (промпты).** 52b дал описательный стандарт, 52c — машинный контракт (writer + валидатор +`REQUIRED_FIELDS`), но валидатор работал warning-only «вхолостую»: 6 системных промптов +`.openclaw/agents/*.md` **не эмитили** поля схемы. ORCH-077 учит все 6 промптов эмитить схему и +переписывает их в едином **каноне Anthropic** — замыкающее звено эпика. Это **docs/prompts-only** +изменение: `src/**`, `STAGE_TRANSITIONS`, `QG_CHECKS`, состав machine-verdict ключей и схема БД — +**не трогаются**; `frontmatter_validation_strict` остаётся `False` (эмиссия **добровольная**, +enforcement не включается). +- **Фиксированный XML-скелет (5 обязательных секций, нормативный порядок):** `` → `` + (+ опц. `` у решающих ролей) → `` → `` (запреты в формате + «❌ X → ✅ Y») → ``. Доп. секции (``/``) — после. +- **Аддитивная схема 52c:** `` каждого промпта перечисляет 6 полей + (`work_item`/`stage`/`author_agent`/`status`/`created_at`/`model_used`) с роле-специфичными + значениями и ставит их **рядом** с machine-verdict ключом, **не меняя его имя/регистр/значения** + (`verdict:`/`result:`/`staging_status:`/`deploy_status:`/`security_status:` — байт-в-байт). Гейты + читают вердикты как раньше (NFR-1). Для `04-test-plan.yaml` (чистый YAML) — top-level ключи. +- **Loading-model (важно для self-hosting):** промпт `cat`-ается из git-worktree агента в момент + запуска (`launcher` `--system-prompt "$(cat .openclaw/agents/.md)"`), НЕ запекается в образ → + новые промпты вступают в силу на следующем worktree от `main` **без прод-рестарта**; reviewer/tester + той же задачи исполняются уже под новыми промптами (естественный in-vivo A/B, BR-6). +- **Анти-регресс:** структурные тесты `tests/test_agent_prompts_canon.py` (5 секций, 6 полей, точный + регистр verdict-ключей, self-hosting-маркеры deployer'а); `test_agent_frontmatter_no_model.py` + остаётся зелёным. **Норматив на будущее:** новые/изменённые агент-промпты следуют этому канону. +- ADR: [adr-0021](adr/adr-0021-prompt-canon-anthropic.md); детально — + `docs/work-items/ORCH-077/06-adr/ADR-001-anthropic-prompt-canon.md`. + ### Модель и эффорт по ролям (ORCH-41, валидация ORCH-74) Модель и `--effort` каждого агента берутся из config (`src/config.py`), резолвятся `launcher.resolve_agent_model` / `resolve_agent_effort` по приоритету **project-override (`projects_json` `agent_models`/`agent_efforts`) > `ORCH_AGENT_MODEL_`/`ORCH_AGENT_EFFORT_` > `*_default` > CLI-дефолт (без флага)**. **Эффорт (ORCH-081):** ниже `*_default` добавлен непустой **per-role floor** — class-default поля `agent_effort_` из `config.py` (его пустой env перебить не может). Floor — строго последний уровень (ниже default) и срабатывает ТОЛЬКО когда все уровни пусты, поэтому пустые прод-`ORCH_AGENT_EFFORT_*=` (которые pydantic трактует как явное `''` и обнуляют дефолт) больше не приводят к запуску без `--effort`: каждая роль получает свой канонический пол (developer=`xhigh`, tester/deployer=`medium`, прочие=`high`). Непустой явный конфиг по-прежнему побеждает floor; опечатка вне `VALID_EFFORTS` дропается валидацией ДО floor (never-break, не маскируется). См. `docs/work-items/ORCH-081/06-adr/ADR-001-effort-resolution-floor.md`. frontmatter `model:` в `.openclaw/agents/*.md` **удалён** (ORCH-74 G1) — он был мёртвой/лживой декларацией (launcher его не читает); config — единственный источник правды о модели. Model-routing (G3) НЕ включён — все 6 агентов на `claude-opus-4-8`. diff --git a/docs/architecture/adr/README.md b/docs/architecture/adr/README.md index 9d79d09..714bccd 100644 --- a/docs/architecture/adr/README.md +++ b/docs/architecture/adr/README.md @@ -26,6 +26,7 @@ Per-work-item решения живут в `docs/work-items//06-adr/ADR-NNN- | adr-0018 | Авто-режим по лейблам (autoApprove + autoDeploy) | accepted | 2026-06-09 | ORCH-089 | | adr-0019 | Стандарт документов конвейера (PIPELINE_DOCS, слой 1) | accepted | 2026-06-09 | ORCH-075 | | adr-0020 | Единый frontmatter-контракт + спека handoff (reader/writer/валидатор) | accepted | 2026-06-09 | ORCH-076 | +| adr-0021 | Канон Anthropic для агент-промптов + эмиссия frontmatter-схемы 52c | proposed | 2026-06-09 | ORCH-077 | > ⚠️ Историческая коллизия: номер `0007` занят двумя файлами — > `adr-0007-reconciler.md` (ORCH-053) и `adr-0007-executable-self-deploy.md` @@ -34,6 +35,7 @@ Per-work-item решения живут в `docs/work-items//06-adr/ADR-NNN- > adr-0014 **amends** adr-0013 (меняет критерий merge-verify на «SHA-в-main»). > adr-0016 **amends** adr-0013/0014 (гарантирует открытый код-PR перед merge_pr, ORCH-082). > adr-0020 реализует машинный слой к adr-0019 (ORCH-52b→52c). +> adr-0021 реализует слой промптов к adr-0019/0020 (ORCH-52d — замыкает эпик 52). ## Формат **Контекст → Решение → Альтернативы → Последствия → Связи.** Статус: proposed / accepted / superseded. diff --git a/docs/architecture/adr/adr-0021-prompt-canon-anthropic.md b/docs/architecture/adr/adr-0021-prompt-canon-anthropic.md new file mode 100644 index 0000000..6f9f1db --- /dev/null +++ b/docs/architecture/adr/adr-0021-prompt-canon-anthropic.md @@ -0,0 +1,84 @@ +# adr-0021: Канон Anthropic для системных промптов агентов + эмиссия frontmatter-схемы 52c + +- **Статус:** proposed +- **Дата:** 2026-06-09 +- **Источник:** ORCH-077 (эпик ORCH-52, слой 52d — замыкающий) +- **Связи:** реализует слой промптов к adr-0019 (52b, PIPELINE_DOCS) и adr-0020 (52c, + frontmatter-контракт). Детально — `docs/work-items/ORCH-077/06-adr/ADR-001-anthropic-prompt-canon.md`. + +## Контекст + +Эпик ORCH-52 строит сквозной контракт документации конвейера: **52b** (adr-0019) — описательный +стандарт документов + скелеты `docs/_templates/`; **52c** (adr-0020) — машинный контракт +`src/frontmatter.py` (reader/writer/валидатор `REQUIRED_FIELDS`) + спека `HANDOFF_PROTOCOL.md` с +обязательной 6-польной схемой `(work_item, stage, author_agent, status, created_at, model_used)`. + +Две незакрытые проблемы: +1. **Цепочка 52b→52c→52d разорвана.** Writer и валидатор схемы есть, но работают warning-only + (`frontmatter_validation_strict=False`); агенты **не эмитят** поля схемы — на входе валидатора нет + данных, петля не замкнута. +2. **Форма 6 промптов `.openclaw/agents/*.md` разнородна** (RU/EN, свободная структура) → снижает + предсказуемость агентов прода, которые исполняются на КАЖДОЙ задаче ВСЕХ проектов из общего + инстанса (self-hosting). + +Факт загрузки (сверено `src/agents/launcher.py`): промпт `cat`-ается из git-worktree агента в момент +запуска (`--system-prompt "$(cat .openclaw/agents/.md)"`), НЕ запекается в образ. + +## Решение + +Ввести **обязательный канон формы** для всех агент-промптов и сделать его машинно-проверяемым. + +1. **Фиксированный XML-скелет (5 обязательных секций, нормативный порядок):** + `` → `` (+ опц. ``) → `` → `` → + ``. Доп. секции (``, ``) — после. Контекст/роль + вперёд, формат вывода последним (recency для следования схеме). +2. **Аддитивная эмиссия схемы 52c.** `` каждого промпта перечисляет 6 полей схемы с + роле-специфичными значениями и инструктирует ставить их **рядом** с существующим machine-verdict + ключом, **не меняя его имя/регистр/значения** (`verdict:`, `result:`, `staging_status:`, + `deploy_status:`, `security_status:` — байт-в-байт). Для `04-test-plan.yaml` (чистый YAML) — как + top-level ключи. Гейты читают вердикты как раньше (схема в boolean-вердикте не участвует). +3. **Few-shot + позитивные альтернативы.** Ссылки на `docs/_templates/` и эталоны (ORCH-073/088); + каждый запрет в формате «❌ X → ✅ Y». +4. **CoT/thinking** у решающих ролей (architect/reviewer/tester/deployer). +5. **Анти-регресс машинно.** Структурные тесты `tests/test_agent_prompts_canon.py` (без запуска + агентов): 5 секций, 6 полей схемы, точный регистр machine-verdict ключей, ключевые + self-hosting-маркеры (deployer: `docker exec orchestrator-staging`, `pr_already_merged`, + «не рестартить 8500»). `test_agent_frontmatter_no_model.py` остаётся зелёным. +6. **Enforcement не включается.** `frontmatter_validation_strict` остаётся `False` (warning-only); + 52d учит эмитить добровольно. Hard-fail — отдельная будущая задача. + +**Границы:** docs/prompts-only. `src/**` (config, launcher, frontmatter, stages, qg/checks, +stage_engine), `STAGE_TRANSITIONS`, `QG_CHECKS`, состав machine-verdict ключей, схема БД, `tools:`-блок +промптов — **не трогаются**. + +**Норматив на будущее:** любая новая правка/добавление агент-промпта следует этому канону (5 секций + +аддитивная схема + ❌→✅). Отступление требует нового ADR. + +## Альтернативы + +- **Сразу включить hard-fail схемы.** Отвергнуто: правка `src/config.py` вне scope; для self-hosting + рискованно (забытое поле валит гейт всех проектов). Сначала эмиссия, enforcement — позже. +- **Канон как рекомендация, не норма.** Отвергнуто: теряется машинная проверяемость, эпик требует + контракт. +- **Запечь промпты в образ.** Отвергнуто: противоречит loading-model (cat из worktree), добавило бы + прод-рестарт-зависимость. + +## Последствия + +- **+** Петля 52 замкнута: схема наполняется реальными данными на каждой стадии всех проектов. +- **+** Единый предсказуемый канон; правки промптов вступают в силу **без прод-рестарта** (следующий + worktree от `main`) → нулевой self-hosting-риск выкатки. +- **+** Естественный in-vivo A/B: reviewer/tester задачи исполняются под новыми промптами в той же + ветке (метод BR-6). +- **−** Рост объёма промптов (митигейшн: ссылки вместо инлайна, контроль объёма). +- **−** Риск регресса инструкции (митигейшн: построчная карта + структурные тесты + приоритетный + review deployer/reviewer). +- **Откат:** `git revert` PR — свободная форма возвращается, эмиссия прекращается, гейты идентичны. + +## Связи +- Реализует: adr-0019 (52b), adr-0020 (52c). +- Per-work-item: `docs/work-items/ORCH-077/06-adr/ADR-001-anthropic-prompt-canon.md`. +- Стандарты: `docs/_standards/PIPELINE_DOCS.md`, `docs/_standards/HANDOFF_PROTOCOL.md`, + `src/frontmatter.py::REQUIRED_FIELDS`. +- Сверено по коду: `src/agents/launcher.py`, `Dockerfile`, + `src/config.py::frontmatter_validation_strict`, `tests/test_agent_frontmatter_no_model.py`. diff --git a/docs/work-items/ORCH-077/06-adr/ADR-001-anthropic-prompt-canon.md b/docs/work-items/ORCH-077/06-adr/ADR-001-anthropic-prompt-canon.md new file mode 100644 index 0000000..0575001 --- /dev/null +++ b/docs/work-items/ORCH-077/06-adr/ADR-001-anthropic-prompt-canon.md @@ -0,0 +1,205 @@ +--- +work_item: ORCH-077 +stage: architecture +author_agent: architect +status: proposed +created_at: 2026-06-09 +model_used: claude-opus-4-8 +--- + +# ADR-001: Канон Anthropic для 6 системных промптов + добровольная эмиссия frontmatter-схемы 52c + +Work Item: **ORCH-077** — ORCH-52d: оптимизация 6 системных промптов по Anthropic (замыкающий слой эпика ORCH-52) +Стадия: **architecture** +Сквозная регистрация: **`docs/architecture/adr/adr-0021-prompt-canon-anthropic.md`** (решение кросс-каттинговое — задаёт долгоживущий стандарт формы ВСЕХ агент-промптов прода). + +## Статус +Proposed + +## Контекст + +Эпик **ORCH-52** строит сквозной контракт документации конвейера тремя слоями: +- **52b (ORCH-075)** — описательный стандарт: `docs/_standards/PIPELINE_DOCS.md` + скелеты `docs/_templates/`. +- **52c (ORCH-076)** — машинный контракт: `src/frontmatter.py` (reader + writer + валидатор + `validate_schema`/`REQUIRED_FIELDS`) + спека `docs/_standards/HANDOFF_PROTOCOL.md` с обязательной + схемой `(work_item, stage, author_agent, status, created_at, model_used)`. +- **52d (эта задача, ORCH-077)** — слой промптов: замыкающее звено. + +**Две проблемы (сверено с кодом и файлами репозитория):** + +1. **Разрыв цепочки 52b→52c→52d.** 52c заложила writer и валидатор обязательной схемы, но работает + warning-only (`frontmatter_validation_strict=False`, дефолт; `src/frontmatter.py`, + `HANDOFF_PROTOCOL.md §1`). Агенты **физически не проставляют** 6 полей схемы — на входе валидатора + нет данных. Петля 52 не замкнута: writer есть, валидатор есть, эмиттера (промпта) нет. + +2. **Разнородная форма промптов.** 6 системных промптов `.openclaw/agents/*.md` написаны в свободной + форме (analyst/architect/developer/reviewer/tester — RU, deployer — EN), без единой структуры. + Это снижает предсказуемость поведения агентов прода и затрудняет сопровождение. + +**Факты загрузки промпта (сверено с `src/agents/launcher.py`):** +- Маппинг роль → путь промпта — `launcher` строки ~297–323 (`"system_prompt": ".openclaw/agents/.md"`). +- Промпт передаётся в Claude CLI как `--system-prompt "$(cat {system_prompt})"` (`launcher` ~577): + файл **читается из рабочего git-worktree агента в момент запуска**, путь относительный, НЕ запечён в + образ (`Dockerfile` копирует только `src/`, не `.openclaw/`). +- Модель/эффорт берутся ТОЛЬКО из config (`resolve_agent_model`/`resolve_agent_effort`, ORCH-41); + frontmatter `model:` удалён как мёртвый (ORCH-074, `tests/test_agent_frontmatter_no_model.py`). + Все 6 ролей сейчас на `claude-opus-4-8`. + +Эти факты определяют две неочевидные следствия (см. D6): прод-рестарт для применения новых промптов +**не требуется**, и новые промпты **частично самоприменяются внутри этой же ветки** (in-vivo A/B). + +## Решение + +### Сводка + +Переписать тело всех 6 промптов в едином XML-каноне Anthropic с фиксированным порядком из 5 +обязательных секций; научить каждый промпт **добровольно** (warning-only, без enforcement) эмитить +6-польную frontmatter-схему 52c **аддитивно** — поверх существующих machine-verdict ключей, не меняя +их имя/регистр/значения. Изменение — **docs/prompts-only**: `src/**` не трогается. Стандарт формы +фиксируется сквозным ADR adr-0021 как обязательный для всех будущих правок промптов. + +### D1 — Канонический скелет: фиксированный порядок 5 обязательных секций (BR-1 / FR-1 / AC-1) + +Тело каждого из 6 промптов строится строго в этом порядке (XML-теги — разделители смысловых блоков): + +1. `` — кто агент, проект orchestrator, стек, self-hosting; **обязательный первый пункт: + «прочти `CLAUDE.md` и `docs/architecture/README.md` перед любым действием»**. +2. `` — что делает роль на своей стадии; **допускается вложенная ``-подсказка** + (D4) для решающих ролей. +3. `` — какие файлы и куда роль создаёт через Write tool; ссылки на скелеты + `docs/_templates/` и эталоны (D3). +4. `` — запреты и обязательные правила; каждый запрет — с позитивной альтернативой (D3). +5. `` — точный формат выходных документов: frontmatter-схема (D2) + machine-verdict + ключи + success-criteria (FR-5). + +Дополнительные семантические секции (``, ``) допустимы ПОСЛЕ пяти +обязательных. **Обоснование порядка:** роль/контекст вперёд (приоритет интерпретации), формат вывода +последним (recency — лучшее следование схеме у Opus 4.8). Порядок — нормативный (структурный тест +проверяет наличие всех 5 тегов; см. test-plan). + +### D2 — Аддитивная эмиссия схемы 52c, machine-verdict ключи неприкосновенны (BR-2/BR-4 / FR-2 / NFR-1) + +Секция `` каждого промпта **явно перечисляет 6 полей** схемы с конкретными для роли +значениями. Инвариант размещения: + +- **Markdown-документы с frontmatter** (`12`/`13`/`14`/`15`/`17`, а также `01`/`02`/`03`, `06-adr`, + `07`/`08`/`10`): 6 полей схемы добавляются в **ведущий YAML-frontmatter-блок РЯДОМ** с существующим + machine-verdict ключом. Machine-verdict ключ сохраняет **имя, регистр и набор значений байт-в-байт** + (`verdict:` `APPROVED|REQUEST_CHANGES`; `result:` `PASS|FAIL`; `staging_status:`/`deploy_status:` + `SUCCESS|FAILED`; `security_status:` `PASS|FAIL`). Порядок ключей в YAML-mapping парсеру безразличен + (`frontmatter.parse_frontmatter` читает по имени), но схему ставим ПОСЛЕ verdict-ключа, чтобы + визуально не «утопить» вердикт. +- **`04-test-plan.yaml`** — чистый YAML (без `---`-fence; сверено со скелетом `docs/_templates/`): + 5 недостающих полей (`stage`/`author_agent`/`status`/`created_at`/`model_used`) кладутся как + **top-level ключи рядом** с уже присутствующими `work_item:` и `tests:`. Структура `tests:` не + трогается. + +**Карта роль → значения схемы** (нормативна; источник `model_used` — README §«Модель и эффорт», ORCH-41): + +| Роль | `stage` | `author_agent` | `status` (пример) | Документы со схемой | Machine-key (НЕ трогать) | +|------|---------|----------------|-------------------|---------------------|--------------------------| +| analyst | `analysis` | `analyst` | `ready-for-review` | `01`,`02`,`03`,`04` | — | +| architect | `architecture` | `architect` | `proposed`/`accepted` | `06-adr/*`,`07`,`08`,`10` | — | +| developer | `development` | `developer` | `in-progress`/`done` | `07`/`08`/`10` (when-applicable) | — (гейт `check_ci_green`) | +| reviewer | `review` | `reviewer` | согласован с `verdict:` | `12-review.md` | `verdict:` | +| tester | `testing` | `tester` | согласован с `result:` | `13-test-report.md` | `result:` | +| deployer | `deploy-staging`,`deploy` | `deployer` | согласован с `*_status:` | `15`,`14`,`17` (w-a) | `staging_status:`,`deploy_status:`,`security_status:` | + +`model_used: claude-opus-4-8` для всех ролей на текущий момент (промпт ссылается на резолв ORCH-41, +а не хардкодит «навсегда» — при будущем model-routing значение пересматривается, вне ORCH-077). +`created_at` — текущая дата `YYYY-MM-DD` (источник — `date +%F` через Bash там, где Bash в `tools:`; +иначе подставляется агентом из контекста задачи). + +### D3 — Few-shot и позитивные альтернативы (BR-3 / FR-3 / AC-3) + +В каждом промпте: (а) ссылка на копируемый скелет роли в `docs/_templates/`; (б) ссылка на ≥1 эталон +(**ORCH-073** и/или **ORCH-088** — заполненные work item высокого качества); (в) каждый запрет в +`` — в формате **«❌ не делай X → ✅ делай Y»** (литеральность Opus 4.8: позитивный +пример рядом с запретом снижает мисинтерпретацию). Эталоны даются **ссылкой**, не инлайном (контроль +объёма, R-4). + +### D4 — Явное место для рассуждения (CoT/thinking) у решающих ролей (FR-4) + +Роли, выносящие вердикт/классификацию, несут ``-подсказку «сначала рассуди, потом пиши +вердикт» внутри ``: **architect** (выбор решения), **reviewer** (APPROVED/REQUEST_CHANGES), +**tester** (PASS/FAIL/BLOCKED), **deployer** (трактовка exit-кодов, ORCH-061 waiver). Для механических +ролей (analyst/developer) — не обязательно. `` — рассуждение агента, не часть выходного +документа. + +### D5 — Анти-регресс через построчный инвентарь + структурные тесты (BR-4 / FR-6 / AC-4, критично) + +Self-hosting: промпт = поведение агента прода для ВСЕХ проектов. Потеря рабочей инструкции = регресс +выхода для enduro-trails и orchestrator. Защита в три слоя: +1. **Построчная карта переноса** «старая инструкция → секция нового промпта» — developer ведёт в + `12-review.md`/коммите как чек-лист; reviewer проверяет ПОСТРОЧНО против инвентаря TRZ §FR-6. +2. **Структурные тесты** (`tests/test_agent_prompts_canon.py`, чистый pytest, БЕЗ запуска агентов, + НЕ трогают `src/`): присутствие 5 XML-секций; присутствие 6 имён полей схемы; присутствие + machine-verdict ключей в точном регистре; присутствие ключевых анти-регресс-маркеров (deployer: + `docker exec orchestrator-staging`, `pr_already_merged`, «не рестартить 8500»; reviewer: правило + «src/ изменён, доки нет → REQUEST_CHANGES»; developer: `--no-verify`/`--force-push`/«не мержить + свой PR»). +3. **Существующий `test_agent_frontmatter_no_model.py`** остаётся зелёным (FR-7): frontmatter промпта + (`name`/`description`/`tools`) сохраняется, `model:` не возвращается. + +### D6 — Rollout & loading-model: без прод-рестарта; in-vivo A/B (BR-6 / FR-7 / NFR-2/NFR-5) + +Из фактов загрузки (Контекст): промпт `cat`-ается из worktree в момент запуска агента, не из образа. +Следствия: +- **Применение без рестарта прода.** После merge ветки в `main` следующий worktree, срезанный от + `main`, уже содержит новые промпты — они вступают в силу **без `docker compose up`/рестарта 8500**. + Это снимает классический self-hosting-риск «правка инструмента требует рестарта прода» (CLAUDE.md + §Self-hosting): данная задача его структурно не несёт. +- **In-vivo A/B (метод для BR-6/AC-6).** Worktree последующих стадий ORCH-077 срезается на HEAD + ветки → как только developer закоммитит новые промпты, **reviewer/tester самой ORCH-077 исполнятся + уже под новыми промптами**. Это естественный A/B: достаточно зафиксировать в `13-test-report.md` + сравнение «старый vs новый» на ≥1 репрезентативной стадии — структурная полнота артефакта, + парсимость machine-verdict, число циклов `REQUEST_CHANGES` (критерий: новый **не хуже**). Метод + **offline**, без прод-рестарта и без деструктива (NFR-2). Дополнительно допустимо ручное сравнение + артефакта одной стадии, сгенерированного под обоими промптами на фиксированном входе. +- **Обратимость (NFR-5).** Изменение чисто текстовое → откат = `git revert` PR, без миграций + состояния/БД. + +### D7 — Enforcement НЕ включается (граница scope) + +`frontmatter_validation_strict` остаётся `False` (warning-only). 52d учит промпты эмитить схему +**добровольно**; включение hard-fail = правка `src/config.py` = вне scope (BR-5/AC-5). Гейты читают +вердикты ровно как раньше — схема в boolean-вердикте не участвует (NFR-1). Этот ADR фиксирует границу +явно, чтобы будущий reviewer не принял отсутствие enforcement за недоделку. + +## Альтернативы + +- **Включить hard-fail валидации схемы сразу (52d = enforcement).** Отвергнуто: правка `src/config.py` + вне scope; рискованно для self-hosting (любой агент, забывший поле, заваливает гейт всех проектов). + Сначала научить эмитить (этот ADR), enforcement — отдельной задачей после накопления данных. +- **Свободный порядок секций / «рекомендация, не норма».** Отвергнуто: теряется предсказуемость и + машинная проверяемость (AC-1), эпик 52 требует именно контракт, не пожелание. +- **Инлайнить эталонные артефакты целиком в промпт.** Отвергнуто: раздувание (R-4) «утопит» ключевые + запреты; ссылка на ORCH-073/088 даёт тот же few-shot-эффект дешевле. +- **Запечь промпты в образ + версионировать через рестарт.** Отвергнуто: противоречит текущей + loading-model (cat из worktree), добавил бы прод-рестарт-зависимость, которой сейчас нет. + +## Последствия + +- **+** Петля 52 замкнута: схема 52c наполняется реальными данными на каждой стадии всех проектов. +- **+** Единый канон → предсказуемее выход агентов, проще сопровождение, дешевле будущие правки. +- **+** Применение без прод-рестарта (D6) — нулевой self-hosting-риск выкатки промптов. +- **−** Объём промптов вырастет (XML + few-shot). Митигейшн: ссылки вместо инлайна, контроль объёма + (NFR-4), структурный тест без жёсткого лимита строк. +- **−** Риск потери рабочей инструкции при рефакторе формы (R-1). Митигейшн: D5 (карта + тесты + + построчный review). +- **−** In-vivo самоприменение (D6) означает, что баг в новом промпте мог бы повлиять на reviewer/ + tester самой ORCH-077. Митигейшн: анти-регресс D5 + откат revert; вердикт-логика гейтов не зависит + от промпта (читается из frontmatter кодом). +- **Откат:** `git revert` PR — промпты возвращаются к свободной форме, схема перестаёт эмититься, + гейты работают идентично (machine-verdict ключи не менялись). Без миграций. + +## Ссылки +- BRD: `docs/work-items/ORCH-077/01-brd.md` +- TRZ: `docs/work-items/ORCH-077/02-trz.md` +- Acceptance: `docs/work-items/ORCH-077/03-acceptance-criteria.md` +- Tech-risks: `docs/work-items/ORCH-077/10-tech-risks.md` +- Сквозной ADR: `docs/architecture/adr/adr-0021-prompt-canon-anthropic.md` +- Стандарты эпика: `docs/_standards/PIPELINE_DOCS.md` (52b), `docs/_standards/HANDOFF_PROTOCOL.md` (52c), + `src/frontmatter.py::REQUIRED_FIELDS` +- Сверено по коду: `src/agents/launcher.py` (~297–323, ~577), `Dockerfile`, + `src/config.py::frontmatter_validation_strict`, `tests/test_agent_frontmatter_no_model.py` diff --git a/docs/work-items/ORCH-077/10-tech-risks.md b/docs/work-items/ORCH-077/10-tech-risks.md new file mode 100644 index 0000000..925b175 --- /dev/null +++ b/docs/work-items/ORCH-077/10-tech-risks.md @@ -0,0 +1,45 @@ +--- +work_item: ORCH-077 +stage: architecture +author_agent: architect +status: ready-for-review +created_at: 2026-06-09 +model_used: claude-opus-4-8 +--- + +# 10 — Технические риски: ORCH-077 — ORCH-52d: оптимизация 6 системных промптов по Anthropic + +Work Item: **ORCH-077** · Repo: **orchestrator** (self-hosting) · Стадия: architecture + +> Информационный (гейтом не парсится). Перечисляет риски реализации и митигейшн. +> Главный класс риска — **анти-регресс поведения агента прода**: промпт исполняется на КАЖДОЙ +> задаче ВСЕХ проектов (orchestrator + enduro-trails) из общего инстанса. + +## Реестр рисков + +| ID | Риск | Вер. | Влия. | Митигейшн | +|----|------|------|-------|-----------| +| TR-1 | **Регресс поведения агента**: при рефакторе формы потеряна рабочая инструкция → агент ломает выход для всех проектов | Сред. | Выс. | Построчная карта переноса (ADR D5) + структурные тесты `test_agent_prompts_canon.py` + построчный review против инвентаря TRZ §FR-6; in-vivo A/B (D6) | +| TR-2 | **Ложный гейт-провал**: случайно изменён регистр/имя/значения machine-verdict ключа (`verdict:`/`result:`/`staging_status:`/`deploy_status:`/`security_status:`) → парсер не находит вердикт | Низ. | Выс. | Эмиссия схемы строго аддитивна (ADR D2); структурный тест проверяет точный регистр ключей и значений; `frontmatter.parse_frontmatter` читает по имени (порядок неважен) | +| TR-3 | **Потеря self-hosting-запрета deployer'а**: пропал «не рестартить 8500 изнутри» / canonical `docker exec orchestrator-staging` / merge-guard `pr_already_merged` → агент роняет прод-конвейер всех проектов | Низ. | Крит. | deployer — самый строгий инвентарь §FR-6; отдельные структурные ассерты на 3 маркера; reviewer проверяет deployer построчно в первую очередь | +| TR-4 | **Раздувание промпта**: XML-канон + few-shot «утопят» ключевые запреты, агент их проигнорирует | Сред. | Сред. | Эталоны ссылкой, не инлайном (D3); контроль объёма (NFR-4); запреты — компактным списком ❌→✅ в `` | +| TR-5 | **Некорректный `model_used`**: захардкожена неверная модель вместо резолва ORCH-41 | Низ. | Низ. | Промпт ссылается на резолв ORCH-41 и таблицу README; текущее значение `claude-opus-4-8` для всех ролей; информационное поле (не гейт) | +| TR-6 | **Сломан frontmatter промпта**: правка тела случайно затронула YAML-шапку (`name`/`description`/`tools`) или вернула `model:` | Низ. | Сред. | `test_agent_frontmatter_no_model.py` остаётся зелёным (FR-7); правится только тело ниже frontmatter | +| TR-7 | **In-vivo самоприменение** (D6): дефект нового промпта влияет на reviewer/tester самой ORCH-077 | Низ. | Сред. | Вердикт-логика гейтов читается кодом из frontmatter, не зависит от текста промпта; анти-регресс D5; откат `git revert` | +| TR-8 | **Расползание scope в код**: соблазн «заодно» включить `frontmatter_validation_strict` или тронуть `src/` | Низ. | Выс. | AC-5 (git diff только `.openclaw/*`, `docs/**`, `CHANGELOG.md`, новые `tests/test_*`); ADR D7 фиксирует границу; reviewer проверяет diff | +| TR-9 | **Несогласованность `status` с machine-verdict**: например `status: ready` при `verdict: REQUEST_CHANGES` → путаница наблюдателя | Низ. | Низ. | Карта ADR D2 предписывает `status`, согласованный с вердиктом для вердикт-ролей; информационное поле, гейт не зависит | + +## Сводный вывод + +Доминирующий класс — **анти-регресс поведения агентов прода** (TR-1/TR-3), критичный из-за +self-hosting и общего инстанса. Изменение при этом **docs/prompts-only**, чисто текстовое, обратимое +`git revert` без миграций; loading-model (cat промпта из worktree, ADR D6) исключает прод-рестарт → +выкатка не несёт классического self-hosting-риска рестарта. + +**Эскалация `arch:major-change` НЕ требуется**: новых стадий/компонентов/QG/смены БД нет; +`STAGE_TRANSITIONS`/`QG_CHECKS`/`check_*`/схема БД не трогаются (BR-5). **Возврат в анализ НЕ +требуется**: ТЗ выполнимо в рамках принципов архитектуры. + +Остаточный риск для прод-конвейера — **низкий при соблюдении D5** (построчная карта + структурные +тесты + приоритетный review deployer/reviewer). Ключевое предписание исполнителю: рефакторить форму +**без потери ни одной функциональной строки**; при сомнении «перенести или выбросить» — переносить.