analyst(ET): auto-commit from analyst run_id=747
All checks were successful
CI / test (push) Successful in 1m12s
All checks were successful
CI / test (push) Successful in 1m12s
This commit is contained in:
201
docs/work-items/ORCH-123/01-brd.md
Normal file
201
docs/work-items/ORCH-123/01-brd.md
Normal file
@@ -0,0 +1,201 @@
|
||||
---
|
||||
work_item: ORCH-123
|
||||
stage: analysis
|
||||
author_agent: analyst
|
||||
status: ready-for-review
|
||||
created_at: 2026-06-16
|
||||
model_used: claude-opus-4-8
|
||||
escalate: full-cycle
|
||||
---
|
||||
|
||||
# 01 — BRD / Bug-report: ORCH-123 — staging-runner assumes Docker CLI inside the orchestrator container and false-fails deploy-staging
|
||||
|
||||
Work Item: **ORCH-123** · Repo: **orchestrator** · Стадия: analysis · Трек: **Bug → эскалация в full-cycle**
|
||||
|
||||
> ⚠️ **`escalate: full-cycle` (ADR-001 D5 ORCH-019).** Метка задачи — `Bug`, но по сути это
|
||||
> **архитектурный + safety-critical (self-hosting)** дефект: требуется **решение о стратегии
|
||||
> исполнения** staging-сюиты из прод-окружения (host-side ssh / Docker SDK поверх смонтированного
|
||||
> сокета / docker CLI в образе / выделенный hook-режим), и любой вариант с доступом к
|
||||
> `docker.sock`/CLI из контейнера требует **явного security-review** (доступ к сокету = root-эквивалент
|
||||
> на хосте). Это не «однострочная» правка кода — нужен ADR. Поэтому выпускается **полный**
|
||||
> analysis-пакет (а не облегчённый bug-пакет). Оператор снимает багфикс-трек:
|
||||
> `POST /bug-fast-track/escalate?work_item=ORCH-123` → задача пойдёт через стадию `architecture`
|
||||
> (architect выпустит ADR для стратегии исполнения staging-runner).
|
||||
|
||||
---
|
||||
|
||||
## 1. Бизнес-контекст и проблема
|
||||
|
||||
### Симптом (наблюдаемое — установленный факт из прод-логов)
|
||||
Задача **ORCH-116** (поверх раската ORCH-115) дошла до стадии `deploy-staging` с **зелёными
|
||||
reviewer и tester**, но **детерминированный staging-runner упал ещё до запуска staging-сюиты**.
|
||||
Запись из прод-логов:
|
||||
```
|
||||
proc_group: spawn error for [docker, exec, orchestrator-staging, python3,
|
||||
/repos/orchestrator/scripts/staging_check.py, ...]: [Errno 2] No such file or directory: docker
|
||||
```
|
||||
Далее runner отработал свой инфра-DEFER **дважды**, исчерпал `staging_runner_infra_max_retries=2`,
|
||||
записал `15-staging-log.md` с `staging_status: FAILED` и `stage_engine` **откатил ORCH-116 на
|
||||
`development`** — как будто это дефект кода/тестов задачи, чем оно не является.
|
||||
|
||||
### Причина симптома (установленный факт — верифицировано по коду и инфраструктуре)
|
||||
ORCH-115 (`src/staging_runner.py`) исполняет staging-сюиту командой
|
||||
`docker exec orchestrator-staging python3 .../staging_check.py …` **изнутри прод-контейнера
|
||||
`orchestrator`** через `proc_group.run_in_process_group`. Прод-контейнер **не содержит docker CLI**:
|
||||
- **`Dockerfile:11`** ставит `openssh-client git curl ca-certificates` — **бинаря `docker` нет**;
|
||||
`python:3.12-slim` его тоже не содержит. Поэтому `subprocess.Popen(["docker", …])` падает
|
||||
`FileNotFoundError: [Errno 2] No such file or directory: docker`.
|
||||
- **`docker-compose.yml:40`** монтирует `/var/run/docker.sock` (rw) в сервис `orchestrator` и
|
||||
добавляет `group_add: ${ORCH_DOCKER_GID}`. То есть **сокет в контейнере есть, а CLI-бинаря, который
|
||||
бы им воспользовался, — нет**. (Это важное уточнение корня: проблема не в доступе к Docker, а в
|
||||
**отсутствии исполняемого клиента** в образе.)
|
||||
|
||||
Цепочка отказа в коде:
|
||||
`build_staging_command()` (`staging_runner.py:154`) → `["docker","exec",…]` → `run_staging_suite()` →
|
||||
`proc_group.run_in_process_group` → `Popen` ⇒ `OSError` ⇒ `ProcResult(returncode=None, timed_out=False)`
|
||||
⇒ в `run_staging_gate` (`staging_runner.py:528`) `suite_ran = (returncode is not None) and (not
|
||||
timed_out)` = **False** ⇒ ветка **tool-error** ⇒ `_handle_tool_error` (`staging_runner.py:415`):
|
||||
инфра-DEFER ×2 → бюджет исчерпан → `write_staging_log(..., "FAILED", tool_error=True)` +
|
||||
`_advance(...)` ⇒ существующий откат `deploy-staging → development`.
|
||||
|
||||
### Корневая классификационная ошибка
|
||||
Двухуровневый исход ORCH-115 (D5) различает только **«сюита исполнилась» vs «сюита не исполнилась
|
||||
(транзиентная инфра)»**. Отсутствие docker CLI — это **детерминированный, постоянный дефект
|
||||
окружения**, а не транзиентная икота: ретраи бессмысленны (каждая попытка падает идентично), а
|
||||
**терминальный исход — откат на `development` с расходом developer-retry** — вводит в заблуждение
|
||||
(винит код/разработчика задачи за environment-проблему раннера). Так до фикса **любая** self-hosting
|
||||
задача, доходящая до `deploy-staging`, обречена на ложный откат.
|
||||
|
||||
### Локализация (анализ — куда смотреть архитектору/разработчику)
|
||||
|
||||
**Установленный факт о топологии исполнения (CLAUDE.md / `docs/operations/INFRA.md` / код):**
|
||||
прод-деплой (ORCH-036, `src/self_deploy.py`) **уже решил ровно эту проблему** и НЕ запускает docker
|
||||
изнутри контейнера. Он исполняет хост-хук **на хосте** через `ssh + setsid` (detached):
|
||||
`build_deploy_command` (`self_deploy.py:220`) формирует `ssh <user>@<host> 'setsid bash -c "… bash
|
||||
<hook> --deploy …"'`, где `deploy_ssh_host=127.0.0.1`, ssh-ключ смонтирован, `openssh-client` стоит в
|
||||
образе (`Dockerfile:11`). Хост-хук `scripts/orchestrator-deploy-hook.sh` уже выполняет `docker
|
||||
compose …` / `docker tag` / **`docker exec "$STAGING_CONTAINER" python3 staging_check.py`**
|
||||
(`--build-staging`, строки 197/261) — **на хосте**, где docker CLI есть.
|
||||
|
||||
**Вывод:** ORCH-115 при замене LLM-деплойера детерминированным раннером **отклонился** от уже
|
||||
установленного паттерна «docker-операции исполняются host-side, не внутри app-контейнера». Дефект —
|
||||
в **стратегии исполнения** `staging_runner` (где/как запускается staging-сюита), а не в гейте
|
||||
`check_staging_status` и не в контракте `15-staging-log.md`. Поэтому фикс должен **восстановить
|
||||
работоспособную стратегию исполнения** staging-сюиты в проде, не завися от недоступного внутри
|
||||
контейнера docker CLI, и **перестать классифицировать постоянный environment-дефект как код-фейл**.
|
||||
|
||||
> 🔎 **Точка для проверки на стадии architecture (не факт, требует верификации):** как
|
||||
> staging-сюита исполнялась **до** ORCH-115 LLM-деплойером — действительно через `docker exec` из
|
||||
> контейнера (тогда путь всегда был сломан и LLM-гейт был «бумажным»), или иным механизмом. Это
|
||||
> определяет, «сломал ли ORCH-115 рабочий путь» или «сделал давний дефект детерминированным и
|
||||
> видимым». На фикс выбор стратегии это не меняет, но влияет на формулировку регресса.
|
||||
|
||||
## 2. Объём (scope)
|
||||
|
||||
### В объёме
|
||||
- Исправить **стратегию исполнения staging-runner** так, чтобы `deploy-staging` для self-hosting
|
||||
`orchestrator` **проходил в проде**, не завися от недоступного внутри прод-контейнера docker CLI.
|
||||
- Гарантировать, что **tool-error / environment-дефект** (в частности отсутствие исполняемого
|
||||
`docker`/невозможность запустить сюиту по причине окружения) **НЕ приводит к вводящему в
|
||||
заблуждение откату `deploy-staging → development`** как код-фейлу и **не жжёт** developer-retry;
|
||||
постоянный environment-дефект должен быть отличим от транзиентной инфры и от настоящего код-фейла.
|
||||
- Добавить **prod-like регресс/preflight**, который ловит «нет исполняемого/стратегия неработоспособна»
|
||||
**до раската** (а не постфактум, ложным откатом реальной задачи).
|
||||
- Задокументировать **границу исполнения** (`docs/operations/INFRA.md` + `docs/architecture/README.md`):
|
||||
где и как staging-сюита исполняется относительно прод-контейнера, какие исполняемые/сокеты доступны.
|
||||
|
||||
### Вне объёма
|
||||
- ❌ Изменение гейта `check_staging_status` / `_parse_staging_status`, контракта `15-staging-log.md`
|
||||
(`staging_status:`), `STAGE_TRANSITIONS`, machine-verdict ключей, схемы БД — **байт-в-байт прежние**
|
||||
(ORCH-115 NFR-1: меняется **продюсер/стратегия исполнения** артефакта, не гейт).
|
||||
- ❌ Изменение содержимого/логики самой `scripts/staging_check.py` (тулинг сюиты корректен; меняется
|
||||
лишь **как/откуда** её запускают).
|
||||
- ❌ Откат ORCH-115 (детерминизация staging корректна по замыслу; чиним способ исполнения).
|
||||
- ❌ Выбор конкретного механизма (ssh host-side / Docker SDK поверх сокета / docker CLI в образе /
|
||||
выделенный hook-режим) — это **зона архитектора** (`06-adr/`), здесь — только требования и ограничения.
|
||||
- ❌ Изменение прод-деплой-пути (ORCH-036 self_deploy) сверх возможного переиспользования его
|
||||
ssh-механизма; happy-path прод-деплоя не трогается.
|
||||
|
||||
## 3. Заинтересованные стороны
|
||||
- **Заказчик/оператор (Слава)** — страдает от ложных откатов и ручного разруливания залипших задач;
|
||||
принимает результат.
|
||||
- **Self-hosting конвейер `orchestrator`** — прямой потребитель: без фикса **ни одна** self-hosting
|
||||
задача не проходит `deploy-staging`.
|
||||
- **Все проекты на общем инстансе (enduro-trails)** — косвенно: застрявшие/откатываемые self-hosting
|
||||
задачи занимают слоты и внимание оператора на общей очереди.
|
||||
|
||||
## 4. Бизнес-требования (BR)
|
||||
- **BR-1** — Для self-hosting `orchestrator` стадия `deploy-staging` (детерминированный staging-runner)
|
||||
**исполняет staging-сюиту и проходит в проде** без зависимости от docker CLI, отсутствующего внутри
|
||||
прод-контейнера. Задача уровня ORCH-116 (reviewer/tester зелёные, код корректен) **доходит до
|
||||
`deploy`**, а не откатывается.
|
||||
- **BR-2** — **Tool-error / environment-дефект ≠ код-фейл.** Невозможность исполнить сюиту по причине
|
||||
окружения (нет исполняемого, недоступна стратегия) **не должна** завершаться откатом
|
||||
`deploy-staging → development` как кодовой ошибкой и **не должна** инкрементировать developer-retry;
|
||||
такой исход должен быть **отдельным, отличимым** (хольд/алерт оператору об инфра/environment-сбое).
|
||||
- **BR-3** — **Настоящий код-фейл сохраняется (анти-over-tolerance).** Если сюита **реально
|
||||
исполнилась** и упала (exit≠0), поведение — **прежний** откат `deploy-staging → development` +
|
||||
developer-retry (BR-2 не должно маскировать настоящие провалы; ср. ORCH-110 BR-6).
|
||||
- **BR-4** — **Prod-like preflight/регресс.** Должен существовать механизм, ловящий «исполняемое
|
||||
отсутствует / стратегия неработоспособна» **до раската** (preflight на старте/в smoke-проверке) и
|
||||
**тест**, воспроизводящий «docker CLI отсутствует в контейнере» (красный до фикса, зелёный после).
|
||||
- **BR-5** — **Граница исполнения задокументирована.** `docs/operations/INFRA.md` (и
|
||||
`docs/architecture/README.md`) явно описывают, где/как исполняется staging-сюита относительно
|
||||
прод-контейнера, какие исполняемые/сокеты доступны, и почему docker-операции идут так, а не «изнутри
|
||||
app-контейнера».
|
||||
- **BR-6** — **Наблюдаемость.** Различие «environment/tool-error» vs «код-фейл» видно в логе
|
||||
(структурная запись), Telegram-алерте (кликабельный номер) и read-only блоке `staging_runner` в
|
||||
`GET /queue`.
|
||||
|
||||
## 5. Нефункциональные требования (NFR)
|
||||
- **NFR-1 (нулевая регрессия конвейера)** — `STAGE_TRANSITIONS` / реестр `QG_CHECKS` / имена и
|
||||
семантика `check_*` (в т.ч. `check_staging_status`/`_parse_staging_status`) / machine-verdict ключи
|
||||
(`staging_status:`/`deploy_status:`/…) / схема БД — **байт-в-байт не тронуты** (фикс — стратегия
|
||||
исполнения продюсера, не гейт и не стадия).
|
||||
- **NFR-2 (self-hosting safety)** — путь исполнения staging-runner **никогда**: не рестартит прод
|
||||
`orchestrator` (8500), не делает `docker compose up orchestrator`/`--build` прода, не force-push, не
|
||||
пишет в `main`, не редактирует `.env`. Только запускает staging-сюиту (8501) и пишет лог
|
||||
(инвариант ORCH-115 BR-7/AC-8 сохраняется).
|
||||
- **NFR-3 (security — если выбран socket/CLI-в-контейнере)** — любой вариант с прямым использованием
|
||||
`docker.sock`/CLI из контейнера = root-эквивалент на хосте → **обязателен явный security-review** в
|
||||
ADR (поверхность атаки, ограничение прав, :ro где возможно). Вариант host-side ssh должен
|
||||
переиспользовать уже существующий доверенный механизм (ORCH-036) без расширения привилегий.
|
||||
- **NFR-4 (обратимость / kill-switch)** — поведение под существующим `staging_runner_enabled`
|
||||
(+ при необходимости — новым флагом выбора стратегии); выключенный kill-switch → прежний LLM-деплойер
|
||||
через `_spawn` **байт-в-байт** (ORCH-115 fail-safe сохраняется).
|
||||
- **NFR-5 (надёжность)** — never-raise / fail-safe / restart-safe (по образцу leaf'ов
|
||||
`staging_runner`/`self_deploy`/`proc_group`); очередь репо **никогда не клинится**; тайм-аут сюиты не
|
||||
растёт сверх бюджета, держащего сквозной инвариант reaper (ORCH-065/109/110).
|
||||
- **NFR-6 (область)** — изменение скоупится на self-hosting (`orchestrator`, единственный с staging
|
||||
8501); поведение для прочих репо/синхронного LLM-деплоя — не ухудшается (`applies(repo)` первым).
|
||||
|
||||
## 6. Допущения и ограничения
|
||||
- Прод и staging контейнеры запущены на **одном хосте**; `/var/run/docker.sock` доступен на хосте,
|
||||
где docker CLI установлен; ssh на `127.0.0.1` под смонтированным ключом — рабочий канал (его уже
|
||||
использует ORCH-036 self-deploy).
|
||||
- `staging_check.py` исполняется **внутри контейнера `orchestrator-staging`** (там есть python3 и
|
||||
приложение 8501) — это контракт сюиты; меняется только то, **кто инициирует** `docker exec` (хост
|
||||
vs прод-контейнер) или **как** (CLI vs SDK поверх сокета).
|
||||
- Источник истины «применять ли детерминированный runner» — `staging_runner.applies(repo)` (ORCH-115);
|
||||
фикс не меняет его семантику.
|
||||
- Конкретный механизм исполнения (host-side ssh / Docker SDK поверх сокета / docker CLI в образе /
|
||||
выделенный режим хука) — **открытый вопрос для архитектуры**, решается в `06-adr/` с security-review.
|
||||
|
||||
## 7. Критерии успеха
|
||||
Self-hosting задача уровня ORCH-116 проходит `deploy-staging` в проде (staging-сюита реально
|
||||
исполняется, вердикт маппится из exit-кода); environment/tool-error **не** даёт ложного код-фейл-отката
|
||||
и не жжёт developer-retry; настоящий код-фейл по-прежнему откатывает на `development`; существует
|
||||
prod-like preflight + обязательный регресс-тест «нет docker CLI в контейнере» (**красный до фикса,
|
||||
зелёный после**); граница исполнения задокументирована; гейт/контракт/`STAGE_TRANSITIONS`/схема БД — без
|
||||
регресса; полный `pytest tests/ -q` зелёный. Детальные PASS/FAIL — `03-acceptance-criteria.md`.
|
||||
|
||||
## 8. Риски
|
||||
- **Security (socket/CLI в контейнере):** прямой доступ к `docker.sock` из app-контейнера = эскалация
|
||||
до root на хосте → ADR обязан взвесить поверхность атаки против host-side ssh-варианта.
|
||||
- **Over-tolerance:** слишком широкая трактовка «environment-дефекта» может замаскировать настоящие
|
||||
код-фейлы/реальные сбои staging-стенда (митигация — BR-3; ср. инцидент ORCH-110).
|
||||
- **Кросс-каттинг:** ORCH-115 (staging-runner, прямой объект), ORCH-036 (self_deploy ssh-механизм —
|
||||
потенциально переиспользуемый), ORCH-110 (proc_group tree-kill + infra-tolerance паттерн), ORCH-058
|
||||
(`--build-staging` host-side docker exec — прецедент), ORCH-101 (host-параметризация). Правки
|
||||
маркированных блоков сверять с их `06-adr/` (CLAUDE.md §9). Детали/митигации — `10-tech-risks.md`
|
||||
(заполняет архитектор).
|
||||
136
docs/work-items/ORCH-123/02-trz.md
Normal file
136
docs/work-items/ORCH-123/02-trz.md
Normal file
@@ -0,0 +1,136 @@
|
||||
---
|
||||
work_item: ORCH-123
|
||||
stage: analysis
|
||||
author_agent: analyst
|
||||
status: ready-for-review
|
||||
created_at: 2026-06-16
|
||||
model_used: claude-opus-4-8
|
||||
---
|
||||
|
||||
# 02 — ТЗ (TRZ): ORCH-123 — staging-runner execution strategy must not depend on Docker CLI inside the app container
|
||||
|
||||
Work Item: **ORCH-123** · Repo: **orchestrator** · Стадия: analysis
|
||||
|
||||
> ТЗ описывает **требования и ограничения к реализации**, выведенные из BRD и фактического кода.
|
||||
> Архитектурное **решение** (какую стратегию исполнения выбрать: host-side ssh / Docker SDK поверх
|
||||
> сокета / docker CLI в образе / выделенный hook-режим, + security-review) — задача архитектора
|
||||
> (`06-adr/`), т.к. задача эскалирована в full-cycle (`01-brd.md` → `escalate: full-cycle`).
|
||||
|
||||
## 1. Сводка изменения
|
||||
Восстановить работоспособную стратегию исполнения staging-сюиты для self-hosting `orchestrator` на
|
||||
стадии `deploy-staging`, не завися от docker CLI, **отсутствующего внутри прод-контейнера**
|
||||
(`Dockerfile:11` ставит `openssh-client git curl ca-certificates`, не docker; `docker.sock`
|
||||
смонтирован — `docker-compose.yml:40` — но клиента нет). Сегодня `staging_runner.build_staging_command`
|
||||
(`src/staging_runner.py:154`) формирует `["docker","exec","orchestrator-staging",…]` и запускает её
|
||||
**изнутри** прод-контейнера через `proc_group` → `Popen` падает `FileNotFoundError` → ветка tool-error
|
||||
→ инфра-DEFER×2 → fail-closed `FAILED` → откат `deploy-staging → development`. Требуется: (а) исполнять
|
||||
сюиту так, чтобы она реально запускалась в проде (паттерн host-side, уже применённый прод-деплоем
|
||||
ORCH-036 / `--build-staging`); (б) **различать** постоянный environment/tool-error от настоящего
|
||||
код-фейла и не делать вводящего в заблуждение код-фейл-отката; (в) prod-like preflight + регресс;
|
||||
(г) документировать границу исполнения.
|
||||
|
||||
## 2. Задействованные модули / пути
|
||||
| Путь | Действие | Примечание |
|
||||
|------|----------|-----------|
|
||||
| `src/staging_runner.py` | **изменить** | `build_staging_command`/`run_staging_suite` — точка, где сюита запускается «изнутри контейнера» (корень дефекта, FR-1); классификация tool-error vs environment-дефект в `run_staging_gate`/`_handle_tool_error` (FR-2) |
|
||||
| `src/self_deploy.py` | возможно переиспользовать | `build_deploy_command`/`initiate_deploy` — рабочий host-side ssh+setsid механизм (ORCH-036); кандидат на общий ssh-хелпер исполнения host-side команды (решает архитектор) |
|
||||
| `scripts/orchestrator-deploy-hook.sh` | возможно изменить | `--build-staging` уже делает host-side `docker exec "$STAGING_CONTAINER" python3 staging_check.py` (строки 197/261) — прецедент/возможная точка выделенного staging-режима |
|
||||
| `Dockerfile` | возможно изменить | строка 11 — если выбран вариант «docker CLI в образе» (тогда + security-обоснование) |
|
||||
| `docker-compose.yml` | возможно изменить | строка 40 — `docker.sock` уже смонтирован; если выбран socket/SDK-вариант, зафиксировать права (`:ro` где возможно) |
|
||||
| `src/proc_group.py` | возможно изменить | `run_in_process_group` уже корректно деградирует spawn-error в `ProcResult(returncode=None)` — кандидат на preflight «исполняемое существует» (FR-4) |
|
||||
| `src/config.py` | возможно изменить | существующие `staging_runner_*`; при необходимости — флаг выбора/режима стратегии (FR-5), дефолт = боевое |
|
||||
| `docs/operations/INFRA.md` | **изменить** | граница исполнения staging-сюиты относительно прод-контейнера (FR-6 / BR-5) |
|
||||
| `docs/architecture/README.md` | **изменить** | описать стратегию исполнения staging-runner (FR-6 / BR-5) |
|
||||
| `CHANGELOG.md`, `CLAUDE.md` | изменить | docs = golden source (CLAUDE.md §2); раздел ORCH-115 дополнить фиксом исполнения |
|
||||
| `tests/test_orch115_staging_runner.py` / `tests/test_orch123_staging_runner_exec.py` | **создать/расширить** | регресс «docker CLI отсутствует» + классификация + preflight (`04-test-plan.yaml`) |
|
||||
|
||||
## 3. Функциональные требования
|
||||
|
||||
### FR-1 — Работоспособная стратегия исполнения staging-сюиты в проде (BR-1)
|
||||
- На стадии `deploy-staging` для self-hosting `orchestrator` staging-сюита (`staging_check.py` внутри
|
||||
`orchestrator-staging`) **должна реально исполняться** в боевом окружении, **не завися** от наличия
|
||||
бинаря `docker` внутри прод-контейнера `orchestrator`.
|
||||
- Стратегия исполнения — **выбор архитектора** (ADR), из перечня BRD §2: host-side через
|
||||
существующий ssh+setsid механизм (ORCH-036, `deploy_ssh_host=127.0.0.1`, ssh-ключ смонтирован,
|
||||
`openssh-client` в образе) **либо** Docker SDK/`docker.sock` (уже смонтирован, + security-review)
|
||||
**либо** docker CLI в образе **либо** выделенный режим хука. ТЗ **не** прескриптивно — фиксирует
|
||||
лишь требуемый инвариант «сюита исполняется».
|
||||
- Команда/контракт сюиты (`python3 staging_check.py --base-url http://localhost:<staging_port>
|
||||
--mode stub`, host-specifics из config — ORCH-101) сохраняются; меняется **инициатор/канал**
|
||||
запуска, не сама сюита.
|
||||
|
||||
### FR-2 — Environment/tool-error ≠ код-фейл (BR-2, BR-3)
|
||||
- Невозможность исполнить сюиту по причине **окружения** (нет исполняемого `docker`/SDK недоступен/
|
||||
стратегия неработоспособна) **не должна** завершаться откатом `deploy-staging → development` как
|
||||
кодовой ошибкой и **не должна** инкрементировать developer-retry. Текущий терминальный путь
|
||||
`_handle_tool_error` → `write_staging_log("FAILED") + _advance` (= откат) для **постоянного**
|
||||
environment-дефекта вводит в заблуждение (см. BRD §1) и должен быть заменён на **отличимый
|
||||
инфра/environment-исход** (хольд на `deploy-staging` + алерт оператору, по образцу
|
||||
`merge_gate` infra-tolerance ORCH-110: задача остаётся на стадии, без developer-retry).
|
||||
- **Анти-over-tolerance (BR-3):** если сюита **реально исполнилась** (получен exit-код) и упала
|
||||
(exit≠0), исход — **прежний** откат `deploy-staging → development` + developer-retry (контракт
|
||||
`staging_runner` D5 для «сюита исполнилась» сохраняется байт-в-байт).
|
||||
- Различение «сюита исполнилась / постоянный environment-дефект / транзиентная инфра» —
|
||||
детерминированная классификация (по образцу `merge_gate.classify_retest_failure`, ORCH-110 D2);
|
||||
никаких догадок — постоянный environment-дефект (spawn-error «исполняемое не найдено») трактуется
|
||||
как НЕ-транзиентный и НЕ как код-фейл.
|
||||
|
||||
### FR-3 — Анти-бессмысленный-ретрай (BR-2)
|
||||
- При постоянном environment-дефекте бессмысленно крутить инфра-DEFER ×N (каждая попытка падает
|
||||
идентично, жжёт время/слот) и затем ложно откатывать. Допустимо: немедленный отличимый
|
||||
инфра-хольд+алерт (без отката, без developer-retry) **или** preflight, не дающий задаче войти в
|
||||
ложный путь. Конкретику решает архитектор; инвариант — **не** оканчиваться код-фейл-откатом.
|
||||
|
||||
### FR-4 — Prod-like preflight (BR-4)
|
||||
- Должен существовать механизм, ловящий «стратегия исполнения неработоспособна (нет исполняемого/
|
||||
канал недоступен)» **до раската** — preflight на старте сервиса и/или в `scripts/staging_check.py`/
|
||||
smoke (`scripts/staging_check.py` Block …) / в `should_intercept`/`applies`. Условие, проявившееся
|
||||
в инциденте (нет бинаря `docker` там, где runner его зовёт), должно детектироваться **до** того,
|
||||
как реальная задача ложно откатится.
|
||||
- Реализационно preflight никак не должен трогать гейты/стадии; never-raise; область — self-hosting.
|
||||
|
||||
### FR-5 — Условность / kill-switch (BR-1, NFR-4, NFR-6)
|
||||
- Поведение под существующим `staging_runner_enabled` (выключен → прежний LLM-деплойер через `_spawn`
|
||||
байт-в-байт) + `staging_runner_repos` (область). При необходимости нового флага выбора/режима
|
||||
стратегии — env `ORCH_*`, **дефолт = боевое** (паттерн ORCH-101); откат = выставить флаг(и) →
|
||||
поведение до ORCH-123. `applies(repo)` (локально, без сети) проверяется первым.
|
||||
|
||||
### FR-6 — Документирование границы исполнения (BR-5)
|
||||
- `docs/operations/INFRA.md` + `docs/architecture/README.md`: явно зафиксировать, что docker-операции
|
||||
для self-hosting исполняются **host-side** (а не из app-контейнера, где нет docker CLI), какие
|
||||
исполняемые/сокеты доступны прод-контейнеру (`openssh-client`/`git`/`curl`; `docker.sock` смонтирован,
|
||||
CLI — нет), и как именно staging-runner запускает сюиту после фикса.
|
||||
|
||||
## 4. Изменения API
|
||||
**Нет** обязательных. Существующий read-only блок `staging_runner` в `GET /queue` (ORCH-115)
|
||||
**дополняется** различием environment/tool-error vs код-фейл и (опц.) статусом preflight; новых
|
||||
управляющих эндпоинтов не требуется (на усмотрение архитектора — опц. read-only preflight-поле).
|
||||
|
||||
## 5. Изменения схемы БД
|
||||
**Нет.** Restart-safe состояние (счётчик инфра-ретраев) уже ведётся маркером в `task_content`
|
||||
(`_INFRA_RETRY_MARKER`, ORCH-115) — без миграции. Новой таблицы/колонки не требуется.
|
||||
|
||||
## 6. Требования к новым/изменённым QG checks
|
||||
**Нет.** Это **не** Quality Gate и **не** стадия — это стратегия исполнения продюсера артефакта
|
||||
`15-staging-log.md`. `STAGE_TRANSITIONS` / реестр `QG_CHECKS` / имена и семантика `check_*`
|
||||
(`check_staging_status`/`_parse_staging_status`) / machine-verdict ключи (`staging_status:`/
|
||||
`deploy_status:`/…) / схема БД — **байт-в-байт не тронуты** (NFR-1; зеркало инварианта ORCH-115 NFR-1).
|
||||
|
||||
## 7. Совместимость / регресс
|
||||
- **Обратная совместимость:** `staging_runner_enabled=False` → стадию `deploy-staging` снова ведёт
|
||||
LLM-`deployer` через `_spawn` **байт-в-байт**; для прочих репо `applies==False` → no-op (нулевая
|
||||
регрессия enduro).
|
||||
- **Контракт артефакта:** `15-staging-log.md` (`staging_status:` + 52c-схема, `author_agent:
|
||||
staging-runner`/`model_used: n/a`) сохраняется; вердикт по-прежнему читается ТОЛЬКО из frontmatter.
|
||||
- **Self-hosting инварианты (NFR-2):** не рестартить прод 8500, не `docker compose up orchestrator`/
|
||||
`--build` прода, не force-push, не писать в `main`, не править `.env` — сохраняются (ORCH-115 BR-7).
|
||||
- **Security (NFR-3):** любой socket/CLI-в-контейнере вариант проходит security-review в ADR; host-side
|
||||
ssh-вариант переиспользует доверенный ORCH-036 механизм без расширения привилегий.
|
||||
- **Бюджеты/инварианты:** тайм-аут сюиты не растёт сверх `staging_runner_timeout_s` (держит сквозной
|
||||
reaper-инвариант ORCH-065/109/110); proc_group tree-kill (ORCH-110) сохраняется.
|
||||
- **Артефакты pipeline:** обычные docs work item (`01..04` этой задачи; `06-adr/` на стадии
|
||||
architecture после эскалации; `15-staging-log.md` при прогоне). Новых pipeline-артефактов задача не
|
||||
вводит.
|
||||
- **Трассировка (CLAUDE.md §9 / ORCH-078):** правки маркированных блоков — ORCH-115 (staging-runner,
|
||||
прямой объект), ORCH-036 (self_deploy ssh), ORCH-110 (proc_group/infra-tolerance), ORCH-058
|
||||
(`--build-staging`) — сверять с их `06-adr/` перед изменением; инварианты не ломать.
|
||||
169
docs/work-items/ORCH-123/03-acceptance-criteria.md
Normal file
169
docs/work-items/ORCH-123/03-acceptance-criteria.md
Normal file
@@ -0,0 +1,169 @@
|
||||
---
|
||||
work_item: ORCH-123
|
||||
stage: analysis
|
||||
author_agent: analyst
|
||||
status: ready-for-review
|
||||
created_at: 2026-06-16
|
||||
model_used: claude-opus-4-8
|
||||
---
|
||||
|
||||
# 03 — Критерии приёмки (Acceptance Criteria): ORCH-123 — staging-runner execution strategy fix
|
||||
|
||||
Work Item: **ORCH-123** · Repo: **orchestrator** · Стадия: analysis
|
||||
|
||||
Формат: каждый критерий имеет **PASS** (что должно быть истинно для приёмки) и **FAIL** (что
|
||||
считается провалом). Любой машинный/ручной reviewer проверяет их буквально по файлам репозитория.
|
||||
Критерии **механизм-агностичны** (конкретную стратегию выбирает архитектор), проверяют **требуемый
|
||||
инвариант**, а не способ реализации.
|
||||
|
||||
---
|
||||
|
||||
## AC-1 — staging-сюита реально исполняется в проде (без docker CLI в контейнере)
|
||||
|
||||
**Условие:** Для self-hosting `orchestrator` на `deploy-staging` staging-runner запускает
|
||||
`staging_check.py` так, что сюита **исполняется** в боевом окружении, не завися от бинаря `docker`
|
||||
внутри прод-контейнера.
|
||||
- **PASS:** Стратегия исполнения staging-сюиты не требует наличия `docker` CLI **внутри**
|
||||
прод-контейнера `orchestrator` (исполняется host-side через существующий доверенный канал, либо
|
||||
через смонтированный сокет/SDK с security-обоснованием, либо CLI добавлен в образ — на выбор ADR);
|
||||
тест воспроизводит окружение «нет `docker` в контейнере» и подтверждает, что сюита **исполняется**
|
||||
(а не падает spawn-error'ом).
|
||||
- **FAIL:** staging-runner по-прежнему вызывает `docker exec` напрямую из прод-контейнера без
|
||||
доступного исполняемого/канала → `proc_group` spawn-error → tool-error.
|
||||
|
||||
---
|
||||
|
||||
## AC-2 — ORCH-116-подобная задача проходит `deploy-staging`
|
||||
|
||||
**Условие:** Задача с зелёными reviewer/tester и корректным кодом доходит до `deploy`, а не
|
||||
откатывается на `development` из-за раннера.
|
||||
- **PASS:** При успешной staging-сюите (exit 0) → `staging_status: SUCCESS` → штатное продвижение по
|
||||
под-гейтам ребра `deploy-staging → deploy` (контракт не тронут); ORCH-116-подобный сценарий в
|
||||
тесте/симуляции достигает `deploy`.
|
||||
- **FAIL:** Корректная задача откатывается на `development` по причине раннера/окружения.
|
||||
|
||||
---
|
||||
|
||||
## AC-3 — environment/tool-error НЕ даёт вводящего в заблуждение код-фейл-отката
|
||||
|
||||
**Условие:** Невозможность исполнить сюиту по причине окружения (нет исполняемого/канал недоступен) не
|
||||
трактуется как код-фейл.
|
||||
- **PASS:** environment/tool-error → **отличимый** инфра/environment-исход (задача **не** откатывается
|
||||
на `development` как код-фейл; developer-retry **не** инкрементируется; оператору идёт алерт «инфра/
|
||||
окружение, НЕ дефект кода»). Подтверждено тестом: при недоступном исполняемом задача **не** уходит в
|
||||
`development` и счётчик developer-retry не растёт.
|
||||
- **FAIL:** environment-дефект завершается `write_staging_log("FAILED") + advance` (откат на
|
||||
`development`) и/или жжёт developer-retry.
|
||||
|
||||
---
|
||||
|
||||
## AC-4 — настоящий код-фейл по-прежнему откатывает (анти-over-tolerance)
|
||||
|
||||
**Условие:** Если сюита **реально исполнилась** и упала (exit≠0), поведение не ослаблено.
|
||||
- **PASS:** exit≠0 при исполнившейся сюите → `staging_status: FAILED` → **прежний** откат
|
||||
`deploy-staging → development` + developer-retry (байт-в-байт контракт ORCH-115 для «сюита
|
||||
исполнилась»). Тест подтверждает, что реальный фейл сюиты НЕ маскируется как «инфра».
|
||||
- **FAIL:** Настоящий код-фейл сюиты трактуется как environment/инфра и не откатывает на `development`.
|
||||
|
||||
---
|
||||
|
||||
## AC-5 — prod-like preflight ловит «исполняемое/стратегия неработоспособна» до раската
|
||||
|
||||
**Условие:** Условие инцидента детектируется заранее, а не ложным откатом реальной задачи.
|
||||
- **PASS:** Существует preflight (на старте сервиса и/или в smoke/`staging_check.py`/`applies`/
|
||||
`should_intercept`), который при неработоспособной стратегии исполнения сигнализирует (лог/алерт/
|
||||
отметка) **до** того, как задача дойдёт до ложного отката; есть тест, симулирующий «нет `docker` в
|
||||
контейнере», и он проверяет именно это.
|
||||
- **FAIL:** Нет механизма раннего детекта; «исполняемое отсутствует» обнаруживается только постфактум
|
||||
откатом реальной задачи.
|
||||
|
||||
---
|
||||
|
||||
## AC-6 — обязательный регресс-тест (red → green)
|
||||
|
||||
**Условие:** Инцидент ORCH-116 воспроизводится тестом.
|
||||
- **PASS:** Есть тест, моделирующий исполнение staging-сюиты в окружении **без `docker` CLI в
|
||||
контейнере**; он **красный на коде до фикса** (воспроизводит spawn-error → tool-error → ложный
|
||||
откат/false-FAILED) и **зелёный после фикса** (сюита исполняется / environment-дефект не даёт
|
||||
код-фейл-отката).
|
||||
- **FAIL:** Регресс-теста нет, либо он зелёный и до фикса (значит, не воспроизводит дефект).
|
||||
|
||||
---
|
||||
|
||||
## AC-7 — гейт/контракт/стадии — без регресса (NFR-1)
|
||||
|
||||
**Условие:** Меняется продюсер/стратегия исполнения, не гейт.
|
||||
- **PASS:** `STAGE_TRANSITIONS`, реестр `QG_CHECKS`, имена и семантика `check_staging_status`/
|
||||
`_parse_staging_status`, machine-verdict ключи (`staging_status:`/`deploy_status:`/…), схема БД —
|
||||
**байт-в-байт прежние** (структурный анти-регресс-тест зелёный); `15-staging-log.md` сохраняет
|
||||
`staging_status:`-frontmatter + 52c-схему (`author_agent: staging-runner`/`model_used: n/a`).
|
||||
- **FAIL:** Любое из перечисленного изменено (имя/регистр/семантика/значение) либо введена миграция БД.
|
||||
|
||||
---
|
||||
|
||||
## AC-8 — self-hosting safety (NFR-2)
|
||||
|
||||
**Условие:** Путь исполнения staging-runner безопасен для общего прод-инстанса.
|
||||
- **PASS:** Путь **никогда** не рестартит прод `orchestrator` (8500), не делает `docker compose up
|
||||
orchestrator`/`--build` прода, не force-push, не пишет в `main`, не правит `.env`; оперирует только
|
||||
запуском staging-сюиты (8501) и записью лога (статический/поведенческий ассерт зелёный).
|
||||
- **FAIL:** Путь способен затронуть прод-контейнер/`main`/`.env`/сделать force-push.
|
||||
|
||||
---
|
||||
|
||||
## AC-9 — security-review для socket/CLI-вариантов (NFR-3)
|
||||
|
||||
**Условие:** Если выбран вариант с прямым `docker.sock`/CLI из контейнера.
|
||||
- **PASS:** ADR (`06-adr/`) содержит явный security-разбор (поверхность атаки `docker.sock` =
|
||||
root-эквивалент, ограничение прав, `:ro` где возможно) **либо** выбран host-side ssh-вариант,
|
||||
переиспользующий доверенный ORCH-036 механизм без расширения привилегий — и это зафиксировано.
|
||||
- **FAIL:** Введён доступ к `docker.sock`/CLI из контейнера без security-обоснования в ADR.
|
||||
|
||||
---
|
||||
|
||||
## AC-10 — kill-switch / область (NFR-4, NFR-6)
|
||||
|
||||
**Условие:** Обратимость и скоуп сохранены.
|
||||
- **PASS:** `staging_runner_enabled=False` → `deploy-staging` снова через LLM-`deployer` (`_spawn`)
|
||||
байт-в-байт; `applies(repo)`: self-hosting `orchestrator` — real, прочие репо — no-op; любой новый
|
||||
флаг стратегии имеет дефолт = боевое (откат флагом → поведение до ORCH-123). Подтверждено тестом.
|
||||
- **FAIL:** Выключение kill-switch не возвращает прежний путь, либо затронуты прочие репо.
|
||||
|
||||
---
|
||||
|
||||
## AC-11 — never-raise / очередь не клинится (NFR-5)
|
||||
|
||||
**Условие:** Сбой стратегии исполнения не роняет worker и не клинит очередь.
|
||||
- **PASS:** Любая ошибка исполнения/классификации изолирована (never-raise); задача либо штатно
|
||||
продвигается, либо остаётся на `deploy-staging` для reconciler/reaper без вечного залипания; полный
|
||||
`pytest tests/ -q` зелёный.
|
||||
- **FAIL:** Ошибка исполнения роняет worker / задача залипает на `deploy-staging` навсегда / тесты
|
||||
красные.
|
||||
|
||||
---
|
||||
|
||||
## AC-12 — документация границы исполнения (BR-5)
|
||||
|
||||
**Условие:** Граница исполнения staging-сюиты задокументирована.
|
||||
- **PASS:** `docs/operations/INFRA.md` и `docs/architecture/README.md` содержат явное описание: где/как
|
||||
исполняется staging-сюита относительно прод-контейнера, какие исполняемые/сокеты доступны, почему
|
||||
docker-операции идут host-side (структурная сверка зелёная); `CHANGELOG.md`/`CLAUDE.md` обновлены.
|
||||
- **FAIL:** Граница исполнения нигде не описана, или docs противоречат фактическому коду.
|
||||
|
||||
---
|
||||
|
||||
## Сводная матрица AC ↔ FR/BR
|
||||
| AC | Покрывает |
|
||||
|----|-----------|
|
||||
| AC-1 | BR-1 / FR-1 |
|
||||
| AC-2 | BR-1 / FR-1 |
|
||||
| AC-3 | BR-2 / FR-2, FR-3 |
|
||||
| AC-4 | BR-3 / FR-2 |
|
||||
| AC-5 | BR-4 / FR-4 |
|
||||
| AC-6 | BR-4 / FR-1, FR-2 |
|
||||
| AC-7 | NFR-1 / FR-(6) |
|
||||
| AC-8 | NFR-2 |
|
||||
| AC-9 | NFR-3 |
|
||||
| AC-10 | NFR-4, NFR-6 / FR-5 |
|
||||
| AC-11 | NFR-5 |
|
||||
| AC-12 | BR-5 / FR-6 |
|
||||
108
docs/work-items/ORCH-123/04-test-plan.yaml
Normal file
108
docs/work-items/ORCH-123/04-test-plan.yaml
Normal file
@@ -0,0 +1,108 @@
|
||||
work_item: ORCH-123
|
||||
stage: analysis
|
||||
author_agent: analyst
|
||||
status: ready-for-review
|
||||
created_at: 2026-06-16
|
||||
model_used: claude-opus-4-8
|
||||
title: "Staging-runner execution strategy: docker CLI absent in container must not false-fail deploy-staging"
|
||||
framework: pytest
|
||||
scope: >
|
||||
Покрывается: исполнение staging-сюиты для self-hosting orchestrator на deploy-staging без
|
||||
зависимости от docker CLI внутри прод-контейнера; различение environment/tool-error vs настоящего
|
||||
код-фейла; анти-over-tolerance (реальный фейл сюиты по-прежнему откатывает); prod-like preflight;
|
||||
сохранность контракта гейта/артефакта/STAGE_TRANSITIONS/схемы БД; self-hosting safety; kill-switch/
|
||||
область; never-raise. Вне покрытия: логика самой staging_check.py (не трогается), выбор конкретного
|
||||
механизма исполнения (host-side ssh / docker.sock+SDK / CLI в образе / hook-режим — решает архитектор),
|
||||
изменения STAGE_TRANSITIONS/QG_CHECKS/схемы БД (их нет).
|
||||
notes: >
|
||||
TC-01 — ОБЯЗАТЕЛЬНЫЙ регресс-тест воспроизведения инцидента ORCH-116/ORCH-115: КРАСНЫЙ до фикса,
|
||||
ЗЕЛЁНЫЙ после. Тесты механизм-агностичны: проверяют ТРЕБУЕМЫЙ ИНВАРИАНТ (сюита исполняется;
|
||||
environment-дефект не даёт код-фейл-отката; настоящий фейл откатывает), а не конкретную стратегию.
|
||||
Окружение «нет docker CLI» моделировать без сети/прода/ssh (монки-патч PATH/spawn-функции
|
||||
proc_group, либо изоляция argv staging_runner). Точные имена тест-функций уточнит разработчик после
|
||||
выбора механизма архитектором. Полный регресс `pytest tests/ -q` обязан оставаться зелёным (NFR-1).
|
||||
|
||||
tests:
|
||||
- id: TC-01
|
||||
type: integration
|
||||
description: "РЕГРЕСС (обязательный, red→green): исполнение staging-сюиты в окружении БЕЗ docker CLI в прод-контейнере. До фикса воспроизводит proc_group spawn-error '[Errno 2] No such file or directory: docker' → tool-error → инфра-DEFER×2 → ложный FAILED-откат на development. После фикса сюита ИСПОЛНЯЕТСЯ (или environment-дефект не даёт код-фейл-отката). Красный до фикса."
|
||||
module: tests/test_orch123_staging_runner_exec.py
|
||||
expected: PASS
|
||||
|
||||
- id: TC-02
|
||||
type: unit
|
||||
description: "Стратегия исполнения не зависит от docker CLI внутри прод-контейнера: argv/канал, формируемый staging-runner, не требует наличия бинаря `docker` на PATH контейнера (host-side / socket-SDK / CLI-в-образе — в зависимости от выбора ADR; ассерт проверяет инвариант, а не конкретный механизм)."
|
||||
module: tests/test_orch123_staging_runner_exec.py
|
||||
expected: PASS
|
||||
|
||||
- id: TC-03
|
||||
type: integration
|
||||
description: "environment/tool-error НЕ даёт код-фейл-отката (AC-3): при неработоспособной стратегии (исполняемое отсутствует) задача НЕ переходит deploy-staging → development, developer-retry НЕ инкрементируется, идёт отличимый инфра/environment-алерт ('НЕ дефект кода')."
|
||||
module: tests/test_orch123_staging_runner_exec.py
|
||||
expected: PASS
|
||||
|
||||
- id: TC-04
|
||||
type: unit
|
||||
description: "Анти-over-tolerance (AC-4): сюита РЕАЛЬНО исполнилась (получен exit-код) и упала (exit≠0) → staging_status: FAILED → ПРЕЖНИЙ откат deploy-staging → development + developer-retry. Настоящий фейл сюиты НЕ маскируется как 'инфра'."
|
||||
module: tests/test_orch123_staging_runner_exec.py
|
||||
expected: PASS
|
||||
|
||||
- id: TC-05
|
||||
type: unit
|
||||
description: "Happy-path: сюита исполнилась, exit 0 → staging_status: SUCCESS → штатная инициация advance_stage(deploy-staging, deployer) без новых рёбер/исходов (контракт ORCH-115 D7 сохранён)."
|
||||
module: tests/test_orch123_staging_runner_exec.py
|
||||
expected: PASS
|
||||
|
||||
- id: TC-06
|
||||
type: unit
|
||||
description: "Классификация (по образцу merge_gate.classify_retest_failure): постоянный environment-дефект (spawn-error 'исполняемое не найдено') отличается от транзиентной инфры и от настоящего код-фейла; постоянный дефект НЕ трактуется как транзиент (бессмысленный ретрай) и НЕ как код-фейл."
|
||||
module: tests/test_orch123_staging_runner_exec.py
|
||||
expected: PASS
|
||||
|
||||
- id: TC-07
|
||||
type: integration
|
||||
description: "Prod-like preflight (AC-5): механизм раннего детекта 'стратегия исполнения неработоспособна (нет исполняемого/канал недоступен)' сигнализирует ДО ложного отката реальной задачи (старт сервиса / smoke / applies / should_intercept — в зависимости от выбора ADR)."
|
||||
module: tests/test_orch123_staging_runner_exec.py
|
||||
expected: PASS
|
||||
|
||||
- id: TC-08
|
||||
type: unit
|
||||
description: "Self-hosting safety (AC-8): путь исполнения никогда не рестартит прод 8500, не делает docker compose up orchestrator/--build прода, не force-push, не пишет в main, не правит .env (статический/поведенческий ассерт; инвариант ORCH-115 BR-7 сохранён)."
|
||||
module: tests/test_orch123_staging_runner_exec.py
|
||||
expected: PASS
|
||||
|
||||
- id: TC-09
|
||||
type: unit
|
||||
description: "Kill-switch/область (AC-10): staging_runner_enabled=False → should_intercept False → прежний LLM-deployer через _spawn байт-в-байт; applies(repo): self-hosting orchestrator real, прочие репо — no-op; новый флаг стратегии (если есть) имеет дефолт = боевое."
|
||||
module: tests/test_orch123_staging_runner_exec.py
|
||||
expected: PASS
|
||||
|
||||
- id: TC-10
|
||||
type: unit
|
||||
description: "Контракт артефакта (AC-7): 15-staging-log.md сохраняет staging_status:-frontmatter (UPPERCASE значение) + 52c-схему (author_agent: staging-runner / model_used: n/a); вердикт читается только из frontmatter через src/frontmatter.py."
|
||||
module: tests/test_orch123_staging_runner_exec.py
|
||||
expected: PASS
|
||||
|
||||
- id: TC-11
|
||||
type: unit
|
||||
description: "Анти-регресс конвейера (AC-7): STAGE_TRANSITIONS / реестр QG_CHECKS / имена и семантика check_staging_status / _parse_staging_status / machine-verdict ключи (staging_status:/deploy_status:) — не изменены; миграции БД нет (структурная сверка)."
|
||||
module: tests/test_orch123_staging_runner_exec.py
|
||||
expected: PASS
|
||||
|
||||
- id: TC-12
|
||||
type: unit
|
||||
description: "never-raise / очередь не клинится (AC-11): любая ошибка исполнения/классификации изолирована, worker не падает, задача не залипает на deploy-staging навсегда; снапшот staging_runner в GET /queue различает environment/tool-error vs код-фейл."
|
||||
module: tests/test_orch123_staging_runner_exec.py
|
||||
expected: PASS
|
||||
|
||||
- id: TC-13
|
||||
type: unit
|
||||
description: "Документация-инвариант (AC-12): docs/operations/INFRA.md и docs/architecture/README.md содержат описание границы исполнения staging-сюиты (host-side vs in-container, доступные исполняемые/сокеты) — структурная сверка наличия раздела."
|
||||
module: tests/test_orch123_staging_runner_exec.py
|
||||
expected: PASS
|
||||
|
||||
- id: TC-14
|
||||
type: unit
|
||||
description: "Анти-дрейф ORCH-115: существующие структурные тесты staging-runner (tests/test_orch115_staging_runner.py) и LLM-determinization анти-дрейф остаются ЗЕЛЁНЫМИ после фикса (фикс не ломает инварианты ORCH-115)."
|
||||
module: tests/test_orch115_staging_runner.py
|
||||
expected: PASS
|
||||
Reference in New Issue
Block a user