[2026-09-28] eagle: personal/plans/balda-runtime-rebuild-mm-validation.md personal/plans/runtime-pr4-openai-toolcalls-fixes.md personal/plans/runtime-pr5-toolset-dedup-review-fixes.md personal/tech/adk-hostedagent-openai-mcp.md
This commit is contained in:
1 parent
73518c5e43
commit
7501feea25
4 files changed
+299
-23
No files matched your search
@@ -0,0 +1,206 @@
|
||||
> Создан 2026-09-28. Статус: **📋 ПЛАН, ЖДЁТ ОДОБРЕНИЯ ALEX.**
|
||||
> Цель: собрать локально runtime (PR4+PR5 влиты) + balda (ревью PR #8), задеплоить на Kraken,
|
||||
> прогнать проверку тулинга и Mattermost.
|
||||
> Связано: [[personal/projects/balda/balda-kraken-mm-deploy]], [[personal/plans/balda-mm-pr8-review-fixes]],
|
||||
> [[personal/plans/runtime-pr5-toolset-dedup-review-fixes]].
|
||||
|
||||
---
|
||||
|
||||
## 0. ФАКТЫ, проверенные сейчас (не предположения)
|
||||
|
||||
| Факт | Значение |
|
||||
|---|---|
|
||||
| `normahq/runtime` PR #4 | **MERGED** 2026-09-28T13:21:59Z, head `22f7f17` |
|
||||
| `normahq/runtime` PR #5 | **MERGED** 2026-09-28T13:22:13Z, head `facb0d0` |
|
||||
| `upstream/main` (runtime) | `c41939f`; содержит `DedupKey` (**6** вхождений) и `openAIToolsFromConfig` (**2**) |
|
||||
| `baldaworks/balda` PR #8 | **OPEN**, head `e0162009`, review **CHANGES_REQUESTED** (2026-09-28T13:54Z) |
|
||||
| Локальный `~/Developer/balda` | `06b2b8d0` — **на 4 коммита позади** `origin/feat/mattermost-channel` |
|
||||
| `~/Developer/balda/runtime-local` | HEAD `06b2b8d0` — **это клон репо balda**, не runtime (!) |
|
||||
|
||||
### 🔴 Проблема №1 (блокирующая): `runtime-local` — фикция
|
||||
`~/Developer/balda/runtime-local` — **не отдельный чекаут runtime**, а вложенный git-клон
|
||||
`mallexxx/balda` (HEAD = balda-коммит `06b2b8d0`). В нём:
|
||||
- `openai.go` от PR #4 **вписан руками** (`openAIToolsFromConfig` — 3 вхождения);
|
||||
- `DedupKey` — **0 вхождений**, т.е. PR #5 **отсутствует**.
|
||||
|
||||
Каталог **git-ignored** в balda (`git ls-files runtime-local` → 0 файлов) и подключён через
|
||||
`replace github.com/normahq/runtime/v2 => ./runtime-local`. В доке
|
||||
[[personal/plans/runtime-pr5-toolset-dedup-review-fixes]] §5 это отмечено как отдельная задача.
|
||||
⚠️ Мои правки Balda-слоя из PR #5 (`DedupKey` в `internalmcp/manager.go` и `sessionapp/module.go`)
|
||||
в локальном дереве **есть** (M-статус), но **не компилируются** против этой копии.
|
||||
|
||||
### 🔴 Проблема №2 (из ревью PR #8): остались 3 блокера
|
||||
Последнее ревью (13:54) подтверждает: canonical chat ingress, command registry, scope
|
||||
classifiers, обязательный `InboundProcessor` — **исправлены**. Осталось **надёжность WS-ingress**:
|
||||
|
||||
| # | Файл:строка | Суть |
|
||||
|---|---|---|
|
||||
| P1 | `channel/mattermost/ingress.go:389` | При заполнении локального semaphore **событие теряется безвозвратно**: MM не получает ack/nack от клиента и не повторит `posted`. Нужен backpressure на read loop или durable bounded queue с повтором по `post.ID` |
|
||||
| P1 | `ingress.go:483` | `InboundRetry` и `err` только логируются → post считается потерянным. Нужен bounded retry/durable handoff с dedupe по `post.ID`; terminal settlement завершать без повтора. Ошибки `HandleCommand` выше тоже игнорируются |
|
||||
| P2 | `ingress.go:164` | Сначала остановить producer, **потом** `processWG.Wait()`. Сейчас read loop может дойти до `processWG.Add(1)` после начала `waitForProcessing` → `Stop` завершается, не дождавшись воркера. Также нарушение контракта `sync.WaitGroup` |
|
||||
|
||||
---
|
||||
|
||||
## 1. План — Часть A: runtime-local → чистый upstream
|
||||
|
||||
**Идея:** `replace` на локальный форк больше не нужен — PR #4 и #5 **влиты в апстрим**.
|
||||
Значит копию можно заменить на настоящий upstream без потери функционала.
|
||||
|
||||
| Шаг | Действие | Обоснование |
|
||||
|---|---|---|
|
||||
| A1 | Зафиксировать текущее состояние: `git -C ~/Developer/balda/runtime-local rev-parse HEAD`, бэкап каталога в `~/Developer/balda/runtime-local.bak-20260928` | Правило: бэкап ДО изменения |
|
||||
| A2 | Заменить `runtime-local` на чекаут `normahq/runtime` @ `c41939f` (или тега, если есть релиз после merge) | Убирает форк-коппию, снимает вечное расхождение |
|
||||
| A3 | Убрать `replace github.com/normahq/runtime/v2 => ./runtime-local` из `go.mod`, поднять `require` до версии с PR4+PR5 | Штатный путь; форк больше не нужен |
|
||||
| A4 | Если тега после merge нет — оставить `replace` на **чистый upstream**, а не на клон balda | Минимальное изменение, если апстрим ещё не тегирован |
|
||||
| A5 | Обновить комментарий в `go.mod` (сейчас ссылается на PR #4 как на открытый) | Док не должен врать |
|
||||
|
||||
⚠️ **Развилка A3/A4 требует решения Alex** — см. §3.
|
||||
|
||||
**Альтернатива (если править runtime у себя не хочется):** оставить `replace`, но заменить
|
||||
содержимое `runtime-local` на актуальный upstream-чекаут. Тогда Balda-код из PR #5 наконец
|
||||
скомпилируется.
|
||||
|
||||
---
|
||||
|
||||
## 2. План — Часть B: подтянуть Balda + закрыть 3 блокера PR #8
|
||||
|
||||
### B0. Синхронизация ветки
|
||||
`git fetch` + `git merge --no-rebase origin/feat/mattermost-channel` (правило AGENTS.md:
|
||||
синхронизировать merge'ем, не rebase). Проверить, что мои незакоммиченные правки
|
||||
(`internalmcp/manager.go`, `sessionapp/module.go`, `sessionmemorymcp/broker.go` — это PR #5-слой)
|
||||
не конфликтуют. 🔴 **Решить: коммитить их сейчас или они уже не нужны** (если `DedupKey`
|
||||
приезжает из апстрима — правки Balda-слоя всё равно нужны, чтобы *включить* дедуп).
|
||||
|
||||
### B1. P1 — не терять событие при заполнении semaphore (`ingress.go:389`)
|
||||
Сейчас: `acquireSlot()` не смог → лог → post потерян.
|
||||
Направление: **backpressure на read loop** — блокирующее взятие слота до чтения следующего
|
||||
кадра (MM не шлёт ack, повтора не будет). Плюс/или bounded queue с повтором по `post.ID`.
|
||||
🔴 Выбор между «блокировать read loop» и «durable queue» — **решение Alex** (§3): блокировка
|
||||
проще, но читающий цикл встаёт; очередь честнее, но требует dedupe и хранилища.
|
||||
|
||||
### B2. P1 — settlement + retry для retryable failure (`ingress.go:483`)
|
||||
Направление: различать terminal и retryable settlement; retryable — bounded retry с dedupe по
|
||||
`post.ID`; terminal завершать без повтора. Ошибки `HandleCommand` перестать игнорировать.
|
||||
|
||||
### B3. P2 — порядок shutdown (`ingress.go:164`)
|
||||
Направление: отменить/закрыть producer → дождаться `done` (новые `Add` невозможны) →
|
||||
и только затем `processWG.Wait()` для drain уже принятых.
|
||||
|
||||
### B4. Гейты Balda
|
||||
```bash
|
||||
go build ./...
|
||||
go vet ./...
|
||||
go test -race ./...
|
||||
go tool golangci-lint run ./...
|
||||
go tool go-arch-lint check --project-path .
|
||||
```
|
||||
|
||||
### B5. 📌 Проверить гипотезу ревьюера фактом, а не на слово
|
||||
Ревьюер сам пишет: *«The first issue needs a real Mattermost integration check because the
|
||||
current command test injects a synthetic `posted` frame»*. Проверка воспроизводимости —
|
||||
на Kraken живым постом (§C).
|
||||
|
||||
---
|
||||
|
||||
## 3. ⛔ Требует решения Alex (до начала работ)
|
||||
|
||||
1. **A3 vs A4:** убрать `replace` совсем (поднять версию runtime) или заменить `runtime-local`
|
||||
на чистый upstream-чекаут и оставить `replace`?
|
||||
2. **B1:** backpressure (блокировать read loop) или durable bounded queue с dedupe?
|
||||
3. **Порядок:** сначала закрыть 3 блокера PR #8, потом собирать/деплоить? Или собрать сейчас
|
||||
(валидация тулинга + MM уже возможна) и блокеры закрыть следом?
|
||||
|
||||
---
|
||||
|
||||
## 4. План — Часть C: сборка и деплой на Kraken
|
||||
|
||||
Проверенный порядок (из [[personal/projects/balda/balda-kraken-mm-deploy]]):
|
||||
```bash
|
||||
cd ~/Developer/balda
|
||||
docker buildx build --builder arm64builder --platform linux/arm64 \
|
||||
-f Dockerfile.release \
|
||||
--build-arg VERSION=<ver> --build-arg COMMIT=<sha> \
|
||||
--build-arg BUILD_DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ) \
|
||||
--provenance=false --load -t balda-mm:<NEXT> .
|
||||
zstd -3 -T0 -o /tmp/balda-mm-<NEXT>.tar.zst --force <(docker save balda-mm:<NEXT>)
|
||||
zstd -dc /tmp/balda-mm-<NEXT>.tar.zst | ssh kraken 'docker load'
|
||||
ssh kraken '/home/kraken/balda/tools/mm-switch-image.sh <NEXT>' # бэкап compose + recreate
|
||||
```
|
||||
|
||||
🔴 **Обязательные питфоллы (проверенные, не забывать):**
|
||||
1. `--provenance=false` — иначе `docker load` на Kraken ругается на формат.
|
||||
2. zstd распаковывать **на Mac** (zstd 1.5.4 на Kraken не читает фрейм macOS 1.5.7).
|
||||
3. **Все правки → финальный `go build`/`go test` → и только потом docker build.**
|
||||
Сборка, начатая до последней правки, даёт устаревший бинарник.
|
||||
4. `command: ["start"]` в compose — без подкоманды бинарь печатает help и висит.
|
||||
5. Образ — **`balda-mm`**, не `claudio-agent`. `-t` определяет, чей контейнер обновится.
|
||||
|
||||
**Текущий образ на Kraken:** `balda-mm:0.1.13` → следующий **`0.1.14`**.
|
||||
|
||||
⚠️ **Проверить состояние хоста ПЕРЕД деплоем** — в доке зафиксировано исчерпание RAM и
|
||||
watchtower-убийца `mm-postgres`, плюс `depends_on` не работает между compose-проектами.
|
||||
`personal/tech/kraken-host-resource-limits.md`, `personal/tech/kraken-docker-startup-order.md`.
|
||||
|
||||
---
|
||||
|
||||
## 5. План — Часть D: валидация (тулинг + MM)
|
||||
|
||||
### D1. Тулинг (MCP-инструменты исполняются)
|
||||
Признак успеха — **вызов инструмента реально исполнен**, не «контейнер Up»:
|
||||
```
|
||||
function_response_part_count = 1
|
||||
duplicate tool: → 0
|
||||
deadletter → 0
|
||||
turn_complete / final_response → true
|
||||
```
|
||||
⚠️ **Питфолл своей же проверки:** `grep -c "duplicate tool"` даёт ложную 1, потому что
|
||||
собственная строка лога — «skipping **duplicate tool**set». Искать строго
|
||||
`grep -c "duplicate tool:"` (с двоеточием).
|
||||
|
||||
### D2. Mattermost — приёмка ОТ АККАУНТА ALEX (не от `testuser`)
|
||||
🔴 `testuser` → `settlement_stage=unauthorized`. Это **не** приёмка.
|
||||
```bash
|
||||
# токен владельца БЕЗ пароля
|
||||
ssh kraken 'docker exec mattermost mmctl --local token generate admin "agent-e2e-$(date +%Y%m%d-%H%M)"'
|
||||
# пост от владельца
|
||||
ssh kraken '/tmp/mm-post-admin.sh <token> 7bjw4g7o1jdsbmjbqd649xxgaw "@balda <текст>"'
|
||||
# чтение ленты
|
||||
ssh kraken '/tmp/mm-feed.sh <token>'
|
||||
```
|
||||
⚠️ Скрипты `mm-post-admin.sh` / `mm-feed.sh` живут только в `/tmp` на Kraken — **не переживут
|
||||
reboot**. Воспроизводить из дока. Собирать заголовок из кусков
|
||||
(`HN="Auth""orization"`), иначе редакция секретов Hermes калечит файл.
|
||||
|
||||
**Сценарии проверки (покрывают и блокеры §2):**
|
||||
| # | Сценарий | Что доказывает |
|
||||
|---|---|---|
|
||||
| D2-a | `@balda вызови executor_health` от Alex | тулинг исполняется, scoped-URL выжил (PR #5) |
|
||||
| D2-b | Burst из ~17 сообщений подряд | **не теряется** ни одно (блокер B1) |
|
||||
| D2-c | `docker compose restart balda` во время обработки | drain, нет потерянных постов (B3) |
|
||||
| D2-d | `/topic` / управляющая команда в канале | command ingress работает |
|
||||
| D2-e | Пост из группового DM от двух участников | одна сессия на канал |
|
||||
|
||||
Метрики: `settlement_stage=accepted`, `bad_seq=0`, `RestartCount=0`.
|
||||
|
||||
---
|
||||
|
||||
## 6. Риски
|
||||
|
||||
1. 🔴 **Смена `runtime-local` — самая опасная правка.** Если в локальной копии есть
|
||||
**незакоммиченные ручные правки**, кроме PR4 (#4 вписан руками), их потеря = регрессия.
|
||||
⇒ До замены: `diff -r runtime-local ~/Developer/runtime-local` и просмотр отличий от апстрима.
|
||||
2. 🔴 **RAM на Kraken (4 ГБ, swap 0).** Прошлый раз load 57, MM недоступен. Проверить перед деплоем.
|
||||
3. ⚠️ `depends_on` между compose-проектами не работает — `balda-mm` может стартовать раньше MM.
|
||||
4. ⚠️ Правки — **только дельта-апплаером** (`tools/run-project-deltas.sh <check|apply|list> <deltas.json> <state.json>`,
|
||||
JSON — **плоский массив**, не объект). Не sed/in-place.
|
||||
5. ⚠️ Мои незакоммиченные правки Balda-слоя (PR #5) — решить судьбу в B0.
|
||||
6. ⚠️ Двойной префикс `display_name` в БД — прошлый раз починили в БД, а не в коде; проверять.
|
||||
|
||||
## Связанные заметки
|
||||
|
||||
- [[personal/projects/balda/balda-kraken-mm-deploy]] — деплой, питфоллы, скрипты приёмки
|
||||
- [[personal/plans/balda-mm-pr8-review-fixes]] — предыдущий раунд правок PR #8
|
||||
- [[personal/plans/runtime-pr5-toolset-dedup-review-fixes]] — PR #5, вопрос копии рантайма
|
||||
- [[personal/plans/runtime-pr4-openai-toolcalls-fixes]] — PR #4, tool_calls
|
||||
- [[personal/tech/kraken-host-resource-limits]] · [[personal/tech/kraken-docker-startup-order]]
|
||||
- [[personal/tech/balda-go-fx-pitfalls]] · [[personal/tech/hermes-secret-redaction-bypass]]
|
||||
Reference in new issue
Block a user