11 KiB
11 KiB
02-ТЗ — Управление зависимостями задач (B ждёт A) в очереди
Work Item: ORCH-026 · Repo: orchestrator · Стадия: analysis
ТЗ фиксирует ТРЕБОВАНИЯ к изменениям (модули, контракты, артефакты). Конкретный механизм сериализации и место хранения связей — решение архитектора (ADR в
06-adr/); ниже отмечены как «КАНДИДАТ / решает архитектор». Аналитик не предлагает архитектуру.
1. Задействованные модули src/
| Модуль | Роль в задаче | Уровень |
|---|---|---|
src/queue_worker.py |
Планировщик: _drain_once / claim_next_job — точка учёта зависимостей и сериализации при выборе job. |
A + B |
src/db.py |
Очередь jobs / tasks; claim_next_job, enqueue_job, count_running_jobs. Кандидат на хранение связей и блокировки claim. |
A + B |
src/merge_gate.py |
merge-lease (ORCH-065), branch_is_behind_main / auto_rebase_onto_main (ORCH-043) — опора для proactive pre-merge rebase и расширения окна сериализации. |
A |
src/qg/checks.py |
check_branch_mergeable (под-гейт ребра deploy-staging → deploy) — точка форсированного pre-merge rebase. |
A |
src/stage_engine.py |
advance_stage — врезки гейтов; точка интеграции сериализации/верификации. |
A |
src/webhooks/plane.py |
handle_work_item_created / start_pipeline — приём задачи; точка чтения relations (если источник — Plane). |
B |
src/plane_sync.py |
set_issue_blocked, get_project_states (blocked/needs_input), relations API. |
B |
src/notifications.py |
live-карточка: индикация Blocked / «ждёт ORCH-NNN». |
B |
src/config.py |
Новые kill-switch + scope-настройки (паттерн *_enabled / *_repos). |
A + B |
src/reconciler.py / src/job_reaper.py |
Не ломать: skip заблокированных задач (как уже делается для Blocked/Needs-Input, ORCH-060/068); реклейм ресурсов сериализации. | A + B |
2. Требования к изменениям — Уровень A (сериализация merge/деплоя)
2.1 Proactive pre-merge rebase (A-2)
- На ребре
deploy-staging → deploy, ДО фактического merge (в составеcheck_branch_mergeableили соседнего под-гейта), ветка задачи всегда догоняется на свежийorigin/main— не только приbranch_is_behind_main/конфликте. - Переиспользовать
merge_gate.auto_rebase_onto_main(rebase +push --force-with-leaseТОЛЬКО ветки задачи). Текстовый конфликт → существующий контракт:rebase --abort→ откат наdevelopment(как ORCH-043). - Инвариант: никаких push/force-push в
main.
2.2 Расширение окна merge-lease (A-1, A-3, A-4)
- КАНДИДАТ (решает архитектор): держать per-repo merge-lease (ORCH-065) не только «на
момент merge», а на окно «merge → main-updated» (для self — до подтверждения
merged_to_main: true/done), чтобы B не дошла до своего merge, пока A не вmain. - Acquire — неблокирующий (как сейчас): занято → defer задачи B через
enqueue_job(available_at_delay_s=...), bounded бюджет (анти-livelock; ср.merge_defer_max_attempts). Откат наdevelopmentНЕ применять для defer. - Release — holder-aware (как
release_merge_lease), на merged-вебхуке /deploy→done/ откате / по проактивному реклейму (ORCH-065reclaim_stale_lease). - Сериализация строго per-repo (
.merge-lease-<repo>.json) — кросс-репо параллелизм не затрагивается (A-3).
2.3 Условность и безопасность (A-5)
- Реально только для применимых репо: kill-switch + CSV-scope (паттерн
merge_gate_repos/merge_verify_repos; пусто → только self-hostingorchestrator). STAGE_TRANSITIONS,Confirm Deploy(ORCH-059), exit-коды deploy-хука, БАГ-8, terminal-sync — без изменений.- Контракт never-raise для всех новых функций (как соседи в
merge_gate.py).
3. Требования к изменениям — Уровень B (декларативные зависимости)
3.1 Декларация связи (B-1)
- КАНДИДАТ хранения (решает архитектор, см. BRD §4.1):
- вариант Plane relations: читать
blocked-byчерез Plane API вhandle_work_item_created; - вариант БД: новая таблица
job_deps(task_id, depends_on_task_id)или поле вtasks(idempotent_ensure_columnмиграция, как ORCH-065jobs.pid); - гибрид: Plane — декларация, БД — кэш для планировщика (offline-устойчивость).
- вариант Plane relations: читать
- Миграция БД (если выбран вариант с таблицей/колонкой) — только аддитивная
(
CREATE TABLE IF NOT EXISTS/_ensure_column), безопасная на живой прод-БД с общими данными enduro-trails.
3.2 Гейт планировщика (B-2)
- При выборе job (
claim_next_job/_drain_once) задача с незавершёнными depends-on не клеймится (аналогavailable_at-gate): пропускается до тех пор, пока все depends-on неdone. Не должна занимать слотmax_concurrency. - Реализация — leaf-функция с чистой логикой «готова ли задача к запуску» (тестируемо
юнитами, never-raise), по образцу
staging_verdict.py/post_deploy.py.
3.3 Защита от дедлоков (B-3)
- Детектор циклов в графе depends-on (DFS/обнаружение цикла) — чистая функция, юнит-тестируемая.
- Цикл → задача(и) НЕ запускается молча:
set_issue_blocked+ alert (Telegram/Plane) с указанием цикла. Не блокировать поток других задач.
3.4 Видимость (B-4)
- Заблокированная задача: Plane-статус
Blocked(set_issue_blocked) и/или строка ожидания в Telegram-карточке («⏳ ждёт ORCH-NNN»). Использовать существующий механизм карточки (notifications.update_task_tracker), контракт never-raise / silent. reconcilerF-1 уже пропускает Blocked/Needs-Input (ORCH-060/068) — убедиться, что новые заблокированные-по-зависимости задачи тоже пропускаются (не «разблокируются» ошибочно).
4. Изменения API (endpoints)
- Новые HTTP endpoints не требуются.
- Наблюдаемость: расширить снимок
GET /queueблоком о зависимостях/сериализации (по образцу блоковreconcile/reaper/post_deploy/merge_verify): кол-во заблокированных задач, держатель merge-lease, defer-счётчики, обнаруженные циклы. Read-only, никогда не источник истины для решений.
5. Изменения схемы БД
- КАНДИДАТ (если выбран БД/гибрид для Уровня B): аддитивная таблица
job_depsили колонка вtasks(см. §3.1). ТолькоCREATE TABLE IF NOT EXISTS/_ensure_column. Без изменения существующих колонокjobs/tasks. Restart-safe, безопасно на общей прод-БД. - Уровень A (сериализация) — без изменения схемы БД (merge-lease файловый, как ORCH-065).
6. Требования к новым QG checks
- Новый зарегистрированный QG-чек НЕ вводится (паттерн ORCH-071/058: под-гейт — врезка в
advance_stageили расширениеcheck_branch_mergeable, а не новая запись вQG_CHECKS). - Реестр
QG_CHECKS— без изменений.
7. Конфигурация (src/config.py)
Новые настройки по паттерну *_enabled (kill-switch) + *_repos (CSV scope, пусто →
self-hosting). КАНДИДАТ-имена (финализирует архитектор):
- Уровень A:
merge_serialize_enabled/merge_serialize_repos(или расширениеmerge_gate_*); опциональноpremerge_rebase_always(вкл proactive rebase). - Уровень B:
task_deps_enabled/task_deps_source(plane|db|hybrid). Дефолты — обратная совместимость (для не-self репо — прежнее поведение).
8. Артефакты pipeline (создать/обновить В ТОМ ЖЕ PR)
06-adr/ADR-001-*.md— решение по сериализации (A) и хранению зависимостей (B).- Обновить
docs/architecture/README.md(раздел про очередь/merge-gate/сериализацию). - Обновить
CLAUDE.md(паспорт: конвейер/инварианты, если меняется поведение очереди). - Обновить
CHANGELOG.md(## [Unreleased]). - Если вводится таблица БД — отразить в
08-data-requirements.md(создаёт архитектор). 07-infra-requirements.md— если требуется новый Plane-статус/настройка relations.
9. Инварианты (НЕ нарушать)
STAGE_TRANSITIONS, реестрQG_CHECKS,check_deploy_status/check_staging_status,Confirm Deploy(ORCH-059), БАГ-8, terminal-sync — без изменений.- Никаких push/force-push в
main; force только--force-with-leaseна ветку задачи. - Сериализация — строго per-repo; кросс-репо параллелизм сохранён.
- never-raise во всех новых функциях; restart-safe состояние.
- ORCH-026 дополняет рубежи ORCH-073, не заменяет.
- Прод-контейнер orchestrator не рестартится вне штатного
Confirm Deploy.