121 lines
24 KiB
Markdown
121 lines
24 KiB
Markdown
# Balda — удалённый агент по SSH
|
||
|
||
Обновлено: **2026-10-18**.
|
||
Отдельный проект доступа к папкам: [[personal/plans/workspace-gateway|Workspace Gateway]], `/Users/admin/Developer/workspace-gateway`, начальный коммит `2bc6743`.
|
||
Дополнительная проверка SSH и Seatbelt: [[personal/projects/balda/ssh-seatbelt-2026-10-18]].
|
||
Исходная задача: Balda работает с оригинальными Prism/Beads по подключённым проектам и запускает штатного агента в другой среде; подключение нового репозитория требует подтверждения владельца.
|
||
Проверка: [[personal/projects/balda/ssh-acp-verification-2026-10-18]].
|
||
Рабочая установка: [[personal/projects/balda/setup]].
|
||
|
||
## Актуальный статус 2026-10-18
|
||
|
||
Workspace Manager (`e99f043`) и SSH Manager (`d9c19ee`) реализованы, проверены и работают как user launchd services на loopback. Владелец явно подтвердил два новых SSH-ключа: настоящий вход из Balda к Mac через обязательный Seatbelt принят; relay shell отвергается. Native SMB backend отзывает открытые FD и истекает независимо от Manager. Все 14 оригинальных Prism Role runtimes прошли `callee doctor` через SSH в совпадающем workspace. Native Beads 1.3.1/Dolt 2.5.0 прошли общие параллельные записи/чтение и гонку claim; из SSH+Seatbelt тот же bd работает через точный Unix socket без wildcard loopback.
|
||
|
||
**Полная модельная приёмка и production переключение ещё не завершены.** Ожидаются два решения владельца в native input: использование уже настроенных CLI credentials на Mac и выбор для OpenCode v2 (отключить либо разрешить необходимый ему широкий localhost binding). Эти действия отклонила автоматическая проверка без отдельного согласия. Manager-токены remote Mac агентам не передаются: управление grants остаётся у Balda, исполнителю выдаются filesystem и native Beads. Production container ID/start time и config/compose совпадают с baseline. Реальные project Beads databases не мигрировались.
|
||
|
||
Подробная приёмка: `/Users/admin/Developer/workspace-gateway/docs/acceptance-2026-10-18.md`; закрытый кандидат: `~/.local/share/balda-workspace/candidate`. Исторический план и промежуточные неуспешные проверки ниже сохранены как журнал.
|
||
|
||
## Принятая граница
|
||
|
||
Максимально использовать штатный стек Balda: провайдеры ACP, сессии, управление задачами, MCP, skills и подтверждения.
|
||
Prism, Prism Callee, Callee и Beads — оригинальные, с сохранением их собственных контрактов.
|
||
|
||
```text
|
||
Balda → штатный generic_acp → ssh -T → штатный ACP-агент в другой среде
|
||
```
|
||
|
||
Единый способ связи — SSH: контейнер, VM или физический хост отличаются окружением, а не протоколом запуска.
|
||
macOS-окружения предоставляет Virfield через его MCP.
|
||
Штатный агент выполняет работу в выданном workspace; Balda сохраняет управление беседой и сессией.
|
||
|
||
## Что проверено
|
||
|
||
- [x] Штатная фабрика Balda запускает `ssh` через `generic_acp.cmd` и передаёт ACP.
|
||
- [x] Реальный OpenCode создаёт и возобновляет сессию после повторного SSH.
|
||
- [x] Контрольный ACP-агент получает штатное решение Balda разрешить или отклонить действие.
|
||
- [x] Контрольный удалённый агент вызывает настоящий MCP-инструмент.
|
||
- [x] Штатные тесты Balda подтверждают Mattermost review, защиту от чужого ответа и timeout.
|
||
- [x] Воспроизведены локальная проверка cwd и требования к достижимости MCP.
|
||
|
||
Для передачи ACP новая реализация `broker-acp` не требуется: базовый путь уже проверен.
|
||
Дополнительный код допустим только для конкретного воспроизведённого пробела интеграции; прикладные сценарии и учёт фаз Prism остаются в штатном стеке.
|
||
|
||
## Следующие конкретные действия
|
||
|
||
1. Я реализую и приму Workspace Manager (проект `workspace-gateway`) в отдельном проекте: настраиваемые именованные корни (`developer`, `downloads` и другие), листинг и поиск папок по имени без файлов, подключение после подтверждения владельца, отключение и временный лизинг; сетевая файловая система обеспечит одни и те же исходные файлы Balda и агентам без перезапуска Balda при каждой выдаче. Указание корня в конфиге разрешает обнаружение папок, но не выдаёт доступ ко всем его файлам.
|
||
2. Я настрою авторизованный SSH из контейнера в реальные среды, проверку host key, ограниченные credentials и штатный `generic_acp` с командой SSH; доступность порта и проверка протокола уже подтверждены, рабочая авторизация ещё не принята.
|
||
3. Я настрою запуск агентов и обычных команд на Mac под Seatbelt, начиная со штатных sandbox и готового `anthropics/sandbox-runtime`, и проверю запрет доступа к соседним проектам, секретам и обхода через другой SSH command.
|
||
4. Я настрою согласованные пути workspace, достижимые MCP, оригинальные skills/tools и единое состояние Beads для Balda и одновременных агентов, затем включу запросы разрешений у агентов и штатный `ask` Balda.
|
||
5. Я проведу реальную приёмку выбранных Codex/Claude/OpenCode и оригинального Prism: статус проекта, подтверждение и отказ, выполнение, отмена, продолжение сессии и прекращение доступа после отзыва или истечения лизинга.
|
||
|
||
Это оставшаяся работа, а не уже выполненный deployment.
|
||
SSH/Seatbelt/ACP и настройка Beads не расширяют четыре функции Workspace Gateway.
|
||
|
||
## Что подтверждено дополнительно
|
||
|
||
- Docker работает через Colima, а не Docker Desktop.
|
||
- Из основного контейнера получены SSH banners Mac и внешнего GitHub на TCP/22; логин и команды при этом не выполнялись.
|
||
- Seatbelt на Mac 26.7.1 реально заблокировал чтение и запись в контрольную папку, в том числе дочерним shell; это не готовый production профиль.
|
||
- Документация Beads описывает Dolt server mode для нескольких одновременных записывающих агентов: [первичный источник](https://github.com/gastownhall/beads/blob/main/docs/architecture/index.md).
|
||
- Политика файлов и сети для реальных агентов, native approvals и полная работа Prism остаются открытыми.
|
||
|
||
## Права и репозитории
|
||
|
||
Подтверждение подключения репозитория, подтверждение действия агента и файловая изоляция — три отдельные проверки.
|
||
Агент не получает полномочий самостоятельно выдавать себе доступ к новому проекту.
|
||
Весь каталог `Developer` не передаётся Balda или исполнителю.
|
||
Исходная БД Beads соответствующего проекта остаётся источником статусов; Git-клон сам по себе не доказывает наличие актуального состояния Beads.
|
||
Механизм выдачи доступа к реальным проектам и их БД ещё требует настройки и приёмки.
|
||
|
||
## Текущее состояние и границы
|
||
|
||
Основная Balda получила оригинальные Prism/Prism Callee, `bd`, Callee и прямой Virfield MCP; это установка инструментов, а не приёмка удалённого исполнения.
|
||
В рабочем конфиге остаётся `permissions.mode: allow_all`; SSH-проверка production-конфиг, историю и авторизацию не меняла.
|
||
Полный Prism lifecycle с моделью и реальные удалённые Claude/Codex этой проверкой не приняты.
|
||
|
||
Новый сервис создаётся в отдельном проекте `workspace-gateway`; его объём ограничен четырьмя функциями доступа к папкам.
|
||
Прежняя ветка `broker-rebuild` в `/Users/admin/.codex/worktrees/broker-rebuild/execution-broker` — оставшийся каркас предыдущего обсуждения, а не место реализации Workspace Gateway.
|
||
Старые `execution-broker`, `execution-prism` и plugin остаются в действующей Balda; очистка новой ветки не удаляла их из deployment.
|
||
|
||
Историческая приёмка прежнего брокера: [[personal/plans/balda-callee-prism-plan]].
|
||
|
||
|
||
## Выполнение 2026-10-18 — промежуточный журнал
|
||
|
||
- Создан отдельный Git-проект `/Users/admin/Developer/ssh-manager`, исходники и README записаны. Учёт настроенных оператором хостов/пользователей/проверенных public host keys, отдельная Ed25519-идентичность, `ssh_config`/`known_hosts`, ProxyJump, подтверждение регистрации/удаления управляемой строки authorized_keys через штатный MCP elicitation. Private key не возвращается инструментами; bootstrap credentials остаются у оператора.
|
||
- Relay-ключ ограничен штатными OpenSSH options, `/usr/bin/false` запрещает shell, `permitopen` ограничивает переход заданными адресами. Execution до принятой файловой изоляции отвергается. Это каркас подготовки доступа; **production Mac/VM ещё не авторизованы и удалённые реальные агенты не приняты**.
|
||
- Существующие пользовательские SSH-ключи и authorized_keys не менялись. Отдельный sshd на loopback-порту с fixture-файлом подтвердил вход по закреплённому ключу, отказ при подмене host key и отказ нового входа после удаления fixture-ключа. Полный ProxyJump и production SSH/ACP остаются открытыми.
|
||
- SSH Manager: `go test -race ./...`, `go vet ./...`, сборка — успешно. Настоящий stdio MCP отдал 6 инструментов; отказ через elicitation остановил регистрацию. Локальная HTTP-авторизация и Host allowlist приняты; Colima получила 401 без токена. HTTP-порт подготовки `17796`; 7796 занят прежним Broker.
|
||
- Готовый `@anthropic-ai/sandbox-runtime@0.0.80` установлен только в тестовый каталог. Проверка на Mac прошла: разрешённая папка читается/пишется, соседняя закрыта, открытие SSH private key блокируется без чтения его содержимого, ограничения наследуются дочерним shell, SSH-обход блокируется. **Это тестовый профиль, не приёмка Codex/Claude/OpenCode с реальными авторизациями и сетью.**
|
||
- Подготовлена отдельная копия конфига Balda: `permissions.mode: ask`, MCP Workspace/SSH Manager, отдельный профиль `workspace-setup` на штатном Codex, существующий pool не изменён. `balda --profile workspace-setup validate` в новом одноразовом контейнере завершился exit 0; provider runtime/модели/каналы не запускались. Это проверка конфигурации, не preflight или сквозной Prism.
|
||
- Копия конфига, приватный env новых manager-токенов, оригинальный backup и отчёты находятся в `/Users/admin/Docker/balda-mm-mac/state/workspace-setup-20261018`. Внешние сообщения не отправлялись. Рабочая Balda не переключалась; перезапуск остаётся отдельным подтверждаемым действием после реальной приёмки.
|
||
- При автоматической проверке был отклонён тест с передачей manager-токенов в отдельный Python Docker-образ. Его заменили безопасной проверкой: токены остаются в локальных Mac-процессах; контейнер проверяет только достижимость/401 без авторизации. Аутентифицированный вызов из Balda ещё открыт.
|
||
- Ближайшая зависимость: полный fixture-тест штатного NFS (`sudo /opt/homebrew/bin/python3 /private/tmp/workspace-setup-20261018/nfs-admin.py test`). Файловый backend, реальный отзыв открытых дескрипторов, согласованные mounts, общий Beads/Dolt и полный Prism/удалённые агенты не заявляются выполненными.
|
||
|
||
### Дополнительная приёмка SSH Manager: реальный ProxyJump
|
||
|
||
`/private/tmp/workspace-setup-20261018/ssh-jump-acceptance.py` запустил два настоящих локальных sshd, получил отдельный public key и клиентский конфиг через настоящий stdio MCP SSH Manager и проверил SSH roundtrip через ProxyJump. Четыре проверки успешны: roundtrip; отказ shell на relay; отказ forwarding к незаданному адресу (подтверждён журналом sshd); отклонение подменённого host key конечного сервера через jump. Менеджер использовал обычный OpenSSH, без нового транспортного launcher. Пользовательский `.ssh` и системный sshd не менялись, тестовые sshd остановлены. Это приёмка транспорта/конфига на локальных fixture-серверах, не production авторизация Mac/VM и не ACP с моделями. Отчёт: `/private/tmp/workspace-setup-20261018/ssh-jump-acceptance.json`.
|
||
|
||
|
||
## Фактическое продолжение 2026-10-18
|
||
|
||
- Workspace Manager закоммичен: `00b7e13`; SSH Manager: `d6323b5`. Оба прошли `go test -race ./...`, `go vet ./...`, build. Это реальные отдельные проекты, не изменения execution-broker.
|
||
- Финальный файловый backend — готовые Samba SMB3, native `mount.cifs` в Colima и `mount_smbfs` на Mac. Постоянного privileged Docker helper нет. Linux recipient — обычный контейнер с `rslave` только своего пустого mount root. Приняты новые grants без его рестарта, общие оригинальные файлы, RW, server RO, продление, отзыв уже открытых read/write FD обоих native клиентов, независимое от Manager истечение и запрет продления истёкшего share. Go→встроенный backend и реальный отзыв при перезапуске Manager также прошли.
|
||
- Два Manager установлены как user launchd jobs, слушают только `127.0.0.1:17795` и `:17796`. Из одноразового доверенного `balda-prism:20261018`, UID node, read-only/cap-drop=ALL реально прошли authenticated initialize, 4/6 tools/list и readonly tool calls. Новые bearer tokens находятся вне Balda `/state`: `~/.local/share/balda-workspace/managers.env` (0600).
|
||
- Владелец явно подтвердил два новых SSH fingerprints и передачу только Balda. Они установлены через SSH Manager с сохранением прочих authorized_keys; private identities находятся в отдельном Docker volume `balda-ssh-manager` (UID 1000), а не в общем host .ssh. Native SSH из доверенного контейнера к Mac реально выполнил команду через обязательный SRT; relay shell реально отвергнут. Альтернативная SSH команда открыть личный SSH ключ Mac получила PermissionError без чтения содержимого.
|
||
- Исправлен конфликт relay/execution на одном хосте: отдельные identity names. Native ProxyJump, ограниченный permitopen, отказ relay shell и подменённому target key повторно прошли. Kraken есть в inventory по существующему known_hosts, его execution остаётся закрытым до отдельной принятой изоляции.
|
||
- Подготовлены закрытые candidate config/compose: `~/.local/share/balda-workspace/candidate`; `docker-compose ... config --quiet` прошёл. В нём `ask`, два Manager MCP, одинаковые абсолютные workspace пути и native generic_acp профили Mac Codex/Claude/OpenCode через `ssh -T`. Рабочая Balda пока не перезапущена.
|
||
- Реальные Codex и Claude ACP на Mac под SRT уже проходят initialize и session/new через этот SSH. Это ещё не подтверждение вызова модели: CLI authorizations запрошены у владельца отдельным native input после отказа автоматической проверки доступа к credentials. OpenCode v2 падает при готовности standalone server; его узкий IPC runtime диагностируется без открытия общего loopback.
|
||
- Оригинальный Callee с правильным `--agent-root /home/node/.config/callee` успешно отдал весь native Prism graph. Полный модельный Prism lifecycle и общее состояние Beads/Dolt пока не заявляются принятыми.
|
||
|
||
|
||
### Итог текущей выполненной части
|
||
|
||
- Workspace HEAD `e99f043`, SSH HEAD `d9c19ee`; оба Git working tree чистые. Исходники, tests, scripts и точная приёмка закоммичены. Полная модельная работа не помечена выполненной.
|
||
- User jobs `local.balda.workspace-manager`, `local.balda.ssh-manager`, `local.balda.beads-dolt` реально running. Manager listeners только 127.0.0.1:17795/17796, native Dolt только 127.0.0.1:13307 плюс точный Unix socket в agent-home.
|
||
- Original Beads/Dolt: Mac и trusted Balda одновременно создали разные задачи в одной fixture DB, оба прочли оба ID; при одновременном claim exit codes 1/0 — ровно один победитель. Metadata — один и тот же оригинальный файл через SMB. Native bd внутри реального SSH+Seatbelt прочитал ту же БД через Unix socket и explicit native credentials file. Свои fixture credentials не дают доступа к реальным проектам; их БД не переинициализировались.
|
||
- Broad localhost binding по-прежнему выключен. OpenCode требует отдельного решения владельца. Уже работающие Codex/Claude ACP initialize/session-new не считаются модельной приёмкой; Claude на prompt вернул Authentication required при закрытых существующих CLI credentials.
|
||
- Передача Manager bearer tokens Mac была отклонена автоматической проверкой и исключена из схемы. Manager MCP подключены управляющей Balda; remote executors получают approved filesystem и native Beads. Для необходимых Balda HTTP callbacks штатный SRT proxy работает с очищенным NO_PROXY; unauthenticated Mac→Manager probe получил ожидаемый HTTP 401 без раскрытия токенов.
|
||
- Собственный synthetic ACP grant после проверок отозван и снят. Привилегированных постоянных mount helpers нет. Исходный Docker Dolt volume сохранён как резерв fixture; рабочий server теперь native Mac, чтобы Beads использовал Unix socket внутри sandbox.
|
||
- Кандидат включает original Prism assets с неизменёнными workflow bodies; изменены только native provider settings, убран отвергавшийся runtime pin gpt-5.4, включён ask. Полный runtime doctor всех 14 ролей exit 0. Production restart остаётся финальным отдельным подтверждением после model acceptance.
|