7.3 KiB
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.
Диагноз (живая разведка 05–06.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 group999. В текущем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 использует hardcodeCLAUDE_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.