work_item: ORCH-110 stage: analysis author_agent: analyst status: ready-for-review created_at: 2026-06-15 model_used: claude-opus-4-8 escalate: full-cycle title: "merge-gate re-test timeout: tolerance + no orphan-process leak + re-test contract" framework: pytest scope: > Покрывает: классификацию инфра-таймаута re-test merge-gate как транзиента (без ложного отката), tree-kill оркестратор-спавненных pytest-прогонов (re-test + coverage), сохранение красно-откат-пути, согласование бюджета re-test со сквозными инвариантами, контракт необходимости re-test, kill-switch и наблюдаемость. Вне покрытия: алерт sidecar-watchdog (ORCH-111), правка конкретного test_install_lite_script.py, поведение enduro (только проверяется no-op). notes: > TC-10 — ОБЯЗАТЕЛЬНЫЙ регресс-тест инцидента ORCH-109/PR#129: красный на текущем коде (инфра-таймаут re-test → ложный rollback / выживший процесс), зелёный после фикса. Подпроцессы в тестах мокаются (управляемый "медленный/спавнящий детей pytest"), без обращения к сети/Plane/Gitea. Полный регресс tests/ должен оставаться зелёным. Точные имена символов/флагов уточняет архитектор (06-adr); модули-плейсхолдеры ниже выровнены под манифест PIPELINE_DOCS. tests: - id: TC-01 type: unit description: "retest_branch: таймаут возвращает (False, 're-test timeout after s') И завершает всё дерево подпроцесса (внуки не переживают таймаут)." module: tests/test_orch110_retest_lifecycle.py expected: PASS - id: TC-02 type: unit description: "coverage_gate.measure_coverage: таймаут завершает всё дерево подпроцесса (сиблинг-источник утечки, BR-3); возврат None сохранён." module: tests/test_orch110_retest_lifecycle.py expected: PASS - id: TC-03 type: unit description: "check_branch_mergeable: исход 'timeout' различим от 'red re-test' в reason/классификации (без смены имени/семантики зарегистрированного check_*)." module: tests/test_orch110_merge_gate_classify.py expected: PASS - id: TC-04 type: unit description: "Маршрутизация исхода: инфра-таймаут → defer/повтор/инфра-alert путь (НЕ _handle_merge_gate_rollback на development, без инкремента developer-retry)." module: tests/test_orch110_merge_gate_routing.py expected: PASS - id: TC-05 type: unit description: "Анти-над-толерантность: детерминированно КРАСНЫЙ re-test по-прежнему → откат на development + developer-retry + release lease (BR-6 сохранён)." module: tests/test_orch110_merge_gate_routing.py expected: PASS - id: TC-06 type: unit description: "Ограниченность (anti-loop): повторы/defer инфра-таймаута лимитированы по попыткам и суммарному времени; исчерпание → один инфра-alert, не бесконечный bounce." module: tests/test_orch110_merge_gate_routing.py expected: PASS - id: TC-07 type: unit description: "Kill-switch off → байт-в-байт прежнее поведение (таймаут → rollback на development, прежний текст alert); not-self repo (enduro) → no-op." module: tests/test_orch110_killswitch.py expected: PASS - id: TC-08 type: unit description: "Бюджет/инварианты: malformed/непозитивный merge_retest_timeout_s → дефолт + WARNING; соблюдён reaper_max_running_s > max(agent_timeout, бюджеты)+grace и согласование с merge_lock_timeout_s." module: tests/test_orch110_budget_invariants.py expected: PASS - id: TC-09 type: unit description: "never-raise: любая ошибка в новом транзиент-пути → безопасный дефолт + WARNING; исключение не уходит в advance_stage." module: tests/test_orch110_merge_gate_routing.py expected: PASS - id: TC-10 type: integration description: "РЕГРЕСС инцидента: tester PASS + зелёный CI + ветка не-behind, но re-test таймаут — задача НЕ откатывается ложно и НЕ упирается в 'Merge-gate still failing after N developer retries'; доходит до deploy или поднимает инфра-alert. Красный до фикса, зелёный после." module: tests/test_orch110_false_rollback_regression.py expected: PASS - id: TC-11 type: integration description: "Контракт необходимости re-test (FR-4/AC-6): при не-behind + зелёном CI по HEAD локальный re-test ведёт себя по выбранному в ADR контракту (skip/scope/trust-CI) и не является избыточной единственной точкой ложного отказа. Финальная форма — после решения архитектора." module: tests/test_orch110_retest_contract.py expected: PASS - id: TC-12 type: integration description: "Наблюдаемость: инфра-таймаут отражён в логах/GET /queue (read-only) и Telegram-уведомлении с кликабельным номером; отличим от код-фейл-отката; без дубля с ORCH-111." module: tests/test_orch110_observability.py expected: PASS