architect(ET): auto-commit from architect run_id=460
This commit is contained in:
@@ -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/<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`
|
||||
45
docs/work-items/ORCH-077/10-tech-risks.md
Normal file
45
docs/work-items/ORCH-077/10-tech-risks.md
Normal file
@@ -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); запреты — компактным списком ❌→✅ в `<constraints>` |
|
||||
| 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). Ключевое предписание исполнителю: рефакторить форму
|
||||
**без потери ни одной функциональной строки**; при сомнении «перенести или выбросить» — переносить.
|
||||
Reference in New Issue
Block a user