Files
obsidian-vault/personal/plans/balda-mm-phase4-agents.md
T

9.3 KiB
Raw Blame History

Фаза 4 — исполнитель на Mac + ~/agents + секция «Agents» в Eagle Dashboard

План. Работа НЕ начата (образ не собран, контейнер не запущен). Часть personal/projects/balda/balda-mm-delegation-plan (Фазы 4-5). Предыдущее: personal/projects/balda/balda-kraken-mm-deploy (Фаза 3 ✅ — бот отвечает Alex).


1. Решения

# Вопрос Решение
1 Папка для проектов исполнителя ~/agents
2 Подтверждения Full access → permissions.mode: allow_all
3 Управление линками в ~/agents Новая секция «Agents» в Eagle Dashboard
4 Auth CLI (claude/codex) на хосте, ~/cli-auth, вне ~/agents
5 Сеть Kraken → Mac Cloudflare Tunnel (существующий cloudflared на Mac)

2. Ограничения macOS Docker (проверено тестами)

Ограничение Итог
Симлинк на внешний путь битый в контейнере — цель резолвится от корня контейнера
Live mount --bind внутри VM контейнер не видит (virtiofs строит маппинг на старте)
Сетевая шара SMB/NFS в контейнер не протянуть (тот же virtiofs)
Hardlink на каталог физически невозможен (ядро запрещает)
Hardlink через границу ФС EXDEV

Следствие: внешние проекты подключаются только bind-mount'ом через -v + docker compose up -d (2-3 сек). Hardlink — только для файлов внутри одного тома.

Детали механизма: personal/tech/macos-docker-virtiofs-mount-limits.


3. Архитектура

Mattermost (Alex)
   │  «почини баг X в project-y»
   ▼
Балда-оркестратор (Kraken, DeepSeek, allow_all)
   │  читает Obsidian, формирует ТЗ, /goalkeeper → work → validate
   ▼
Cloudflare Tunnel: agents-bridge.qentra.top → localhost:8790
   │  (существующий cloudflared на Mac, PID + LaunchAgent)
   ▼
Мост (Mac, FastAPI :8790)
   │  idempotency key, таймаут, лимит 1-2 параллельных задач, shared secret
   ▼
Контейнер-исполнитель (Mac, Docker)
   │  -v ~/agents:/agents:rw
   │  -v ~/Developer/<proj>:/agents/<name>:rw    ← внешние проекты
   │  -v ~/cli-auth/claude:/root/.claude:rw      ← auth на хосте
   │  -v ~/cli-auth/codex:/root/.codex:rw        ← auth на хосте
   │  Node 24 + codex + claude + git
   ▼
diff + тесты + коммит → Балда → Mattermost

Auth CLI на хосте

Данные Хост В контейнере Права
Claude auth ~/cli-auth/claude /root/.claude 0700
Codex auth ~/cli-auth/codex /root/.codex 0700
OAuth-токен Claude ~/Docker/balda-executor/.env env 0600

Пересборка образа и обновление CLI auth не сбрасывают. Токены вне /agents → агент их не видит.


4. Секция «Agents» в Eagle Dashboard

Правки: main.py (роуты) · templates/index.html (вкладка ?tab=agents) · services.yaml (запись agents-bridge, health.type: http) · health.py.

Функция Что делает
Список содержимое ~/agents: имя, тип, размер, mtime, статус линка
Создать mkdir ~/agents/<name>
Подключить внешний запись в agents-mounts.yaml → compose up -d
Hardlink ln -F для файлов, проверка st_dev
Отключить убрать из манифеста + up -d; файлы на диске целы
Терминал ссылка на вкладку files

API:

GET    /api/agents                     → список
POST   /api/agents                     {name} → mkdir
POST   /api/agents/{name}/mount        {host_path} → bind + recreate
DELETE /api/agents/{name}/mount        → отвязать (файлы целы)
POST   /api/agents/{name}/hardlink     {file, name} → ln -F со st_dev
GET    /api/agents/{name}/usage        → размер

Не делает: не удаляет файлы, не убивает процессы, не создаёт symlink на внешние цели.


5. Подтверждения

Режимы Balda: allow_all (выбран) · ask · deny_all. ask поддержан только для Telegram и Slackagent; для Mattermost фейлится закрыто. Сценарий «подтвердить из чата» требует: A — дописать ask в MM (~1-2 дня, расширение PR #8), либо B — апрув в мосте (~0.5 дня). При allow_all не нужно; начинать с B, когда понадобится.


6. Шаги

Артефакты, уже созданные на диске (2026-09-26)

Созданы до подтверждения плана — статус «черновик», при старте сверить и доделать:

Путь Что
~/agents рабочая область (drwxr-xr-x, admin:staff)
~/cli-auth/{claude,codex} auth CLI, 0700, вне ~/agents
~/Docker/balda-executor/Dockerfile Node 24 + claude + codex + git, HEALTHCHECK
~/Docker/balda-executor/docker-compose.yml 4 тома, сеть executor-net, лимит 8G
~/Docker/balda-executor/.env ⏳ не создан (токен)

docker-compose.yml ссылается на compose.override.yaml, который генерирует tools/render-mounts.py из agents-mounts.yaml — override вручную не править. Ни образ не собран, ни контейнер не запущен.

1. ~/agents + ~/cli-auth + контейнер (~2 ч) mkdir ~/agents, ~/cli-auth/{claude,codex} 0700 → ~/Docker/balda-executor/Dockerfile (Node 24 + claude + codex + git) → docker-compose.yml с 4 томами → claude setup-token в .env 0600 → проверка claude --version, codex --version, повторный up -d остаётся залогинен.

2. Мост (~3-4 ч) ~/Developer/agents-bridge/, FastAPI :8790, POST /task (idempotency), GET /task/{id}, GET /healthz; запуск CLI headless в контейнере; лимит 1-2 задач; shared secret.

3. Сеть (~1 ч) Cloudflare Tunnel: добавить published route agents-bridge.qentra.top → HTTP localhost:8790 + Access Application. Токен и процесс cloudflared не трогаются. Проверка: curl извне на /healthz. ⚠️ hostname — одноуровневый (двухуровневые дают TLS handshake failure).

4. Секция «Agents» (~3-4 ч) 6 роутов + вкладка + запись в services.yaml → __pycache__ + launchctl kickstart -k.

5. Связка Балда → мост (~2 ч) MCP-инструмент в Балде → POST /task; проба echo ok > /agents/test/probe.txt.

6. Приёмка (~1 день) Сквозной тест от аккаунта Alex в MM: @balda → задача → diff в ответе. Замер расходов (DeepSeek + подписка), документация отката.


7. Риски

Риск Оценка Митигация
Мост опубликован в интернет высокий Access Application + shared secret
Полный доступ агента к ~/agents средний бэкапы; git rm-семантика вместо rm
Бан подписки за «unusual traffic» средний 1-2 параллельных задачи, официальный бинарь, без прокси токена
Hardlink через ФС → EXDEV высокий проверка st_dev в UI
Mac спит → туннель и мост недоступны средний задачи в durable-очереди Балды, идемпотентность

8. Открыто

  1. Провайдер исполнителя — claude или codex
  2. Нужен ли ask-апрув в будущем
  3. Hostname для моста (agents-bridge.qentra.top?)

Связанные заметки