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

182 lines
9.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.
# Фаза 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`?)
## Связанные заметки
- [[personal/projects/balda/balda-mm-delegation-plan]] — общий план (Фазы 4-5)
- [[personal/projects/balda/balda-kraken-mm-deploy]] — Фаза 3 (✅)
- [[personal/plans/balda-mm-pr-plan]] — Фаза 2 (PR #8)
- [[personal/tech/macos-docker-virtiofs-mount-limits]] — ограничения macOS Docker
- [[personal/tech/balda-go-fx-pitfalls]] — fx-питфоллы, дельта-апплаер
- [[family/how-to/kraken-portainer-access]] — cloudflared, routes
- скилл `eagle-dashboard` — архитектура дашборда