feat(worktree): git worktree per task to isolate shared /repos (ORCH-2 / S-4)
- add src/git_worktree.py: ensure/remove/get_worktree_path - config: worktrees_dir=/repos/_wt - launcher: agent runs in per-branch worktree; task-file + commit/push in worktree; no shared checkout - qg/checks: read artifacts + run make test from worktree (branch arg, backward-compatible) - webhooks/plane: pass branch into QG dispatch; review fallback from worktree - webhooks/gitea: keep read-only branch --contains in main clone (documented) - tests: test_git_worktree.py (isolation) + update test_launcher write-task-file - docs: ARCHITECTURE worktree section + BUGFIXES_2026-06-02_ORCH2 Preserves B-1/B-2/S-1/S-5 fixes (paths now point at worktree).
This commit is contained in:
@@ -39,7 +39,7 @@ STAGE_TRANSITIONS = {
|
||||
|-------|---------------|
|
||||
| check_analysis_approved | Filesystem: 4 файла + :approved: comment в Plane |
|
||||
| check_architecture_done | Filesystem: ADR dir или infra-requirements.md |
|
||||
| check_tests_local | Оркестратор сам гоняет `make test` в `/repos/<repo>` (judge по exit-code). Заменил check_ci_green: Gitea CI не сконфигурирован. |
|
||||
| check_tests_local | Оркестратор сам гоняет `make test` в **worktree задачи** `/repos/_wt/<repo>/<branch>` (judge по exit-code). Заменил check_ci_green: Gitea CI не сконфигурирован. Worktree-изоляция → безопасно при параллельных задачах (ORCH-2 / S-4). |
|
||||
| check_reviewer_verdict | Filesystem: читает `verdict: APPROVED\|REQUEST_CHANGES` из YAML-frontmatter `12-review.md` (только машиночитаемое поле, не подстроки в тексте) |
|
||||
| check_tests_passed | Filesystem: test-report.md содержит "PASS" |
|
||||
| check_ci_green | (legacy) Gitea API: GET /commits/{branch}/status — больше не используется как QG развития |
|
||||
@@ -188,7 +188,7 @@ services:
|
||||
|
||||
Каждый агент — Claude CLI с:
|
||||
- **System prompt**: `.openclaw/agents/{role}.md` (в репозитории)
|
||||
- **Task file**: `.task-{suffix}.md` — генерируется orchestrator **прямой записью в смонтированный volume `/repos/<repo>/`** (B-1, без docker). В `.gitignore` репозитория проекта (рантайм-артефакт, не коммитится).
|
||||
- **Task file**: `.task-{suffix}.md` — генерируется orchestrator **прямой записью в worktree задачи** `/repos/_wt/<repo>/<branch>/` (B-1, без docker; ORCH-2 — в изолированную рабочую копию, не в shared `/repos/<repo>`). В `.gitignore` репозитория проекта (рантайм-артефакт, не коммитится).
|
||||
- **Tools**: Read, Write, Edit, Bash
|
||||
- **Output**: `--print` mode (весь вывод в stdout после завершения)
|
||||
|
||||
@@ -201,13 +201,39 @@ services:
|
||||
| tester | test-report.md, e2e results | 10-25 мин |
|
||||
| deployer | merge PR + SSH deploy-hook + smoke | 5-10 мин |
|
||||
|
||||
## Изоляция через git worktree (ORCH-2 / S-4)
|
||||
|
||||
Каждая задача (= одна git-ветка) работает в **изолированной git worktree**, а не в общем
|
||||
`/repos/<repo>`. Это убирает гонки `git checkout`, когда две задачи активны одновременно.
|
||||
|
||||
```
|
||||
/repos/<repo> ← основной clone (fetch / управление worktree, read-only запросы)
|
||||
/repos/_wt/<repo>/<safe-branch> ← worktree конкретной задачи (рабочая копия агента)
|
||||
```
|
||||
|
||||
Модуль `src/git_worktree.py`:
|
||||
- `get_worktree_path(repo, branch)` — путь worktree (не создаёт).
|
||||
- `ensure_worktree(repo, branch)` — создаёт (или переиспользует) worktree на нужной ветке;
|
||||
для новой ветки создаёт её от `origin/main`. Возвращает путь.
|
||||
- `remove_worktree(repo, branch)` — опциональная очистка при `done`.
|
||||
|
||||
Где используется worktree:
|
||||
- **launcher**: агент запускается с `cd <worktree>` (без `git checkout` в cmd); task-файл
|
||||
пишется в worktree; commit/push в `_monitor_agent` идут в worktree.
|
||||
- **qg/checks**: чтение артефактов агента (`check_analysis_complete`, `check_architecture_done`,
|
||||
`check_tests_passed`, `check_reviewer_verdict`) и `check_tests_local` (`make test`) — из worktree.
|
||||
Артефакт-функции принимают опциональный `branch`; без него падают на shared `/repos/<repo>`
|
||||
(обратная совместимость).
|
||||
- **webhooks/gitea**: `git branch -r --contains <sha>` оставлен в основном clone — это
|
||||
**read-only** запрос (нет checkout/мутации), гонок не создаёт.
|
||||
|
||||
> Один branch может быть checked out только в одной worktree одновременно —
|
||||
> это и есть нужное свойство: одна задача = одна ветка = одна worktree.
|
||||
|
||||
## Известные ограничения
|
||||
|
||||
- **Shared `/repos` checkout (гонки при параллельных задачах).** Все агенты и
|
||||
`check_tests_local` делают `git checkout` в одном `/repos/<repo>`. При двух
|
||||
одновременно активных задачах checkout одной перетрёт рабочую копию другой.
|
||||
Пока приемлемо (задачи идут последовательно). **Исправление — git worktree per task/branch
|
||||
(запланировано отдельной задачей S-4).**
|
||||
- ~~Shared `/repos` checkout (гонки при параллельных задачах).~~ **РЕШЕНО (ORCH-2 / S-4):**
|
||||
git worktree per task/branch — см. раздел «Изоляция через git worktree» ниже.
|
||||
- **In-process daemon-потоки.** Агенты запускаются в daemon-потоках uvicorn. При
|
||||
рестарте uvicorn запущенные агенты осиротевают → ловит orphan-recovery (M-1).
|
||||
Целевая архитектура — очередь задач (F-2b, отдельно).
|
||||
|
||||
Reference in New Issue
Block a user