Files
orchestrator/docs/architecture/llm-determinization-roadmap.md
claude-bot b50cf1dd08
All checks were successful
CI / test (push) Successful in 1m8s
CI / test (pull_request) Successful in 1m8s
feat(staging): deterministic staging-runner replacing LLM deployer on deploy-staging (ORCH-115)
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>
2026-06-16 01:59:43 +03:00

6.9 KiB
Raw Permalink Blame History

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-115src/staging_runner.py (перехват в launch_job до _spawn, как D1/D2): на стадии deploy-staging для self-hosting orchestrator вердикт staging_status: производит детерминированный код (маппинг exit-кода staging_check.py через self_deploy.map_exit_code_to_status), а не LLM. Под kill-switch staging_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):

  1. Деривируемость максимальна. Вердикт staging_status:чистый маппинг exit-кода scripts/staging_check.py; готовый leaf src/staging_verdict.py::compute_staging_verdict (ORCH-061) уже считает этот вердикт детерминированно.
  2. Прод уже детерминирован. Ребро deploy (deploy_status:) для self-hosting orchestrator производит детерминированный finalizer (Phase A/B/C, ORCH-036) — LLM в критическом self-restart-пути нет. Срез не трогает критический путь → минимальная поверхность риска.
  3. Опирается на прецедент D1/D2 (launch_job-перехват до _spawn) — архитектурный риск замены агента уже снят рабочим паттерном.
  4. 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.