Files
orchestrator/docs/work-items/ORCH-040/01-brd.md
claude-bot 5436c4110e
All checks were successful
CI / test (push) Successful in 13s
analyst(ET): auto-commit from analyst run_id=175
2026-06-06 14:55:35 +00:00

107 lines
7.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 01 — BRD: Агенты пишут файлы под root в смонтированный хост-репо
Work Item: **ORCH-040**
Тип: инфра-фикс (runtime / docker-compose)
Исполнение: через Dev напрямую (по решению Owner)
## 1. Бизнес-контекст и проблема
Контейнер `orchestrator` (prod, 8500) работает под `uid=0 (root)`. Он монтирует
хостовый каталог `/home/slin/repos``/repos` (rw). Claude-CLI агенты запускаются
через `subprocess.Popen` **внутри контейнера**, то есть тоже под root. Они пишут:
- в git worktree задач — `/repos/_wt/<repo>/<branch>/...`;
- в прод-клон — `/repos/<repo>/docs/work-items/...` (через коммит/пуш из worktree).
В результате на **хосте** файлы создаются с владельцем `root:root`.
### Симптом
При ребилде/деплое прода `git pull` / `git reset` под пользователем `slin` падает:
```
error: insufficient permission for adding an object to repository database .git/objects
Permission denied (на docs/work-items/ORCH-016, владелец root:root)
```
Каждый будущий деплой будет ломаться, пока вручную не выполнить `chown`.
### Диагноз (живая разведка 0506.06)
- `docker exec orchestrator id``uid=0(root) gid=0(root) groups=0,999`.
- Хост `slin` = `uid=1000 gid=1000`, группы: `sudo`, `docker(999)`.
- `/home/slin/repos``/repos` (rw); на хосте `/repos` уже `1000:1000 rwxrwxr-x`.
- `docs/work-items/*` на хосте — `root:root` (наследие прошлых прогонов).
## 2. Цель
Агенты конвейера **не должны** создавать `root`-файлы в хостовом репозитории.
После любого прогона конвейера `git pull/status/reset` под `slin` на хосте
работает **без ручного chown**.
## 3. Объём (scope)
В объёме:
- Изменение runtime-режима контейнера так, чтобы артефакты создавались под
`uid:gid` хоста (`1000:1000`).
- Сохранение работоспособности: claude-auth (preflight), git/ssh, docker.sock
(деплой), запуск конвейера.
- Обновление документации (INFRA.md, CHANGELOG, ADR с обоснованием варианта).
- Проверка на staging (8501) ДО прода.
Вне объёма:
- Массовое исправление прав уже существующих `root:root` файлов в истории
(разовый `chown` на хосте делает Owner; в задаче — только описать команду).
- Изменение логики конвейера, QG, схемы БД.
- Смена модели/effort агентов, прочие фичи.
## 4. Заинтересованные стороны
- Owner (Слава) — заказчик, владелец хоста mva154.
- Стрим — разведка/контекст.
- Проект enduro-trails — co-tenant того же прод-инстанса (групповой риск).
## 5. Ограничения и риски (off-limits)
Self-hosting: прод-инстанс `orchestrator` ОДИН на все прод-проекты, общая БД и
очередь. **Нельзя ломать**: запуск конвейера, доступ к Plane/Gitea/SSH из агентов,
docker.sock. Любой рестарт контейнера под новым uid — **только в окно тишины**
(нет активных задач). Тестировать на staging ПЕРЕД продом.
### Известные мины (подтверждены разведкой)
- **МИНА 1 — docker.sock**: `/var/run/docker.sock` = `srw-rw---- root:999`.
Доступ идёт через gid 999, не через root. При переходе на непривилегированный
uid обязателен supplementary group `999`. *В текущем `docker-compose.yml` уже
есть `group_add: ["999"]` для обоих сервисов — учесть, не сломать.*
- **МИНА 2 — claude creds (БЛОКЕР)**: `/home/slin/.claude/.credentials.json` =
`root:root 0600`. Сейчас читает контейнер-root. Под `uid=1000` без доступа →
`claude-auth` ломается → весь конвейер умирает (preflight ORCH-044 заворачивает).
Проверить ПЕРВЫМ.
- **МИНА 3 — claude бинарь**: реальный бинарь `/opt/claude-code/bin/claude.exe`
(root:root, `+x` для всех — ok). `ORCH_CLAUDE_BIN=/usr/bin/claude` в env не
существует; launcher использует hardcode `CLAUDE_BIN=/opt/claude-code/bin/claude.exe`.
Под uid 1000 исполним, но проверить запуск.
- **SSH-маунт**: `/home/slin/.orchestrator-ssh``/root/.ssh:ro`. При смене uid
HOME/домашний каталог меняется — путь к ключам нужно поправить (деплой по ssh).
- **HOME**: launcher форсит `HOME=/home/slin` (две точки: env Popen и git_env).
Креды читаются из `/home/slin/.claude`. Учесть при смене uid.
## 6. Бизнес-ценность
Устранение постоянного ручного `chown` после каждого деплоя; деплой прода
перестаёт ломаться на правах; снимается источник простоя конвейера всех проектов.
## 7. Допущения
- Хост-каталоги `/app/data` и `/repos` уже `1000:1000` (запись под uid 1000 пройдёт).
- Dockerfile уже содержит `git config --system --add safe.directory '*'`.
- Окно тишины для рестарта контейнера согласуется с Owner.
## 8. Host-prerequisites (предусловия на стороне Owner)
Часть фикса невозможно закрыть только кодом — есть действия на хосте mva154,
которые выполняет Owner (в гит не коммитятся, фиксируются в ADR/INFRA). Это
обязательные предусловия Варианта 1; без них переход на uid 1000 ломает конвейер:
- **P-1 (блокер, МИНА 2):** обеспечить чтение `/home/slin/.claude/.credentials.json`
под uid 1000 (рекомендация — `chown -R 1000:1000 /home/slin/.claude`). Способ
выбирает ADR; анализ фиксирует факт предусловия.
- **P-2:** ssh-ключи (`/home/slin/.orchestrator-ssh`) читаемы uid 1000.
- **P-3:** подтверждение `slin = uid 1000 gid 1000` (подтверждено разведкой).
- **P-4:** рестарт прод-self только в окно тишины (`GET /status` без активных задач).
Детализация и команды — в `02-trz.md` §10.