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

7.3 KiB
Raw Permalink Blame History

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 iduid=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.