Merge pull request 'ORCH-078 — ORCH-52e: трассировка ORCH-NNN (стандарт маркеров + правило чтения ADR)' (#95) from feature/ORCH-078-orch-52e-orch-nnn into main
Some checks failed
CI / test (push) Has been cancelled
Some checks failed
CI / test (push) Has been cancelled
This commit was merged in pull request #95.
This commit is contained in:
@@ -71,6 +71,12 @@ deploy-staging → deploy → done.
|
||||
- ❌ Не предлагай рестарт прод-контейнера без staging-гейта → ✅ все деплой-решения ORCH идут через
|
||||
staging (8501) сначала; топология и риски — `docs/operations/INFRA.md`.
|
||||
- ❌ Не используй Kubernetes / Helm / k8s / облако → ✅ Docker Compose.
|
||||
- ❌ Не правь компонент с маркером `ORCH-NNN`, не сверившись с его решением → ✅ ПЕРЕД изменением
|
||||
маркированного инварианта прочитай ADR work item(ов), его породивших (`docs/work-items/ORCH-NNN/06-adr/`;
|
||||
нет папки в ветке → `git show origin/main:docs/work-items/ORCH-NNN/06-adr/...`), и не сломай инвариант.
|
||||
- ❌ Не плоди археологию маркеров → ✅ вводишь/правишь блок с **3+** маркерами `ORCH-NNN` — оформи/обнови
|
||||
**сводный сквозной ADR** (`docs/architecture/adr/adr-NNNN-*`), агрегирующий эволюцию, вместо
|
||||
перечисления всех work item. Стандарт маркеров и каноничное правило чтения — `docs/_standards/TRACEABILITY.md`.
|
||||
</constraints>
|
||||
|
||||
<output_format>
|
||||
|
||||
@@ -27,6 +27,8 @@ tools:
|
||||
5. `docs/work-items/<plane-id>/04-test-plan.yaml`.
|
||||
6. `docs/work-items/<plane-id>/06-adr/` — как реализовать.
|
||||
7. Существующий код в `src/`, `tests/`.
|
||||
8. `docs/_standards/TRACEABILITY.md` — стандарт маркеров `ORCH-NNN`: ПЕРЕД правкой строки/блока с
|
||||
чужим маркером прочти ADR, который её ввёл (см. правило в `<constraints>`).
|
||||
</context>
|
||||
|
||||
<task>
|
||||
@@ -64,6 +66,12 @@ work item **ORCH-073** и **ORCH-088**.
|
||||
задним числом.
|
||||
- ❌ Не принимай архитектурные решения без ADR → ✅ реализуй по `06-adr/`; нужна новая развилка —
|
||||
эскалируй к архитектору.
|
||||
- ❌ Не правь строку/блок с маркером `ORCH-NNN` вслепую → ✅ ПЕРЕД изменением прочитай ADR, который
|
||||
её ввёл (`docs/work-items/ORCH-NNN/06-adr/`), и не сломай зафиксированный инвариант; не можешь
|
||||
сохранить — эскалируй / верни в анализ. Стандарт и каноничное правило — `docs/_standards/TRACEABILITY.md`.
|
||||
Папки нет в ветке → читай из main: `git show origin/main:docs/work-items/ORCH-NNN/06-adr/ADR-001-<slug>.md`
|
||||
(листинг — `git ls-tree origin/main:docs/work-items/ORCH-NNN/06-adr/`). Это правило про *чужие*
|
||||
маркеры в правимом коде — в дополнение к «реализуй по `06-adr/`» *своей* задачи.
|
||||
- ❌ Не коммить секреты (`.env`, токены) → ✅ секреты только в `.env`/`.env.staging` на хосте; канон —
|
||||
`.env.example`.
|
||||
- ❌ Не делай PR > 1500 строк без декомпозиции → ✅ разбивай на меньшие PR.
|
||||
|
||||
@@ -36,6 +36,10 @@ tools:
|
||||
выполнены?
|
||||
2. **Соответствие ADR** — реализация соответствует `06-adr/`? Нет нарушений глобальных ADR
|
||||
(`docs/architecture/adr/`)?
|
||||
- **Трассировка (`docs/_standards/TRACEABILITY.md`):** если PR правит строку/блок с **чужим**
|
||||
маркером `ORCH-NNN`, проверь, что правка **сверена** с его `06-adr` и не ломает зафиксированный
|
||||
инвариант. Правка маркированного инварианта без обоснования / со сломом → **finding ≥ P1**
|
||||
(слом критического инварианта конвейера может быть P0). Это усиление оси, а не отдельная ось.
|
||||
3. **Качество кода** — нет явных ошибок/утечек/security-дыр? Есть docstrings на публичных функциях?
|
||||
Тесты содержательные (не тривиальные)?
|
||||
4. **Документация — ОБЯЗАТЕЛЬНАЯ ПРОВЕРКА** (приоритет над остальным): если PR меняет `src/`
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
Формат: [Keep a Changelog](https://keepachangelog.com/). Записи — на смысловой PR/задачу.
|
||||
|
||||
## [Unreleased]
|
||||
- **Стандарт маркеров-трассировки `ORCH-NNN` + правило чтения ADR перед правкой** (ORCH-078 / ORCH-52e, `docs`): слой 4 (трассировка) эпика ORCH-52, замыкающий цепочку 52b (структура) / 52c (frontmatter) / 52d (промпты). Маркеры `ORCH-NNN`/`ET-NNN` в коде (де-факто 51 уникальный в `src/`) привязывают нетривиальные инварианты к породившему их work item — была сложившаяся практика без формального контракта. **Docs + prompts-only:** `src/**`, `STAGE_TRANSITIONS`, `QG_CHECKS`, `check_*`/`_parse_*`, `src/frontmatter.py`, схема БД — **не тронуты**; `frontmatter_validation_strict` остаётся `False`; новый QG не вводится; массовый ретро-фит 51 маркера вне объёма (стандарт нормативен «на будущее»).
|
||||
- **Новый стандарт `docs/_standards/TRACEABILITY.md`** (рядом с `PIPELINE_DOCS.md`/`HANDOFF_PROTOCOL.md`): формат маркера, правило размещения (рядом с нетривиальным инвариантом), чтение истории с реальным проверяемым примером (`src/serial_gate.py` → ORCH-088 → `ADR-001-serial-gate.md`), fallback-доступ (`git show origin/main:docs/work-items/...`), анти-археология (3+ маркеров → сводный сквозной ADR), каноничный текст правила чтения (единый источник).
|
||||
- **Точечные врезки в промпты (аддитивно, 52d-канон не переписан):** `developer.md` — правило чтения чужого маркера + fallback («❌ X → ✅ Y»); `architect.md` — правило чтения + анти-археология (3+ → сквозной ADR); `reviewer.md` — усиление оси «Соответствие ADR» под-пунктом «правка маркированного кода сверена с ADR; слом → finding ≥P1». Все три **ссылаются** на единый текст в `TRACEABILITY.md`, не копируют (анти-дубль BR-6).
|
||||
- **Сопутствующе:** `CLAUDE.md` (правило трассировки + ссылка), `docs/architecture/README.md` (слой 4 эпика 52), сквозной `adr-0022` + per-work-item `ORCH-078/06-adr/ADR-001`. **Анти-регресс:** расширен `tests/test_agent_prompts_canon.py` (наличие правила/ссылок в 3 промптах, существование примера в стандарте); проверки 52d (5 секций, 6 полей, регистр verdict-ключей) и `test_agent_frontmatter_no_model.py` остаются зелёными. Полностью обратимо `git revert` (нет машинного поведения/состояния/kill-switch).
|
||||
- **Канон Anthropic для 6 системных промптов + добровольная эмиссия frontmatter-схемы 52c** (ORCH-077 / ORCH-52d, `docs`): замыкающий слой эпика ORCH-52. 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 обязательных секций, нормативный порядок):** `<context>` → `<task>` (+ опц. `<thinking>` у решающих ролей: architect/reviewer/tester/deployer) → `<deliverables>` → `<constraints>` (запреты «❌ X → ✅ Y») → `<output_format>`. Доп. секции (`<success_criteria>`/`<escalation>`) — после пяти обязательных.
|
||||
- **Аддитивная схема 52c:** `<output_format>` каждого промпта перечисляет 6 полей (`work_item`/`stage`/`author_agent`/`status`/`created_at`/`model_used`) с роле-специфичными значениями (`stage`/`author_agent` по карте ролей; `model_used: claude-opus-4-8` по резолву ORCH-41) и ставит их **рядом** с machine-verdict ключом, **не меняя его имя/регистр/значения** (`verdict:` `APPROVED|REQUEST_CHANGES`; `result:` `PASS|FAIL`; `staging_status:`/`deploy_status:` `SUCCESS|FAILED`; `security_status:` `PASS|FAIL`). Для `04-test-plan.yaml` — top-level YAML-ключи. Гейты читают вердикты 1:1 как раньше (NFR-1).
|
||||
|
||||
@@ -133,6 +133,10 @@ created → analysis → architecture → development → review → testing →
|
||||
6. **Reviewer проверяет: обновлена ли документация. Нет → REQUEST_CHANGES.**
|
||||
7. Не использовать `--no-verify` без явного одобрения Owner.
|
||||
8. Секреты — только в `.env`/`.env.staging` на хосте, в гит НЕ коммитятся (канон — `.env.example`).
|
||||
9. **Трассировка маркеров (ORCH-078, ORCH-52e):** правишь строку/блок с маркером `ORCH-NNN` →
|
||||
ПЕРЕД изменением прочитай его `docs/work-items/ORCH-NNN/06-adr/` и не сломай зафиксированный
|
||||
инвариант; блок с 3+ маркерами → опирайся на сводный сквозной ADR. Стандарт маркеров (формат,
|
||||
размещение, fallback-доступ, анти-археология, каноничное правило чтения) — `docs/_standards/TRACEABILITY.md`.
|
||||
|
||||
## ⚠️ Self-hosting — оркестратор правит САМ СЕБЯ
|
||||
Задачи проекта ORCH меняют инструмент, который СЕЙЧАС работает в продакшене и обслуживает ДРУГИЕ проекты (enduro-trails) из ОДНОГО инстанса с ОБЩЕЙ БД и общей очередью.
|
||||
|
||||
147
docs/_standards/TRACEABILITY.md
Normal file
147
docs/_standards/TRACEABILITY.md
Normal file
@@ -0,0 +1,147 @@
|
||||
# TRACEABILITY — стандарт маркеров-трассировки `ORCH-NNN` (golden source трассировки)
|
||||
|
||||
> **Назначение.** Единый нормативный контракт: как нетривиальная строка/блок/инвариант в коде
|
||||
> привязывается к work item, который его ввёл, и к его архитектурному решению (ADR). Это **слой 4
|
||||
> (трассировка)** эпика **ORCH-52** — рядом с `PIPELINE_DOCS.md` (слой 1, структура документов) и
|
||||
> `HANDOFF_PROTOCOL.md` (слой 2, машинный frontmatter-контракт).
|
||||
>
|
||||
> **Статус истины.** Документ **кодифицирует сложившуюся практику**, а не вводит новый синтаксис.
|
||||
> Источник истины о *поведении* остаётся код (`src/stages.py`, `src/qg/checks.py`,
|
||||
> `src/stage_engine.py`); этот стандарт — описательно-нормативный, **не машинный гейт конвейера**.
|
||||
> Соблюдение держится на дисциплине агентов + оси ревью (`reviewer.md`), а не на CI-lint.
|
||||
|
||||
Введён задачей **ORCH-078** (ORCH-52e). Сквозной ADR:
|
||||
[`docs/architecture/adr/adr-0022-traceability-marker-standard.md`](../architecture/adr/adr-0022-traceability-marker-standard.md);
|
||||
детально — `docs/work-items/ORCH-078/06-adr/ADR-001-traceability-marker-standard.md`. Продолжает
|
||||
цепочку стандартов эпика 52: adr-0019 (52b), adr-0020 (52c), adr-0021 (52d).
|
||||
|
||||
---
|
||||
|
||||
## 1. Назначение и определение
|
||||
|
||||
**Маркер `ORCH-NNN`** (а для проекта enduro-trails — `ET-NNN`) в коде = обязательный стандарт
|
||||
трассировки: он привязывает нетривиальную строку / блок / инвариант к work item, который его ввёл,
|
||||
и к его ADR. Это даёт читающему агенту прямой путь «строка кода → решение, которое её породило»,
|
||||
вместо `git blame`-археологии.
|
||||
|
||||
**Факт (сверено на 2026-06-09):** в `src/` де-факто живёт **51 уникальный** маркер `ORCH-NNN`
|
||||
(`grep -rhoE 'ORCH-[0-9]+' src/ | sort -u | wc -l` → `51`) — сложившаяся практика. Этот стандарт её
|
||||
формализует. **Массовый ретро-фит существующих 51 маркера вне объёма** — стандарт нормативен «на
|
||||
будущее»: его правила применяются к **новому и правимому** коду.
|
||||
|
||||
---
|
||||
|
||||
## 2. Формат маркера
|
||||
|
||||
Маркер — это **inline-комментарий** (или фрагмент docstring модуля/функции), содержащий идентификатор
|
||||
work item `ORCH-NNN`. Рекомендуется рядом указывать ссылку на конкретное решение в ADR, чтобы трасса
|
||||
вела не просто к задаче, а к пункту решения:
|
||||
|
||||
```python
|
||||
# Ordering term — ``t2.id < jobs.task_id`` (FIFO, ORCH-088, ADR-001 D1 / FR-2): a task
|
||||
# does not enter `analysis` while an earlier unfinished task exists in the same repo.
|
||||
```
|
||||
|
||||
Нового синтаксиса не вводится — кодифицируется уже сложившийся стиль (`ORCH-NNN[, ADR-001 D1]`).
|
||||
|
||||
---
|
||||
|
||||
## 3. Где ставится маркер
|
||||
|
||||
Маркер ставится рядом с **нетривиальным инвариантом**, понимание которого требует контекста решения:
|
||||
|
||||
- выбор fail-open / fail-closed поведения;
|
||||
- точное условие сериализации / упорядочивания (FIFO, lease, барьер);
|
||||
- идемпотентность / защита от повторной обработки;
|
||||
- обходимая «дыра» конвейера, которую блок закрывает;
|
||||
- любое условие, чьё «почему именно так» зафиксировано в ADR.
|
||||
|
||||
Маркер **НЕ ставится** на тривиальном/самоочевидном коде (геттеры, простые присваивания, очевидные
|
||||
проверки) — это только зашумляет.
|
||||
|
||||
**Правило для нового кода:** вводишь значимый инвариант → ставь маркер своей задачи (`ORCH-NNN`)
|
||||
рядом, по возможности со ссылкой на пункт ADR.
|
||||
|
||||
---
|
||||
|
||||
## 4. Как читать историю (с реальным проверяемым примером)
|
||||
|
||||
Пошагово, от строки кода к решению:
|
||||
|
||||
1. Видишь в коде маркер `ORCH-NNN` у строки/блока, который собираешься менять.
|
||||
2. Открываешь его архитектурное решение: `docs/work-items/ORCH-NNN/06-adr/`.
|
||||
3. Читаешь зафиксированный инвариант ПЕРЕД правкой; не ломаешь его (см. §7).
|
||||
|
||||
**Проверяемый пример из реального кода (`main`):**
|
||||
|
||||
> `src/serial_gate.py` несёт условие сериализации `t2.id < jobs.task_id` с маркером **ORCH-088**
|
||||
> и отсылкой `ADR-001 D1 / FR-2` (FIFO-уточнение serial-gate). Чтобы понять, почему задача не входит
|
||||
> в `analysis`, пока в репо есть более ранняя незавершённая задача, читаешь:
|
||||
> `docs/work-items/ORCH-088/06-adr/ADR-001-serial-gate.md`.
|
||||
|
||||
Пример ссылается на **реально существующие** в `main` файл и ADR — иначе стандарт опровергал бы сам
|
||||
себя (нерабочая трассировка).
|
||||
|
||||
---
|
||||
|
||||
## 5. Fallback-доступ к чужому ADR
|
||||
|
||||
Папки `docs/work-items/ORCH-NNN/` может **не быть в текущей ветке** (она срезана от `main` без неё —
|
||||
типично для ветки другой задачи). Штатный способ прочитать чужой ADR — взять его из `origin/main`:
|
||||
|
||||
```bash
|
||||
git fetch origin # при необходимости заранее
|
||||
git ls-tree origin/main:docs/work-items/ORCH-NNN/06-adr/ # листинг доступных ADR
|
||||
git show origin/main:docs/work-items/ORCH-NNN/06-adr/ADR-001-<slug>.md # прочитать конкретный
|
||||
```
|
||||
|
||||
Это не блокер: отсутствие папки в ветке ≠ отсутствие решения — оно всегда есть в `main`.
|
||||
|
||||
---
|
||||
|
||||
## 6. Анти-археология: 3+ маркеров → сводный сквозной ADR
|
||||
|
||||
Если функция/блок несёт **3+** маркеров `ORCH-NNN` (эволюционировал через много задач), раскопки по
|
||||
каждому work item нечитаемы. Вместо перечисления всех задач ставится **одна сводная ссылка на
|
||||
сквозной ADR** (`docs/architecture/adr/adr-NNNN-*`), агрегирующий эволюцию.
|
||||
|
||||
Числовой порог `3` — граница, за которой inline-перечисление перестаёт быть читаемым (один-два
|
||||
маркера ещё информативны, три и больше — уже археология).
|
||||
|
||||
**Пример из кода:** `src/merge_gate.py` несёт маркеры ORCH-043/065/071/073 (и ещё несколько) →
|
||||
читать сводные сквозные `adr-0006` (merge-gate), `adr-0013` (merge-verify-gate),
|
||||
`adr-0014` (sha-source-of-truth), `adr-0016` (ensure-open-PR) в `docs/architecture/adr/`, а не 8
|
||||
отдельных work item.
|
||||
|
||||
Это конвенция для **нового/правимого** блока; массовая переразметка существующих файлов вне объёма.
|
||||
|
||||
---
|
||||
|
||||
## 7. Правило чтения (каноничная формулировка — единый источник)
|
||||
|
||||
Это **единственное** место, где живёт каноничный текст правила. Промпты агентов
|
||||
(`developer.md`/`architect.md`/`reviewer.md`) **ссылаются** на него, а не копируют — чтобы не было
|
||||
дрейфа формулировок между файлами.
|
||||
|
||||
> **Правишь код с маркером `ORCH-NNN` → прочитай его `docs/work-items/ORCH-NNN/06-adr/` ПЕРЕД
|
||||
> изменением; не сломай зафиксированный инвариант. Не можешь сохранить инвариант — эскалируй /
|
||||
> верни задачу в анализ, не правь вслепую.** Папки нет в ветке → читай из `origin/main` (§5). Блок
|
||||
> несёт 3+ маркеров → опирайся на сводный сквозной ADR (§6).
|
||||
|
||||
Кто и как применяет правило:
|
||||
|
||||
- **developer / architect** — обязаны выполнить чтение ПЕРЕД правкой маркированного кода.
|
||||
- **architect** — при введении/правке блока с 3+ маркерами оформляет/обновляет сводный сквозной ADR.
|
||||
- **reviewer** — проверяет соблюдение: правка маркированного (`ORCH-NNN`) кода без сверки с его ADR
|
||||
или со сломом инварианта → finding (рекомендуемая severity **P1**; слом критического инварианта
|
||||
конвейера — на усмотрение reviewer вплоть до P0).
|
||||
|
||||
---
|
||||
|
||||
## Связи
|
||||
|
||||
- Сквозной ADR: [`adr-0022`](../architecture/adr/adr-0022-traceability-marker-standard.md).
|
||||
- Стандарты-соседи: [`PIPELINE_DOCS.md`](PIPELINE_DOCS.md) (слой 1),
|
||||
[`HANDOFF_PROTOCOL.md`](HANDOFF_PROTOCOL.md) (слой 2).
|
||||
- Цепочка эпика 52: adr-0019 (52b) / adr-0020 (52c) / adr-0021 (52d) / adr-0022 (52e).
|
||||
- Прецедент класса ошибки (слом инварианта без чтения ADR): `docs/history/LESSONS_2026-06-08_phantom-merge.md`.
|
||||
@@ -83,6 +83,26 @@ enforcement не включается).
|
||||
- ADR: [adr-0021](adr/adr-0021-prompt-canon-anthropic.md); детально —
|
||||
`docs/work-items/ORCH-077/06-adr/ADR-001-anthropic-prompt-canon.md`.
|
||||
|
||||
#### Слой трассировки: стандарт маркеров `ORCH-NNN` (ORCH-078, 52e — слой 4 эпика 52)
|
||||
**Слой 4 (трассировка).** Маркеры `ORCH-NNN`/`ET-NNN` в коде (де-факто **51 уникальный** в `src/`)
|
||||
привязывают нетривиальные инварианты к породившему их work item, но это была **сложившаяся практика
|
||||
без формального контракта**. ORCH-078 кодифицирует её как нормативный стандарт
|
||||
[`docs/_standards/TRACEABILITY.md`](../_standards/TRACEABILITY.md) (рядом с `PIPELINE_DOCS.md` и
|
||||
`HANDOFF_PROTOCOL.md`) и точечно дополняет 3 промпта правилом чтения. Это **docs/prompts-only**
|
||||
изменение: `src/**`, `STAGE_TRANSITIONS`, `QG_CHECKS`, схема БД — **не трогаются**; стандарт —
|
||||
описательно-нормативный, **не машинный гейт** (массовый ретро-фит 51 маркера вне объёма).
|
||||
- **Каноничное правило чтения (единый источник):** правишь код с маркером `ORCH-NNN` → прочитай его
|
||||
`06-adr` ПЕРЕД изменением, не сломай инвариант. Промпты `developer`/`architect`/`reviewer`
|
||||
**ссылаются** на текст в `TRACEABILITY.md`, а не копируют его (нет дрейфа между файлами).
|
||||
- **Fallback-доступ:** папки `docs/work-items/ORCH-NNN/` нет в ветке → `git show origin/main:...`.
|
||||
- **Анти-археология:** блок с **3+** маркерами → одна сводная ссылка на сквозной ADR
|
||||
(`docs/architecture/adr/`) вместо перечисления всех work item.
|
||||
- **Контроль:** reviewer ловит правку маркированного кода без сверки с ADR → finding ≥P1.
|
||||
- **Анти-регресс:** расширенный `tests/test_agent_prompts_canon.py` (наличие правила/ссылок); канон
|
||||
52d (5 секций, 6 полей, регистр verdict-ключей) и `test_agent_frontmatter_no_model.py` зелёные.
|
||||
- ADR: [adr-0022](adr/adr-0022-traceability-marker-standard.md); детально —
|
||||
`docs/work-items/ORCH-078/06-adr/ADR-001-traceability-marker-standard.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_<AGENT>`/`ORCH_AGENT_EFFORT_<AGENT>` > `*_default` > CLI-дефолт (без флага)**. **Эффорт (ORCH-081):** ниже `*_default` добавлен непустой **per-role floor** — class-default поля `agent_effort_<role>` из `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`.
|
||||
|
||||
|
||||
106
docs/architecture/adr/adr-0022-traceability-marker-standard.md
Normal file
106
docs/architecture/adr/adr-0022-traceability-marker-standard.md
Normal file
@@ -0,0 +1,106 @@
|
||||
---
|
||||
work_item: ORCH-078
|
||||
stage: architecture
|
||||
author_agent: architect
|
||||
status: proposed
|
||||
created_at: 2026-06-09
|
||||
model_used: claude-opus-4-8
|
||||
---
|
||||
|
||||
# adr-0022: Стандарт маркеров-трассировки `ORCH-NNN` + правило чтения ADR перед правкой
|
||||
|
||||
- **Статус:** proposed
|
||||
- **Дата:** 2026-06-09
|
||||
- **Источник:** ORCH-078 (эпик ORCH-52, слой 52e — трассировка, слой 4)
|
||||
- **Связи:** продолжает цепочку стандартов эпика 52 — adr-0019 (52b, `PIPELINE_DOCS.md`),
|
||||
adr-0020 (52c, frontmatter-контракт), adr-0021 (52d, канон промптов). Детально —
|
||||
`docs/work-items/ORCH-078/06-adr/ADR-001-traceability-marker-standard.md`.
|
||||
|
||||
## Контекст
|
||||
|
||||
Эпик ORCH-52 строит сквозной контракт документации конвейера: **52b** (adr-0019) — описательный
|
||||
стандарт документов + скелеты; **52c** (adr-0020) — машинный frontmatter-контракт + `HANDOFF_PROTOCOL.md`;
|
||||
**52d** (adr-0021) — 6 промптов в каноне Anthropic + добровольная эмиссия 52c-схемы. Закрыты слои
|
||||
структуры (52b), машинного вердикта (52c) и формы промптов (52d), но **слой трассировки кода к
|
||||
решениям не формализован**.
|
||||
|
||||
Факты, сверенные с кодом `main`:
|
||||
- В `src/` живёт **51 уникальный** маркер `ORCH-NNN` (`grep -rhoE 'ORCH-[0-9]+' src/ | sort -u | wc -l`),
|
||||
привязывающий нетривиальные инварианты к породившему их work item — **сложившаяся практика без
|
||||
формального стандарта** (`docs/_standards/` несёт лишь `PIPELINE_DOCS.md`/`HANDOFF_PROTOCOL.md`).
|
||||
- Высокая плотность: `config.py`=63, `stage_engine.py`=55, `agents/launcher.py`=50, `plane_sync.py`=48,
|
||||
`merge_gate.py`=26 вхождений.
|
||||
|
||||
Три незакрытые проблемы:
|
||||
1. **Нет правила чтения.** Агент, правя маркированную строку, не обязан прочитать ADR, который её
|
||||
ввёл → риск молча сломать инвариант. Это класс «фантомного merge»
|
||||
(`docs/history/LESSONS_2026-06-08_phantom-merge.md`), породившего ORCH-071/073.
|
||||
2. **Reviewer не контролирует соблюдение** — ось «Соответствие ADR» проверяет ADR текущей задачи, не
|
||||
сверку правки чужого маркированного кода с его ADR.
|
||||
3. **Анти-археология** — блок с 50+ маркерами = раскопки по 4+ work item.
|
||||
|
||||
## Решение
|
||||
|
||||
Ввести **нормативный стандарт маркеров-трассировки** `docs/_standards/TRACEABILITY.md` (слой 4 эпика
|
||||
52) и точечно дополнить промпты правилом чтения / контролем соблюдения **со ссылкой на единый
|
||||
источник**. Это **docs + prompts-only**, нулевое касание кода; стандарт — описательно-нормативный
|
||||
документ + анти-регресс-тест промптов, **не машинный гейт конвейера**.
|
||||
|
||||
1. **`TRACEABILITY.md`** кодифицирует существующий контракт (не вводит новый синтаксис): определение
|
||||
маркера, формат (inline-комментарий, рекомендуется ссылка на решение), правило размещения (рядом с
|
||||
нетривиальным инвариантом), чтение истории **с реальным проверяемым примером**
|
||||
(`src/serial_gate.py` → ORCH-088 → `ADR-001-serial-gate.md`), fallback-доступ, анти-археология,
|
||||
каноничный текст правила чтения.
|
||||
2. **Единый источник истины правила.** Каноничная формулировка живёт только в `TRACEABILITY.md`;
|
||||
промпты несут короткую врезку-**ссылку**, не копию → нет дрейфа между файлами (анти-дубль 52d).
|
||||
3. **Точечные врезки (аддитивно, 52d-канон не переписывается):** `developer.md` — правило чтения +
|
||||
fallback-доступ («❌ X → ✅ Y»); `architect.md` — правило чтения + анти-археология; `reviewer.md` —
|
||||
усиление оси «Соответствие ADR» под-пунктом «правка маркированного кода сверена с его ADR; слом →
|
||||
finding ≥P1».
|
||||
4. **Анти-археология:** блок с **≥3** маркерами → одна сводная ссылка на сквозной ADR
|
||||
(`docs/architecture/adr/`) вместо перечисления всех work item. Пример: `src/merge_gate.py` →
|
||||
`adr-0006/0013/0014/0016`.
|
||||
5. **Fallback-доступ:** `git show origin/main:docs/work-items/ORCH-NNN/06-adr/ADR-001-<slug>.md` —
|
||||
когда папки нет в текущей ветке.
|
||||
6. **Анти-регресс машинно:** расширение `tests/test_agent_prompts_canon.py` (tests-only) — утверждает
|
||||
присутствие reading-rule/`TRACEABILITY`-маркеров; существующие проверки 52d и
|
||||
`test_agent_frontmatter_no_model.py` остаются зелёными.
|
||||
|
||||
**Границы:** `src/**`, `STAGE_TRANSITIONS`, `QG_CHECKS`, `check_*`, `_parse_*`, `src/frontmatter.py`,
|
||||
схема БД — **не трогаются**. `frontmatter_validation_strict` остаётся `False`; новый QG не вводится.
|
||||
Массовый ретро-фит 51 существующего маркера **вне объёма** — стандарт действует «на будущее».
|
||||
|
||||
**Норматив на будущее:** новый/правимый значимый инвариант → ставь маркер своей задачи рядом; блок с
|
||||
3+ маркерами → сводный сквозной ADR; правка чужого маркера → читай его `06-adr` до изменения.
|
||||
|
||||
## Альтернативы
|
||||
|
||||
- **Машинный гейт/CI-lint маркеров.** Отвергнуто: правка `src/`/CI вне scope; для self-hosting
|
||||
рискованно (ложный fail валит конвейер всех проектов); премэйчур до описательного стандарта.
|
||||
Enforcement — потенциальная будущая задача (как hard-fail схемы в adr-0021).
|
||||
- **Массовый ретро-фит 51 маркера.** Отвергнуто: огромный диф, риск регресса смысла, вне объёма.
|
||||
- **Копировать правило в каждый промпт.** Отвергнуто: дрейф между файлами, нарушение анти-дубль.
|
||||
- **Только per-work-item ADR без глобального.** Отвергнуто: рвёт цепочку эпика 52 (52b/c/d имеют
|
||||
глобальный ADR); нет точки входа для будущих агентов.
|
||||
|
||||
## Последствия
|
||||
|
||||
- **+** Замкнут слой 4 эпика 52: практика маркеров формализована, правило чтения защищает от слома
|
||||
инвариантов; reviewer получает ось контроля.
|
||||
- **+** Единый источник правила → нет дрейфа; обновление в одном файле.
|
||||
- **+** Self-hosting без рестарта: промпт `cat`-ается из worktree → правило действует на следующем
|
||||
worktree от `main` без рестарта 8500.
|
||||
- **+** Полная обратимость: чисто текстовое изменение, нет миграций/состояния/kill-switch.
|
||||
- **−** Рост объёма 3 промптов (митигейшн: короткие врезки-ссылки).
|
||||
- **−** Стандарт нормативен, но не enforced машинно → соблюдение на дисциплине + ревью (осознанный
|
||||
компромисс).
|
||||
- **Откат:** `git revert` PR — стандарт удаляется, врезки исчезают, поведение кода/гейтов идентично.
|
||||
|
||||
## Связи
|
||||
- Продолжает: adr-0019 (52b), adr-0020 (52c), adr-0021 (52d).
|
||||
- Per-work-item: `docs/work-items/ORCH-078/06-adr/ADR-001-traceability-marker-standard.md`.
|
||||
- Стандарты-соседи: `docs/_standards/PIPELINE_DOCS.md`, `docs/_standards/HANDOFF_PROTOCOL.md`,
|
||||
будущий `docs/_standards/TRACEABILITY.md` (создаёт стадия development).
|
||||
- Сверено по коду: `src/serial_gate.py:241,269` (ORCH-088), `src/merge_gate.py` (26 маркеров),
|
||||
`tests/test_agent_prompts_canon.py`, `.openclaw/agents/{developer,architect,reviewer}.md`.
|
||||
- Прецедент класса ошибки: `docs/history/LESSONS_2026-06-08_phantom-merge.md`.
|
||||
7
docs/work-items/ORCH-078/00-business-request.md
Normal file
7
docs/work-items/ORCH-078/00-business-request.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Business Request: ORCH-52e: трассировка ORCH-NNN (маркеры-стандарт + правило чтения)
|
||||
|
||||
Work Item ID: ORCH-078
|
||||
|
||||
## Description
|
||||
|
||||
TBD
|
||||
142
docs/work-items/ORCH-078/01-brd.md
Normal file
142
docs/work-items/ORCH-078/01-brd.md
Normal file
@@ -0,0 +1,142 @@
|
||||
---
|
||||
work_item: ORCH-078
|
||||
stage: analysis
|
||||
author_agent: analyst
|
||||
status: ready-for-review
|
||||
created_at: 2026-06-09
|
||||
model_used: claude-opus-4-8
|
||||
---
|
||||
|
||||
# 01 — BRD (бизнес-требования): ORCH-078 — ORCH-52e: трассировка ORCH-NNN (маркеры-стандарт + правило чтения)
|
||||
|
||||
Work Item: **ORCH-078** · Repo: **orchestrator** (self-hosting) · Стадия: analysis
|
||||
|
||||
## 1. Бизнес-контекст и проблема
|
||||
|
||||
Эпик **ORCH-52** формализует «golden source» документации конвейера слоями:
|
||||
- **52b** (ORCH-075) — стандарт структуры документов `docs/_standards/PIPELINE_DOCS.md` + скелеты `docs/_templates/`.
|
||||
- **52c** (ORCH-076) — машинный frontmatter-контракт `src/frontmatter.py` + спека handoff `docs/_standards/HANDOFF_PROTOCOL.md`.
|
||||
- **52d** (ORCH-077) — 6 системных промптов переписаны в каноне Anthropic + эмиссия 52c-схемы.
|
||||
|
||||
**52e — слой 4 (трассировка).** В коде `src/` де-факто живёт **51 уникальный маркер** `ORCH-NNN`
|
||||
(проверено `grep -rhoE 'ORCH-[0-9]+' src/ | sort -u | wc -l`), привязывающий нетривиальные строки/
|
||||
инварианты к work item, который их ввёл (напр. `src/serial_gate.py` несёт `t2.id < jobs.task_id`
|
||||
с маркером ORCH-088; `src/merge_gate.py` — ORCH-043/065/071/073). Это **сложившаяся практика без
|
||||
формального стандарта**: `docs/_standards/` содержит только `PIPELINE_DOCS.md` и
|
||||
`HANDOFF_PROTOCOL.md` — стандарта маркеров-трассировки НЕТ.
|
||||
|
||||
**Боль, которую закрывает 52e:**
|
||||
1. **Нет правила чтения.** Агент (developer/architect), правя маркированную строку, не обязан
|
||||
прочитать ADR work item, который её ввёл, → риск молча сломать зафиксированный инвариант
|
||||
(класс ошибки «фантомный merge», постмортем `docs/history/LESSONS_2026-06-08_phantom-merge.md`,
|
||||
из-за которого появились ORCH-071/073). Маркер должен означать «здесь есть зафиксированное
|
||||
решение — прочти его прежде, чем менять».
|
||||
2. **Reviewer не проверяет соблюдение.** Reviewer-промпт проверяет ADR-соответствие *текущей*
|
||||
задачи, но не контролирует, что правка чужого маркированного кода свелась с его ADR.
|
||||
3. **Анти-археология.** Файлы с высокой плотностью маркеров (`config.py`=60, `stage_engine.py`=55,
|
||||
`launcher.py`=49, `plane_sync.py`=47, `merge_gate.py`=26 вхождений) превращают понимание блока
|
||||
в раскопки по 4+ work item. Нужна конвенция: блок с 3+ маркерами ссылается на **один сквозной
|
||||
ADR** (`docs/architecture/adr/`) вместо перечисления всех.
|
||||
4. **Доступ к чужому work item.** Папка `docs/work-items/ORCH-NNN/06-adr/` может отсутствовать в
|
||||
текущей ветке (срезана от `main` без неё) — нужен задокументированный fallback
|
||||
`git show origin/main:docs/work-items/ORCH-NNN/06-adr/...`.
|
||||
|
||||
**⚠️ Что УЖЕ сделано в 52d (анти-дубль, проверено в `main`):** промпты `developer.md`/`architect.md`
|
||||
упоминают `ORCH-NNN`/`06-adr`, но **только** как (а) ADR *текущей* задачи («реализуй по `06-adr/`»),
|
||||
(б) именование веток `feature/ORCH-NNN-slug`, (в) поля frontmatter-схемы. **Правила «правишь
|
||||
маркированный код → читай его ADR перед изменением» среди них НЕТ** (проверено
|
||||
`grep -nE 'ORCH-NNN|06-adr|маркер'`). Поэтому 52e **не переписывает промпты** и **не дублирует**
|
||||
52d — он добавляет именно отсутствующее правило, точечно, сохраняя XML-канон 52d.
|
||||
|
||||
## 2. Объём (scope)
|
||||
|
||||
### В объёме
|
||||
- Формальный **стандарт маркеров-трассировки** `docs/_standards/TRACEABILITY.md`: что такое маркер,
|
||||
формат, где ставится, как читать историю (с реальным примером из кода), fallback-доступ,
|
||||
анти-археология.
|
||||
- **Правило чтения** «правишь код с маркером `ORCH-NNN` → прочитай его `06-adr` ПЕРЕД правкой, не
|
||||
сломай инвариант» — точечно добавить в `developer.md` и `architect.md` (где 52d его не покрыла).
|
||||
- **Контроль соблюдения** — точечно добавить в `reviewer.md` ось «правка маркированного кода
|
||||
сверена с его ADR».
|
||||
- **Fallback-доступ** `git show origin/main:docs/work-items/ORCH-NNN/...` — задокументировать в
|
||||
стандарте и в developer-промпте.
|
||||
- **Анти-археология** «3+ маркеров в блоке → сводная ссылка на сквозной ADR» — зафиксировать в
|
||||
стандарте и в architect/reviewer-промптах.
|
||||
- Обновление `CLAUDE.md`, `docs/architecture/README.md`, `CHANGELOG.md`; анти-регресс-тест промптов.
|
||||
|
||||
### Вне объёма
|
||||
- **Массовый ретро-фит маркеров** в существующий код (≥51 маркер уже есть — не трогаем; стандарт
|
||||
действует «на будущее»).
|
||||
- **Любое изменение `src/**`**, в т.ч. гейтов, `STAGE_TRANSITIONS`, `QG_CHECKS`, `check_*`,
|
||||
`_parse_*`, схемы БД.
|
||||
- **Полная перезапись промптов** — 52d уже дал канон; 52e лишь точечно дополняет.
|
||||
- Включение `frontmatter_validation_strict` / любого enforcement.
|
||||
|
||||
## 3. Заинтересованные стороны
|
||||
- **Owner (Слава)** — заказчик эпика ORCH-52; ручной BRD-гейт (Approved) этой задачи. Лейбл
|
||||
`autoDeploy` (орк сам деплоит после staging), BRD-гейт — ручной.
|
||||
- **Агенты developer/architect** — потребители правила чтения (получают защиту от слома инвариантов).
|
||||
- **Агент reviewer** — получает явную ось контроля соблюдения трассировки.
|
||||
- **Self-hosting** — промпты `cat`-аются из worktree в момент запуска → правило вступает в силу на
|
||||
следующем worktree от `main` без прод-рестарта (групповой риск не возникает).
|
||||
|
||||
## 4. Бизнес-требования (BR)
|
||||
|
||||
- **BR-1** — В `docs/_standards/` создан формальный стандарт маркеров-трассировки (`TRACEABILITY.md`):
|
||||
определение маркера `ORCH-NNN`, формат, правило размещения (рядом с нетривиальным инвариантом, не
|
||||
на тривиальном коде), способ чтения истории — с **реальным, проверяемым примером из кода**
|
||||
(маркер в `src/` → конкретный `docs/work-items/ORCH-NNN/06-adr/...`).
|
||||
- **BR-2** — Правило «правишь код с маркером `ORCH-NNN` → прочитай `docs/work-items/ORCH-NNN/06-adr`
|
||||
ПЕРЕД изменением, не сломай инвариант» присутствует в `developer.md` и `architect.md`. Если 52d
|
||||
частично покрыла смежное — **ссылаться/усилить, не повторять** (BR-5).
|
||||
- **BR-3** — Reviewer-промпт **проверяет соблюдение** правила: правка чужого маркированного кода без
|
||||
сверки с его ADR / со сломом инварианта → finding с severity.
|
||||
- **BR-4** — Задокументирован fallback-доступ к чужому work item:
|
||||
`git show origin/main:docs/work-items/ORCH-NNN/06-adr/...` (когда папки нет в текущей ветке).
|
||||
- **BR-5** — Анти-археология: конвенция «функция/блок несёт 3+ маркеров → сводная ссылка на сквозной
|
||||
ADR (`docs/architecture/adr/`) вместо раскопок по каждому» зафиксирована в стандарте.
|
||||
- **BR-6 (АНТИ-ДУБЛЬ)** — 52e НЕ дублирует уже сделанное 52d. Там, где 52d уже задаёт смежное
|
||||
поведение, 52e ссылается/усиливает. XML-структура 52d (5 секций) и эмиссия 52c-схемы сохраняются.
|
||||
- **BR-7** — Сопутствующая документация обновлена: `CLAUDE.md` (правила для агентов), `docs/
|
||||
architecture/README.md` (упоминание стандарта как слоя 4 эпика 52), `CHANGELOG.md`; архитектор
|
||||
заводит ADR.
|
||||
|
||||
## 5. Нефункциональные требования (NFR)
|
||||
|
||||
- **NFR-1 (нулевое касание кода)** — Изменяются ТОЛЬКО `docs/**` и `.openclaw/agents/*.md`
|
||||
(+ структурный тест промптов в `tests/`). `src/**`, `STAGE_TRANSITIONS`, `QG_CHECKS`, `check_*`,
|
||||
`_parse_*`, схема БД — **не трогаются**.
|
||||
- **NFR-2 (анти-регресс промптов, как 52d)** — Не потеряны: 5 обязательных XML-секций
|
||||
(`<context>`/`<task>`/`<deliverables>`/`<constraints>`/`<output_format>`), 6 полей 52c-схемы,
|
||||
и machine-verdict ключи **байт-в-байт** (`verdict:`/`result:`/`staging_status:`/`deploy_status:`/
|
||||
`security_status:` с точным регистром и наборами значений). Существующие
|
||||
`tests/test_agent_prompts_canon.py` и `tests/test_agent_frontmatter_no_model.py` остаются
|
||||
зелёными; полный `pytest tests/ -q` зелёный.
|
||||
- **NFR-3 (только на будущее)** — Стандарт описательно-нормативный для нового/изменяемого кода;
|
||||
существующие 51 маркер не переразмечаются.
|
||||
- **NFR-4 (self-hosting, без рестарта)** — Промпт `cat`-ается из git-worktree агента в момент
|
||||
запуска → правка вступает в силу на следующем worktree от `main` без прод-рестарта контейнера
|
||||
`orchestrator` (8500).
|
||||
- **NFR-5 (обратимость)** — Чисто текстовое изменение: `git revert` PR полностью откатывает; нет
|
||||
миграций/состояния/kill-switch (нечего гейтить — поведение кода идентично).
|
||||
|
||||
## 6. Допущения и ограничения
|
||||
- Промпты 52d в `main` — стабильная база; 52e накладывается на неё (XML-канон не меняем).
|
||||
- Стандарт `PIPELINE_DOCS.md`/`HANDOFF_PROTOCOL.md` — соседи нового `TRACEABILITY.md` в
|
||||
`docs/_standards/`; формат и тон выдерживаются в том же стиле.
|
||||
- Реальный пример в стандарте ссылается на существующие в `main` файл `src/` + ADR (проверяемость).
|
||||
- Архитектурное обоснование (нужен ли сквозной ADR, точные формулировки правок промптов) —
|
||||
зона архитектора (`06-adr`), не аналитика.
|
||||
|
||||
## 7. Критерии успеха
|
||||
Создан стандарт маркеров с реальным примером; правило чтения есть в developer/architect, reviewer
|
||||
его проверяет; fallback-доступ и анти-археология задокументированы; 52d не продублирована; код не
|
||||
изменён, анти-регресс промптов держится, регресс зелёный; доки обновлены. Детальные PASS/FAIL —
|
||||
`03-acceptance-criteria.md`.
|
||||
|
||||
## 8. Риски
|
||||
- **Дублирование 52d** (правило уже частично есть) → митигируется явной сверкой (см. §1, BR-6) и
|
||||
ссылками вместо повтора.
|
||||
- **Расползание в ретро-фит** (соблазн расставить маркеры по коду) → жёсткая граница «вне объёма».
|
||||
- **Регресс промптов** (потеря verdict-ключа/запрета при точечной правке) → анти-регресс-тест (NFR-2).
|
||||
- Детальный разбор технических рисков — `10-tech-risks.md` (заполняет архитектор).
|
||||
156
docs/work-items/ORCH-078/02-trz.md
Normal file
156
docs/work-items/ORCH-078/02-trz.md
Normal file
@@ -0,0 +1,156 @@
|
||||
---
|
||||
work_item: ORCH-078
|
||||
stage: analysis
|
||||
author_agent: analyst
|
||||
status: ready-for-review
|
||||
created_at: 2026-06-09
|
||||
model_used: claude-opus-4-8
|
||||
---
|
||||
|
||||
# 02 — ТЗ (TRZ): ORCH-078 — ORCH-52e: трассировка ORCH-NNN (маркеры-стандарт + правило чтения)
|
||||
|
||||
Work Item: **ORCH-078** · Repo: **orchestrator** (self-hosting) · Стадия: analysis
|
||||
|
||||
> ТЗ описывает **конкретные изменения** (выведенные из BRD и фактического содержимого репозитория).
|
||||
> Архитектурное обоснование (нужен ли сквозной ADR, точные формулировки врезок в промпты, форма
|
||||
> стандарта) — задача архитектора (`06-adr`). Это **docs + prompts-only** задача: `src/**` не меняется.
|
||||
|
||||
## 1. Сводка изменения
|
||||
|
||||
Ввести формальный стандарт маркеров-трассировки `docs/_standards/TRACEABILITY.md` и **точечно**
|
||||
(не переписывая) дополнить 3 системных промпта правилом чтения ADR перед правкой маркированного
|
||||
кода (developer/architect) и контролем его соблюдения (reviewer). Задокументировать fallback-доступ
|
||||
к чужому work item и анти-археологию (3+ маркеров → сводный сквозной ADR). Сопутствующе обновить
|
||||
`CLAUDE.md`, `docs/architecture/README.md`, `CHANGELOG.md`; расширить структурный анти-регресс-тест
|
||||
промптов. **Существующие 51 маркер в `src/` не переразмечаются.**
|
||||
|
||||
## 2. Задействованные модули / пути
|
||||
|
||||
| Путь | Действие |
|
||||
|------|----------|
|
||||
| `docs/_standards/TRACEABILITY.md` | **создать** (новый стандарт; см. FR-1) |
|
||||
| `.openclaw/agents/developer.md` | **точечно дополнить** — правило чтения + fallback-доступ (FR-2, FR-5); ссылка на стандарт |
|
||||
| `.openclaw/agents/architect.md` | **точечно дополнить** — правило чтения + анти-археология (FR-3, FR-6); ссылка на стандарт |
|
||||
| `.openclaw/agents/reviewer.md` | **точечно дополнить** — ось контроля соблюдения трассировки (FR-4); ссылка на стандарт |
|
||||
| `CLAUDE.md` | обновить — раздел «Правила для агентов» / «Конвенции»: правило трассировки + ссылка на `TRACEABILITY.md` (FR-7) |
|
||||
| `docs/architecture/README.md` | обновить — упоминание стандарта как слоя 4 эпика 52 (FR-7) |
|
||||
| `CHANGELOG.md` | добавить запись `## [Unreleased]` |
|
||||
| `tests/test_agent_prompts_canon.py` | **расширить** (tests-only) — анти-регресс reading-rule маркеров (FR-8); НЕ трогает `src/` |
|
||||
| `docs/work-items/ORCH-078/06-adr/ADR-001-*.md` | создать (архитектор) |
|
||||
| `docs/architecture/adr/adr-NNNN-*.md` | создать при необходимости (архитектор, если решение сквозное) |
|
||||
| **НЕ трогать** | `src/**` (любой), `STAGE_TRANSITIONS`, `QG_CHECKS`, `check_*`, `_parse_*`, `src/frontmatter.py`, схема БД; XML-канон и 52c-эмиссия промптов 52d |
|
||||
|
||||
## 3. Функциональные требования
|
||||
|
||||
### FR-1 — Стандарт `docs/_standards/TRACEABILITY.md` (BR-1, BR-4, BR-5)
|
||||
|
||||
Новый нормативный документ в стиле соседей (`PIPELINE_DOCS.md`/`HANDOFF_PROTOCOL.md`). Обязательные
|
||||
смысловые блоки:
|
||||
|
||||
1. **Назначение и определение.** Маркер `ORCH-NNN` (и `ET-NNN`) в коде = обязательный стандарт
|
||||
трассировки: привязка нетривиальной строки/блока/инварианта к work item, который его ввёл, и к
|
||||
его ADR. (Зафиксировать существующий факт: ~51 уникальный маркер в `src/`.)
|
||||
2. **Формат маркера.** Inline-комментарий, содержащий `ORCH-NNN` (например, в docstring модуля
|
||||
и/или у строки инварианта); рекомендуется указывать ссылку на решение
|
||||
(`ORCH-088, ADR-001 D1`). Не вводить нового синтаксиса — кодифицировать сложившийся.
|
||||
3. **Где ставится.** Рядом с **нетривиальным инвариантом** (fail-open/fail-closed выбор, точное
|
||||
условие сериализации, идемпотентность, обходимая дыра конвейера), а **не** на тривиальном/
|
||||
самоочевидном коде. Правило для нового кода: вводишь значимый инвариант → ставь маркер своей
|
||||
задачи рядом.
|
||||
4. **Как читать историю — с РЕАЛЬНЫМ примером (AC-1).** Пошагово: маркер в коде → `docs/work-items/
|
||||
ORCH-NNN/06-adr/`. Обязателен ≥1 проверяемый пример из существующего кода, например:
|
||||
`src/serial_gate.py` строка `t2.id < jobs.task_id` несёт маркер **ORCH-088** (ADR-001 D1 / FR-2,
|
||||
FIFO-уточнение) → читать `docs/work-items/ORCH-088/06-adr/ADR-001-serial-gate.md`. Пример обязан
|
||||
ссылаться на реально существующие в `main` файл и ADR.
|
||||
5. **Fallback-доступ (BR-4).** Если папки `docs/work-items/ORCH-NNN/` нет в текущей ветке (срезана
|
||||
от `main` без неё) — читать из `origin/main`:
|
||||
`git show origin/main:docs/work-items/ORCH-NNN/06-adr/ADR-001-<slug>.md`
|
||||
(при необходимости `git fetch origin` заранее; листинг — `git ls-tree origin/main:docs/work-items/ORCH-NNN/06-adr/`).
|
||||
6. **Анти-археология (BR-5).** Если функция/блок несёт **3+ маркеров** `ORCH-NNN` — вместо раскопок
|
||||
по каждому work item ставится **сводная ссылка на один сквозной ADR** (`docs/architecture/adr/
|
||||
adr-NNNN-*`), агрегирующий эволюцию. Пример из кода: `src/merge_gate.py` несёт ORCH-043/065/071/073
|
||||
→ сводные сквозные `adr-0006`/`adr-0013`/`adr-0014`/`adr-0016`.
|
||||
7. **Правило чтения (нормативная формулировка).** «Правишь код с маркером `ORCH-NNN` → прочитай его
|
||||
`06-adr` ПЕРЕД изменением; не сломай зафиксированный инвариант; не можешь — эскалируй/верни в
|
||||
анализ» — каноничный текст, на который ссылаются промпты (BR-6: единый источник, без повтора).
|
||||
|
||||
### FR-2 — Правило чтения в `developer.md` (BR-2)
|
||||
|
||||
Точечная врезка (НЕ перезапись), сохраняющая 5 XML-секций и 52c-эмиссию. В `<constraints>` (и/или
|
||||
`<context>` списком «что прочесть») добавить пункт в формате «❌ X → ✅ Y»:
|
||||
- ❌ Не правь строку/блок с маркером `ORCH-NNN` вслепую → ✅ перед изменением прочитай
|
||||
`docs/work-items/ORCH-NNN/06-adr/` и не сломай зафиксированный инвариант; стандарт —
|
||||
`docs/_standards/TRACEABILITY.md`.
|
||||
- Включить fallback-доступ (FR-5).
|
||||
Существующее 52d-упоминание «реализуй по `06-adr/`» относится к ADR *текущей* задачи — НЕ дублировать,
|
||||
а **дополнить** правилом для *чужих* маркеров.
|
||||
|
||||
### FR-3 — Правило чтения + анти-археология в `architect.md` (BR-2, BR-5)
|
||||
|
||||
Точечная врезка: при изменении маркированного компонента архитектор обязан свериться с ADR work
|
||||
item(ов), породивших инвариант; при введении/правке блока с 3+ маркерами — оформить/обновить
|
||||
**сводный сквозной ADR** (`docs/architecture/adr/`) согласно `TRACEABILITY.md` §анти-археология.
|
||||
Ссылка на стандарт; без перезаписи существующих секций.
|
||||
|
||||
### FR-4 — Контроль соблюдения в `reviewer.md` (BR-3)
|
||||
|
||||
Точечная врезка в ось «Соответствие ADR» (или новый под-пункт): reviewer проверяет, что правка
|
||||
кода, несущего чужой маркер `ORCH-NNN`, **сверена** с его `06-adr` и не ломает инвариант; нарушение
|
||||
(правка маркированного инварианта без обоснования / со сломом) → finding. Рекомендуемая severity —
|
||||
**P1** (must-fix); слом критического инварианта конвейера может быть P0 на усмотрение reviewer.
|
||||
Ссылка на `TRACEABILITY.md`. НЕ дублировать существующую общую ADR-ось — усилить её этим под-пунктом.
|
||||
|
||||
### FR-5 — Fallback-доступ задокументирован (BR-4)
|
||||
|
||||
Команда `git show origin/main:docs/work-items/ORCH-NNN/06-adr/...` присутствует и в `TRACEABILITY.md`
|
||||
(FR-1.5), и в `developer.md` (рядом с правилом чтения), чтобы агент, у которого нет папки в ветке,
|
||||
знал штатный способ прочитать чужой ADR.
|
||||
|
||||
### FR-6 — Анти-археология зафиксирована (BR-5)
|
||||
|
||||
Конвенция «3+ маркеров → сводный сквозной ADR» присутствует в `TRACEABILITY.md` (FR-1.6) и в
|
||||
`architect.md` (FR-3). Reviewer может опираться на неё при ревью (FR-4).
|
||||
|
||||
### FR-7 — Сопутствующая документация (BR-7)
|
||||
|
||||
- `CLAUDE.md` — в «Правила для агентов» и/или «Конвенции» добавить правило трассировки одной строкой
|
||||
+ ссылку на `docs/_standards/TRACEABILITY.md` (по образцу того, как там уже ссылаются на
|
||||
`PIPELINE_DOCS.md`/`HANDOFF_PROTOCOL.md`).
|
||||
- `docs/architecture/README.md` — в разделе про стандарты документов конвейера (ORCH-075/077)
|
||||
упомянуть `TRACEABILITY.md` как **слой 4 (трассировка)** эпика ORCH-52 со ссылкой.
|
||||
- `CHANGELOG.md` — запись под `## [Unreleased]` (`docs:`).
|
||||
|
||||
### FR-8 — Анти-регресс промптов (NFR-2)
|
||||
|
||||
Расширить `tests/test_agent_prompts_canon.py` (tests-only, `src/` не трогается) так, чтобы он
|
||||
утверждал присутствие reading-rule маркеров в developer/architect/reviewer (напр. строка
|
||||
`TRACEABILITY` и/или паттерн правила чтения у маркированного кода) — аналогично существующим
|
||||
`_ANTI_REGRESS`-проверкам. Существующие проверки 52d (5 XML-секций, 6 полей схемы, точный регистр
|
||||
verdict-ключей, self-hosting-маркеры deployer) остаются и зелёные;
|
||||
`tests/test_agent_frontmatter_no_model.py` остаётся зелёным.
|
||||
|
||||
## 4. Изменения API
|
||||
Нет. Эндпоинты не добавляются/не меняются.
|
||||
|
||||
## 5. Изменения схемы БД
|
||||
Нет. Таблицы/миграции/индексы не трогаются.
|
||||
|
||||
## 6. Требования к новым/изменённым QG checks
|
||||
Нет. `QG_CHECKS`, `check_*`, `_parse_*`, `STAGE_TRANSITIONS` — без изменений.
|
||||
`frontmatter_validation_strict` остаётся `False`; enforcement не вводится. Новый QG не добавляется
|
||||
(стандарт трассировки — нормативный документ + анти-регресс-тест промптов, не машинный гейт
|
||||
конвейера).
|
||||
|
||||
## 7. Совместимость / регресс
|
||||
- **Нулевое касание кода (NFR-1):** меняются только `docs/**` и `.openclaw/agents/*.md` (+ tests-only
|
||||
расширение структурного теста). Поведение `src/` идентично → нулевая функциональная регрессия,
|
||||
enduro-trails не затронут.
|
||||
- **Анти-регресс промптов (NFR-2):** точечные врезки сохраняют 5 XML-секций, 52c-эмиссию и
|
||||
machine-verdict ключи байт-в-байт; гарантируется расширенным `test_agent_prompts_canon.py`.
|
||||
- **Self-hosting (NFR-4):** промпт `cat`-ается из worktree при запуске → новое правило действует на
|
||||
следующем worktree от `main` без прод-рестарта (8500).
|
||||
- **Обратимость (NFR-5):** чисто текстовое изменение; `git revert` PR — полный откат; kill-switch
|
||||
не нужен (нет машинного поведения); нет миграций/состояния.
|
||||
- **Анти-дубль (BR-6):** промпты ссылаются на единый текст правила в `TRACEABILITY.md`, а не
|
||||
повторяют его; 52d-канон не переписывается.
|
||||
- **Тесты:** полный `pytest tests/ -q` — зелёный.
|
||||
120
docs/work-items/ORCH-078/03-acceptance-criteria.md
Normal file
120
docs/work-items/ORCH-078/03-acceptance-criteria.md
Normal file
@@ -0,0 +1,120 @@
|
||||
---
|
||||
work_item: ORCH-078
|
||||
stage: analysis
|
||||
author_agent: analyst
|
||||
status: ready-for-review
|
||||
created_at: 2026-06-09
|
||||
model_used: claude-opus-4-8
|
||||
---
|
||||
|
||||
# 03 — Критерии приёмки (Acceptance Criteria): ORCH-078 — ORCH-52e: трассировка ORCH-NNN
|
||||
|
||||
Work Item: **ORCH-078** · Repo: **orchestrator** · Стадия: analysis
|
||||
|
||||
Формат: каждый критерий имеет **PASS** (что должно быть истинно для приёмки) и **FAIL** (что
|
||||
считается провалом). Reviewer проверяет их буквально по файлам репозитория.
|
||||
|
||||
---
|
||||
|
||||
## AC-1 — Стандарт маркеров создан с реальным примером из кода
|
||||
|
||||
**Условие:** в `docs/_standards/` существует `TRACEABILITY.md` с форматом маркера, правилом
|
||||
размещения и проверяемым примером из реального кода.
|
||||
- **PASS:** файл `docs/_standards/TRACEABILITY.md` существует; описывает формат `ORCH-NNN`, где
|
||||
ставится (рядом с нетривиальным инвариантом), как читать историю; содержит ≥1 пример, ссылающийся
|
||||
на **реально существующие** в `main` файл `src/...` + маркер `ORCH-NNN` + путь
|
||||
`docs/work-items/ORCH-NNN/06-adr/...` (напр. `src/serial_gate.py` → ORCH-088 → `ADR-001-serial-gate.md`).
|
||||
- **FAIL:** файла нет; нет формата/правила размещения; пример отсутствует или ссылается на
|
||||
несуществующие файл/ADR (нерабочая трассировка).
|
||||
|
||||
---
|
||||
|
||||
## AC-2 — Правило чтения присутствует в developer и architect
|
||||
|
||||
**Условие:** правило «правишь код с маркером `ORCH-NNN` → прочитай его `06-adr` ПЕРЕД изменением,
|
||||
не сломай инвариант» присутствует в `developer.md` и `architect.md`.
|
||||
- **PASS:** оба промпта содержат правило (со ссылкой на `TRACEABILITY.md`), сформулированное как
|
||||
правило для **чужих** маркеров в правимом коде (не просто «реализуй по `06-adr/` текущей задачи»);
|
||||
developer-формулировка соблюдает формат «❌ X → ✅ Y».
|
||||
- **FAIL:** правило отсутствует в одном из промптов; либо лишь повторяет 52d-упоминание ADR текущей
|
||||
задачи без сути «читай ADR чужого маркера перед правкой».
|
||||
|
||||
---
|
||||
|
||||
## AC-3 — Reviewer проверяет соблюдение трассировки
|
||||
|
||||
**Условие:** `reviewer.md` содержит ось/под-пункт контроля: правка маркированного кода без сверки с
|
||||
его ADR / со сломом инварианта → finding.
|
||||
- **PASS:** reviewer-промпт явно требует проверять сверку правок маркированного (`ORCH-NNN`) кода с
|
||||
его `06-adr`; нарушение даёт finding с severity (≥P1); есть ссылка на `TRACEABILITY.md`.
|
||||
- **FAIL:** reviewer не проверяет соблюдение трассировки (правило есть у автора, но никто не
|
||||
контролирует) либо проверка не привязана к severity/finding.
|
||||
|
||||
---
|
||||
|
||||
## AC-4 — Fallback-доступ задокументирован
|
||||
|
||||
**Условие:** способ `git show origin/main:docs/work-items/ORCH-NNN/06-adr/...` задокументирован.
|
||||
- **PASS:** команда присутствует в `TRACEABILITY.md` и в `developer.md` (рядом с правилом чтения),
|
||||
с пояснением «когда папки нет в текущей ветке».
|
||||
- **FAIL:** fallback не задокументирован нигде, либо приведён без контекста применения.
|
||||
|
||||
---
|
||||
|
||||
## AC-5 — Анти-археология зафиксирована
|
||||
|
||||
**Условие:** конвенция «3+ маркеров в блоке → сводная ссылка на сквозной ADR (`docs/architecture/
|
||||
adr/`)» зафиксирована.
|
||||
- **PASS:** правило присутствует в `TRACEABILITY.md` (с примером, напр. `src/merge_gate.py` →
|
||||
ORCH-043/065/071/073 → сквозные `adr-0006/0013/0014/0016`) и в `architect.md`.
|
||||
- **FAIL:** правило отсутствует либо сформулировано без числового порога/без указания на сквозной ADR.
|
||||
|
||||
---
|
||||
|
||||
## AC-6 — Анти-дубль: 52e не повторяет 52d
|
||||
|
||||
**Условие:** 52e не дублирует уже сделанное в 52d; где смежное поведение есть — ссылается/усиливает.
|
||||
- **PASS:** промпты ссылаются на единый текст правила в `TRACEABILITY.md` (а не копируют его в
|
||||
каждый); XML-канон 52d (5 секций) и 52c-эмиссия сохранены; нет дословного повтора уже имевшихся
|
||||
52d-формулировок.
|
||||
- **FAIL:** правило скопировано дословно в несколько промптов вместо ссылки; либо промпты переписаны
|
||||
целиком (нарушен канон 52d).
|
||||
|
||||
---
|
||||
|
||||
## AC-7 — Код не изменён; анти-регресс промптов держится; регресс зелёный
|
||||
|
||||
**Условие:** изменены только `docs/**` и `.openclaw/agents/*.md` (+ tests-only расширение
|
||||
структурного теста); `src/**` не тронут; анти-регресс промптов сохранён.
|
||||
- **PASS:** `git diff --name-only origin/main` показывает изменения только в `docs/**`,
|
||||
`.openclaw/agents/*.md`, `tests/test_agent_prompts_canon.py`, `CLAUDE.md`, `CHANGELOG.md` (нет
|
||||
`src/**`, `STAGE_TRANSITIONS`, `QG_CHECKS`, `_parse_*`, схемы БД); `tests/test_agent_prompts_canon.py`
|
||||
и `tests/test_agent_frontmatter_no_model.py` зелёные; machine-verdict ключи
|
||||
(`verdict:`/`result:`/`staging_status:`/`deploy_status:`/`security_status:`) сохранены байт-в-байт;
|
||||
полный `pytest tests/ -q` зелёный.
|
||||
- **FAIL:** любой файл `src/**` изменён; потерян verdict-ключ/XML-секция/запрет; красный тест.
|
||||
|
||||
---
|
||||
|
||||
## AC-8 — Сопутствующая документация обновлена
|
||||
|
||||
**Условие:** `CLAUDE.md`, `docs/architecture/README.md`, `CHANGELOG.md` обновлены; есть ADR задачи.
|
||||
- **PASS:** `CLAUDE.md` и `docs/architecture/README.md` ссылаются на `TRACEABILITY.md` (слой 4 эпика
|
||||
52); в `CHANGELOG.md` есть запись `## [Unreleased]`; создан `docs/work-items/ORCH-078/06-adr/
|
||||
ADR-001-*.md`.
|
||||
- **FAIL:** любой из перечисленных документов не обновлён/не создан (для reviewer: необновлённая
|
||||
документация при изменении репозитория → `REQUEST_CHANGES`).
|
||||
|
||||
---
|
||||
|
||||
## Сводная матрица AC ↔ FR/BR
|
||||
| AC | Покрывает |
|
||||
|----|-----------|
|
||||
| AC-1 | BR-1 / FR-1 |
|
||||
| AC-2 | BR-2 / FR-2, FR-3 |
|
||||
| AC-3 | BR-3 / FR-4 |
|
||||
| AC-4 | BR-4 / FR-1, FR-5 |
|
||||
| AC-5 | BR-5 / FR-1, FR-6 |
|
||||
| AC-6 | BR-6 / FR-1..FR-4 |
|
||||
| AC-7 | NFR-1, NFR-2 / FR-8 |
|
||||
| AC-8 | BR-7 / FR-7 |
|
||||
98
docs/work-items/ORCH-078/04-test-plan.yaml
Normal file
98
docs/work-items/ORCH-078/04-test-plan.yaml
Normal file
@@ -0,0 +1,98 @@
|
||||
work_item: ORCH-078
|
||||
stage: analysis
|
||||
author_agent: analyst
|
||||
status: ready-for-review
|
||||
created_at: 2026-06-09
|
||||
model_used: claude-opus-4-8
|
||||
title: "ORCH-52e: трассировка ORCH-NNN — стандарт маркеров + правило чтения"
|
||||
framework: pytest
|
||||
scope: >
|
||||
Покрытие — структурные текстовые проверки (без запуска агентов, без импорта src/):
|
||||
наличие и содержание docs/_standards/TRACEABILITY.md, присутствие правила чтения в
|
||||
developer/architect, контроль соблюдения в reviewer, fallback-доступ, анти-археология,
|
||||
анти-регресс промптов 52d. Вне покрытия — массовый ретро-фит маркеров в src/ и любое
|
||||
поведение кода (src/** не меняется).
|
||||
notes: >
|
||||
Тесты — расширение существующего tests/test_agent_prompts_canon.py (tests-only; src/ не
|
||||
трогается, что согласуется с AC-7). Проверки текстовые (open()+read() по файлам репозитория),
|
||||
как и канон 52d. test_agent_frontmatter_no_model.py остаётся зелёным. Полный регресс
|
||||
pytest tests/ -q должен оставаться зелёным.
|
||||
|
||||
tests:
|
||||
- id: TC-01
|
||||
type: unit
|
||||
description: "docs/_standards/TRACEABILITY.md существует и непустой (AC-1)."
|
||||
module: tests/test_agent_prompts_canon.py
|
||||
expected: PASS
|
||||
|
||||
- id: TC-02
|
||||
type: unit
|
||||
description: "TRACEABILITY.md описывает формат маркера ORCH-NNN и правило размещения рядом с нетривиальным инвариантом (AC-1)."
|
||||
module: tests/test_agent_prompts_canon.py
|
||||
expected: PASS
|
||||
|
||||
- id: TC-03
|
||||
type: unit
|
||||
description: "TRACEABILITY.md содержит реальный пример: ссылается на существующий путь src/...py и на существующий docs/work-items/ORCH-NNN/06-adr/...md (AC-1)."
|
||||
module: tests/test_agent_prompts_canon.py
|
||||
expected: PASS
|
||||
|
||||
- id: TC-04
|
||||
type: unit
|
||||
description: "TRACEABILITY.md документирует fallback-доступ git show origin/main:docs/work-items/... (AC-4)."
|
||||
module: tests/test_agent_prompts_canon.py
|
||||
expected: PASS
|
||||
|
||||
- id: TC-05
|
||||
type: unit
|
||||
description: "TRACEABILITY.md документирует анти-археологию: порог 3+ маркеров → сводная ссылка на сквозной ADR docs/architecture/adr/ (AC-5)."
|
||||
module: tests/test_agent_prompts_canon.py
|
||||
expected: PASS
|
||||
|
||||
- id: TC-06
|
||||
type: unit
|
||||
description: "developer.md несёт правило чтения чужого маркера + ссылку на TRACEABILITY.md + fallback git show origin/main: (AC-2, AC-4)."
|
||||
module: tests/test_agent_prompts_canon.py
|
||||
expected: PASS
|
||||
|
||||
- id: TC-07
|
||||
type: unit
|
||||
description: "architect.md несёт правило чтения маркированного кода + анти-археологию (3+ → сквозной ADR) + ссылку на TRACEABILITY.md (AC-2, AC-5)."
|
||||
module: tests/test_agent_prompts_canon.py
|
||||
expected: PASS
|
||||
|
||||
- id: TC-08
|
||||
type: unit
|
||||
description: "reviewer.md несёт ось контроля: правка маркированного кода без сверки с ADR → finding (AC-3)."
|
||||
module: tests/test_agent_prompts_canon.py
|
||||
expected: PASS
|
||||
|
||||
- id: TC-09
|
||||
type: unit
|
||||
description: "АНТИ-РЕГРЕСС 52d: 5 XML-секций и 6 полей 52c-схемы присутствуют во всех 6 промптах (NFR-2)."
|
||||
module: tests/test_agent_prompts_canon.py
|
||||
expected: PASS
|
||||
|
||||
- id: TC-10
|
||||
type: unit
|
||||
description: "АНТИ-РЕГРЕСС 52d: machine-verdict ключи сохранены байт-в-байт (verdict:/result:/staging_status:/deploy_status:/security_status:, точный регистр и наборы значений) (NFR-2)."
|
||||
module: tests/test_agent_prompts_canon.py
|
||||
expected: PASS
|
||||
|
||||
- id: TC-11
|
||||
type: unit
|
||||
description: "frontmatter промптов остаётся валидным без ключа model: (повторно зелёный) (NFR-2)."
|
||||
module: tests/test_agent_frontmatter_no_model.py
|
||||
expected: PASS
|
||||
|
||||
- id: TC-12
|
||||
type: unit
|
||||
description: "CLAUDE.md и docs/architecture/README.md ссылаются на docs/_standards/TRACEABILITY.md как слой 4 эпика 52 (AC-8)."
|
||||
module: tests/test_agent_prompts_canon.py
|
||||
expected: PASS
|
||||
|
||||
- id: TC-13
|
||||
type: integration
|
||||
description: "Полный регресс pytest tests/ -q зелёный; src/ не изменён (поведение кода идентично) (AC-7)."
|
||||
module: tests/
|
||||
expected: PASS
|
||||
@@ -0,0 +1,190 @@
|
||||
---
|
||||
work_item: ORCH-078
|
||||
stage: architecture
|
||||
author_agent: architect
|
||||
status: proposed
|
||||
created_at: 2026-06-09
|
||||
model_used: claude-opus-4-8
|
||||
---
|
||||
|
||||
# ADR-001: Стандарт маркеров-трассировки `ORCH-NNN` + правило чтения ADR перед правкой
|
||||
|
||||
Work Item: **ORCH-078** — ORCH-52e: трассировка `ORCH-NNN` (слой 4 эпика ORCH-52)
|
||||
Стадия: **architecture**
|
||||
Сквозная регистрация: **`docs/architecture/adr/adr-0022-traceability-marker-standard.md`**
|
||||
(решение кросс-каттинговое — вводит нормативный стандарт разработки и ось ревью для ВСЕХ
|
||||
агентов/проектов; продолжает цепочку adr-0019/0020/0021 эпика 52).
|
||||
|
||||
## Статус
|
||||
Proposed
|
||||
|
||||
## Контекст
|
||||
|
||||
Эпик **ORCH-52** строит сквозной «golden source» документации конвейера слоями: **52b** (ORCH-075,
|
||||
adr-0019) — стандарт структуры документов `PIPELINE_DOCS.md` + скелеты; **52c** (ORCH-076, adr-0020) —
|
||||
машинный frontmatter-контракт `src/frontmatter.py` + `HANDOFF_PROTOCOL.md`; **52d** (ORCH-077,
|
||||
adr-0021) — 6 промптов в каноне Anthropic + эмиссия 52c-схемы. **52e — слой 4 (трассировка)**.
|
||||
|
||||
**Факты, сверенные с кодом `main` (на 2026-06-09):**
|
||||
- В `src/` де-факто живёт **51 уникальный** маркер `ORCH-NNN`
|
||||
(`grep -rhoE 'ORCH-[0-9]+' src/ | sort -u | wc -l` → 51), привязывающий нетривиальные строки/
|
||||
инварианты к work item, который их ввёл. Это **сложившаяся практика без формального стандарта**:
|
||||
`docs/_standards/` содержит только `PIPELINE_DOCS.md` и `HANDOFF_PROTOCOL.md`.
|
||||
- Проверяемый одиночный пример: `src/serial_gate.py:241,269` несёт условие сериализации
|
||||
`t2.id < jobs.task_id` с маркером **ORCH-088** и явной отсылкой `ADR-001 D1 / FR-2` →
|
||||
`docs/work-items/ORCH-088/06-adr/ADR-001-serial-gate.md` существует.
|
||||
- Проверяемый пример высокой плотности: `src/merge_gate.py` несёт **26** вхождений маркеров
|
||||
(ORCH-043/065/067/069/071/073/074/082) — раскопки по 8 work item; сквозные
|
||||
`adr-0006/0013/0014/0016` существуют и агрегируют эволюцию.
|
||||
- Плотность маркеров по файлам (сверено): `config.py`=63, `stage_engine.py`=55,
|
||||
`agents/launcher.py`=50, `plane_sync.py`=48, `merge_gate.py`=26.
|
||||
|
||||
**Почему «как есть» не годится (боль):**
|
||||
1. **Нет правила чтения.** Агент (developer/architect), правя маркированную строку, не обязан
|
||||
прочитать ADR, который её ввёл, → риск молча сломать зафиксированный инвариант. Это ровно класс
|
||||
«фантомного merge» (`docs/history/LESSONS_2026-06-08_phantom-merge.md`), породившего ORCH-071/073.
|
||||
2. **Reviewer не контролирует соблюдение.** Reviewer-ось «Соответствие ADR» (`reviewer.md:37`)
|
||||
проверяет ADR *текущей* задачи, но не сверку правки *чужого* маркированного кода с его ADR.
|
||||
3. **Анти-археология.** Файлы с плотностью 50+ маркеров превращают понимание блока в раскопки.
|
||||
4. **Доступ к чужому work item.** Папки `docs/work-items/ORCH-NNN/06-adr/` может не быть в текущей
|
||||
ветке (срезана от `main` без неё) — нужен задокументированный fallback.
|
||||
|
||||
**Что УЖЕ покрыто 52d (анти-дубль, сверено `grep -nE 'ORCH-NNN|06-adr'`):** `developer.md:65`
|
||||
говорит «реализуй по `06-adr/`» — но только про ADR *текущей* задачи; `architect.md:41`/`reviewer.md:37`
|
||||
— аналогично. **Правила «правишь чужой маркированный код → прочти его ADR перед правкой» среди них
|
||||
НЕТ.** Поэтому 52e не переписывает промпты — добавляет именно отсутствующее правило.
|
||||
|
||||
## Решение
|
||||
|
||||
### Сводка
|
||||
|
||||
Кодифицировать сложившуюся практику маркеров как **нормативный документ-стандарт**
|
||||
`docs/_standards/TRACEABILITY.md` (слой 4 эпика 52, рядом с `PIPELINE_DOCS.md`/`HANDOFF_PROTOCOL.md`),
|
||||
и **точечно** дополнить 3 промпта правилом чтения / контролем соблюдения **со ссылкой на единый
|
||||
источник** (не копируя текст). Это **docs + prompts-only** изменение с нулевым касанием кода:
|
||||
стандарт — описательно-нормативный документ + анти-регресс-тест промптов, **не машинный гейт
|
||||
конвейера**. Никакого ретро-фита 51 существующего маркера — стандарт действует «на будущее».
|
||||
|
||||
### D1 — `TRACEABILITY.md` как нормативный документ, НЕ машинный гейт (FR-1, AC-1)
|
||||
|
||||
Стандарт фиксирует **существующий контракт**, а не вводит новый синтаксис. Обязательные смысловые
|
||||
блоки (7 шт., по FR-1): (1) назначение и определение маркера `ORCH-NNN`/`ET-NNN`; (2) формат —
|
||||
inline-комментарий, рекомендуется ссылка на решение (`ORCH-088, ADR-001 D1`); (3) где ставится —
|
||||
рядом с **нетривиальным инвариантом** (fail-open/-closed, точное условие сериализации,
|
||||
идемпотентность, обходимая дыра конвейера), не на тривиальном коде; (4) как читать историю **с
|
||||
реальным проверяемым примером** (`src/serial_gate.py` → ORCH-088 → `ADR-001-serial-gate.md`);
|
||||
(5) fallback-доступ (D3); (6) анти-археология (D4); (7) каноничный текст правила чтения (D2).
|
||||
|
||||
**Архитектурное решение:** стандарт остаётся **слоем 1 (описательным)** в терминологии 52b —
|
||||
источник истины о *поведении* остаётся код (`src/stages.py`, `src/qg/checks.py`); enforcement
|
||||
маркеров в CI/гейт **не вводится** (см. «Альтернативы»). Реальный пример обязан ссылаться на
|
||||
существующие в `main` файл+ADR (проверяемость трассировки — иначе стандарт сам себя опровергает).
|
||||
|
||||
### D2 — Единый источник истины правила чтения; промпты ссылаются, не дублируют (BR-6, AC-6)
|
||||
|
||||
Каноничная формулировка правила живёт **только** в `TRACEABILITY.md` §7:
|
||||
|
||||
> «Правишь код с маркером `ORCH-NNN` → прочитай его `docs/work-items/ORCH-NNN/06-adr/` ПЕРЕД
|
||||
> изменением; не сломай зафиксированный инвариант; не можешь сохранить — эскалируй / верни в анализ.»
|
||||
|
||||
Промпты несут **короткую врезку со ссылкой** на этот текст, а не его копию. Это структурно гасит
|
||||
риск дрейфа формулировок между 4 файлами и удовлетворяет анти-дубль BR-6: 52d-канон (5 XML-секций +
|
||||
52c-эмиссия) **не переписывается**, врезки **аддитивны**.
|
||||
|
||||
### D3 — Точные точки врезок в промпты (FR-2..FR-6)
|
||||
|
||||
Сверено по фактической структуре промптов; врезки минимальны и не трогают machine-verdict ключи:
|
||||
|
||||
| Промпт | Точка врезки | Содержание | Формат |
|
||||
|--------|--------------|------------|--------|
|
||||
| `developer.md` | `<constraints>` (рядом с пунктом `06-adr/` строка 65) + строка списка «что прочесть» в `<context>` | правило чтения чужого маркера + **fallback-доступ** (D5) | пункт «❌ X → ✅ Y» (AC-2) |
|
||||
| `architect.md` | `<constraints>` | правило чтения + **анти-археология** (D4): блок с 3+ маркерами → сводный сквозной ADR | пункт + ссылка на стандарт |
|
||||
| `reviewer.md` | усиление оси «Соответствие ADR» (`<task>` п.2, строка 37) под-пунктом | проверка: правка маркированного кода **сверена** с его `06-adr`; слом/несверка → finding | под-пункт оси, не новая ось |
|
||||
|
||||
Во всех трёх — **ссылка** на `docs/_standards/TRACEABILITY.md` (D2). Существующие 52d-упоминания
|
||||
ADR *текущей* задачи не удаляются и не дублируются — рядом добавляется правило для *чужих* маркеров.
|
||||
|
||||
### D4 — Анти-археология: порог 3+ маркеров → сводный сквозной ADR (FR-6, AC-5)
|
||||
|
||||
Нормативная конвенция: если функция/блок несёт **≥3** маркеров `ORCH-NNN`, вместо перечисления всех
|
||||
work item ставится **одна сводная ссылка на сквозной ADR** (`docs/architecture/adr/adr-NNNN-*`),
|
||||
агрегирующий эволюцию. Числовой порог `3` выбран как граница, за которой inline-перечисление
|
||||
перестаёт быть читаемым (один-два маркера ещё информативны, три и больше — уже раскопки). Пример из
|
||||
кода: `src/merge_gate.py` (ORCH-043/065/071/073…) → сводные `adr-0006/0013/0014/0016`. Это конвенция
|
||||
для **нового/правимого** блока — массовая переразметка существующих файлов вне объёма (NFR-3).
|
||||
|
||||
### D5 — Fallback-доступ к чужому ADR (FR-5, AC-4)
|
||||
|
||||
Когда папки `docs/work-items/ORCH-NNN/` нет в текущей ветке (срезана от `main` без неё) —
|
||||
задокументированный штатный способ чтения из `origin/main`:
|
||||
|
||||
```
|
||||
git show origin/main:docs/work-items/ORCH-NNN/06-adr/ADR-001-<slug>.md
|
||||
git ls-tree origin/main:docs/work-items/ORCH-NNN/06-adr/ # листинг
|
||||
git fetch origin # при необходимости заранее
|
||||
```
|
||||
|
||||
Присутствует и в `TRACEABILITY.md` §5, и в `developer.md` (рядом с правилом чтения) — агент без
|
||||
папки в ветке знает штатный путь к чужому ADR.
|
||||
|
||||
### D6 — Сквозная регистрация adr-0022 (BR-7)
|
||||
|
||||
Решение кросс-каттинговое: вводит нормативный стандарт разработки и ось ревью, действующие на ВСЕХ
|
||||
агентов и ВСЕ проекты из общего инстанса (self-hosting). По прецеденту цепочки эпика 52
|
||||
(52b→adr-0019, 52c→adr-0020, 52d→adr-0021) заводится **adr-0022** (следующий 4-значный номер).
|
||||
Per-work-item ADR (этот файл) — детальное решение; глобальный — точка входа для будущих агентов.
|
||||
|
||||
### D7 — Нулевое касание кода и QG (NFR-1, FR раздела «Изменения схемы/QG»)
|
||||
|
||||
`src/**`, `STAGE_TRANSITIONS`, `QG_CHECKS`, `check_*`, `_parse_*`, `src/frontmatter.py`, схема БД —
|
||||
**не трогаются**. `frontmatter_validation_strict` остаётся `False` — enforcement не вводится. Новый
|
||||
QG не регистрируется. Анти-регресс — расширение `tests/test_agent_prompts_canon.py` (tests-only):
|
||||
утверждение присутствия reading-rule/`TRACEABILITY`-маркеров в developer/architect/reviewer, по
|
||||
образцу `_ANTI_REGRESS`. Существующие проверки 52d (5 секций, 6 полей, точный регистр verdict-ключей,
|
||||
self-hosting-маркеры deployer) и `test_agent_frontmatter_no_model.py` остаются зелёными.
|
||||
|
||||
## Альтернативы
|
||||
|
||||
- **Машинный гейт маркеров** (CI-lint: «правка маркированной строки без касания соответствующего
|
||||
ADR → fail», или enforcement через frontmatter) — **отвергнуто**: требует правки `src/`/CI вне
|
||||
scope (NFR-1); для self-hosting рискованно (ложный fail валит конвейер всех проектов); премэйчур
|
||||
при отсутствии даже описательного стандарта. Сначала норматив + анти-регресс промптов; машинный
|
||||
enforcement — потенциальная будущая задача (как hard-fail схемы в adr-0021).
|
||||
- **Массовый ретро-фит 51 маркера** (привести все к формату «маркер + ссылка на ADR») —
|
||||
**отвергнуто**: огромный диф, риск регресса смысла, вне объёма; стандарт нормативен «на будущее»
|
||||
(NFR-3).
|
||||
- **Копировать текст правила в каждый промпт** (без `TRACEABILITY.md` как источника) —
|
||||
**отвергнуто**: дрейф формулировок между 4 файлами, нарушение анти-дубль BR-6; теряется единая
|
||||
точка обновления.
|
||||
- **Не заводить сквозной ADR (только per-work-item)** — **отвергнуто**: рвёт цепочку эпика 52
|
||||
(52b/c/d все имеют глобальный ADR); будущий агент не найдёт точку входа в стандарт трассировки.
|
||||
|
||||
## Последствия
|
||||
|
||||
- **+** Замыкается слой 4 эпика 52: сложившаяся практика маркеров получает формальный контракт +
|
||||
правило чтения, защищающее от слома инвариантов (класс «фантомного merge»).
|
||||
- **+** Reviewer получает явную ось контроля → правка чужого маркированного кода без сверки с ADR
|
||||
ловится в ревью (finding ≥P1).
|
||||
- **+** Единый источник правила (D2) → нет дрейфа между промптами; обновление — в одном файле.
|
||||
- **+** Self-hosting без рестарта: промпт `cat`-ается из worktree при запуске → правило вступает в
|
||||
силу на следующем worktree от `main` без рестарта прод-контейнера 8500 (NFR-4).
|
||||
- **+** Полная обратимость: чисто текстовое изменение, нет миграций/состояния/kill-switch.
|
||||
- **−** Рост объёма 3 промптов (митигейшн: короткие врезки-ссылки вместо инлайна — D2).
|
||||
- **−** Риск регресса инструкции при точечной правке (митигейшн: расширенный
|
||||
`test_agent_prompts_canon.py` — D7; см. `10-tech-risks.md` TR-2).
|
||||
- **−** Стандарт нормативен, но не enforced машинно → соблюдение держится на дисциплине агентов +
|
||||
ревью (осознанный компромисс; машинный gate — отдельная будущая задача).
|
||||
- **Откат:** `git revert` PR полностью возвращает прежнее состояние — стандарт удаляется, врезки
|
||||
исчезают, поведение кода и гейтов идентично (нечего гейтить, NFR-5).
|
||||
|
||||
## Ссылки
|
||||
- BRD: `docs/work-items/ORCH-078/01-brd.md`
|
||||
- TRZ: `docs/work-items/ORCH-078/02-trz.md`
|
||||
- Acceptance: `docs/work-items/ORCH-078/03-acceptance-criteria.md`
|
||||
- Технические риски: `docs/work-items/ORCH-078/10-tech-risks.md`
|
||||
- Сквозной ADR: `docs/architecture/adr/adr-0022-traceability-marker-standard.md`
|
||||
- Цепочка эпика 52: `adr-0019` (52b), `adr-0020` (52c), `adr-0021` (52d)
|
||||
- Сверено по коду: `src/serial_gate.py:241,269` (ORCH-088, `t2.id < jobs.task_id`),
|
||||
`src/merge_gate.py` (26 маркеров), `tests/test_agent_prompts_canon.py` (`_ANTI_REGRESS`),
|
||||
`.openclaw/agents/{developer,architect,reviewer}.md`
|
||||
- Прецедент класса ошибки: `docs/history/LESSONS_2026-06-08_phantom-merge.md`
|
||||
41
docs/work-items/ORCH-078/10-tech-risks.md
Normal file
41
docs/work-items/ORCH-078/10-tech-risks.md
Normal file
@@ -0,0 +1,41 @@
|
||||
---
|
||||
work_item: ORCH-078
|
||||
stage: architecture
|
||||
author_agent: architect
|
||||
status: proposed
|
||||
created_at: 2026-06-09
|
||||
model_used: claude-opus-4-8
|
||||
---
|
||||
|
||||
# 10 — Технические риски: ORCH-078 — ORCH-52e: трассировка `ORCH-NNN`
|
||||
|
||||
Work Item: **ORCH-078** · Repo: **orchestrator** (self-hosting) · Стадия: architecture
|
||||
|
||||
> Информационный документ (гейтом не парсится). Перечисляет риски реализации и митигейшн.
|
||||
> Класс задачи — **docs + prompts-only**, нулевое касание кода (NFR-1) → доминируют риски
|
||||
> регресса промптов и дублирования 52d, а не функциональные.
|
||||
|
||||
## Реестр рисков
|
||||
|
||||
| ID | Риск | Вер. | Влия. | Митигейшн |
|
||||
|----|------|------|-------|-----------|
|
||||
| TR-1 | **Дублирование 52d.** Правило чтения частично смежно с 52d-упоминаниями ADR текущей задачи → соблазн скопировать текст в каждый промпт (нарушение BR-6/AC-6). | Сред. | Низ. | D2: единый источник правила в `TRACEABILITY.md`; промпты несут короткую врезку-**ссылку**, не копию. Reviewer проверяет AC-6 (нет дословного повтора, 52d-канон цел). |
|
||||
| TR-2 | **Регресс промптов.** Точечная врезка случайно сдвигает/ломает 5 XML-секций, 6 полей 52c-схемы или machine-verdict ключ (`verdict:`/`result:`/`staging_status:`/`deploy_status:`/`security_status:`) → ложное падение гейта на следующей задаче. | Низ. | Выс. | NFR-2: расширенный `test_agent_prompts_canon.py` (5 секций, 6 полей, точный регистр verdict-ключей) + `test_agent_frontmatter_no_model.py` остаются зелёными; полный `pytest tests/ -q` зелёный перед merge. |
|
||||
| TR-3 | **Расползание в ретро-фит.** Соблазн расставить/переразметить маркеры по 51 существующему вхождению → большой диф, риск регресса смысла, выход за scope. | Сред. | Сред. | Жёсткая граница «вне объёма» (NFR-3, ADR D4); стандарт нормативен «на будущее»; reviewer заворачивает любой `src/**`-диф (AC-7). |
|
||||
| TR-4 | **Устаревший пример в стандарте.** Реальный пример (`src/serial_gate.py` → ORCH-088) ссылается на строку/ADR, которые позже переименуют/удалят → нерабочая трассировка (FAIL AC-1). | Низ. | Низ. | Пример выбран по стабильному инварианту (условие сериализации serial-gate, ORCH-088 — недавний и активный); сверено существование файла+ADR на 2026-06-09; ссылка на ADR-файл (стабилен), не на номер строки в тексте стандарта. |
|
||||
| TR-5 | **Касание `src/**` по ошибке.** Реализатор тронет код/`STAGE_TRANSITIONS`/`QG_CHECKS`/схему БД вопреки NFR-1. | Низ. | Выс. | AC-7: `git diff --name-only origin/main` показывает только `docs/**`, `.openclaw/agents/*.md`, `tests/test_agent_prompts_canon.py`, `CLAUDE.md`, `CHANGELOG.md`; reviewer заворачивает любой `src/**`. |
|
||||
| TR-6 | **Self-hosting раскат.** Новые промпты вступают в силу на следующем worktree от `main` без рестарта — на текущей задаче reviewer/tester уже исполнятся под новыми промптами (in-vivo). Дефектная врезка повлияла бы на конвейер всех проектов. | Низ. | Сред. | NFR-4: изменение чисто текстовое и аддитивное; обратимо `git revert` (NFR-5); анти-регресс-тест ловит структурный слом до merge; нет машинного поведения/состояния. |
|
||||
| TR-7 | **Dangling-ссылка в README/CLAUDE.md.** Если ссылку на `TRACEABILITY.md` добавить раньше создания файла → битая ссылка в `main`. | Низ. | Низ. | Архитектор НЕ создаёт `TRACEABILITY.md` и НЕ правит README на стадии architecture; FR-7 (`CLAUDE.md`/`README.md`/`CHANGELOG.md`) выполняется на development в **одном** PR вместе с созданием файла. |
|
||||
|
||||
## Сводный вывод
|
||||
|
||||
Доминирующий класс — **риски документации/промптов** (TR-1, TR-2, TR-3), не функциональные:
|
||||
поведение `src/` идентично (NFR-1), enduro-trails не затронут. Самый высокий по влиянию — **TR-2**
|
||||
(регресс machine-verdict ключа мог бы ложно валить гейт всех проектов), но вероятность низкая и
|
||||
полностью покрывается машинным анти-регресс-тестом промптов. Остаточный риск для прод-конвейера
|
||||
(self-hosting) — **низкий**: изменение аддитивно, обратимо `git revert`, без миграций/состояния/
|
||||
kill-switch.
|
||||
|
||||
**Эскалация не требуется:** `arch:major-change` не нужен (нет новой стадии/компонента/смены БД —
|
||||
сквозной adr-0022 регистрирует нормативный стандарт, а не архитектурный компонент); возврат в анализ
|
||||
(`back-to:analysis`) не нужен (ТЗ реализуемо без нарушения принципов архитектуры).
|
||||
81
docs/work-items/ORCH-078/12-review.md
Normal file
81
docs/work-items/ORCH-078/12-review.md
Normal file
@@ -0,0 +1,81 @@
|
||||
---
|
||||
verdict: APPROVED
|
||||
work_item: ORCH-078
|
||||
stage: review
|
||||
author_agent: reviewer
|
||||
status: approved
|
||||
created_at: 2026-06-09
|
||||
model_used: claude-opus-4-8
|
||||
type: review
|
||||
work_item_id: ORCH-078
|
||||
version: 1
|
||||
---
|
||||
|
||||
# Review ORCH-078 — ORCH-52e: стандарт трассировки `ORCH-NNN` + правило чтения ADR
|
||||
|
||||
## Summary
|
||||
|
||||
Docs + prompts-only задача (слой 4 эпика ORCH-52). Проверено по 4 осям. Изменение **точно
|
||||
соответствует ТЗ и ADR-001 (D1–D7)**: введён нормативный стандарт `docs/_standards/TRACEABILITY.md`,
|
||||
точечно (аддитивно, без перезаписи 52d-канона) дополнены 3 промпта (developer/architect/reviewer),
|
||||
обновлены `CLAUDE.md` / `docs/architecture/README.md` / `CHANGELOG.md`, создан сквозной `adr-0022` +
|
||||
per-work-item `ADR-001`, расширен анти-регресс-тест.
|
||||
|
||||
Ключевые факты подтверждены прогоном:
|
||||
- `git diff --name-only origin/main` — изменены **только** `docs/**`, `.openclaw/agents/*.md`,
|
||||
`CLAUDE.md`, `CHANGELOG.md`, `tests/test_agent_prompts_canon.py`. **`src/**` не тронут** (AC-7 ✓).
|
||||
- `pytest tests/ -q` → **1253 passed**; `test_agent_prompts_canon.py` (53 — вкл. новые 9 TC) и
|
||||
`test_agent_frontmatter_no_model.py` зелёные. Machine-verdict ключи сохранены байт-в-байт.
|
||||
- **Самопроверяемость стандарта подтверждена против реального кода:** `src/serial_gate.py:241,269`
|
||||
действительно несёт `t2.id < jobs.task_id` + маркер `ORCH-088`; `src/merge_gate.py` несёт
|
||||
ORCH-043/065/071/073 (и др.); `grep -rhoE 'ORCH-[0-9]+' src/ | sort -u | wc -l` → ровно **51**.
|
||||
Цитируемые ADR (`ORCH-088/06-adr/ADR-001-serial-gate.md`) существуют. Трассировка рабочая.
|
||||
|
||||
Поскольку `src/` не менялся, ось «правка чужого маркированного кода без сверки с ADR» неприменима
|
||||
(нет маркированного кода в дифе) — нарушений трассировки нет по построению.
|
||||
|
||||
**Вердикт: APPROVED.** P0/P1 findings отсутствуют. Один P2 (несинхронный индекс ADR) — не блокер.
|
||||
|
||||
## Findings
|
||||
|
||||
### P0 — Blocker
|
||||
- Нет.
|
||||
|
||||
### P1 — Must fix
|
||||
- Нет.
|
||||
|
||||
### P2 — Should fix
|
||||
- [ ] **Индекс сквозных ADR не обновлён под adr-0022.** Создан новый cross-cutting
|
||||
`docs/architecture/adr/adr-0022-traceability-marker-standard.md`, но таблица-реестр в
|
||||
`docs/architecture/adr/README.md` (перечисляет adr-0001…adr-0021) **не получила строку adr-0022**.
|
||||
Это противоречит конвенции `CLAUDE.md` («Новые ADR добавляет архитектор») и устоявшемуся паттерну
|
||||
цепочки эпика 52 (adr-0019/0020/0021 — у каждого строка + footnote). Сам ADR-001 ORCH-078 (D6)
|
||||
заявляет adr-0022 как «точку входа для будущих агентов» — отсутствие строки в индексе подрывает
|
||||
именно тот discoverability-эффект, ради которого задача и делается. Дополнительно footnote индекса
|
||||
«текущий максимум — `0020`» устарел (уже 0022). **Не блокер:** adr-0022 остаётся достижим из
|
||||
`docs/architecture/README.md` (раздел «слой 4»), `TRACEABILITY.md` и work-item ADR.
|
||||
**Рекомендация:** добавить строку `| adr-0022 | Стандарт маркеров-трассировки ORCH-NNN + правило
|
||||
чтения ADR | proposed | 2026-06-09 | ORCH-078 |` и поправить footnote максимума.
|
||||
|
||||
### P3 — Nice to have
|
||||
- Нет.
|
||||
|
||||
## Документация
|
||||
|
||||
**Проверка обязательна — выполнена явно.** `src/**` НЕ изменён → P0-правило «изменён src без
|
||||
обновления документации» **не триггерится**. Профильная документация задачи обновлена полно:
|
||||
|
||||
| Документ | Статус |
|
||||
|----------|--------|
|
||||
| `docs/_standards/TRACEABILITY.md` | ✓ создан; 7 смысловых блоков (FR-1), реальный проверяемый пример, fallback, анти-археология, каноничное правило чтения |
|
||||
| `.openclaw/agents/developer.md` | ✓ правило чтения чужого маркера + fallback `git show origin/main:…` в формате «❌ X → ✅ Y» (AC-2, AC-4) |
|
||||
| `.openclaw/agents/architect.md` | ✓ правило чтения + анти-археология «3+ → сводный сквозной ADR» (AC-2, AC-5) |
|
||||
| `.openclaw/agents/reviewer.md` | ✓ усиление оси «Соответствие ADR» под-пунктом, finding ≥P1 (AC-3) |
|
||||
| `CLAUDE.md` | ✓ правило #9 + ссылка на `TRACEABILITY.md` (FR-7) |
|
||||
| `docs/architecture/README.md` | ✓ раздел «слой 4 (трассировка)» со ссылкой (FR-7) |
|
||||
| `CHANGELOG.md` | ✓ запись под `## [Unreleased]` (`docs`) |
|
||||
| `docs/work-items/ORCH-078/06-adr/ADR-001-*.md` | ✓ детальное решение D1–D7 |
|
||||
| `docs/architecture/adr/adr-0022-*.md` | ✓ файл создан, НО не внесён в индекс `adr/README.md` (см. P2) |
|
||||
|
||||
Анти-дубль (AC-6) соблюдён: промпты **ссылаются** на единый текст правила в `TRACEABILITY.md`, не
|
||||
копируют; 52d-канон (5 XML-секций, 52c-эмиссия) сохранён — врезки строго аддитивны.
|
||||
76
docs/work-items/ORCH-078/13-test-report.md
Normal file
76
docs/work-items/ORCH-078/13-test-report.md
Normal file
@@ -0,0 +1,76 @@
|
||||
---
|
||||
result: PASS # PASS | FAIL — машинный вердикт, UPPERCASE
|
||||
work_item: ORCH-078
|
||||
stage: testing
|
||||
author_agent: tester
|
||||
status: pass
|
||||
created_at: 2026-06-09
|
||||
model_used: claude-opus-4-8
|
||||
type: test-report
|
||||
work_item_id: ORCH-078
|
||||
---
|
||||
|
||||
# Test Report — ORCH-078 — ORCH-52e: трассировка `ORCH-NNN` (стандарт маркеров + правило чтения)
|
||||
|
||||
Repo: **orchestrator** (self-hosting) · Branch: `feature/ORCH-078-orch-52e-orch-nnn` · Стадия: **testing**
|
||||
Вердикт review (`12-review.md`): **APPROVED** ✓ — гейт пройден, регресс прогнан.
|
||||
|
||||
## Окружение
|
||||
- Python: 3.12.13
|
||||
- pytest: 8.3.3
|
||||
- Дата: 2026-06-09
|
||||
- Worktree: `/repos/_wt/orchestrator/feature_ORCH-078-orch-52e-orch-nnn`
|
||||
|
||||
### Smoke API (read-only, прод 8500)
|
||||
| Endpoint | Результат |
|
||||
|----------|-----------|
|
||||
| `GET /health` | `{"status":"ok","service":"orchestrator"}` — OK |
|
||||
| `GET /status` | OK — задача `ORCH-078` (id 71) видна на стадии `testing`; конвейер enduro-trails не затронут |
|
||||
| `GET /queue` | OK — breaker `closed`, preflight OK; `serial_gate.orchestrator.active_task = ORCH-078/testing`, репо не заморожен |
|
||||
|
||||
### Контроль scope (AC-7)
|
||||
`git diff --name-only origin/main` — изменены **только** `docs/**`, `.openclaw/agents/*.md`,
|
||||
`tests/test_agent_prompts_canon.py`, `CLAUDE.md`, `CHANGELOG.md`. **`src/**` НЕ тронут** →
|
||||
поведение кода идентично, нулевая функциональная регрессия (enduro-trails не затронут).
|
||||
|
||||
## Результаты
|
||||
|
||||
| TC ID | Описание | Результат |
|
||||
|-------|----------|-----------|
|
||||
| TC-01 | `docs/_standards/TRACEABILITY.md` существует и непустой (AC-1) | PASS |
|
||||
| TC-02 | TRACEABILITY.md описывает формат `ORCH-NNN` + правило размещения у нетривиального инварианта (AC-1) | PASS |
|
||||
| TC-03 | TRACEABILITY.md содержит реальный пример: существующий `src/...py` + `docs/work-items/ORCH-NNN/06-adr/...md` (AC-1) | PASS |
|
||||
| TC-04 | TRACEABILITY.md документирует fallback `git show origin/main:docs/work-items/...` (AC-4) | PASS |
|
||||
| TC-05 | TRACEABILITY.md документирует анти-археологию: 3+ маркеров → сводный сквозной ADR `docs/architecture/adr/` (AC-5) | PASS |
|
||||
| TC-06 | `developer.md`: правило чтения чужого маркера + ссылка на TRACEABILITY.md + fallback `git show origin/main:` (AC-2, AC-4) | PASS |
|
||||
| TC-07 | `architect.md`: правило чтения + анти-археология (3+ → сквозной ADR) + ссылка на TRACEABILITY.md (AC-2, AC-5) | PASS |
|
||||
| TC-08 | `reviewer.md`: ось контроля — правка маркированного кода без сверки с ADR → finding (AC-3) | PASS |
|
||||
| TC-09 | АНТИ-РЕГРЕСС 52d: 5 XML-секций + 6 полей 52c-схемы во всех 6 промптах (NFR-2) | PASS |
|
||||
| TC-10 | АНТИ-РЕГРЕСС 52d: machine-verdict ключи байт-в-байт (`verdict:`/`result:`/`staging_status:`/`deploy_status:`/`security_status:`) (NFR-2) | PASS |
|
||||
| TC-11 | frontmatter промптов валиден без ключа `model:` (`test_agent_frontmatter_no_model.py`) (NFR-2) | PASS |
|
||||
| TC-12 | `CLAUDE.md` и `docs/architecture/README.md` ссылаются на TRACEABILITY.md как слой 4 эпика 52 (AC-8) | PASS |
|
||||
| TC-13 | Полный регресс `pytest tests/` зелёный; `src/` не изменён (AC-7) | PASS |
|
||||
|
||||
Все 13 TC из `04-test-plan.yaml` выполнены и сопоставлены с критериями `03-acceptance-criteria.md`
|
||||
(AC-1…AC-8). Расхождений нет.
|
||||
|
||||
## Вывод pytest
|
||||
|
||||
```
|
||||
$ python -m pytest tests/ -v --tb=short
|
||||
...
|
||||
======================= 1253 passed, 1 warning in 34.31s =======================
|
||||
```
|
||||
|
||||
Целевые анти-регресс-файлы (TC-01…TC-12):
|
||||
```
|
||||
$ python -m pytest tests/test_agent_prompts_canon.py tests/test_agent_frontmatter_no_model.py -q
|
||||
53 passed, 1 warning in 0.43s
|
||||
```
|
||||
|
||||
(Единственный warning — внешний `PydanticDeprecatedSince20` из `src/config.py`, не относится к задаче,
|
||||
не является провалом теста.)
|
||||
|
||||
## Итог
|
||||
**PASS** — все 1253 теста зелёные, оба анти-регресс-файла (53 теста) зелёные, smoke API OK,
|
||||
`src/**` не изменён (scope соответствует AC-7). Задача готова к переходу на стадию `deploy-staging`.
|
||||
12
docs/work-items/ORCH-078/14-deploy-log.md
Normal file
12
docs/work-items/ORCH-078/14-deploy-log.md
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
deploy_status: SUCCESS
|
||||
work_item: ORCH-078
|
||||
hook_exit_code: 0
|
||||
deployed_by: deploy-finalizer
|
||||
---
|
||||
|
||||
# Deploy log — ORCH-036 executable self-deploy
|
||||
|
||||
Прод-деплой завершён хост-хуком с exit-code `0` -> `deploy_status: SUCCESS`.
|
||||
|
||||
Вердикт зафиксирован детерминированным finalizer'ом (Фаза C), не LLM.
|
||||
@@ -17,10 +17,11 @@ import pytest
|
||||
_AGENTS = ("analyst", "architect", "developer", "reviewer", "tester", "deployer")
|
||||
|
||||
# tests/ is one level under the repo root; .openclaw/agents lives at the root.
|
||||
_AGENTS_DIR = os.path.join(
|
||||
os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
|
||||
".openclaw", "agents",
|
||||
)
|
||||
_REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
_AGENTS_DIR = os.path.join(_REPO_ROOT, ".openclaw", "agents")
|
||||
|
||||
# ORCH-078 (ORCH-52e): the traceability-marker standard (layer 4 of epic ORCH-52).
|
||||
_TRACEABILITY = os.path.join(_REPO_ROOT, "docs", "_standards", "TRACEABILITY.md")
|
||||
|
||||
# The 5 mandatory XML sections, in normative order (D1 / AC-1).
|
||||
_REQUIRED_SECTIONS = ("context", "task", "deliverables", "constraints", "output_format")
|
||||
@@ -94,6 +95,11 @@ def _read(agent: str) -> str:
|
||||
return f.read()
|
||||
|
||||
|
||||
def _read_repo(*parts: str) -> str:
|
||||
with open(os.path.join(_REPO_ROOT, *parts), encoding="utf-8") as f:
|
||||
return f.read()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("agent", _AGENTS)
|
||||
def test_five_xml_sections_present(agent):
|
||||
"""TC-01: each prompt carries all 5 XML sections (open + close tag)."""
|
||||
@@ -163,3 +169,92 @@ def test_role_anti_regress_markers(agent):
|
||||
text = _read(agent)
|
||||
for marker in _ANTI_REGRESS[agent]:
|
||||
assert marker in text, f"{agent}.md lost anti-regress marker {marker!r}"
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# ORCH-078 (ORCH-52e): traceability-marker standard + reading-rule anti-regress
|
||||
# (TRZ §FR-1..FR-8; AC-1..AC-5, AC-8). Pure-text checks, NO `src/` import.
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def test_traceability_standard_exists_and_nonempty():
|
||||
"""TC-01 (AC-1): docs/_standards/TRACEABILITY.md exists and is non-empty."""
|
||||
assert os.path.isfile(_TRACEABILITY), "docs/_standards/TRACEABILITY.md is missing"
|
||||
assert _read_repo("docs", "_standards", "TRACEABILITY.md").strip(), (
|
||||
"TRACEABILITY.md is empty"
|
||||
)
|
||||
|
||||
|
||||
def test_traceability_describes_marker_format_and_placement():
|
||||
"""TC-02 (AC-1): standard describes the ORCH-NNN marker and where it is placed."""
|
||||
text = _read_repo("docs", "_standards", "TRACEABILITY.md")
|
||||
assert "ORCH-NNN" in text, "TRACEABILITY.md does not describe the ORCH-NNN marker"
|
||||
# placement rule: next to a non-trivial invariant (not on trivial code).
|
||||
assert "инвариант" in text, "TRACEABILITY.md does not state the placement rule"
|
||||
|
||||
|
||||
def test_traceability_has_real_verifiable_example():
|
||||
"""TC-03 (AC-1): the worked example points at files that really exist in main.
|
||||
|
||||
A traceability standard whose example references a missing file/ADR would
|
||||
refute itself, so the example must be checkable against the repo tree.
|
||||
"""
|
||||
text = _read_repo("docs", "_standards", "TRACEABILITY.md")
|
||||
assert "src/serial_gate.py" in text and "ORCH-088" in text, (
|
||||
"TRACEABILITY.md lacks the serial_gate/ORCH-088 worked example"
|
||||
)
|
||||
assert os.path.isfile(os.path.join(_REPO_ROOT, "src", "serial_gate.py")), (
|
||||
"example references src/serial_gate.py which does not exist"
|
||||
)
|
||||
assert os.path.isfile(os.path.join(
|
||||
_REPO_ROOT, "docs", "work-items", "ORCH-088", "06-adr",
|
||||
"ADR-001-serial-gate.md",
|
||||
)), "example references an ORCH-088 ADR that does not exist"
|
||||
|
||||
|
||||
def test_traceability_documents_fallback_access():
|
||||
"""TC-04 (AC-4): standard documents the git show origin/main fallback."""
|
||||
text = _read_repo("docs", "_standards", "TRACEABILITY.md")
|
||||
assert "git show origin/main:docs/work-items/" in text, (
|
||||
"TRACEABILITY.md does not document the cross-branch ADR fallback"
|
||||
)
|
||||
|
||||
|
||||
def test_traceability_documents_anti_archeology():
|
||||
"""TC-05 (AC-5): standard documents the 3+ markers -> cross-cutting ADR rule."""
|
||||
text = _read_repo("docs", "_standards", "TRACEABILITY.md")
|
||||
assert "docs/architecture/adr/" in text, (
|
||||
"TRACEABILITY.md anti-archeology rule does not point at the cross-cutting ADR dir"
|
||||
)
|
||||
assert "3+" in text, "TRACEABILITY.md does not state the 3+ markers threshold"
|
||||
|
||||
|
||||
def test_developer_carries_reading_rule_and_fallback():
|
||||
"""TC-06 (AC-2, AC-4): developer.md carries the reading rule + standard + fallback."""
|
||||
text = _read("developer")
|
||||
assert "TRACEABILITY.md" in text, "developer.md does not reference TRACEABILITY.md"
|
||||
assert "git show origin/main:docs/work-items/" in text, (
|
||||
"developer.md does not carry the cross-branch ADR fallback"
|
||||
)
|
||||
|
||||
|
||||
def test_architect_carries_reading_rule_and_anti_archeology():
|
||||
"""TC-07 (AC-2, AC-5): architect.md carries reading rule + anti-archeology."""
|
||||
text = _read("architect")
|
||||
assert "TRACEABILITY.md" in text, "architect.md does not reference TRACEABILITY.md"
|
||||
assert "3+" in text, "architect.md does not carry the 3+ markers anti-archeology rule"
|
||||
|
||||
|
||||
def test_reviewer_carries_traceability_control_axis():
|
||||
"""TC-08 (AC-3): reviewer.md carries the traceability-compliance control axis."""
|
||||
text = _read("reviewer")
|
||||
assert "TRACEABILITY.md" in text, "reviewer.md does not reference TRACEABILITY.md"
|
||||
|
||||
|
||||
def test_claude_md_and_readme_reference_traceability_standard():
|
||||
"""TC-12 (AC-8): CLAUDE.md and architecture README reference the standard."""
|
||||
assert "TRACEABILITY.md" in _read_repo("CLAUDE.md"), (
|
||||
"CLAUDE.md does not reference docs/_standards/TRACEABILITY.md"
|
||||
)
|
||||
assert "TRACEABILITY.md" in _read_repo("docs", "architecture", "README.md"), (
|
||||
"architecture README does not reference docs/_standards/TRACEABILITY.md"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user