[2026-09-29] eagle: personal/plans/balda-callee-prism-plan.md

This commit is contained in:
Alexey Martemyanov committed 2026-09-29 18:26:41 +06:00
1 parent 6ea574a07b
commit 1e8681f7cc
1 file changed
+168 -28
+168 -28
View File
@@ -272,7 +272,46 @@ Runner:
Broker не должен парсить человекочитаемый ANSI/TTY-вывод Callee. Если Callee уже имеет стабильный machine-readable API, runner становится тонким адаптером. Broker не должен парсить человекочитаемый ANSI/TTY-вывод Callee. Если Callee уже имеет стабильный machine-readable API, runner становится тонким адаптером.
## 9. Изоляция и секреты ## 9. Execution workers и распределение ресурсов
Broker планирует не только macOS VM. Все среды исполняют один versioned Runner protocol, но имеют разные `runtime_class`:
- `linux-container` — обычный код, CLI, Docker builds и инфраструктурная автоматизация;
- `macos-vm` — Xcode, macOS APIs, GUI и UI tests;
- `remote-host` — изменение конкретного хоста после Human approval.
Минимальный WorkerSpec:
```json
{
"runtime_class": "macos-vm",
"worker_profile": "xcode-27",
"agent_profile": "codex-default",
"workflow_id": "prism/story",
"repository": "git@host:org/repo.git",
"revision": "main"
}
```
### Параллельные задачи
Balda поддерживает несколько независимых chat sessions. Turns внутри одной session сериализуются, разные sessions могут работать параллельно.
Callee поддерживает `Parallel`, но это fan-out Role visits внутри одного workflow. VM создаёт и распределяет Broker, не Balda и не Callee.
Политика пула:
1. Одна изменяющая macOS Story получает одну эксклюзивную VM.
2. Implementer, reviewer и verifier используют ту же VM, но свежие ACP-сессии.
3. Отдельная VM на каждый Role не создаётся.
4. Одновременно работают максимум две macOS VM; остальные run стоят в очереди.
5. Linux containers масштабируются отдельно и не занимают macOS VM slots.
Параллельные read-only роли могут работать в одной VM. Параллельные изменения получают отдельные Git worktrees; запись нескольких агентов в один checkout запрещена политикой Runner.
Ограничение в две macOS VM задаёт Apple Virtualization.framework, а не Balda. Практический лимит дополнительно зависит от RAM и CPU.
## 10. Изоляция, shared folder и секреты
Основная граница безопасности — одноразовая macOS VM. Основная граница безопасности — одноразовая macOS VM.
@@ -284,7 +323,35 @@ Broker не должен парсить человекочитаемый ANSI/TT
Хостовый Virfield API разрешает только операции жизненного цикла VM. Balda и Broker не получают `docker.sock`, пользовательский `~/.ssh` или произвольный shell на Mac. Хостовый Virfield API разрешает только операции жизненного цикла VM. Balda и Broker не получают `docker.sock`, пользовательский `~/.ssh` или произвольный shell на Mac.
## 10. Неподтверждённое ### Shared folder Lume
Lume монтирует shared folder через virtiofs. Изменения содержимого должны появляться динамически; Lume также умеет добавлять folder к уже запущенной VM без reboot/remount.
Для mutable workspace и Xcode build shared folder не считается надёжным источником истины. В текущем Virfield уже потребовались `sudo purge` и уникальные DerivedData snapshots из-за stale guest cache.
Рабочий контракт:
- репозиторий клонируется на локальный диск VM;
- обновления передаются через Git или `rsync/scp`;
- shared folder используется для immutable inputs и выгрузки artifacts;
- каждый набор artifacts получает уникальный путь `run_id/...`;
- Xcode не собирает проект непосредственно из `/Volumes/My Shared Files`.
### Изменение других хостов
Задачи настройки Mac, Kraken, TrueNAS и других машин используют `runtime_class: remote-host`.
1. Agent в контейнере формирует plan и выполняет read-only preflight.
2. Balda показывает точный diff действий и запрашивает Human approval.
3. Broker выдаёт capability lease на конкретные host, identity, operations и TTL 15–30 минут.
4. Runner применяет изменения через dedicated service account или установленный host-runner.
5. Verify, audit log и rollback закрывают lease.
Личные ключи из пользовательского `~/.ssh` не передаются. Для managed host используется небольшой Go host-runner. Для первичного bootstrap допускается отдельный SSH account с short-lived certificate и ограниченным `sudo`.
Изменения самого Mac выполняет отдельный native launchd helper. Он принимает подписанный capability lease; Balda и модель не получают постоянный host shell.
## 11. Неподтверждённое
### Блокирует прототип ### Блокирует прототип
@@ -302,7 +369,7 @@ Broker не должен парсить человекочитаемый ANSI/TT
- восстановление Broker после падения во время `waiting_human`; - восстановление Broker после падения во время `waiting_human`;
- параллельные Story и лимиты VM/CPU/RAM на Mac. - параллельные Story и лимиты VM/CPU/RAM на Mac.
## 11. Варианты ## 12. Варианты
### A. Sidecar Broker + VM runner — выбран ### A. Sidecar Broker + VM runner — выбран
@@ -320,7 +387,69 @@ Balda остаётся оркестратором, Broker изолирует и
Будущая transport abstraction в `runtime + acpagent` позволит Balda или Callee подключаться к ACP по WebSocket/Streamable HTTP. Она может заменить SSH-транспорт, но не заменяет Broker, VM lifecycle, durable events и cleanup. Будущая transport abstraction в `runtime + acpagent` позволит Balda или Callee подключаться к ACP по WebSocket/Streamable HTTP. Она может заменить SSH-транспорт, но не заменяет Broker, VM lifecycle, durable events и cleanup.
## 12. Pitfalls ## 13. Аудит Virfield и целевая версия v2
### Что существует сейчас
Virfield — TypeScript/Node.js приложение:
- Express + WebSocket backend;
- React/Vite Web UI;
- SQLite;
- отдельный stdio MCP server;
- shell/Python provisioning scripts.
Web UI уже реализован. TypeScript typecheck проходит. Собственной automated test suite практически нет.
### Подтверждённые архитектурные проблемы
1. Состояние VM определяется одновременно Lume API, Lume CLI, SQLite, JSON-файлами, PID и in-memory maps.
2. REST и MCP дублируют orchestration; MCP вызывает REST, а при ошибке обходит его и управляет Lume напрямую.
3. Recovery основан на `pgrep`, `pkill`, PID probing и ручном склеивании stale states.
4. Virfield читает личные SSH keys, имеет password fallback `lume`, хранит GitHub PAT в SQLite и предоставляет широкий `vm_ssh_exec`.
5. Long-running jobs частично живут только в памяти и теряют нормальную управляемость после restart.
### Решение: переписать control plane, не Lume
Lume остаётся hypervisor/backend. Проверенные provisioning scripts временно сохраняются как versioned jobs и постепенно заменяются только при наличии тестов.
Virfield v2 состоит из пяти частей:
1. `virfieldd` на Go — единственный владелец SQLite, Lume adapter, VM leases, jobs, events и cleanup; запускается через `launchd`.
2. Image Manager — модуль `virfieldd` для download/pull/build/promote golden images; отдельный daemon ему не нужен.
3. Web UI — отдельный API client на embedded HTML/HTMX или простом JavaScript без Node toolchain.
4. `virfield-mcp` на Go — тонкий stdio/HTTP adapter; не обращается к Lume или SQLite напрямую.
5. Execution Broker и Runner на Go — отдельный execution-контур рядом с Balda и внутри workers.
Один Lume adapter скрывает различия HTTP/CLI. UI, MCP и Broker используют только versioned API `virfieldd`.
Оценка: Virfield v2 MVP — 7–12 рабочих дней; Broker/Runner — 5–10 дней; UI migration и hardening — ещё 5–8 дней.
## 14. Agent profiles и модельная политика
Broker и Runner не содержат vendor-specific workflow logic. Run выбирает `agent_profile` из статического allowlist.
Для Callee напрямую подтверждены Codex, Claude, Copilot, Grok, OpenCode и Cursor. Gemini и GLM подключаются через `generic_acp` или отдельный ACP adapter и считаются неподтверждёнными до integration test.
Worker image содержит Runner, Callee и нужные provider binaries. Credentials выбранного provider выдаются только на срок run. Node отсутствует в Virfield/Broker control plane; он допускается внутри специализированного worker image, если конкретный agent CLI без него не работает.
### Распределение моделей
Схема `Balda → Callee → coding agent` остаётся правильной. Текущее назначение DeepSeek единственным оркестратором не оптимально: Balda использует один app-scoped provider для всех sessions.
Рекомендуемая раскладка:
- Balda — надёжное понимание запроса, выбор workflow, управление state и Human interaction;
- specify/design/review — сильная reasoning-модель;
- implementation — Codex или другой сильный coding agent;
- build/test/SSH apply — детерминированные Script/Runner operations;
- дешёвая модель — routing, summarization и простая диагностика.
DeepSeek подходит для ограниченного routing и простых операций с жёсткими tool schemas. Он не принимает самостоятельные решения о privileged SSH-командах и сложной архитектуре.
Оптимизация стоимости строится на deterministic routing, token/run budgets, bounded retries и escalation: после повторной неудачи задача повышает model tier, а не повторяет дешёвую модель бесконечно.
## 15. Pitfalls
### Архитектура ### Архитектура
@@ -346,49 +475,57 @@ Balda остаётся оркестратором, Broker изолирует и
4. Host path, переданный как ACP cwd, не существует или указывает не туда внутри VM. 4. Host path, переданный как ACP cwd, не существует или указывает не туда внутри VM.
5. VM с доступом в локальную сеть может атаковать хостовые сервисы; egress и host API нужно ограничить. 5. VM с доступом в локальную сеть может атаковать хостовые сервисы; egress и host API нужно ограничить.
## 13. План реализации Broker ### Исполнение и ресурсы
### Этап 1 — spike контрактов, 4–8 часов 1. Mutable build через virtiofs может прочитать stale content; workspace должен жить на локальном диске worker.
2. Более двух активных macOS VM невозможны; Broker обязан иметь очередь и admission control.
3. Parallel Callee roles, пишущие в один checkout, создают file conflicts даже внутри одной VM.
4. Свободный provider command или agent-generated `cmd` превращает профиль в arbitrary code execution.
5. Установка всех provider credentials в один golden image нарушает isolation и усложняет rotation.
1. Запустить один Callee workflow вручную внутри тестовой VM. ## 16. План реализации
2. Зафиксировать фактический stdout/API, Human pause/resume и cancel.
3. Запустить Codex Role через локальный ACP stdio.
4. Проверить workspace path, build и terminal result.
5. Принять формат VM runner protocol на основании фактов.
Результат: подтверждённый протокол Callee/runner без предположений. ### Этап 1 — live spike контрактов, 1–2 дня
### Этап 2 — Virfield control API, 4–8 часов 1. Запустить Virfield и Lume и проверить clone/start/stop/delete без fallback paths.
2. Проверить stale-cache сценарии shared folder и зафиксировать Git/rsync contract.
3. Запустить один Callee workflow вручную внутри тестовой VM.
4. Проверить Codex ACP, Human pause/resume, cancel и terminal result.
5. Принять versioned contracts Virfield API и VM Runner.
1. Обернуть существующий `vm_prepare_session` в узкий authenticated HTTP API. Результат: фактические runtime-контракты без предположений.
2. Добавить операции lease status, stop и delete.
3. Ограничить templates, TTL и число параллельных VM.
4. Добавить idempotency key и audit log.
5. Проверить cleanup после таймаута и падения клиента.
Результат: Broker может безопасно получить и освободить VM без host shell. ### Этап 2 — Virfield v2 core, 7–12 дней
### Этап 3 — VM runner, 1–2 дня 1. Реализовать `virfieldd` и единую SQLite job/event model.
2. Реализовать один Lume adapter и reconciliation loop.
3. Добавить leases, idempotency, quotas, audit и cleanup.
4. Подключить существующие image/provisioning scripts как jobs.
5. Реализовать Go CLI/MCP adapters и минимальный Web UI.
Результат: один надёжный владелец VM и images без Node runtime.
### Этап 3 — универсальный Runner, 2–4 дня
1. Описать versioned JSON protocol command/event. 1. Описать versioned JSON protocol command/event.
2. Реализовать start, events, Human response и cancel. 2. Реализовать start, events, Human response и cancel.
3. Подключить Callee workflow pack и Codex ACP. 3. Подключить Callee workflow pack и allowlisted agent profiles.
4. Сформировать artifact manifest для git diff, commit, logs и `.xcresult`. 4. Сформировать artifact manifest для git diff, commit, logs и `.xcresult`.
5. Добавить terminal result и гарантированное завершение дочерних процессов. 5. Добавить terminal result и гарантированное завершение дочерних процессов.
Результат: одна команда запускает workflow в VM и возвращает структурированные события. Результат: один протокол запускает workflow в VM или container и возвращает структурированные события.
### Этап 4 — Broker MVP, 1–2 дня ### Этап 4 — Broker MVP, 3–6 дней
1. Реализовать SQLite schema для runs, events, responses и artifacts. 1. Реализовать SQLite schema для runs, events, responses и artifacts.
2. Реализовать state machine и транзакционный event journal. 2. Реализовать state machine и транзакционный event journal.
3. Подключить Virfield API и SSH/runner transport. 3. Подключить Virfield API, container driver и Runner transport.
4. Опубликовать MCP tools из §8. 4. Опубликовать MCP tools из §8.
5. Добавить restart recovery, lease renewal и cleanup worker. 5. Добавить restart recovery, lease renewal и cleanup worker.
Результат: Balda управляет долговечным run через HTTP MCP. Результат: Balda управляет долговечным run через HTTP MCP.
### Этап 5 — Balda + Prism, 1–2 дня ### Этап 5 — Balda + Prism, 2–4 дня
1. Подключить Broker MCP к runtime Balda. 1. Подключить Broker MCP к runtime Balda.
2. Развернуть Prism adapter и Dolt/Beads container. 2. Развернуть Prism adapter и Dolt/Beads container.
@@ -398,7 +535,7 @@ Balda остаётся оркестратором, Broker изолирует и
Результат: Story ведётся в Beads, выполнение и approvals видны в Mattermost. Результат: Story ведётся в Beads, выполнение и approvals видны в Mattermost.
### Этап 6 — сквозная приёмка, 4–8 часов ### Этап 6 — сквозная приёмка, 1–2 дня
1. Создать Story из реального сообщения Mattermost. 1. Создать Story из реального сообщения Mattermost.
2. Пройти specify/design/approval/implement/review/verify. 2. Пройти specify/design/approval/implement/review/verify.
@@ -408,15 +545,18 @@ Balda остаётся оркестратором, Broker изолирует и
Результат: воспроизводимый end-to-end прогон без исполнения агентских команд на хосте. Результат: воспроизводимый end-to-end прогон без исполнения агентских команд на хосте.
Оценка MVP после spike: 4–7 рабочих дней. Production hardening зависит от возможностей Callee API и обычно добавит 3–7 дней. Оценка после spike: рабочий end-to-end MVP — 17–30 рабочих дней. Срок сильнее всего зависит от Callee machine API, Lume reconciliation и переноса Web UI.
## 14. Критерии готовности ## 17. Критерии готовности
1. Balda создаёт одну Story и один idempotent run из сообщения Mattermost. 1. Balda создаёт одну Story и один idempotent run из сообщения Mattermost.
2. Все команды Codex, Xcode build и тесты исполняются внутри leased VM. 2. Все команды Codex, Xcode build и тесты исполняются внутри leased VM.
3. Callee управляет ролями и циклами; Broker не содержит workflow policy. 3. Callee управляет ролями и циклами; Broker не содержит workflow policy.
4. После рестарта Balda или Broker прогресс восстанавливается без двойного запуска. 4. После рестарта Balda или Broker прогресс восстанавливается без двойного запуска.
5. Terminal run обновляет Beads, публикует артефакты и удаляет VM по lease policy. 5. Terminal run обновляет Beads, публикует артефакты и удаляет VM по lease policy.
6. Linux-задачи исполняются в containers и не занимают macOS VM slots.
7. Remote-host задача не использует личные SSH keys и не выполняется без capability lease.
8. UI и MCP показывают одно состояние из `virfieldd`, без собственных fallback orchestration paths.
## Связанные заметки ## Связанные заметки