Second realised slice of the determinization-roadmap (ORCH-118 A5, needs-hybrid-fallback): on the `testing` stage for the self-hosting `orchestrator` repo the LLM `tester` agent is replaced by a deterministic test-runner (src/test_runner.py), intercepted in launch_job BEFORE _spawn (deploy-finalizer / post-deploy-monitor / staging-runner precedent). It runs the regression `python -m pytest <target>` in the task worktree via proc_group (tree-kill) + an optional read-only smoke (/health, /status, /queue + serial_gate), maps the exit-code -> result: PASS|FAIL via the existing self_deploy.map_exit_code_to_status contract, writes 13-test-report.md and initiates the EXISTING check_tests_passed gate exactly as a finished LLM-tester. Invariant (NFR-1): only the *producer* changes — the artifact contract (13-test-report.md / result:), the gate check_tests_passed / _parse_tests_verdict, STAGE_TRANSITIONS and the DB schema are byte-for-byte UNCHANGED. Additive, under a kill-switch (test_runner_enabled), never-raise, fail-closed, self-hosting scope, two-level outcome (tool-error DEFER, anti ORCH-110), hybrid (LLM strictly off-control-path). 52c-`status:` is aligned with the verdict (D6.1) so the three-field _parse_tests_verdict never false-negatives a PASS. Docs (ORCH-118 NFR-6, atomic with code): llm-call-sites.md (A5 implemented), llm-determinization-roadmap.md (rank 2 implemented), llm-usage-policy.md, README/internals/overview, tester.md, CLAUDE.md, CHANGELOG.md. Coverage: tests/test_orch116_test_runner.py (TC-01..TC-14); LLM anti-drift tests green. Full suite: 2137 passed. Refs: ORCH-116 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
7.7 KiB
Блок 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 не тронут. Второй срез реализован (ORCH-116): на testing для self-hosting
orchestrator LLM-tester заменён детерминированным src/test_runner.py (вердикт result: = exit-код
pytest + read-only smoke); это гибрид (needs-hybrid-fallback) — LLM-ветвь остаётся fallback'ом /
будущим off-control-path триажем, гейт check_tests_passed/_parse_tests_verdict не тронут.
- Карта вызовов LLM:
../architecture/llm-call-sites.md - Нормативная политика:
../architecture/llm-usage-policy.md - Порядок замен:
../architecture/llm-determinization-roadmap.md
Self-hosting-страховки
Платформа дорабатывает сама себя тем же конвейером — прод-инстанс при этом обслуживает и другие проекты. Страховки:
- Песочница обязательна: перед прод-выкладкой платформы изменение репетируется на staging-инстансе (отдельный порт/БД); guard не даёт staging-операциям коснуться прод-порта.
- Прод-выкладка — только по явному человеческому статусу Confirm Deploy (обычный approve прод не выкатывает); деплой идёт детачнутым процессом с финализатором — честный исход фиксируется даже при рестарте.
mainнеприкосновенен: слияние только через PR-API, force-push запрещён всем.- Прод-контейнер никогда не роняется задачей: агенты проверяют изменения локально и на песочнице; рестарт прода — только штатным деплой-маршрутом.
- Пост-деплой наблюдение: после выкладки платформа следит за своим здоровьем; деградация замораживает репозиторий и зовёт человека.
Операционные детали и топология прода — docs/operations/ (см.
инженерный справочник); наблюдение за здоровьем —
блок 7.