135 lines
11 KiB
Markdown
135 lines
11 KiB
Markdown
# 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-065 `reclaim_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-hosting `orchestrator`).
|
||
- `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-065 `jobs.pid`);
|
||
- гибрид: Plane — декларация, БД — кэш для планировщика (offline-устойчивость).
|
||
- Миграция БД (если выбран вариант с таблицей/колонкой) — **только аддитивная**
|
||
(`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.
|
||
- `reconciler` F-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. Инварианты (НЕ нарушать)
|
||
1. `STAGE_TRANSITIONS`, реестр `QG_CHECKS`, `check_deploy_status`/`check_staging_status`,
|
||
`Confirm Deploy` (ORCH-059), БАГ-8, terminal-sync — без изменений.
|
||
2. Никаких push/force-push в `main`; force только `--force-with-lease` на ветку задачи.
|
||
3. Сериализация — строго per-repo; кросс-репо параллелизм сохранён.
|
||
4. never-raise во всех новых функциях; restart-safe состояние.
|
||
5. ORCH-026 дополняет рубежи ORCH-073, не заменяет.
|
||
6. Прод-контейнер orchestrator не рестартится вне штатного `Confirm Deploy`.
|