Files
obsidian-vault/personal/projects/balda/execution-broker.md
T

26 KiB
Raw Blame History

Execution Broker — текущий локальный контур

Проверено: 2026-10-14, включая GitHub, репозитории, конфигурацию и работающие контейнеры.

Текущий статус

Broker ещё не полностью реализован и не прошёл production-приёмку нового кандидата. Локальные проверки rc.26 завершены; работающий контур использует прежние образы. Открытый PR #52 относится к Balda: все 11/11 GitHub checks SUCCESS, PR открыт и не draft; конфликтов нет, но CHANGES_REQUESTED / merge BLOCKED, ещё не merged.

Открытый блокер Balda PR #52

Внешнее ревью metalagman, 2026-10-14 14:41:30 UTC, запросило изменения. FIFO в рамках одной сессии нарушается между разными actor targets: после ошибки публикации command:session-1 outbox всё равно публикует следующий session:session-1, потому что блокирует по Envelope.To, а не общему session scope. Поведение независимо воспроизведено на HEAD 085a0d43: одноразовый race overlay probe получил [first second] вместо [first]. Исходники и ветка этим probe не менялись.

Нужно исправление session-scoped FIFO с fallback для команд без session и regression для смешанных targets. Reviewer также запросил ссылку на Story/plan/acceptance в shared Beads; локальная balda-7w4 такой ссылкой не является. Оба пункта остаются открытыми. Зелёные существующие 11 CI checks не покрывали новый FIFO repro; кандидат Balda сейчас не принят к merge.

Репозитории и действующие образы

Компонент Подтверждённое состояние
Broker repository /Users/admin/Developer/execution-broker; main и origin/main: 437cbf8
Broker candidate 0.1.0-rc.26; код проверен на b64a1ba83c82475b08276ea3fb6a54c99d4a1509; текущая codex/production-readiness: b7106b5 с последующими изменениями документации
Broker production execution-broker:production-a3594c3
Gateway production execution-broker-gateway:quality-437cbf8
Prism production execution-prism-adapter:session-fix-20261004
Balda production контейнер balda-mm-mac, образ balda-balda, image ID sha256:56c00100258b1a478484ef20e044981ed0a569ec0ae7d6ba8608e8878a9e1f95
Balda PR candidate codex/ingress-outbox-v2, HEAD 085a0d435f727a1f4628a3259998c6498d42fcf2, checkout /private/tmp/execution-broker-balda-upstream

Ветка Broker остаётся локальной. Ветка Balda опубликована в mallexxx/balda. Открытие PR не обновляло контейнеры.

Что проверено у Broker rc.26

На принятой ревизии прошли make check build и проверки Callee на macOS ARM64 и Linux ARM64, race-тесты, adapter/plugin checks, source/binary govulncheck и gitleaks истории. Reachable vulnerabilities — 0; недостижимые findings сохранены в отчётах.

Реальный изолированный Docker/Callee flow прошёл Human pause → restart → resume → пять артефактов → cleanup. Linux ARM64 архив отдельно установлен без Go и source checkout: четыре сервисных образа, MCP, перезапуск Broker, пять артефактов, succeeded, cleanup=done. Закреплённые Claude/OpenCode/Node и ACP initialize проверены на macOS/Linux ARM64 без provider inference.

Четыре платформенных архива rc.26 и отдельный plugin находятся в dist/ с SHA256SUMS. Runtime probes архивов прошли; результаты AMD64 получены через эмуляцию. Native AMD64 этим не подтверждён. Старые live coding runs ниже относятся к прежним образам.

Что остаётся у Broker

Область Состояние
Согласованное развёртывание Не выполнено для кандидата: Broker/gateway, Runner/Callee, workflow/config pins, VM bootstrap и plugin должны составлять один принятый комплект
Финальная live-приёмка После обновления нужны реальный conversational run, артефакты, credential settlement, cleanup и outage/restart на совместимой версии Balda
Универсальная подготовка стеков В плане: версии инструментов, проверенные источники, readiness probes и восстановимое изменение окружения для Make/C/C++, CMake/Ninja, Python, Node, Rust/JVM на Linux/macOS
Immutable caches Общие tooling/Git caches остаются в плане; существующий Go SDK cache не является универсальным provisioning
Артефакты между запусками Digest-bound inputs и retention holds остаются в плане
Платформы и recovery Native AMD64 и восстановление после потери хоста/Keychain не подтверждены

В текущих broker.json и worker.json сохраняется drift image pins для linux-smoke и linux-opencode-deepseek; три coding-профиля содержат Docker socket. Защиты rc.26 запрещают такой доступ и отклоняют несовпадение pin до allocation, но прежний production-контур этих новых защит не получает.

Источник объёма работ — /Users/admin/Developer/execution-broker/docs/work-plan.md. Настраиваемый remote-action API — отдельное будущее расширение. iPad, прикладные UI/PR workflows, search/Obsidian и общая политика прав локального агента принадлежат Balda или конкретному проекту. Новая политика доступа к Obsidian этим прогоном не вводилась.

Balda: PR #52 и восстановление ingress

PR #52 открыт из 085a0d43 в baldaworks/balda:main. Все восемь required checks прошли: lint, test, SQLite/PostgreSQL integrations, architecture lint, projection replay, JetStream, ingress E2E. Дополнительно прошли native-launch jobs Ubuntu, macOS и Windows — всего 11/11 SUCCESS. Это проверки Balda; native AMD64 acceptance Broker остаётся отдельной границей.

Локально основной агент отревьюил весь diff из 58 файлов. Прошли полный go test -race ./... в штатном macOS TMPDIR, обе tagged SQL integration suites, lint, architecture, govulncheck, Goose validations, projection replay 15 раз, ingress/native MCP scenarios и build. Хэши проверенных файлов совпадают с HEAD PR. Одноразовый PostgreSQL удалён. GitHub CI завершился после локальных проверок; полный test job завершился 2026-10-14 14:13:40 UTC.

Durable admission сохраняет команду до receipt, background publication переживает NATS outage. Terminal receipts/tombstones собираются через семь дней, новые NATS budgets включаются только явно. Retry policy принадлежит jobs/commandoutbox, автономное восстановление ответов — jobs/questionoutbox; concrete wiring находится в commandoutboxfx.

Ответ и два recovery-маркера сохраняются одной SQL-операцией. Worker восстанавливает continuation без нового inbound, после receipt отдельно сохраняет cleanup controls. Ошибка cleanup не переотправляет continuation, положительный Telegram Selected следует durable admission. Late delivery binding и повтор завершённой очистки проверены. Regression использует реальный pinned webhook/runtime, production control publisher, один HTTP update и десять failure/restart случаев для callback/text; второго bot/callback после reopen нет.

SQLite migration 63 / PostgreSQL migration 28 требуют согласованного backup. Исторические answered-записи не переигрываются автоматически. Гарантия начинается с SQL settlement; webhook HTTP 200 означает transport intake. Сохраняются границы: один publisher на state DB, outbox pending lifetime до 24 часов, terminal dedupe семь дней. PR ещё не merged и заблокирован review; его исправления не объявляются развёрнутыми.

Прежняя Balda codex/production-readiness / 223b85ad — отклонённый прототип, оставленный для истории. Источником текущей реализации является PR #52. PR #8 merged 2026-09-29, PR #12 merged 2026-10-03.

Навигация и доказательства

  • personal/projects/balda/setup
  • personal/projects/balda/balda
  • state/production-readiness-20261014/review-followup.json — текущий Balda diff, self-review, проверки, PR/CI и история пересмотренных выводов.
  • state/production-readiness-20261014/local-checks.json — исторический прогон Broker rc.26. Его результаты по старому Balda prototype не заменяют текущий review-followup.
  • state/production-readiness-20261014/balda-v5-reviewed-files.json — хэши 58 проверенных файлов; полные логи лежат рядом. balda-review-fifo-probe.log фиксирует новый независимо воспроизведённый блокер.
  • Beads balda-7w4 была закрыта после прежнего локального прогона в явно временной базе; после этого upstream reviewer нашёл FIFO blocker. Это не shared upstream acceptance record. Актуальный запрос на его привязку и дефект ведутся в review PR #52.
  • personal/plans/balda-callee-prism-plan, personal/projects/archive/balda-reference-before-2026-10-14.

История приёмки действующих версий

Проверка продолжения: run-0175c98134e42a9d912dcc2626264bcd получил точный план из одобрения human-1 запуска run-3a21ab05f78f688abc923d0946728233 (SHA256 994b9c5492136ff1710ace38aef33767658585fd597f553d74f85a3122f287dc). Реальная macOS VM начала с implementer, без specify/design/breakdown и нового Human. Claude ответил Authentication required; конкретная ошибка доставлена в Mattermost. Код не создан и не опубликован.

Native CLI обнулил оба токена и expiresAt в private cache, из-за чего прежний checkpoint застрял. Восстановление распознаёт этот явный результат с привязкой к аккаунту/организации: сохраняет предыдущий зашифрованный cache, отмечает необходимость входа и разрешает cleanup остановленного worker. Реальный cleanup=done подтверждён; issuer не revoked, owner освобождён, reauthentication_required=true. Владелец вошёл по ссылке из Mattermost; issuer подтвердил credentials_saved 2026-10-14 08:20:37 UTC, и run-3fcbd9a52b55e9c750671ea4357b705a автоматически продолжился с прежним утверждённым планом. Реализация, тесты и ревью прошли, но quality gate отклонил verifier: ACP склеил поясняющий текст с финальным JSON. Конкретная ошибка доставлена в Mattermost (g4nbxpzff78s8e5jjwgwxoxcjo). Исправление 437cbf8 допускает текст перед первым JSON, сохраняет исходный отчёт и по-прежнему отвергает несколько объектов, trailing content, failed и невыполненные проверки. Реальный отчёт воспроизведён исправленным шлюзом успешно.

Итоговый run-a1b236aaff2e3d877049cf790262ac37 той же Story завершился succeeded, cleanup=done 2026-10-14 около 08:36 UTC. Он начал сразу с implementer, без нового планового Human. На Darwin 27.0.0 / Go 1.26.9 ARM64 прошли gofmt, go vet, go test -count=1 ./..., сборка и smoke (--version, --help, greet, отсутствие имени и неизвестная команда с ожидаемым exit=2), ревью без findings, quality.json passed=true. SHA256 всех артефактов проверены. execution_publish_artifacts опубликовал b5a238cd478ae89923cdbb4908c4f26fd7ddabfc в /Users/admin/Developer/go-cli-claude-test, checkout чистый. Через Prism закрыты Task eb-9840de48c9a2090fdb1b6a4f, затем Story eb-bae3eaa3bfcaeb17678c1bc7; обе операции вернули completed=true, а read-only Beads подтвердил status=closed. Broker → Balda → исходный Mattermost-тред доставил итог: коммит опубликован, Task и Story закрыты. Это проверенный coding flow; первоначальный повтор потерянной MM-команды запускал оператор через штатный Broker retry, поэтому восстановление conversational ingress после NATS outage отдельно не объявляется проверенным. Эфемерные login URL в документации не хранить.

Молчание по команде владельца подтверждено: 2026-10-14 06:24:56 UTC Mattermost принял post, NATS вернул 503 insufficient resources, после трёх попыток ingress прекратил dispatch без ответа. История BALDA_EVENTS заняла около 1.9 ГБ при account max_store=2gb. Локальный max_store повышен до 16gb, история сохранена, Balda перезапущен. Новая ошибка запуска после этого доставлена. Повышение max_store было только восстановлением ёмкости. В локальной ветке Balda 223b85ad теперь реализованы durable ingress outbox на AppKV, сохранение исходного envelope до публикации, повтор после рестарта, dedupe receipts, FIFO внутри сессии и ограниченные retry/retention. Для NATS добавлены отдельные бюджеты streams с резервом для Commands и отказом при попытке установить лимит ниже уже хранимых данных. После исчерпания входных retries Mattermost получает безопасный ответ в исходной теме со стабильным pending_post_id. SQLite restart, переполнение настоящего NATS и доставка через HTTP-fixture проверены. В работающий Balda эти исходники в этом прогоне не устанавливались; реальный conversational outage/recovery в Mattermost заново не запускался.

Конфигурация и перезапуск

  • Действующий Compose-файл: /Users/admin/Developer/execution-broker/state/deploy/compose.production.json (приватный, не коммитить). Это полный снимок действующей конфигурации вместо цепочки временных override.
  • Broker config: state/deploy/broker.json; worker config: state/deploy/worker.json; bootstrap assets: state/deploy/assets.
  • Контейнеры Broker/gateway/Prism: execution-broker-broker-1, execution-broker-worker-1, execution-broker-prism-1. Balda: balda-mm-mac.
  • Применение выбранного образа: docker-compose -f state/deploy/compose.production.json -p execution-broker up -d --no-deps broker из каталога репозитория. Изменение Git само по себе ничего не разворачивает.
  • Перед изменением активной конфигурации сохранять образ, config и согласованный Broker backup; не прерывать чужие задачи.

Одобрения

Для явно запрошенного повторного запуска использовать execution_retry: исходный run_id, chat/topic и новый idempotency_key. Broker выводит точный прежний scope и сохраняет одобрённый текст, вместо пересказа задачи моделью. Тот же Story/task/repository revision/worker/image/agent не требует нового одобрения плана. Изменение scope или позднейшие замечания владельца требуют нового решения. Сохранённый план — приватный admission snapshot; публичный status его не раскрывает. Native sign-in и ACP permissions остаются отдельными механизмами.

telegram_approvals.enabled=true и выбранная исходная сессия: запрос только в @balda_approval_bot; при выключенном Telegram — в исходном канале Balda. Результат, причина сбоя и очистка приходят в исходный Mattermost-тред. Original execution_respond сохранён для восстановления. После истечения срока самого Telegram-запроса кнопка «Обновить запрос» создаёт свежие кнопки для того же ожидающего Human в том же run и VM, пока не истёк исходный deadline запуска; она не одобряет задачу и не продлевает run. Токены находятся только в приватных secret-файлах.

Бот отправляет одно читаемое сообщение с кнопками. Длинный план явно помечен как preview; полный файл отправляется только по кнопке «Полный план». Просмотр не одобряет задачу. Reply на сообщение с кнопками передаёт замечания к плану: до трёх доработок в том же run с повторным одобрением. Обычное сообщение или Reply на вложение не считается ответом. Для ACP permission нужно выбрать предложенный вариант, для остановки — «Отменить задачу».

Это одобрения Broker workflows и worker ACP. Прямые ACP-запросы хостовых агентов Balda и operator grants для существующих папок/managed hosts — отдельные механизмы. Контекстный субагент для autoapproval остаётся плановой работой.

VM и доработка

VM принадлежит run. Терминальный исход завершает её после сбора артефактов; открытая Story сама по себе VM не удерживает. Claude/OpenCode теперь выполняют до трёх циклов implementation → verification → review в одном checkout и VM, с передачей проверок и findings в доработку. Исчерпанный цикл блокирует публикацию финальным quality gate. Инфраструктурный сбой, отмена и исходный deadline остаются терминальными.

Тестом на двух независимых соединениях воспроизведён SQLite database is locked / SQLITE_BUSY_SNAPSHOT (517). Запись теперь резервирует writer до чтения через BEGIN IMMEDIATE. Это доказанный дефект, но он не объявляется установленной причиной четвёртого запуска: его исходная ошибка не записана.

Автоматическое окружение и качество

Новые Broker-managed проекты не требуют ручного allowlist в каждой VM: Broker выводит guest config для своей Git namespace, а run-bound Git capability ограничивает доступ конкретным проектом. Digest пакета и версии workflow проверяются до запуска.

Go 1.26.9 Darwin ARM64 автоматически загружается Broker, проверяется по SHA256, кешируется и устанавливается только в disposable VM. Golden image и пользовательский Mac не меняются. SDK wrapper задаёт правильный GOROOT и доступные права каталогов.

Detached HEAD — штатный checkout закреплённой ревизии; локальные коммиты сохраняются в commits.bundle. Одобрение — факт workflow journal, переданный subsequent roles, а не файл в репозитории. Кандидат rc.26 усиливает quality gate: каждый verifier command повторно исполняется в disposable reviewed checkout, фактические exit/output сохраняются в private quality.json; изменение HEAD, tracked source или index блокирует публикацию. Любая проверка должна сама завершиться с exit=0; expected_exit_code != 0 отвергается. Отрицательный CLI-сценарий оформляется shell assertion, которая проверяет ненулевой код и сообщение приложения, а сама возвращает 0. Эта новая защита пока относится к кандидату, а исторические live-прогоны выше выполнены прежним Callee.

execution_diagnostics проверяет checksum артефактов и извлекает bounded причину Callee или Runner из callee.log, даже без quality.json, для failed, expired и canceled. Реальный expired run проверен через MCP после развёртывания fd29974. Отдельным тестом воспроизведён прежний отказ журнала для длинного Human: теперь вопрос до 256 КиБ сохраняется целиком, Human event ограничен 512 КиБ, остальные события — 32 КиБ. Конкретная ошибка обработки события сохраняется в редактированном логе Runner. Ошибки cleanup записываются отдельно в cleanup_error и не заменяют исходную причину исполнения. Cleanup, завершившийся во время отложенной доставки terminal, получает отдельное уведомление; более поздний receipt не скрывает его.

Подробные контракты: docs/telegram-approvals.md, docs/operations.md, docs/protocol.md, docs/testing.md. Собственные задачи Broker и границы релиза перечислены в docs/work-plan.md. iPad, search/Obsidian, общие права локального агента и персональные workflows относятся к вызывающему проекту или Balda; они не являются release gates Broker.