Files
orchestrator/docs/overview/tech-quality-security.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

7.3 KiB
Raw Permalink Blame History

Блок 6. Качество и безопасность

Реестр гейтов и их распределение по стадиям — блок 2; механизм machine-verdict доков — PIPELINE_DOCS §3; машинный контракт стадий — HANDOFF_PROTOCOL.

Философия Quality Gates

Вердикты — машинные, никогда проза. Гейт читает вердикт ТОЛЬКО из YAML-frontmatter артефакта (ключи вида verdict:, result:, staging_status:, deploy_status:, security_status: — имена и регистр неизменны байт-в-байт). Агент не может «уговорить» гейт красивым отчётом: нет ключа — нет прохода. Парсинг frontmatter сведён к единому контракту src/frontmatter.py — одна точка чтения для всех гейтов.

Гейт ≠ маршрутизация. Маршруты задач (багфикс-трек, авто-лейблы, serial gate) — свойство планировщика; ни один из них не ослабляет ни одного гейта. Любая новая способность платформы проектируется так, чтобы реестр гейтов и карта стадий не трогались.

Анти-петля. Откаты на доработку ограничены (max 3 подряд); инструментальные сбои вспомогательных проверок по умолчанию fail-open с предупреждением (не запирают конвейер), критичные проверки — fail-closed.

Специальные гейты деплойного ребра

  • Security-гейт (check_security_gate) — детерминированная (без LLM) проверка секретов и зависимостей перед продом; вердикт — security_status: в отчёте задачи.
  • Coverage-гейт (check_coverage_gate) — покрытие тестами измеряется на финальном коде ветки; базовая линия по репозиторию растёт только вверх (ratchet при подтверждённом слиянии) — покрытие не может деградировать молча.

Оба — врезки в переход (блок 2), включаются по конфигу и скоупятся по репозиториям.

Канон секретов

  • Секреты живут только в .env-файлах на хосте и никогда не коммитятся; в git — только канон-примеры с пустыми плейсхолдерами.
  • Для нового хоста секреты выпускаются свежими (scripts/gen_secrets.py), боевые не копируются.
  • Анти-регресс машинный: структурные тесты сканируют исполняемый код на боевые хост-литералы, а документацию — на секретоподобные значения; находка рвёт CI.

Где уместен LLM: карта вызовов и нормативная политика

Платформа держит доказательную карту всех мест, где поток управления потребляет суждение LLM, и нормативную политику «LLM — только там, где нужно настоящее суждение». Карта разводит три факта: консультация ≠ транспорт/слот; control-path (вердикт LLM ветвит поток управления) ≠ artifact-producer (детерминированный гейт судит артефакт независимо); и деривируемость вердикта из tool-сигналов. Путь называется avoidable LLM control path, когда он одновременно control-path и его вердикт деривируем из exit-кодов (тогда консультацию можно заменить детерминированным раннером). Поимённо: avoidable = {tester, deployer}; настоящее суждение сохраняется у {analyst, architect, developer, reviewer}. Карта — снимок, прибитый структурными анти-дрейф тестами. Первый срез реализован (ORCH-115): на deploy-staging для self-hosting orchestrator LLM-deployer заменён детерминированным src/staging_runner.py (вердикт staging_status: = маппинг exit-кода staging-сюиты); LLM-ветвь остаётся fallback'ом, гейт check_staging_status не тронут. Замена второго кандидата (tester) — follow-up по роли.

Self-hosting-страховки

Платформа дорабатывает сама себя тем же конвейером — прод-инстанс при этом обслуживает и другие проекты. Страховки:

  • Песочница обязательна: перед прод-выкладкой платформы изменение репетируется на staging-инстансе (отдельный порт/БД); guard не даёт staging-операциям коснуться прод-порта.
  • Прод-выкладка — только по явному человеческому статусу Confirm Deploy (обычный approve прод не выкатывает); деплой идёт детачнутым процессом с финализатором — честный исход фиксируется даже при рестарте.
  • main неприкосновенен: слияние только через PR-API, force-push запрещён всем.
  • Прод-контейнер никогда не роняется задачей: агенты проверяют изменения локально и на песочнице; рестарт прода — только штатным деплой-маршрутом.
  • Пост-деплой наблюдение: после выкладки платформа следит за своим здоровьем; деградация замораживает репозиторий и зовёт человека.

Операционные детали и топология прода — docs/operations/ (см. инженерный справочник); наблюдение за здоровьем — блок 7.