# Dev Report: ORCH-2 [S-4] git worktree per task Дата: 2026-06-02 Статус: DONE ## Задача Каждая задача (ветка) работает в изолированной git worktree (`/repos/_wt//`) вместо общего `/repos/` — убрать гонки `git checkout` при двух активных задачах. ## Сделано - [x] Task 1 — `src/git_worktree.py` (`_safe`, `get_worktree_path`, `ensure_worktree`, `remove_worktree`) + `config.worktrees_dir=/repos/_wt` - [x] Task 2 — launcher: ветка резолвится заранее → `ensure_worktree`; cmd = `cd ` без checkout; `_write_task_file(repo, branch, ...)` пишет в worktree; `_monitor_agent` commit/push в worktree (checkout убран); questions/conflict читаются из worktree - [x] Task 3 — qg/checks: `_repo_path(repo, branch)` helper; артефакт-чеки получили опц. `branch`; `check_tests_local` → `ensure_worktree`+`make test`; диспетчеры в launcher и webhooks/plane прокидывают `branch` - [x] Task 4 — webhooks/gitea ~152: `git branch -r --contains ` подтверждён read-only, оставлен в main clone (+ комментарий) - [x] Task 5 — tests/test_git_worktree.py (9 tests, реальные git-репо в tmp); test_launcher обновлён; ARCHITECTURE.md + BUGFIXES_2026-06-02_ORCH2.md - [x] Task 6 — commit/push, PR #1, rebuild+deploy, тест изоляции пройден ## Изменённые файлы - `src/config.py` — + worktrees_dir - `src/git_worktree.py` (новый) — модуль worktree - `src/agents/launcher.py` — launch/_write_task_file/_monitor_agent/_try_advance_stage → worktree - `src/qg/checks.py` — worktree-aware артефакт-чеки + check_tests_local - `src/webhooks/plane.py` — QG-диспетчер прокидывает branch - `src/webhooks/gitea.py` — комментарий (read-only, без изменений логики) - `tests/test_git_worktree.py` (новый), `tests/test_launcher.py` - `docs/ARCHITECTURE.md`, `docs/BUGFIXES_2026-06-02_ORCH2.md` ## Результат - Тесты (в контейнере через образ): **37 passed, 9 failed** — 9 = pre-existing test_webhooks (401/signature), идентичны baseline на main (там 28 passed + те же 9). Мои изменения добавили 9 проходящих тестов (test_git_worktree) и ничего не сломали. - test_git_worktree.py изолированно: 9 passed. - Деплой: образ пересобран на feature-ветке, `docker compose up -d --build`, health `{"status":"ok"}`. - Тест изоляции (в работающем контейнере): - A: /repos/_wt/enduro-trails/feature_wt-test-A (branch feature/wt-test-A) - B: /repos/_wt/enduro-trails/feature_wt-test-B (branch feature/wt-test-B) - A≠B, branch A≠B → **ISOLATION OK** - Shared `/repos/enduro-trails` НЕ мутирован `ensure_worktree` (только fetch, без checkout в main). - Тестовые worktree + локальные ветки очищены `remove_worktree` + branch -D. - PR: https://git.mva154.duckdns.org/admin/orchestrator/pulls/1 ## Совместимость прежних фиксов - B-1 (запись task-файла без docker) — сохранена, путь = worktree. - B-2 (Popen→файл, monitor wait, без зомби) — не тронут. - S-1 (check_tests_local свой make test) — сохранён, теперь в worktree. - S-5 (reviewer verdict из frontmatter) — не тронут, добавлен лишь worktree-путь. - Обратная совместимость QG-диспетчеризации: артефакт-чеки принимают branch опционально (default None → shared /repos), 2-арг вызовы/тесты не сломаны. ## Проблемы и решения - Расхождение с ТЗ: артефакт-QG функции вызываются как 2-арг в существующих тестах и в webhooks/plane. Чтобы не сломать — добавил `branch` опциональным (default None → fallback на shared путь), а не сделал обязательным. Диспетчеры орка прокидывают реальный branch. - ТЗ упоминал BUGFIXES_2026-06-03 «или дату прогона» — использовал дату прогона 2026-06-02: `docs/BUGFIXES_2026-06-02_ORCH2.md`. - `git worktree add wt branch` для существующей remote-ветки и `-b ... origin/main` для новой — оба пути покрыты тестами. ## Не сделано (вне scope, по ТЗ) - Автовызов `remove_worktree` при переходе в `done` — модуль умеет, но подключение опционально/отдельным шагом. - Очередь задач (ORCH-1 / F-2b) — не входит.