---
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/<role>.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. `<context>` — кто агент, проект orchestrator, стек, self-hosting; **обязательный первый пункт:
   «прочти `CLAUDE.md` и `docs/architecture/README.md` перед любым действием»**.
2. `<task>` — что делает роль на своей стадии; **допускается вложенная `<thinking>`-подсказка**
   (D4) для решающих ролей.
3. `<deliverables>` — какие файлы и куда роль создаёт через Write tool; ссылки на скелеты
   `docs/_templates/` и эталоны (D3).
4. `<constraints>` — запреты и обязательные правила; каждый запрет — с позитивной альтернативой (D3).
5. `<output_format>` — точный формат выходных документов: frontmatter-схема (D2) + machine-verdict
   ключи + success-criteria (FR-5).

Дополнительные семантические секции (`<success_criteria>`, `<escalation>`) допустимы ПОСЛЕ пяти
обязательных. **Обоснование порядка:** роль/контекст вперёд (приоритет интерпретации), формат вывода
последним (recency — лучшее следование схеме у Opus 4.8). Порядок — нормативный (структурный тест
проверяет наличие всех 5 тегов; см. test-plan).

### D2 — Аддитивная эмиссия схемы 52c, machine-verdict ключи неприкосновенны (BR-2/BR-4 / FR-2 / NFR-1)

Секция `<output_format>` каждого промпта **явно перечисляет 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 высокого качества); (в) каждый запрет в
`<constraints>` — в формате **«❌ не делай X → ✅ делай Y»** (литеральность Opus 4.8: позитивный
пример рядом с запретом снижает мисинтерпретацию). Эталоны даются **ссылкой**, не инлайном (контроль
объёма, R-4).

### D4 — Явное место для рассуждения (CoT/thinking) у решающих ролей (FR-4)

Роли, выносящие вердикт/классификацию, несут `<thinking>`-подсказку «сначала рассуди, потом пиши
вердикт» внутри `<task>`: **architect** (выбор решения), **reviewer** (APPROVED/REQUEST_CHANGES),
**tester** (PASS/FAIL/BLOCKED), **deployer** (трактовка exit-кодов, ORCH-061 waiver). Для механических
ролей (analyst/developer) — не обязательно. `<thinking>` — рассуждение агента, не часть выходного
документа.

### 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`
