4.2 KiB
adr-0015: Зависимости задач + сериализация merge внутри репо
Статус: accepted · Дата: 2026-06-08 · Источник: ORCH-026
Связи: дополняет adr-0006 (merge-gate), adr-0011 (merge-lease + reclaim), adr-0013/0014
(merge-verify, SHA-in-main), adr-0002 (очередь). Детально —
docs/work-items/ORCH-026/06-adr/ADR-001-merge-serialization-and-task-deps.md.
Контекст
Эрозия main 08.06 родилась из некоординированного параллелизма задач одного репо (ветки от
устаревшего main, фантом-merge затирает соседа). adr-0014 закрыл последствия; ORCH-026 — корень
на уровне планировщика. Плюс исходный скоуп ORCH-026: декларативные зависимости задач (B ждёт A).
Решение
Уровень A — сериализация merge/деплоя (per-repo). Окно сериализации уже обеспечивается
merge-lease (adr-0011): захват в check_branch_mergeable, удержание до release (PR-merged webhook /
deploy→done=SHA-in-main для self / откат / проактивный reclaim). Это и есть окно
«merge → main-updated» — механизм не переписывается. Добавляется единственное новое поведение:
безусловный proactive pre-merge rebase (флаг premerge_rebase_always, дефолт True, скоуп
merge_gate_repos): под лизом всегда вызывается auto_rebase_onto_main (no-op + «Everything
up-to-date» на актуальной ветке → CI не триггерится; реальный догон на отстающей). Инвариант:
никаких push в main, force только --force-with-lease на ветку.
Уровень B — декларативные зависимости. Аддитивная таблица job_deps(task_id, depends_on_task_id) — источник истины планировщика (offline-устойчивость: сетевой Plane в
горячем claim встанет очередью всех проектов). Источник декларации настраивается
task_deps_source = db|plane|hybrid (дефолт db); планировщик всегда читает БД-кэш. Гейт —
условие NOT EXISTS в claim_next_job (задача не выбирается, пока есть незавершённая зависимость;
слот max_concurrency не занимается). Циклы — DFS-детектор (src/task_deps.py) + set_issue_blocked
- alert. Видимость — строка «⏳ ждёт ORCH-NNN» в Telegram-карточке (Plane Blocked — на дедлоке). Зависимости — только intra-repo (v1).
Альтернативы
Отдельный merge-lock/merge-queue (дублирует adr-0011); расширение release-точек лиза (не нужно —
окно уже корректно); Plane как источник истины планировщика (self-hosting risk); гейт зависимостей
в воркере с claim+requeue (churn vs. чистый NOT EXISTS); поле в tasks вместо таблицы (M:N хуже).
Последствия
Минимально-инвазивно: STAGE_TRANSITIONS/QG_CHECKS не тронуты (паттерн врезки), переиспользует
merge-gate/merge-lease целиком. Обе фичи инертны без данных → нулевая регрессия для enduro-trails.
restart-safe, never-raise, kill-switch на каждую (premerge_rebase_always, task_deps_enabled).
Миграция — только аддитивная (CREATE TABLE/INDEX IF NOT EXISTS). Ограничение: B v1 — intra-repo.
Self-hosting safety: изменения идут через deploy-staging → Confirm Deploy, без внеочередного
рестарта прода.