From d60980c14936f7ec53776566f9bc83086e6ff1c2 Mon Sep 17 00:00:00 2001 From: claude-bot Date: Mon, 15 Jun 2026 22:49:43 +0300 Subject: [PATCH] analyst(ET): auto-commit from analyst run_id=722 --- docs/work-items/ORCH-118/01-brd.md | 154 ++++++++++++++++++ docs/work-items/ORCH-118/02-trz.md | 152 +++++++++++++++++ .../ORCH-118/03-acceptance-criteria.md | 124 ++++++++++++++ docs/work-items/ORCH-118/04-test-plan.yaml | 80 +++++++++ 4 files changed, 510 insertions(+) create mode 100644 docs/work-items/ORCH-118/01-brd.md create mode 100644 docs/work-items/ORCH-118/02-trz.md create mode 100644 docs/work-items/ORCH-118/03-acceptance-criteria.md create mode 100644 docs/work-items/ORCH-118/04-test-plan.yaml diff --git a/docs/work-items/ORCH-118/01-brd.md b/docs/work-items/ORCH-118/01-brd.md new file mode 100644 index 0000000..f4d1773 --- /dev/null +++ b/docs/work-items/ORCH-118/01-brd.md @@ -0,0 +1,154 @@ +--- +work_item: ORCH-118 +stage: analysis +author_agent: analyst +status: ready-for-review +created_at: 2026-06-15 +model_used: claude-opus-4-8 +--- + +# 01 — BRD (бизнес-требования): ORCH-118 — replace avoidable LLM control paths with deterministic implementations + +Work Item: **ORCH-118** · Repo: **orchestrator** · Стадия: analysis + +> ⚠️ **Inventory-first.** Это **зонтичная inventory/architecture-задача**, а НЕ реализация +> детерминированных раннеров. Её результат — **карта** всех мест вызова LLM + классификация + +> упорядоченный roadmap + нормативная политика использования LLM, защищённая структурными тестами. +> Реализация конкретных замен (tester — ORCH-115, deployer — ORCH-116 и др.) — **последующие +> задачи**, запускаемые ПОСЛЕ утверждения карты. Их код в ORCH-118 **не вносится** (см. §2 «Вне объёма»). + +--- + +## 1. Бизнес-контекст и проблема + +Зонтичный follow-up по итогам RCA-цепочки **ORCH-114/117** (и предшествующих ORCH-110/111/112/113): +корневым классом инцидентов было то, что **side-effectful и решающие control-path'ы не имели единого +детерминированного владения** — где-то решение принималось «потому что так удобно» через LLM-агента, +хотя по сути это исполнение фиксированных команд и маппинг результата. + +Установленный факт по текущему коду (инвентаризация — §1 TRZ, артефакт-карта): + +- В оркестраторе **ровно одна точка запуска LLM** — `src/agents/launcher.py::_spawn` (одна + `subprocess.Popen` сборка Claude CLI), которой пользуются **6 ролей-агентов** (analyst, architect, + developer, reviewer, tester, deployer). +- **Все остальные control-path'ы уже детерминированы (без LLM):** маршрутизация стадий + (`STAGE_TRANSITIONS`/`advance_stage`), все Quality Gate'ы и под-гейты (`check_*`, security/merge/ + coverage/image-freshness), парсеры вердиктов (`_parse_*` через `frontmatter.py`), классификатор + ретраев (`error_classifier.py`), serial-gate/transition-lease/reconciler/reaper, а также **две + зарезервированные job-роли** `deploy-finalizer` и `post-deploy-monitor` (перехватываются в + `launch_job` **до** `_spawn` — это рабочий прецедент детерминированной замены агента). +- Среди 6 LLM-ролей **tester** и **deployer** по факту почти полностью исполняют детерминированные + команды (`pytest`, `staging_check.py`, exit-code → вердикт; прод-деплой на self-hosting уже идёт + детерминированным путём Phase A/B/C, ORCH-036), завёрнутые в LLM «для удобства». + +Боль/риск, который закрывает задача: LLM на механических путях — это (а) лишний источник +недетерминизма и инцидентов (ложный вердикт/действие), (б) задержка (запуск opus-агента вместо +прямого вызова), (в) расход токенов/денег. При этом «вслепую» убирать LLM нельзя — часть путей несёт +**настоящее суждение** (анализ, архитектура, написание кода, ревью), и автономность/гибкость должны +сохраниться. + +ORCH-118 даёт **доказательную карту** «где LLM действительно нужен, а где это удобство» и +**упорядоченный план** безопасных замен — фундамент, на котором ORCH-115/116 (и возможные следующие +срезы) выполняются предсказуемо и без регресса. + +## 2. Объём (scope) + +### В объёме +- **BR-1** Полная инвентаризация всех мест вызова LLM и всех ролей-агентов (карта call-site'ов). +- **BR-2** Классификация каждого call-site в один из 4 классов (keep / replace-now / replace-later / + hybrid-fallback) с явным обоснованием. +- **BR-3** Доказательное подтверждение (с привязкой `file:line`), что не-агентские control-path'ы + (маршрутизация / ретраи / QG / парсеры / finalizer'ы) уже детерминированы. +- **BR-4** Упорядоченный roadmap замен: зависимости, оценка экономии токенов/времени, риски + безопасности, потребность в hybrid-fallback, рекомендованный **первый срез**. +- **BR-5** Нормативная **политика использования LLM** («LLM — только там, где нужно настоящее + суждение») как durable-документ. +- **BR-6** Структурные regression-тесты, **прибивающие инварианты карты к коду** (единственная точка + запуска; детерминированные модули не несут запуска LLM; карта покрывает все промпты) — анти-дрейф. +- **BR-7** Явно позиционировать ORCH-115 (tester) и ORCH-116 (deployer) как **кандидаты-follow-up**. + +### Вне объёма +- ❌ **Реализация** детерминированных раннеров tester/deployer (ORCH-115/116) и любых других замен — + это отдельные задачи ПОСЛЕ утверждения карты (явное требование заказчика в business request). +- ❌ Изменение `STAGE_TRANSITIONS` / реестра `QG_CHECKS` / семантики и имён `check_*` / + machine-verdict-ключей (`verdict:`/`result:`/`staging_status:`/`deploy_status:`/`security_status:`/ + `coverage_status:`) / схемы БД. +- ❌ Включение model-routing (G3 ORCH-41) или смена модели/эффорта ролей. +- ❌ Любая правка поведения `src/**` в рантайме (ORCH-118 — **docs + tests only**, по образцу + ORCH-077/079/101/102/103/011). +- ❌ Снижение автономности или гибкости конвейера. + +## 3. Заинтересованные стороны +- **Заказчик / Owner** — инициатор RCA-трека ORCH-114/117; принимает карту и roadmap (gate утверждения). +- **Сопровождающие платформы (self-hosting)** — выигрывают в стабильности, скорости, экономии токенов. +- **Downstream-проекты (enduro-trails)** — делят общий прод/очередь; для них требуется **нулевая + регрессия** (NFR-1). +- **Будущие исполнители ORCH-115/116/…** — потребители карты, roadmap и политики. + +## 4. Бизнес-требования (BR) + +- **BR-1 — Инвентарь call-site'ов LLM.** Выпустить durable-документ, перечисляющий **каждое** место, + где LLM вызывается или может быть вызван: единственную точку `_spawn`, все 6 ролей-агентов и обе + зарезервированные детерминированные job-роли (как доказательство «уже без LLM»). Для каждого — + `file:line`, триггер, стадия/владелец, выходной артефакт, machine-verdict-ключ (если есть), оценка + токенов/времени. Проверяемо: каждый `file:line` резолвится в реальный код. +- **BR-2 — Классификация.** Каждому call-site присвоить **ровно один** класс из таксономии: + `keep-LLM` (нужно настоящее суждение), `replace-deterministic-now` (безопасная замена сейчас), + `replace-later/risky` (замена позже / рискованно), `needs-hybrid-fallback` (детерминированное ядро + + LLM-фолбэк на суждение). Для `keep-LLM` — **назвать конкретное суждение**, ради которого LLM + сохраняется. +- **BR-3 — Подтверждение детерминизма не-агентских путей.** Документально, с `file:line`-доказательством, + зафиксировать, что маршрутизация стадий, ретраи, QG-проверки, парсеры вердиктов и finalizer'ы **не + вызывают LLM**. Если инвентаризация найдёт неожиданный LLM-путь — он попадает в карту и + классификацию. +- **BR-4 — Упорядоченный roadmap.** Ранжированный план замен: для каждого кандидата — зависимости, + **оценка** экономии токенов/времени (из телеметрии `agent_runs`), риск безопасности, нужен ли + hybrid-fallback, ожидание kill-switch/обратимости, привязка к follow-up work item. Явно указать + **рекомендованный первый срез** и обоснование выбора. +- **BR-5 — Политика использования LLM.** Нормативный durable-документ: «LLM — только там, где требуется + настоящее суждение»; критерии решения keep vs replace; требование к новым/изменённым control-path'ам + обосновывать любое использование LLM против этой политики. +- **BR-6 — Анти-дрейф структурными тестами.** Тесты, привязывающие инварианты карты к коду: + единственная точка запуска LLM; перечисленные детерминированные модули/job-роли не несут запуска; + карта перечисляет ровно те 6 промптов, что лежат в `.openclaw/agents/`; классификация покрывает все + call-site'ы по одному разу. Тесты — offline (без сети/LLM/subprocess-к-модели). +- **BR-7 — Позиционирование follow-up'ов.** Карта/roadmap явно отмечают ORCH-115 (tester) и ORCH-116 + (deployer) как кандидаты-замены, **не** реализуемые в ORCH-118; их старт гейтится утверждением карты. + +## 5. Нефункциональные требования (NFR) + +- **NFR-1 — Сохранение поведения (нулевая регрессия).** ORCH-118 — docs+tests only: + `STAGE_TRANSITIONS`/`QG_CHECKS`/`check_*`/machine-verdict-ключи/схема БД — **байт-в-байт**; поведение + конвейера 1:1; enduro-trails не затронут. +- **NFR-2 — Сохранение автономности и гибкости.** Ни инвентаризация, ни политика не должны + предлагать решений, снижающих автономный/пакетный режим (ORCH-088/089) или гибкость; политика + **защищает** автономность как инвариант любой будущей замены. +- **NFR-3 — Self-hosting безопасность.** Задача только **читает** код и пишет docs+tests — не + деплоит, не рестартит прод-контейнер, не трогает `main`/force-push, не запускает процессов/сети. +- **NFR-4 — Трассируемость и сопровождаемость.** Карта привязана к коду маркерами/тестом и остаётся + честной при эволюции кода; формат — по `docs/_standards/PIPELINE_DOCS.md` и `TRACEABILITY.md`. +- **NFR-5 — Доказательность экономии.** Цифры экономии берутся из реальной телеметрии `agent_runs` + (модель/эффорт/токены/стоимость/время по ролям) и помечаются как **оценки** до фактического замера + после реализации. + +## 6. Допущения и ограничения +- Единственный транспорт LLM сейчас — Claude CLI через `launcher._spawn`; прямых вызовов Anthropic API + в `src/**` нет (подтверждается инвентаризацией). +- Model-routing не включён — все 6 ролей на `claude-opus-4-8` (ORCH-41), что упрощает оценку экономии. +- Карта — **снимок на момент задачи**, защищённый структурными тестами от тихого расхождения с кодом. +- Прецедент детерминированной замены агента уже существует и работает (`deploy-finalizer`/ + `post-deploy-monitor` в `launch_job` до `_spawn`) — это снижает архитектурный риск follow-up'ов. + +## 7. Критерии успеха +Карта call-site'ов полна и привязана к коду; каждый site классифицирован с обоснованием; детерминизм +не-агентских путей доказан; есть упорядоченный roadmap с зависимостями/экономией/рисками и +рекомендованным первым срезом; есть нормативная политика; структурные тесты зелёные и осмысленные; +ни один рантайм-инвариант не тронут; ORCH-115/116 НЕ реализованы. Детальные PASS/FAIL — в +`03-acceptance-criteria.md`. + +## 8. Риски +- **Недо-/пере-классификация** (LLM убран там, где нужно суждение, или сохранён там, где не нужен) → + митигирует требование «назвать конкретное суждение» для `keep-LLM` и ревью карты. +- **Дрейф карты** относительно кода со временем → митигируют структурные тесты (BR-6). +- **Преждевременная замена** в погоне за экономией ценой автономности/гибкости → инвентаризация + отделена от реализации; первый срез — самый низкорисковый. Детали — `10-tech-risks.md` (архитектор). diff --git a/docs/work-items/ORCH-118/02-trz.md b/docs/work-items/ORCH-118/02-trz.md new file mode 100644 index 0000000..a2bd34a --- /dev/null +++ b/docs/work-items/ORCH-118/02-trz.md @@ -0,0 +1,152 @@ +--- +work_item: ORCH-118 +stage: analysis +author_agent: analyst +status: ready-for-review +created_at: 2026-06-15 +model_used: claude-opus-4-8 +--- + +# 02 — ТЗ (TRZ): ORCH-118 — replace avoidable LLM control paths with deterministic implementations + +Work Item: **ORCH-118** · Repo: **orchestrator** · Стадия: analysis + +> ТЗ описывает **что** должно измениться и **где** (артефакты/контракты/тесты), выведено из BRD и +> фактического кода. **Как** (точная структура/размещение документов карты, формат классификации, +> схема структурных тестов) — решает архитектор в `06-adr/`. ТЗ фиксирует требования и границы. +> +> ⚠️ **Скоуп — inventory + классификация + roadmap + политика + структурные тесты.** Реализация +> детерминированных раннеров (ORCH-115/116) — **вне скоупа** (FR-7). Это **docs + tests only**: +> `src/**`-рантайм не меняется. + +--- + +## 1. Сводка изменения + +Выпустить **доказательную карту** всех мест вызова LLM в оркестраторе с классификацией и +упорядоченным roadmap'ом детерминированных замен, а также нормативную **политику использования LLM**; +прибить инварианты карты к коду набором **структурных тестов**. Реализация замен не входит. Все +рантайм-контракты (`STAGE_TRANSITIONS` / `QG_CHECKS` / `check_*` / machine-verdict-ключи / схема БД) — +**не меняются**. + +Опорный факт инвентаризации (ground-truth кода на момент задачи): + +| # | Call-site (LLM-capable) | Где | Что делает | +|---|--------------------------|-----|------------| +| S0 | **Единственная точка запуска** | `src/agents/launcher.py::_spawn` (сборка Claude CLI + `subprocess.Popen`) | запускает любую из 6 ролей | +| A1 | analyst | промпт `.openclaw/agents/analyst.md`, стадия `analysis` | анализ бизнес-запроса → 01–04 | +| A2 | architect | `.openclaw/agents/architect.md`, стадия `architecture` | архитектурные решения → 06-adr | +| A3 | developer | `.openclaw/agents/developer.md`, стадия `development` | реализация + PR | +| A4 | reviewer | `.openclaw/agents/reviewer.md`, стадия `review` | ревью → `12-review.md` (`verdict:`) | +| A5 | tester | `.openclaw/agents/tester.md`, стадия `testing` | `pytest`+smoke → `13-test-report.md` (`result:`) | +| A6 | deployer | `.openclaw/agents/deployer.md`, стадии `deploy-staging`/`deploy` | `staging_check.py`/exit-code → `15`/`14` логи | +| D1 | deploy-finalizer | `launch_job` перехват **до** `_spawn` | детерминированный (LLM не запускается) | +| D2 | post-deploy-monitor | `launch_job` перехват **до** `_spawn` | детерминированный (LLM не запускается) | + +> Не-агентские control-path'ы (маршрутизация `advance_stage`, `QG_CHECKS`/`check_*`/`_parse_*`, +> `error_classifier`, `serial_gate`/`merge_gate`/`coverage_gate`/`security_gate`/`staging_verdict`/ +> `review_parse`/`frontmatter`, `self_deploy` Phase A/B/C) — **уже детерминированы** (FR-3). + +## 2. Задействованные модули / пути + +| Путь | Действие | +|------|----------| +| `src/agents/launcher.py` | **читать** (инвентарь S0/D1/D2; `_spawn`, `launch_job`, `AGENT_CONFIGS`, `resolve_agent_model/effort`) — **не менять** | +| `.openclaw/agents/{analyst,architect,developer,reviewer,tester,deployer}.md` | **читать** (инвентарь 6 ролей) — **не менять** | +| `src/stages.py`, `src/stage_engine.py` | **читать** (доказать детерминизм маршрутизации) — **не менять** | +| `src/qg/checks.py` | **читать** (`QG_CHECKS`/`check_*`/`_parse_*` — детерминизм) — **не менять** | +| `src/{serial_gate,merge_gate,coverage_gate,security_gate,staging_verdict,review_parse,error_classifier,frontmatter,self_deploy,post_deploy,transition_lease,reconciler,job_reaper}.py` | **читать** (детерминированные leaf'ы — доказательная база) — **не менять** | +| `src/usage.py`, `src/db.py` (`agent_runs`) | **читать** (источник оценок экономии токенов/времени) — **не менять** | +| `docs/architecture/llm-call-sites.md` *(имя — пример; финально решает архитектор)* | **создать**: карта call-site'ов + классификация (FR-1/FR-2/FR-3) | +| `docs/architecture/llm-determinization-roadmap.md` *(имя — пример)* | **создать**: упорядоченный roadmap (FR-4) | +| `docs/architecture/llm-usage-policy.md` *(имя — пример)* | **создать**: нормативная политика (FR-5) | +| `docs/work-items/ORCH-118/06-adr/ADR-001-*.md` | **создать** (архитектор): фиксация карты/таксономии/первого среза как ADR | +| `tests/test_llm_call_site_inventory.py` *(имя — пример)* | **создать**: структурные анти-дрейф тесты (FR-6) | +| `docs/architecture/README.md`, `docs/overview/*`, `CHANGELOG.md` | **обновить** (ссылка на карту/политику; норматив golden-source) | + +> Документы карты/политики целесообразно разместить в `docs/architecture/` (durable, сквозное), а не +> только в `docs/work-items/ORCH-118/` — окончательное размещение/формат решает архитектор. + +## 3. Функциональные требования + +### FR-1 — Полнота и привязка инвентаря (BR-1) +Карта перечисляет **каждый** LLM-capable call-site: `S0` (единственный `_spawn`), `A1…A6` (6 ролей), +`D1/D2` (детерминированные job-роли — как доказательство паттерна). Поля записи: `id`, `location` +(`file:line`), `trigger`, `stage/owner`, `output artifact`, `machine-verdict key` (если есть), +`est. tokens/runtime`, `classification`, `rationale`, `dependency`, `risk`. Каждый `file:line` +обязан резолвиться в реальный код. Инвариант: иных мест запуска LLM в `src/**`, кроме `S0`, нет — и +это подтверждается тестом FR-6(a). + +### FR-2 — Таксономия классификации (BR-2) +Ровно 4 взаимоисключающих класса с определениями: +- `keep-LLM` — нужно настоящее суждение; **обязательно назвать** конкретное суждение. +- `replace-deterministic-now` — безопасная детерминированная замена сейчас. +- `replace-later/risky` — замена возможна, но позже / с риском (нужны предпосылки). +- `needs-hybrid-fallback` — детерминированное ядро + LLM-фолбэк только на суждение. + +Каждому call-site присвоен **ровно один** класс. Ожидаемое (из инвентаризации; финальное решение +фиксирует архитектор в ADR): `analyst/architect/developer/reviewer → keep-LLM`; +`tester → needs-hybrid-fallback` (детерминированный прогон `pytest`+smoke, LLM-суждение только на +маппинг TC↔критерии / триаж падений) — кандидат **ORCH-115**; `deployer → replace-deterministic-now` +или `replace-later/risky` (staging = exit-code-маппинг; прод self-hosting уже детерминирован Phase +A/B/C) — кандидат **ORCH-116**; `deploy-finalizer/post-deploy-monitor → already-deterministic` (вне +таксономии замен, как эталон). + +### FR-3 — Подтверждение детерминизма не-агентских путей (BR-3) +Карта отдельным разделом фиксирует, с `file:line`-доказательством, что НЕ вызывают LLM: +маршрутизация (`advance_stage`/`STAGE_TRANSITIONS`), все `QG_CHECKS`/`check_*`, парсеры вердиктов +(`_parse_*` через `frontmatter.parse_frontmatter`), `error_classifier` (regex), под-гейты +(security/merge/coverage/image-freshness), `self_deploy` Phase A/B/C, reconciler/reaper/serial-gate/ +transition-lease. Любой найденный неожиданный LLM-путь добавляется в инвентарь (FR-1) и +классифицируется (FR-2). + +### FR-4 — Упорядоченный roadmap замен (BR-4) +Ранжированный список кандидатов; для каждого: зависимости (предпосылки/блокеры), **оценка** экономии +токенов/времени (из `agent_runs`), риск безопасности, нужен ли hybrid-fallback, ожидание +kill-switch/обратимости, привязка к follow-up work item (ORCH-115/116/…). Явно: **рекомендованный +первый срез** + обоснование (самый низкорисковый, опирающийся на существующий прецедент D1/D2). + +### FR-5 — Политика использования LLM (BR-5) +Нормативный durable-документ: принцип «LLM — только где нужно настоящее суждение»; критерии решения +keep vs replace (детерминируемость выхода, наличие machine-verdict, обратимость, влияние на +автономность); требование к новым/изменённым control-path'ам обосновывать любое использование LLM +против политики. Может включать рекомендацию reviewer-оси (как ORCH-079) — **как требование, не как +реализацию гейта** (новый QG не вводится, FR-6 §QG). + +### FR-6 — Структурные анти-дрейф тесты (BR-6) +Новый offline-тест-файл (без сети/LLM/subprocess-к-модели), проверяющий инварианты карты: +- **(a)** В `src/**` ровно **одна** точка сборки/запуска Claude CLI (поиск по `CLAUDE_BIN` + + `--system-prompt` + `Popen`/`bash -c`), и это `launcher._spawn`. +- **(b)** Перечисленные детерминированные модули и обработчики `D1/D2` **не** содержат запуска LLM. +- **(c)** Карта перечисляет ровно те промпт-файлы, что физически лежат в `.openclaw/agents/` + (двусторонняя сверка — нет дрейфа). +- **(d)** Классификация покрывает каждый перечисленный call-site **ровно один раз** (тотальность, + без дублей/пропусков). +- **(e)** `D1/D2` действительно перехватываются в `launch_job` **до** `_spawn` (детерминированы). + +### FR-7 — Скоуп-гард (BR-7) +ORCH-115/116 (и любые другие замены) **не реализуются** в ORCH-118. Карта/roadmap явно помечают их +как кандидаты-follow-up, старт которых гейтится утверждением карты. Тест/диф не должны содержать новых +детерминированных раннеров tester/deployer. + +## 4. Изменения API +Нет. (Опциональная read-only наблюдаемость в `GET /queue`/`GET /metrics` — **вне скоупа** ORCH-118; +если архитектор сочтёт полезным — отдельная аддитивная врезка, но не требуется этой задачей.) + +## 5. Изменения схемы БД +Нет. (Источник оценок экономии — существующие колонки `agent_runs`: `model`/`effort`/токены/стоимость/ +время; только чтение.) + +## 6. Требования к новым/изменённым QG checks +Нет. `QG_CHECKS` / `check_*` / `_parse_*` / machine-verdict-ключи — **байт-в-байт**. Структурные тесты +FR-6 — обычные `pytest`-тесты, **не** Quality Gate и **не** стадия. Политика LLM (FR-5) — нормативный +документ, а не машинный гейт. + +## 7. Совместимость / регресс +- **Docs + tests only:** рантайм `src/**` не меняется → нулевая регрессия; enduro-trails не затронут; + kill-switch не нужен (нет рантайм-поведения), как в ORCH-077/079/101/102/103/011. +- **Обратимость:** артефакты — документы и тесты; откат = удаление/правка docs (рантайм-риска нет). +- **Анти-дрейф:** структурные тесты держат карту синхронной с кодом; норматив сопровождения — «менял + места вызова LLM → обнови карту и политику в том же PR» (фиксируется в политике и golden-source + docs). +- **Self-hosting:** не деплоит/не рестартит прод/не трогает `main` — безопасно для общего инстанса. diff --git a/docs/work-items/ORCH-118/03-acceptance-criteria.md b/docs/work-items/ORCH-118/03-acceptance-criteria.md new file mode 100644 index 0000000..5d11b9d --- /dev/null +++ b/docs/work-items/ORCH-118/03-acceptance-criteria.md @@ -0,0 +1,124 @@ +--- +work_item: ORCH-118 +stage: analysis +author_agent: analyst +status: ready-for-review +created_at: 2026-06-15 +model_used: claude-opus-4-8 +--- + +# 03 — Критерии приёмки (Acceptance Criteria): ORCH-118 — replace avoidable LLM control paths with deterministic implementations + +Work Item: **ORCH-118** · Repo: **orchestrator** · Стадия: analysis + +Формат: каждый критерий имеет **PASS** (что должно быть истинно для приёмки) и **FAIL** (что считается +провалом). Reviewer/тестер проверяет их буквально по файлам репозитория. Напоминание: ORCH-118 — +**inventory-first**, docs+tests only; реализация раннеров (ORCH-115/116) приёмкой **запрещена** в этой +задаче (AC-7). + +--- + +## AC-1 — Полнота и привязка инвентаря call-site'ов + +**Условие:** Документ-карта перечисляет каждый LLM-capable call-site с обязательными полями, привязанными к коду. +- **PASS:** Карта содержит `S0` (`launcher._spawn` — единственная точка запуска), все 6 ролей + (analyst/architect/developer/reviewer/tester/deployer) и обе детерминированные job-роли + (deploy-finalizer/post-deploy-monitor); у каждой записи заполнены `location (file:line)` / `trigger` / + `stage/owner` / `output` / `machine-verdict key (если есть)` / `est. tokens-runtime` / + `classification` / `rationale`; каждый `file:line` резолвится в реальный код. +- **FAIL:** Пропущен любой LLM-capable site; отсутствует любое обязательное поле; `file:line` не + резолвится; заявлена «вторая точка запуска LLM», не подтверждённая кодом. + +--- + +## AC-2 — Классификация по таксономии (4 класса, тотально и однозначно) + +**Условие:** Каждый перечисленный call-site отнесён ровно к одному классу с обоснованием. +- **PASS:** Таксономия определена явно (`keep-LLM` / `replace-deterministic-now` / + `replace-later/risky` / `needs-hybrid-fallback`); каждому site присвоен **ровно один** класс; у + `keep-LLM`-записей назван **конкретный** вид суждения, ради которого LLM сохраняется. +- **FAIL:** Site не классифицирован / классифицирован дважды; класс вне таксономии; `keep-LLM` без + названного суждения. + +--- + +## AC-3 — Доказанный детерминизм не-агентских путей + +**Условие:** Карта отдельно фиксирует, что control-path'ы вне 6 агентов не вызывают LLM, с доказательством. +- **PASS:** Перечислены маршрутизация (`advance_stage`/`STAGE_TRANSITIONS`), все `QG_CHECKS`/`check_*`, + парсеры `_parse_*`, `error_classifier`, под-гейты (security/merge/coverage/image-freshness), + `self_deploy` Phase A/B/C, reconciler/reaper/serial-gate/transition-lease — каждый с `file:line`, + подтверждающим отсутствие вызова LLM. +- **FAIL:** Утверждение о детерминизме без `file:line`-доказательства; путь, заявленный + детерминированным, фактически запускает LLM (и это не отражено в инвентаре/классификации). + +--- + +## AC-4 — Упорядоченный roadmap с обязательными атрибутами и первым срезом + +**Условие:** Есть ранжированный roadmap детерминированных замен. +- **PASS:** Roadmap упорядочен; для каждого кандидата указаны зависимости, **оценка** экономии + токенов/времени (со ссылкой на источник — `agent_runs`/`usage`), риск безопасности, потребность в + hybrid-fallback, ожидание kill-switch/обратимости и привязка к follow-up work item; явно назван + **рекомендованный первый срез** с обоснованием. +- **FAIL:** Roadmap не упорядочен; у кандидата отсутствует любой обязательный атрибут; оценка экономии + не привязана к источнику; нет рекомендованного первого среза. + +--- + +## AC-5 — Нормативная политика использования LLM + +**Условие:** Существует durable-документ политики. +- **PASS:** Политика формулирует принцип «LLM — только где нужно настоящее суждение», даёт критерии + решения keep vs replace и требование обосновывать любое новое использование LLM против политики; + документ нормативный (durable, в `docs/`), а не разовая заметка. +- **FAIL:** Политика отсутствует; не нормативна; противоречит сохранению автономности (NFR-2). + +--- + +## AC-6 — Структурные анти-дрейф тесты: зелёные и осмысленные + +**Условие:** Новый offline-тест-файл прибивает инварианты карты к коду. +- **PASS:** Тесты проверяют: (a) единственную точку запуска LLM в `src/**` (= `launcher._spawn`); + (b) отсутствие запуска LLM в перечисленных детерминированных модулях и в обработчиках + deploy-finalizer/post-deploy-monitor; (c) двустороннюю сверку списка промптов карты с + `.openclaw/agents/`; (d) тотальность классификации (каждый site ровно один раз); (e) перехват + `D1/D2` в `launch_job` до `_spawn`. Тесты не используют сеть/LLM/subprocess-к-модели. Полный + `pytest tests/ -q` — зелёный. +- **FAIL:** Тестов нет; тест тривиально проходит (не привязан к коду); любой тест красный; полный + прогон `tests/` падает. + +--- + +## AC-7 — Скоуп и сохранение поведения + +**Условие:** ORCH-118 не меняет рантайм и не реализует раннеры. +- **PASS:** Диф не меняет `STAGE_TRANSITIONS` / реестр и имена `QG_CHECKS`/`check_*` / + machine-verdict-ключи / схему БД; в `src/**` нет нового детерминированного раннера tester/deployer + (ORCH-115/116 не реализованы); изменения ограничены docs + новый(е) тест-файл(ы). +- **FAIL:** Изменён любой из перечисленных рантайм-контрактов; реализован детерминированный раннер + (фолд ORCH-115/116); правки `src/**`-поведения вне инвентаря/тестов. + +--- + +## AC-8 — Синхронизация golden-source документации + +**Условие:** Обзорные/архитектурные доки и CHANGELOG отражают новые артефакты. +- **PASS:** `docs/architecture/README.md` и витрина `docs/overview/*` ссылаются на карту call-site'ов + и политику использования LLM; `CHANGELOG.md` обновлён в том же PR. +- **FAIL:** Карта/политика введены, но golden-source доки/витрина/CHANGELOG не обновлены (ось ORCH-079/ + ORCH-011 → finding ≥P1). + +--- + +## Сводная матрица AC ↔ FR/BR +| AC | Покрывает | +|----|-----------| +| AC-1 | BR-1 / FR-1 | +| AC-2 | BR-2 / FR-2 | +| AC-3 | BR-3 / FR-3 | +| AC-4 | BR-4 / FR-4 | +| AC-5 | BR-5 / FR-5 | +| AC-6 | BR-6 / FR-6 | +| AC-7 | BR-7 / FR-7 / NFR-1 / NFR-3 | +| AC-8 | NFR-4 / правила агентов §2,§6 (golden-source) | diff --git a/docs/work-items/ORCH-118/04-test-plan.yaml b/docs/work-items/ORCH-118/04-test-plan.yaml new file mode 100644 index 0000000..07ea2cb --- /dev/null +++ b/docs/work-items/ORCH-118/04-test-plan.yaml @@ -0,0 +1,80 @@ +work_item: ORCH-118 +stage: analysis +author_agent: analyst +status: ready-for-review +created_at: 2026-06-15 +model_used: claude-opus-4-8 +title: "LLM call-site inventory + classification + roadmap + usage policy (inventory-first, docs+tests only)" +framework: pytest +scope: > + Покрываются СТРУКТУРНЫЕ инварианты карты вызовов LLM и анти-дрейф (FR-6), плюс скоуп-гард + (рантайм-контракты не тронуты, раннеры не реализованы). ВНЕ покрытия: реализация + детерминированных раннеров tester/deployer (ORCH-115/116) — отдельные follow-up задачи. +notes: > + Все тесты детерминированы и offline: без сети, без запуска LLM, без subprocess-к-модели. + Имена файла теста и документов карты — примерные (финально решает архитектор); тест-кейсы + привязываются к фактическим путям артефактов, выбранным в 06-adr. Полный регресс tests/ + должен оставаться зелёным (TC-08). Регрессом считается: появление второй точки запуска LLM, + запуск LLM в детерминированном модуле, дрейф карты относительно .openclaw/agents/, изменение + рантайм-контрактов (STAGE_TRANSITIONS / QG_CHECKS / check_* / machine-verdict / схема БД). + +tests: + - id: TC-01 + type: unit + description: "Единственная точка запуска LLM: ровно одно место в src/** собирает/запускает Claude CLI (CLAUDE_BIN + --system-prompt + Popen/bash -c), и это launcher._spawn (FR-6a / AC-1)" + module: tests/test_llm_call_site_inventory.py + expected: PASS + + - id: TC-02 + type: unit + description: "Детерминированные модули без LLM: перечисленные leaf'ы (serial_gate, merge_gate, coverage_gate, security_gate, staging_verdict, review_parse, error_classifier, frontmatter, self_deploy, post_deploy, transition_lease, reconciler, job_reaper) не содержат запуска Claude CLI (FR-6b / AC-3)" + module: tests/test_llm_call_site_inventory.py + expected: PASS + + - id: TC-03 + type: unit + description: "Анти-дрейф промптов: карта перечисляет ровно те 6 промпт-файлов, что физически лежат в .openclaw/agents/ (двусторонняя сверка, нет лишних/пропущенных) (FR-6c / AC-1)" + module: tests/test_llm_call_site_inventory.py + expected: PASS + + - id: TC-04 + type: unit + description: "Тотальность классификации: каждый перечисленный в карте call-site отнесён ровно к одному классу из таксономии {keep-LLM, replace-deterministic-now, replace-later/risky, needs-hybrid-fallback}; без дублей и пропусков (FR-6d / AC-2)" + module: tests/test_llm_call_site_inventory.py + expected: PASS + + - id: TC-05 + type: unit + description: "keep-LLM требует обоснования: каждая запись класса keep-LLM несёт непустое поле названного конкретного суждения (FR-2 / AC-2)" + module: tests/test_llm_call_site_inventory.py + expected: PASS + + - id: TC-06 + type: unit + description: "Детерминированные job-роли: launch_job перехватывает deploy-finalizer и post-deploy-monitor ДО _spawn (LLM не запускается) — эталон паттерна замены (FR-6e / AC-3)" + module: tests/test_llm_call_site_inventory.py + expected: PASS + + - id: TC-07 + type: unit + description: "Полнота roadmap: документ roadmap для каждого кандидата содержит обязательные атрибуты (зависимости / оценка экономии со ссылкой на agent_runs / риск / hybrid-need / follow-up work item) и явно называет рекомендованный первый срез (FR-4 / AC-4)" + module: tests/test_llm_determinization_docs.py + expected: PASS + + - id: TC-08 + type: unit + description: "Политика LLM существует и нормативна: документ политики содержит принцип 'LLM только где нужно суждение' и критерии keep vs replace (FR-5 / AC-5)" + module: tests/test_llm_determinization_docs.py + expected: PASS + + - id: TC-09 + type: integration + description: "Скоуп-гард рантайм-контрактов: снимок set ролей-агентов из STAGE_TRANSITIONS и набора имён QG_CHECKS не изменился относительно эталона — ORCH-118 не тронул машину стадий/гейты (FR-7 / AC-7)" + module: tests/test_llm_call_site_inventory.py + expected: PASS + + - id: TC-10 + type: integration + description: "Полный регресс tests/ остаётся зелёным (pytest tests/ -q) — инвентаризация и тесты не ломают существующий конвейер (NFR-1 / AC-6, AC-7)" + module: tests/ + expected: PASS