From f3b07534e483d43422cafa142b8b41b953b8610b Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Sat, 26 Sep 2026 12:10:18 +0600 Subject: [PATCH] [2026-09-26] eagle: personal/projects/balda/balda-kraken-mm-deploy.md personal/projects/balda/balda-mm-delegation-plan.md personal/tech/balda-go-fx-pitfalls.md personal/tech/hermes-secret-redaction-bypass.md --- .../projects/balda/balda-kraken-mm-deploy.md | 41 +++++++++++++++++-- .../balda/balda-mm-delegation-plan.md | 40 ++++++++---------- personal/tech/balda-go-fx-pitfalls.md | 15 +++++++ .../tech/hermes-secret-redaction-bypass.md | 25 +++++++++++ 4 files changed, 96 insertions(+), 25 deletions(-) diff --git a/personal/projects/balda/balda-kraken-mm-deploy.md b/personal/projects/balda/balda-kraken-mm-deploy.md index d7609dca..5d89429b 100644 --- a/personal/projects/balda/balda-kraken-mm-deploy.md +++ b/personal/projects/balda/balda-kraken-mm-deploy.md @@ -268,14 +268,49 @@ MM возвращает `{"id":"app.channel…missing","message":…}`, т.е. ` - несовпадение `BotUsername` (`balda`) с тем, что реально приходит в событии; - фильтр системных/`Type != ""` постов. -**Следующий шаг (не сделан):** поднять `logger.level` до `debug` в -`/home/kraken/balda/config/config.yaml`, перезапустить, отправить `@balda` снова — найти -строку-отказ. Затем править `inbound.go` дельтой. +**Следующий шаг (частично сделан):** `logger.level` поднят до `debug` в +`/home/kraken/balda/config/config.yaml` + `docker compose up -d --force-recreate`. Перезапуск +прошёл, пост `@balda` отправлен повторно — **в логах по-прежнему ни одного кадра от WS**. +Осталась проверка: шлёт ли MM вообще события этому боту. Кандидат — сервер не пушит +`posted` (клиентская сторона чистая: логика `handleFrame`/`dispatchPosted` разобрана, фильтры +логируют только на `Debug`, поэтому «тишина» = кадров нет вообще). + +**Метод проверки (не доведён):** пробник, который подключается к +`ws://localhost:8065/api/v4/websocket` с токеном бота, шлёт `authentication_challenge` и +печатает raw-кадры. Разделяет два случая: MM не пушит событие ↔ событие пушится и теряется +в фильтре `inbound.go`. + +⚠️ `python3` на Kraken **без модуля `websocket`** (`ModuleNotFoundError`). Пробник писать на +Go stdlib, **собирать нативно на Mac**, на хост класть готовый статический бинарь — тянуть +`golang:1.26.6-bookworm` (~800 МБ) на Kraken ради одного теста не надо. ⚠️ Приёмка — **ответ бота виден в UI Mattermost**, не «контейнер Up». Пока НЕ выполнена. --- +## 🔵 Проверка расходования диска (2026-09-26, по вопросу Alex) + +Alex спросил «почему ты работаешь на SD карте?» — проверено, ответ: **Docker целиком на HDD**, +SD под Docker не используется. + +``` +Docker Root: /srv/…-6194539b…/docker-data ← USB-HDD (1.8T) +/var/lib/docker: No such file or directory ← на SD его НЕТ +/etc/docker/daemon.json: data-root = /srv/…-49e8f586…/docker-data ← symlink на 6194539b +docker system df → Build Cache: 0B +``` + +SD (`/dev/mmcblk0p2`, 14 ГБ, 36%): `/usr` 2.9 ГБ · `/var/swap` 513 МБ · `/var/cache` 404 МБ · +`/home` 486 МБ. Единственный крупный файл на SD — `/var/swap` (swapfile), это штатно. + +📌 **Вывод:** buildkit-кэш, из-за которого правило и появилось, **пуст** — первая сборка шла на +`arm64builder` (colima на Mac) с `--load`, кэш на Kraken не писался вообще. Путь +`49e8f586…` и `6194539b…` — **один и тот же диск** (первый — симлинк). +⚠️ Неаккуратность этой сессии: `docker run golang:1.26.6-bookworm` тянул ~800 МБ на Kraken ради +одноразовой проверки WS. Лёг на HDD, но это лишний мусор — такие пробы гонять на Mac. + +--- + ## Файлы | Что | Путь | diff --git a/personal/projects/balda/balda-mm-delegation-plan.md b/personal/projects/balda/balda-mm-delegation-plan.md index eca88cb0..11235e94 100644 --- a/personal/projects/balda/balda-mm-delegation-plan.md +++ b/personal/projects/balda/balda-mm-delegation-plan.md @@ -246,36 +246,32 @@ Mattermost (Alex) — итог + артефакты и отсутствующие провайдеры видны только при `fx.ValidateApp`/`validateBaldaApplication`. 13 падающих пакетов в апстриме — **предсуществующие**, проверено `git stash`, не наши. -### Фаза 3 — оркестратор на Kraken (~1-2 дня) -Детальный док: [[personal/projects/balda/balda-kraken-mm-deploy]]. - -**Старт 2026-09-26 (вечер):** Alex дал команду «разворачивай бота на кракене с привязкой к ММ, -токен deepseek возьми скриптом из hermes whale env, сборка на маке». - -⚠️ **Решение «бота не создавать» отменено этой командой.** Бот в MM создан автоматически -(детали и id — в [[personal/projects/balda/balda-kraken-mm-deploy]]). Ранее (2026-09-26, утро) -в §5 было зафиксировано «токен даст Alex» — пункт устарел. - -1. ✅ Бот `balda` создан в MM, токен добыт и лежит на Kraken (0600), проверен `/users/me`. -2. ✅ `ServiceSettings.EnableBotAccountCreation` включён (`mmctl --local`; REST `PUT /config` - значение не менял — env MM перебивает конфиг). ### Фаза 3 — оркестратор на Kraken — 🟡 РАЗВЁРНУТА, бот пока не отвечает Детальный док: [[personal/projects/balda/balda-kraken-mm-deploy]]. -1. ✅ **Собран образ на Mac** — из апстримного `Dockerfile.release` (свой писать не пришлось), +**Старт 2026-09-26:** Alex дал команду «разворачивай бота на кракене с привязкой к ММ, +токен deepseek возьми скриптом из hermes whale env, сборка на маке». +⚠️ **Решение «бота не создавать» отменено этой командой.** Бот в MM создан автоматически. + +1. ✅ **Бот `balda` создан в MM**, токен проверен `/users/me`, лежит на Kraken (0600). + `ServiceSettings.EnableBotAccountCreation` включён (`mmctl --local`; REST `PUT /config` + значение не менял — env MM перебивает конфиг). +2. ✅ **Собран образ на Mac** — из апстримного `Dockerfile.release` (свой писать не пришлось), `balda-mm:0.1.1`, linux/arm64, 20.6 МБ, ~110 с. Перенос `docker save | zstd` → `docker load`. -2. ✅ **Развёрнута на Kraken** — `/home/kraken/balda/`, данные на USB-HDD, сеть +3. ✅ **Развёрнута на Kraken** — `/home/kraken/balda/`, данные на USB-HDD, сеть `mattermost_mm-net`, конфиг монтируется в `/workspace/.config/balda/config.yaml`. -3. ✅ **Провайдер DeepSeek** — `type: openai` + `base_url: https://api.deepseek.com/v1`, +4. ✅ **Провайдер DeepSeek** — `type: openai` + `base_url: https://api.deepseek.com/v1`, ключ из `~/.hermes/hermes-whale/.env` прочитан скриптом, в чат не выводился. -4. ✅ **WebSocket к MM подключён** — `mattermost websocket connected`. -5. ✅ **Backoffice-админ забутстрапен** (не был в плане, но обязателен — иначе отказ старта). -6. 🔴 **Обнаружен и исправлен дефект Фазы 2:** `advertised commands have no actor handler: goal` +5. ✅ **WebSocket к MM подключён** — `mattermost websocket connected`. +6. ✅ **Backoffice-админ забутстрапен** (не был в плане, но обязателен — иначе отказ старта). +7. ✅ **Обнаружен и исправлен дефект Фазы 2:** `advertised commands have no actor handler: goal` — опечатка в `Advertisement.Names` роняет **весь fx-граф** и даёт crash-loop. См. [[personal/tech/balda-go-fx-pitfalls]] §«Дефект 4». Ни один quality gate Фазы 2 его не видел. -7. 🔴 **ОТКРЫТО: бот не отвечает на `@balda`.** Пост доставлен, в логах ингресса тишина. - Следующий шаг — `logger.level: debug` + искать строку-отказ в `inbound.go`. -8. ⏳ **Верификация Alex в UI MM — не пройдена** (приёмка = ответ бота в UI). +8. 🔴 **ОТКРЫТО: бот не отвечает на `@balda`.** Пост доставлен, но в логах ингресса **нет ни + одного кадра от WS** даже на `logger.level: debug`. Клиентская логика разобрана и чистая — + значит подозрение смещается на **серверную сторону: MM не пушит `posted` боту**. + Метод проверки — WS-пробник с токеном бота (см. детальный док, §«Что осталось»). +9. ⏳ **Верификация Alex в UI MM — не пройдена** (приёмка = ответ бота в UI). ### Фаза 4 — исполнитель в VM/Docker на Mac (~2-3 дня) 1. Docker-контейнер (или UTM VM) с Node 24 + `codex` + `claude` + `git`. diff --git a/personal/tech/balda-go-fx-pitfalls.md b/personal/tech/balda-go-fx-pitfalls.md index 09ae3d97..7d276890 100644 --- a/personal/tech/balda-go-fx-pitfalls.md +++ b/personal/tech/balda-go-fx-pitfalls.md @@ -175,6 +175,21 @@ MM-адаптер при копировании «на глаз». **живой запуск бинаря**. Для нового транспорта добавлять в чек-лист шаг: `docker run` (или локальный `balda start`) с включённым транспортом **до** объявления готовности. +✅ **Фикс подтверждён живым запуском (2026-09-26).** После снятия `goal` контейнер `balda-mm` +на Kraken перестал падать и дошёл до рабочего состояния: + +``` +{"component":"balda.session_manager","balda_provider":"deepseek","message":"session manager ready"} +{"component":"balda.channel.mattermost.ingress","url":"ws://mattermost:8065/api/v4/websocket", + "message":"mattermost websocket connected"} +{"message":"Balda bot started. Press Ctrl+C to stop."} +``` + +📌 Порядок проверки, который сработал: правка дельтой → `go build ./...` → `go test +./internal/apps/balda/actors/command/...` → пересборка образа → `docker compose up -d` → +`docker logs | grep -E "started|websocket connected"`. **Не** объявлять транспорт готовым +по «exit 0» и «conтейнер Up» — только по этим двум строкам в логах. + --- ## ⚠️ Env-override работает только по ключам, уже присутствующим в YAML diff --git a/personal/tech/hermes-secret-redaction-bypass.md b/personal/tech/hermes-secret-redaction-bypass.md index fbaf1f18..bd64f3cc 100644 --- a/personal/tech/hermes-secret-redaction-bypass.md +++ b/personal/tech/hermes-secret-redaction-bypass.md @@ -291,6 +291,28 @@ ssh kraken "MM_ADMIN_PW='…' bash /tmp/x.sh" < /dev/null --- +### 📌 Как отличить «транспорт испортил» от «файл испорчен» + +Серия из шести осыпавшихся вариантов дала чёткий критерий. Признак транспорта: **локальный файл +цел, а хост видит мусор**. Проверка за один вызов: + +```bash +ssh host "cat > /tmp/p.sh && bash -n /tmp/p.sh && echo SYNTAX_OK || echo SYNTAX_FAIL" +# затем сравнить длину строки на хосте и в локальном файле: +ssh host 'awk "NR==N{print length(\$0)}" /tmp/p.sh' < /dev/null +awk 'NR==N{print length($0)}' ./p.sh # локально +``` + +Если длины **совпадают** — файл доехал, проблема в логике. Если в логе хоста строка короче +или содержит `***` — сработала редакция, и править надо **не файл**, а способ передачи. + +⚠️ Симметричная ловушка: `read_file` тоже показывает отредактированный текст. Отсюда правило — +**никогда не собирать `patch`-овский `search` по выводу `read_file`**, если в строке есть +`TOKEN`/`AUTH`/`Bearer`/`$o`. Файл на диске целый, и `patch` запишет байт-в-байт, вырезав код +по-настоящему. Проверять `awk`/`grep -c`/`od -c`, а не глазами. + +--- + ## Валидация результата (обязательный шаг) После записи конфига — проверить, что в файле **нет** заглушки, но **есть** значение: @@ -320,3 +342,6 @@ grep "MM_SQLSETTINGS_DATASOURCE" compose.yml | grep -q 'postgres://${PGUSR}:\${P **E** (`printf` с format-строкой), **F** (`ssh 'bash -s' < file` съедает stdin) и **предпочтительный паттерн**: скрипт файлом → `cat > /tmp/x.sh` → `bash -n` на хосте → исполнение. Найдено на деплое Балды на Kraken. +- **2026-09-26 (позже)**: добавлен §«Как отличить "транспорт испортил" от "файл испорчен"» — + критерий по расхождению длин строки на хосте и локально, плюс правило не собирать + `patch`-овский `search` из обрезанного `read_file`.