[2026-09-27] eagle: personal/plans/balda-mm-phase4-agents.md personal/projects/balda/balda-kraken-mm-deploy.md personal/projects/balda/balda-valera.md personal/tech/balda-go-fx-pitfalls.md personal/tech/music-broken-toload.md

This commit is contained in:
Alexey Martemyanov committed 2026-09-27 01:15:17 +06:00
1 parent 586d9e8ffd
commit de100184d6
5 files changed
+467 -14

No files matched your search

+107
View File
@@ -32,6 +32,11 @@
> 📌 Урок метода: **прежде чем объявлять ограничение апстрима — свериться со своим
> старым патчем.** Ключ Alex: «Это не та же проблема, что мы решали в форке?»
> Зеркало секции скилла `devops/docker-balda-service`, добавленной 2026-09-26.
> 🔴🔴🔴 **Добавлено 2026-09-27 (четвёртая итерация):** §«Патч tool_calls ОБНАЖИЛ двойную
> паковку инструментов» — почему `duplicate tool` вернулся на `0.1.12`, хотя конфиг чист.
> Ключевой инсайт: апстримный `TurnComplete: true` **маскировал** баг — агент не доходил
> до паковки инструментов. Как только патч включил второй раунд, ADK-механика проявилась.
> Плюс метод: §«Доказать, что код патча в образе» (распаковать OCI-слои, грепнуть бинарник).
> Источник: работа над Mattermost-адаптером Балды (Фаза 2) + деплой на Kraken (Фаза 3).
> Проектные доки: [[personal/projects/balda/balda-mattermost-connector]],
> [[personal/projects/balda/balda-kraken-mm-deploy]],
@@ -1615,3 +1620,105 @@ MM websocket frame
`frame received` → `event decoded` → `posted event accepted` → `post accepted for processing`
→ `conversational ingress settled` (`settlement_stage`!) → `assembled provider user content`
→ `turn task failed`. Пока нет строки `assembled provider user content` — провайдер не виноват.
---
## 🔴🔴🔴 Патч tool_calls ОБНАЖИЛ двойную паковку инструментов (2026-09-27)
**Симптом.** После деплоя `balda-mm:0.1.12` (форк `runtime` с поддержкой `tool_calls`) **каждый**
ход падает, Балда молчит:
```
error … "agent run: duplicate tool: \"balda.control.shutdown\""
warn … command failed with retryable error (delivery_attempt 1..4)
warn … publish event "balda.v1.evt.command.in_progress": context deadline exceeded
```
**Это тот же `duplicate tool`, что уже чинили через конфиг** (§13 в
[[personal/plans/balda-mm-phase4-agents]]) — но конфиг **чист** (`balda.mcp_servers: []`,
ID только у провайдера). Значит причина другая, и правкой конфига она не лечится.
### Ключевой инсайт: `TurnComplete: true` МАСКИРОВАЛ баг
| Образ | `TurnComplete` | Что происходило |
|---|---|---|
| `0.1.11` (апстримный `openai.go:107`) | жёстко `true` | агент завершался после **первого** ответа модели → инструменты **не пакались вообще** → `duplicate tool` не возникал, **но и инструменты не работали** |
| `0.1.12` (форк) | `!hasToolCalls` | при `tool_calls` агент идёт на **второй раунд** → начинается паковка инструментов → всплывает двойная регистрация |
> 📌 **Формулировка для будущих сессий:** форк **не регрессия — форк диагност.** Ошибка жила
> в связке Balda↔ADK всё время; не было только пути её вызвать. Прежде чем объявлять новый
> патч виновником — проверить, не **обнажил** ли он dormant-баг.
### Механика: два независимых пути паковки в один `req.Tools`
`google.golang.org/adk/v2@v2.4.0`:
```
base_flow.go:778 toolPreprocess() — пакует agent.Tools → req.Tools
base_flow.go:798 toolsetPreprocess() — пакует agent.Toolsets → req.Tools
└─ mcptoolset/tool.go:89 → toolutils.PackTool()
toolutils.go:47-48:
if _, ok := req.Tools[name]; ok {
return fmt.Errorf("duplicate tool: %q", name)
}
```
- `tools_processor.go:31` — `if f.Tools != nil { return }` — защищает **только** сборку `f.Tools`,
**не** повторный вызов `toolsetPreprocess`.
- `PackTool` **идемпотентным не является by design** — дублировать источник нельзя.
- Дубль возникает, если инструмент присутствует **и в `Tools`, и в одном из `Toolsets`**, либо
в двух toolsets. Кандидат в нашем случае: `agentfactory.go:655-656` кладёт в `llmagent.Config`
одновременно `Tools: req.Tools` и `Toolsets: toolsets` (bundled `balda` мог попасть в оба).
📌 `grep -rn "duplicate tool"` по репозиторию Balda **пуст** — искать в ADK
(`$(go env GOMODCACHE)/google.golang.org/adk/v2@v2.4.0/tool/toolutils/toolutils.go`).
### Что исключено фактами (не проверять снова)
| Версия | Проверка | Итог |
|---|---|---|
| Конфиг дублирует MCP-ID | `balda.mcp_servers: []`, ID у провайдера | ❌ чисто |
| Сессия накопила мусор | `/reset` **от владельца** (admin PAT) | ❌ не лечит |
| Форк не попал в образ | `strings` бинарника из `0.1.12` | ❌ форк на месте |
| Каталог `state.db` замусорен | уникальные ID: `builtin/balda`, `configured-mcp/executor-mcp`, `configured-mcp/obsidian` — по одному | ❌ по одной записи |
| Bundled MCP стартует дважды | лог `bundled MCP listener started` — один раз | ❌ однократно |
| Патч трогает сборку инструментов | `git diff v2.0.11 --stat` → только `openai.go` + тест | ❌ патч чист |
| `ContextBroker.Wrap` добавляет инструменты | `broker.go:118-153` — только HTTP-заголовки | ❌ не источник |
| `hostedToolsets()` дублирует серверы | `agentfactory.go:360-384` — `resolvedMCP` это **map** по `id` | ❌ дубля нет |
⚠️ **Ловушка ложной тревоги:** `strings state.db | grep -c '"balda"'` ≈ **112**. Это счётчик
вхождений **подстроки**, а не серверов: `balda` есть в каждом логе, в `balda.v1.*`,
в `balda.control.shutdown`. Считать только **уникальные** ID.
### Метод: доказать, что код патча попал в образ (`scratch`, shell нет)
```bash
docker save balda-mm:0.1.12 -o /tmp/chk.tar
mkdir -p /tmp/chkx && tar -xf /tmp/chk.tar -C /tmp/chkx
# OCI-формат: слои в blobs/sha256/*, бинарник — в самом большом слое
for f in /tmp/chkx/blobs/sha256/*; do
file -b "$f" | grep -q gzip && tar -xzf "$f" -C /tmp/chkx 2>/dev/null
done
strings /tmp/chkx/usr/local/bin/balda | grep -E "tool_call_id|missing content and tool_calls"
```
⚠️ `tar -tf image.tar | grep ca-certificates` на OCI-образе даёт **ложный 0** — файлы внутри
слоёв. То же и с поиском кода патча: смотреть только распакованный бинарник.
🔴 **Кэш сборки — реальный риск, но не засорение диска.** `COPY runtime-local/` мог подставить
**старые исходники** без ошибки. В этот раз обошлось, потому что изменились `go.mod` и
`Dockerfile.release` (слои инвалидировались сами). Если менять **только содержимое**
`runtime-local/` — брать `--no-cache`, иначе тихо соберутся старые исходники.
### Побочный эффект откатов: долгий старт из-за WAL
Жёсткое убийство контейнера оставляет незакрытый `state.db-wal`. Следующий старт на `0.1.11`
идёт **~4.5 мин** вместо ~1m11s (переигрывание WAL). **Это не зависание:** `docker logs | wc -l`
растёт рывками, процесс висит в `do_epoll_wait` — живой.
Признак настоящего зависания — рост лога остановился **и** нет ни одного потока в `epoll`.
📌 Метод чтения состояния застрявшего процесса в контейнере без shell:
```bash
PID=$(docker inspect balda-mm --format '{{.State.Pid}}')
for t in $(sudo ls /proc/$PID/task); do echo -n "$t: "; sudo cat /proc/$PID/task/$t/wchan; echo; done
```
`do_epoll_wait` = слушает · `blk_mq_get_tag` = дисковый I/O · `futex_wait_queue` = ждёт мьютекс/канал.
+102
View File
@@ -0,0 +1,102 @@
---
title: Битые и DRM аудиофайлы — на перезагрузку
updated: 2026-09-26
type: tech
tags: [music, truenas, toload]
related: personal/tech/yandex-music-api, personal/tech/music-tags-repair-truenas
---
# Битые и DRM аудиофайлы — на перезагрузку
> Файлы в `/mnt/RED_2TB/storage/Music`, которые **не читаются** и подлежат
> удалению с последующей загрузкой заново.
> Рядом с [[personal/tech/yandex-music-api]] (выгрузка библиотеки).
> Составлено: 2026-09-26. Источник: диагностика ffmpeg/ffprobe в контейнере `tagwriter`.
---
## Итог
| Категория | Файлов | Объём | Причина |
|---|---|---|---|
| **Битые** (контейнер разрушен) | 16 | ~152 МБ | ID3-заголовок записан поверх структуры формата |
| **DRM** (Windows Media защита) | 13 | ~33 МБ | `License_URL` в ASF-заголовке |
| **Итого** | **29** | **~185 МБ** | |
**Бэкап:** все 29 в `/mnt/RED_2TB/storage/Music/backup_raw/`.
⚠️ **Бэкап не помогает** — файлы там идентичны диску (побиты до сессии).
---
## 1. Битые (контейнер разрушен) — 16 файлов
**Причина:** файл начинается с `ID3` вместо `ftyp` (m4a) / `ASF` (wma) →
`moov atom not found` / `Invalid data found`. Структура контейнера затёрта.
**Восстановлению не подлежит.**
### Infected Mushroom — (2012) Army of Mushrooms (13 m4a, ~130 МБ)
Папка: `!Pop, Club, Любэ/Infected Mushroom/(2012) Army of Mushrooms/`
| Файл | Размер |
|---|---|
| `01 Never Mind.m4a` | 12.5 МБ |
| `02 Nothing to Say.m4a` | 13.0 МБ |
| `03 Send Me an Angel.m4a` | 14.7 МБ |
| `04 U R So Fucked.m4a` | 9.9 МБ |
| `05 The Rat.m4a` | 15.5 МБ |
| `06 Nation of Wusses.m4a` | 13.9 МБ |
| `07 Wanted To.m4a` | 7.0 МБ |
| `08 Serve My Thirst.m4a` | 13.5 МБ |
| `09 I Shine.m4a` | 11.9 МБ |
| `10 Drum n Bassa.m4a` | 14.4 МБ |
| `11 The Pretender.m4a` | 13.0 МБ |
| `12 The Messenger 2012.m4a` | 21.0 МБ |
| `13 Swingish (Bonus Track).m4a` | 12.4 МБ |
**Искать:** `Infected Mushroom Army of Mushrooms 2012` (альбом целиком, MP3 320)
### Прочее (3 файла, ~9 МБ)
| Файл | Размер | Искать |
|---|---|---|
| `!Рэп/НТЛ/NTL - ВЕРТИТЕ ЗАДОМ_old.wma` | 1.7 МБ | НТЛ — Вертите задом |
| `!Rock&Folk/Агата Кристи/Ближе.wma` | 2.7 МБ | Агата Кристи — Ближе |
| `!Rock&Folk/Ундервуд/2002 Все пройдет, милая/02 - Гагарин, я вас любила.wma` | 4.3 МБ | Ундервуд — Гагарин, я вас любила |
---
## 2. DRM (Windows Media защита) — 13 файлов
**Причина:** в ASF-заголовке `License_URL: ...sbp=DRM&...` — файлы зашифрованы
Windows Media DRM. Microsoft закрыл инфраструктуру выдачи лицензий → **обойти
нельзя**. Требуется загрузка заново.
**Папка:** `!Рэп/НТЛ/wma/` — все 13 `Track N.wma` (1–13), ~33 МБ
**Искать:** `НТЛ` (группа) — альбом целиком. Файлы безымянные (`Track N`),
названия треков неизвестны — уточнить по треклисту на источнике.
| Файл | Размер |
|---|---|
| `Track 1.wma` … `Track 13.wma` | 1.8–3.1 МБ каждый |
---
## 3. Что делать
1. Скачать заново по списку выше (в MP3).
2. Теги — по общему правилу библиотеки (`tag-fix-plan` / `rebuild_summaries`).
3. ⚠️ **Не применять массовые ID3-правки к не-MP3** — именно это разрушило
контейнеры m4a/wma. Теги не-MP3 писать только родными инструментами формата.
---
## 4. Связанные документы
- [[personal/tech/yandex-music-api]] — выгрузка библиотеки Яндекс Музыки
- [[personal/tech/music-tags-repair-truenas]] — ремонт тегов на TrueNAS
- [[personal/tech/music-tags-final-review]] — финальное ревью
---
*Создано: 2026-09-26 | Источник: диагностика 70 не-MP3 файлов в Music*