Replace the LLM `deployer` agent on the `deploy-staging` stage (self-hosting orchestrator) with a deterministic staging-runner intercepted in launch_job BEFORE _spawn (the deploy-finalizer / post-deploy-monitor reserved-agent precedent). The runner executes the SAME staging suite, maps the exit-code to `staging_status:` via the existing self_deploy.map_exit_code_to_status contract, writes 15-staging-log.md, and initiates the UNCHANGED check_staging_status gate exactly as a finished LLM-deployer would. Invariant (NFR-1): this replaces only the *producer* of the artifact — the artifact contract, the gate / _parse_staging_status / check_staging_status name, STAGE_TRANSITIONS, the machine-verdict key `staging_status:` and the DB schema are byte-for-byte unchanged. Additive, under a kill-switch + repo-scope CSV, never-raise, fail-safe back to the LLM path. Two-level outcome (D5, anti ORCH-110): suite executed -> verdict -> advance (FAILED -> the existing deploy-staging -> development rollback + developer-retry, same as a FAILED LLM verdict); tool-error (suite did not execute) -> bounded DEFER -> fail-closed FAILED + alert on exhaustion (infra != code fault; never a silent advance / false green). First implemented slice of the LLM determinization roadmap (ORCH-118 A6, replace-deterministic-now). - New leaf src/staging_runner.py (never-raise; proc_group tree-kill + timeout) - launch_job intercept + _run_staging_runner_job (mirror _run_deploy_finalizer_job) - config: ORCH_STAGING_RUNNER_* keys (enabled/repos/timeout/infra-retry budget) - GET /queue staging_runner observability block - docs: llm-call-sites/roadmap/usage-policy (A6 implemented; machine blocks + single-transport invariant intact), deployer.md (LLM branch -> fallback), CLAUDE.md, CHANGELOG.md, overview (tech-pipeline/tech-agents/tech-quality-security), .env.example - tests/test_orch115_staging_runner.py (TC-01..TC-13); LLM anti-drift green (TC-14) Refs: ORCH-115 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
6.9 KiB
LLM determinization roadmap (ORCH-118)
Что это. Упорядоченный план детерминированных замен avoidable LLM control paths (
{tester, deployer}— см.llm-call-sites.md). Это транзиентный план: он обновляется по мере закрытия follow-up'ов. ORCH-118 раннеры не реализует (FR-7); старт каждого кандидата гейтится утверждением карты.Кандидаты названы ПО РОЛИ. Конкретные follow-up Plane-ID не фиксируются ни в одном артефакте (R3 / NFR-6): этих work item нет в подтверждённом backlog; ID присваивается при заведении задачи. Анти-фабрикация прибита тестом
TC-11(tests/test_llm_determinization_docs.py).Оценки экономии — «оценка до фактического замера» (NFR-5). Источник — существующие колонки
agent_runs(model/effort/токены/стоимость/время); точные числа снимаются при заведении follow-up'а черезGET /metrics/ запрос кagent_runs. Здесь — порядок величины, а не контракт.
1. Рекомендованный первый срез — deployer (staging-status) — ✅ РЕАЛИЗОВАН (ORCH-115)
Статус: реализовано. Срез выполнен в ORCH-115 —
src/staging_runner.py(перехват вlaunch_jobдо_spawn, какD1/D2): на стадииdeploy-stagingдля self-hostingorchestratorвердиктstaging_status:производит детерминированный код (маппинг exit-кодаstaging_check.pyчерезself_deploy.map_exit_code_to_status), а не LLM. Под kill-switchstaging_runner_enabled+ скоупstaging_runner_repos(пусто → self-hosting only); LLM-ветвь остаётся fallback'ом. Контракт артефакта/гейтаcheck_staging_status/STAGE_TRANSITIONS/схема БД — не тронуты. Детали —docs/work-items/ORCH-115/06-adr/ADR-001-deterministic-staging-runner.md, сквознойdocs/architecture/adr/adr-0048-deterministic-staging-runner.md. Записьrank 1в машинном блоке §4 сохраняется (first_slice = yes, инвариант карты) как историческая фиксация первого среза.
Обоснование (самый низкорисковый «чисто деривируемый» control path):
- Деривируемость максимальна. Вердикт
staging_status:— чистый маппинг exit-кодаscripts/staging_check.py; готовый leafsrc/staging_verdict.py::compute_staging_verdict(ORCH-061) уже считает этот вердикт детерминированно. - Прод уже детерминирован. Ребро
deploy(deploy_status:) для self-hostingorchestratorпроизводит детерминированный finalizer (Phase A/B/C, ORCH-036) — LLM в критическом self-restart-пути нет. Срез не трогает критический путь → минимальная поверхность риска. - Опирается на прецедент
D1/D2(launch_job-перехват до_spawn) — архитектурный риск замены агента уже снят рабочим паттерном. replace-deterministic-now, без hybrid-fallback (в отличие от tester).
2. Второй кандидат — tester (гибрид)
Детерминированное ядро (pytest + smoke даёт PASS/FAIL по exit-коду) покрывает основной вердикт;
LLM-фолбэк сохраняется только на суждение, не сводимое к exit-коду: триаж падений и маппинг
TC ↔ критерии приёмки. Поэтому needs-hybrid-fallback, а не replace-deterministic-now: поверхность
суждения шире и объём работы больше.
3. Общие требования к каждому follow-up'у
Каждый кандидат при заведении задачи несёт: kill-switch + обратимость (паттерн
ORCH-022/027/043/089/090 — флаг *_enabled, пустой CSV *_repos → self-hosting only), скоуп-гард
(не трогать STAGE_TRANSITIONS/QG_CHECKS/check_*/machine-verdict/схему БД), а замена-агента —
перехват в launch_job до _spawn (как D1/D2). Свежесть прецедента — инцидент-трек
ORCH-110/111/112/113/114/117 (единое детерминированное владение side-effectful путями).
4. Машинно-читаемый блок roadmap
Заголовок (
rank | role | dependencies | savings_estimate_source | security_risk | hybrid_needed | followup_type | first_slice) парситсяtests/test_llm_determinization_docs.py::test_tc07_*.followup_type— по роли, без Plane-ID. Ровно одинfirst_slice = yes.
| rank | role | dependencies | savings_estimate_source | security_risk | hybrid_needed | followup_type | first_slice |
|---|---|---|---|---|---|---|---|
| 1 | deployer | staging_verdict.compute_staging_verdict (ORCH-061) + launch_job pre-spawn precedent (D1/D2) | agent_runs (deployer rows; estimate pending GET /metrics) | low (prod already deterministic via Phase A/B/C ORCH-036) | no | deployer-replacement (staging-status mapping) | yes |
| 2 | tester | deterministic pytest+smoke core; LLM fallback for failure triage / TC-to-criteria mapping | agent_runs (tester rows; estimate pending GET /metrics) | medium (failure-triage judgment must stay correct) | yes | tester-hybrid (deterministic core + LLM fallback) | no |
5. Вне scope
reviewer— C, но keep (вердикт «приемлемость кода/решения» не деривируем): не в roadmap'е.analyst/architect/developer— P (artifact-producer, не control path): не в roadmap'е.- Реализация раннеров — отдельные follow-up задачи (по роли), стартуют после утверждения карты.
Связанные документы: llm-call-sites.md, llm-usage-policy.md.