Address reviewer P1 (ось ORCH-011/ORCH-079, правило агентов №6): витрина описывала паузу serial-gate как исключительно операторскую, но ORCH-120 добавил движковый авто-park/unpark на analyst Needs Input. - tech-pipeline.md: абзац пауз теперь называет два источника (оператор + авто-park движком на Needs Input, флаг analyst_needs_input_autopause_enabled, скоуп self-hosting, симметричный unpark на resume). - tech-observability.md: пункт пауз в GET /queue — оба источника. - tech-agents.md: when-applicable сигнальный канал 01-questions.md у analyst (строка таблицы + поясняющая врезка; не machine-verdict, не deliverable). - CHANGELOG: запись ORCH-120 дополнена строкой про обновление витрины. tests/test_system_docs.py зелёный (29 passed). src/STAGE_TRANSITIONS/QG_CHECKS не тронуты — docs-only. Refs: ORCH-120 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
12 KiB
Блок 2. Конвейер: стадии, гейты, маршруты
Источник истины — карта переходов
STAGE_TRANSITIONSвsrc/stages.pyи реестр гейтовQG_CHECKSвsrc/qg/checks.py; перечень ниже сверяется с кодом структурным тестом (tests/test_system_docs.py). Норматив структуры доков конвейера — PIPELINE_DOCS.
Схема конвейера
created → analysis → architecture → development → review → testing → deploy-staging → deploy → done
↑ │
└──── REQUEST_CHANGES ─────┘ (откат на доработку, max 3)
Плюс системный сток cancelled — терминальное состояние отменённой задачи (кнопка STOP,
см. ниже). Это не ребро конвейера, а равноправный done сток: попасть в него можно с любой
стадии, выйти — нельзя.
Стадии и гейты выхода
Гейт выхода (exit-гейт) — машинная проверка, без которой задача не покидает стадию:
| Стадия | Кто работает | Гейт выхода (имя в реестре) | Что проверяет |
|---|---|---|---|
created |
— | — | вход конвейера (вебхук Plane) |
analysis |
analyst | check_analysis_approved |
пакет аналитики полон И постановка одобрена человеком |
architecture |
architect | check_architecture_done |
ADR / инфра-требования зафиксированы |
development |
developer | check_ci_green |
CI на ветке задачи зелёный |
review |
reviewer | check_reviewer_verdict |
машинный вердикт ревью: APPROVED |
testing |
tester | check_tests_passed |
машинный вердикт тестера: PASS |
deploy-staging |
deployer | check_staging_status |
репетиция выкладки на песочнице успешна |
deploy |
deployer / finalizer | check_deploy_status |
прод-выкладка реально успешна |
done |
— | — | терминал |
cancelled |
— | — | терминал (сток отмены) |
Детерминированный staging-раннер (ORCH-115). На стадии
deploy-stagingдля self-hostingorchestratorработу ведёт детерминированный код (src/staging_runner.py), а не LLM-агентdeployer: он перехватывается вlaunch_jobдо запуска агента (как Phase A/B/C прод-деплоя), исполняет ту же staging-сюиту, маппит exit-код вstaging_status:и инициирует тот же гейтcheck_staging_status. Это замена продюсера артефакта, а не гейта: контракт15-staging-log.md, имя/семантикаcheck_staging_status,STAGE_TRANSITIONS— не изменились. Под kill-switchstaging_runner_enabled(скоупstaging_runner_repos, пусто → self-hosting only); при выключении на стадии снова работает LLM-deployerбайт-в-байт. Это первый реализованный срез determinization-roadmap (см.docs/architecture/llm-determinization-roadmap.md).
Детерминированный test-раннер (ORCH-116). На стадии
testingдля self-hostingorchestratorработу ведёт детерминированный код (src/test_runner.py), а не LLM-агентtester: он перехватывается вlaunch_jobдо запуска агента (тем же паттерном, что staging-раннер), исполняет регрессpytestв worktree ветки + read-only smoke, маппит exit-код вresult:и инициирует тот же гейтcheck_tests_passed. Это замена продюсера артефакта, а не гейта: контракт13-test-report.md, имя/семантикаcheck_tests_passed/_parse_tests_verdict,STAGE_TRANSITIONS— не изменились. Под kill-switchtest_runner_enabled(скоупtest_runner_repos, пусто → self-hosting only; репо без тест-контракта → LLM-tester); при выключении снова работает LLM-testerбайт-в-байт. Это второй реализованный срез determinization-roadmap (гибрид: LLM-фолбэк остаётся на off-control-path триаж, не на вынесениеresult:).
Под-гейты деплойного ребра — врезки, не стадии
На переходе deploy-staging → deploy исполняются четыре под-гейта в нормативном порядке
(security → merge → coverage → image-freshness):
check_security_gate— секреты/зависимости, вердикт из security-отчёта;check_branch_mergeable— merge-gate: ветка догнана до свежегоmain(под merge-lease) и мержабельна;check_coverage_gate— покрытие тестами не ниже базовой линии/порога (baseline-ratchet);check_staging_image_fresh— staging-образ собран из актуального кода.
Это врезки в переход, а не стадии: они не появляются в карте STAGE_TRANSITIONS, а
исполняются stage engine'ом внутри ребра. Провал любого из них — откат на доработку. Исключение
(ORCH-110): инфра-таймаут локального re-test merge-gate (а не детерминированный красный тест) —
это транзиент, а не дефект кода → ограниченный повтор + отдельный инфра-alert, без отката на
доработку и без расхода developer-retry (красный re-test/конфликт по-прежнему откатывают). На ребре
deploy → done аналогичная врезка merge-verify подтверждает, что код задачи реально слит в
main (слияние — только через PR-API Gitea, см. интеграции).
Откаты
REQUEST_CHANGES от ревьюера, проваленные тесты или красный под-гейт возвращают задачу на
стадию разработки с дословным перечнем замечаний. Лимит — 3 попытки подряд, дальше задача
останавливается и требует человека (анти-петля).
Человеческие гейты и их снятие авто-лейблами
В штатном прогоне человек принимает ровно два решения:
- Одобрение постановки (на
analysis): перевод задачи в статус Approved пропускает её дальше; - Подтверждение прод-выкладки (на
deploy): отдельный статус Confirm Deploy — чтобы привычный «approve» не выкатывал прод случайным кликом.
Оба решения можно снять декларативно — лейблами autoApprove / autoDeploy на задаче (пакетный авто-режим). Снимается только ожидание человеческого сигнала: ни одна техническая проверка не пропускается, autoDeploy физически не может выкатить непрошедшее под-гейты.
Багфикс-маршрут
Задача с меткой Bug едет коротким путём: облегчённая аналитика (но полный пакет
документов) и пропуск стадии architecture — из аналитики сразу в разработку. Срезается
только аналитика/проектирование: все гейты исполняются без изменений. Сложный баг
эскалируется обратно в полный цикл.
Последовательность внутри репозитория (serial gate)
Новая задача репозитория не входит в работу, пока не завершена более ранняя (FIFO): ветка
каждой задачи срезается от свежего main, уже содержащего код предшественника. Деградация
прода после выкладки замораживает репозиторий (freeze) до ручного разбора — следующие задачи
ждут.
У FIFO-порядка есть управляемое исключение — пауза без блокировки: более раннюю задачу можно
снять с активной очереди репозитория, не дожидаясь её завершения, и тогда срочный успешник её
обгоняет. Паузу (durable-сигнал tasks.paused_at) ставят два источника. Оператор — явно
(POST /serial-gate/pause, снять — /resume). Движок — автоматически, когда аналитик
упирается в блокирующие открытые вопросы и задача уходит в Needs Input (узкий триггер под
флагом analyst_needs_input_autopause_enabled, скоуп self-hosting); на возобновлении (ответ
человека) движок снимает паузу симметрично. Авто-park нужен, чтобы задача, ждущая человека часы
или дни, не клинила FIFO-очередь репозитория в автономном пакетном прогоне. Пауза — отдельная ось:
она ≠ отмена (задача не терминальна и возвращается в гейт обратной командой) и не обходит ни
freeze, ни объявленные зависимости. Свежесть базы возобновлённой задачи гарантируют те же
механизмы (отложенный срез ветки + ребейз на слиянии), что и для обычного FIFO.
Отмена: STOP → cancelled
Перевод задачи в статус STOP останавливает агента, снимает job'ы с очереди, удаляет
рабочую ветку и worktree и переводит задачу в cancelled. Если задача в необратимой фазе
(идёт слияние/выкладка) — отмена откладывается и применяется после честного завершения шага.
STOP никогда не трогает main и прод-контейнер.
Статусная модель Plane: индикация ≠ управление
Статусы в Plane — слой индикации: они показывают человеку осмысленную картину хода задачи,
но никогда не управляют конвейером (машина стадий — только STAGE_TRANSITIONS). Управляющих
статусов ровно три: запуск в работу, Approved/Confirm Deploy (человеческие гейты) и STOP
(отмена). Полная карта статусов — в инженерном справочнике.
Кто работает на каждой стадии и что сдаёт — агенты; как гейты читают вердикты — качество и безопасность.