[2026-09-29] eagle: personal/projects/balda/mattermost-kraken-deploy.md personal/tech/hermes-whale-mattermost-transport.md

This commit is contained in:
Alexey Martemyanov committed 2026-09-29 10:59:48 +06:00
1 parent dae4d91fcf
commit d9aa3abc79
2 files changed
+264

No files matched your search

@@ -0,0 +1,233 @@
---
title: hermes-whale — Mattermost как транспорт
created: '2026-09-29'
updated: '2026-09-29'
type: tech
namespace: personal
status: in-progress — бот и канал созданы, транспорт НЕ дописан
tags:
- hermes
- mattermost
- transport
- whale
- kraken
- lsp
related:
- '[[personal/projects/balda/mattermost-kraken-deploy.md]]'
- '[[personal/tech/kraken-host-resource-limits.md]]'
- '[[personal/tech/hermes-fork-vs-upstream.md]]'
---
# hermes-whale — Mattermost как транспорт
> Задача Alex 2026-09-29: «Добавь mattermost на кракене транспортом в hermes-whale
> и добавь в MM бота себе нового (Кит/whale)».
> Статус: **бот `whale` и канал созданы ✅, транспорт в `.env` НЕ дописан ⏳**.
## Расклад (решение)
| Компонент | Где | Почему |
|---|---|---|
| **hermes-whale gateway** | **Mac** (не Kraken) | профиль живёт на Mac; это НЕ переезд |
| **Mattermost сервер** | Kraken | уже работает, `health=healthy` |
| Связь | `https://mm.qentra.top` (Cloudflare Tunnel) | проверено 2026-09-29: `{"status":"OK"}` |
⚠️ **На Kraken транспорт НЕ разворачивается.** Там 4 ГБ RAM и история OOM
(см. [[personal/tech/kraken-host-resource-limits.md]]). Mattermost-транспорт
в контейнере `hermes-kraken` не поднимаем.
## Готовое: плагин уже существует
Код писать **не нужно** — платформа `mattermost` уже в дереве:
```
~/.hermes/hermes-agent/plugins/platforms/mattermost/adapter.py
~/.hermes/hermes-agent/plugins/platforms/mattermost/plugin.yaml
```
### Env-переменные (из `plugin.yaml`)
| Переменная | Обяз. | Смысл |
|---|---|---|
| `MATTERMOST_URL` | ✅ | URL сервера, напр. `https://mm.qentra.top` |
| `MATTERMOST_TOKEN` | ✅ | токен бота или PAT |
| `MATTERMOST_HOME_CHANNEL` | — | канал для cron/уведомлений |
| `MATTERMOST_REPLY_MODE` | — | `thread` (вложенно) или `off` (плоско). **Дефолт `off`** |
| `MATTERMOST_REQUIRE_MENTION` | — | требовать `@bot` в каналах (дефолт `true`) |
| `MATTERMOST_ALLOWED_USERS` | — | белый список user id |
| `MATTERMOST_ALLOW_ALL_USERS` | — | любой юзер триггерит бота (dev) |
| `MATTERMOST_FREE_RESPONSE_CHANNELS` | — | каналы без обязательного `@mention` |
| `MATTERMOST_ALLOWED_CHANNELS` | — | если задан — бот отвечает ТОЛЬКО в них |
📌 Адаптер читает `config.extra.{url, reply_mode}` **ИЛИ** env (`adapter.py:77-97`).
В `config.yaml` профиля есть блок `mattermost:` (пока только `channel_prompts`).
## Созданные объекты MM (2026-09-29)
| Объект | ID | Как создано |
|---|---|---|
| Бот `whale` (Кит) | `k4i3uihzp3gdxj5gx3en3tbeso` | `mmctl user create` → `mmctl user convert --bot` |
| Канал `whale` | `fnm6auyc8trz5njxrfofebkbfr` | `mmctl channel create --team qentra` |
| Команда | `qentra` = `m1iwp7t9w7no3y8gi876iw39he` | существовала |
| Владелец бота | `whale` (Owned by whale) | ⚠️ не `admin`, см. ниже |
✅ **Бот в канале** — подтверждено живой командой:
```
channel users list qentra:whale
→ k4i3uihzp3gdxj5gx3en3tbeso: whale (whale@localhost) channel_user
```
⚠️ **Бот в команде — не подтверждено.** `mmctl team users add qentra <bot_id>` вернул
`exit=0` (молчаливый успех), но проверить нечем: **`mmctl team users list`
не существует** (только `add` / `remove`). Проверять через API
`GET /api/v4/teams/{team_id}/members/{user_id}` — требует рабочего PAT.
## 🔴 Питфоллы, найденные на месте
1. **`mmctl user convert --bot` требует ШЕСТЬ флагов, не один.**
`--owner` не существует вовсе. Минимальный набор из `--help`:
```
mmctl --local user convert <user> --bot \
--email <e> --firstname <f> --lastname <l> --locale en --system-admin
```
Без `--email`/`--firstname`/`--lastname`/`--locale` конвертация не проходит.
Вывод успеха: `whale converted to bot.`
2. **`mmctl user convert` НЕ выдаёт токен.** Токен выпускается отдельно:
`mmctl --local token generate whale <desc>`. MM отдаёт значение **ровно один раз**.
3. **`mmctl channel list --json` печатает не-JSON перед JSON.** Первая строка —
`There are 4 channels on local instance`, потом `[`. `jq` падает с
`parse error: Invalid numeric literal at line 1, column 6`.
Обход: `sed -n '/^\[/,$p' | jq …`.
4. **`mmctl team users list` НЕ существует.** Есть только `add`/`remove`.
Проверка членства — только через REST API.
5. **REST `/api/v4/...` с токеном из `.adminpw` даёт 401**
(`api.context.session_expired.app_error`). `.adminpw` — пароль, не токен.
Для API нужен PAT: `mmctl --local token generate admin <desc>`,
заголовок `Authorization: Bearer <token>`. ⚠️ Заголовок `Token:` в MM 11.x не принимается.
6. **`mmctl` не имеет команды чтения состава команды** — приходится идти в API.
Постинг тоже недоступен (`post create` → `not supported in local mode`), чтение работает.
## Что осталось (следующий заход)
1. Выпустить токен бота:
```
ssh kraken "docker exec mattermost mmctl --local token generate whale whale-hermes"
```
⚠️ Значение показывается один раз — перехватить сразу, записать в 0600-файл.
2. Вписать в `/Users/admin/.hermes/hermes-whale/.env`:
```
MATTERMOST_URL=https://mm.qentra.top
MATTERMOST_TOKEN=<токен>
MATTERMOST_HOME_CHANNEL=fnm6auyc8trz5njxrfofebkbfr
MATTERMOST_REPLY_MODE=thread
MATTERMOST_REQUIRE_MENTION=true
```
3. Перезапустить gateway на Mac: `hermes gateway run --replace`.
4. **Приёмка = Alex пишет `@whale привет` в канале `whale`, видит ответ в UI.**
Не «контейнер Up», не «curl отвечает».
## Main delivery / Telegram — 🔴 ЗАБЛОКИРОВАНО
Alex: «main delivery поставь телеграм, там есть вроде бот для Кита».
**Бота для Telegram НЕТ.** Проверено: в `hermes-whale/.env` — **ни одной
`TELEGRAM_*` переменной**. Полный список ключей `.env`:
```
DEEPSEEK_API_KEY FIRECRAWL_API_URL GLM_API_KEY
ZULIP_ALLOWED_USERS ZULIP_API_KEY ZULIP_BOT_EMAIL ZULIP_DEFAULT_TOPIC
ZULIP_FREE_STREAMS ZULIP_HOME_CHANNEL ZULIP_POLLING_DISABLED
ZULIP_REQUIRE_MENTION ZULIP_URL
```
Код адаптера есть (`gateway/platforms/telegram.py`), токена нет.
🔴 **Создать Telegram-бота программно невозможно** — только через BotFather вручную.
Нужен `TELEGRAM_BOT_TOKEN` от Alex. Пока его нет — main delivery на Telegram
поставить нечем.
Действующий home-канал профиля сейчас — **Zulip** (`/master::hermes`).
## LSP-серверы — разбор (вопрос Alex)
**Что это.** Подсистема `agent/lsp/` — language-серверы, которые `write_file`/`patch`
дёргают **сразу после записи файла** для семантической проверки (pyright → `.py`,
gopls → `.go`, yaml-language-server → `.yaml`). Это те самые «auto-runs syntax checks».
**Обязательны? Нет.** Мастер-тумблер `lsp.enabled` (дефолт `true`).
**Почему их 15 и почему 2.4 ГБ.** Это **живые дети gateway pid 31763**, не осиротевшие.
Не переиспользуются: каждое открытие Go-проекта поднимает **новый** `gopls`.
```
ppid=31763 pid=99339 604MB up 3д 09:38 gopls
ppid=31763 pid=67249 383MB up 2д 10:44 gopls
ppid=31763 pid=71815 256MB up 2д 09:14 gopls
ppid=31763 pid=95153 14MB up 19:44 bash-language-server
… ещё 11 × 8-14 МБ (pyright / yaml-language-server / docker-langserver)
```
Итог: **~1.24 ГБ в трёх `gopls` + ~1.1 ГБ в node-серверах ≈ 2.4 ГБ**.
| Ручка | Что делает |
|---|---|
| `hermes lsp restart` | рвёт клиентов, при следующей правке спавнятся заново. Разово вернёт ~2 ГБ |
| `lsp.enabled: false` | выключает подсистему целиком — «no servers spawn, no background event loop, no cost» |
| `lsp.install_strategy: manual` | `auto` (дефолт) сам ставит бинари в `<HERMES_HOME>/lsp/bin/` |
| `lsp.servers.<id>.disabled: true` | отключить конкретный сервер (напр. `gopls`) |
📌 **Gating:** LSP включается только когда cwd (или файл) внутри **git-worktree**.
Вне git-репо подсистема спит, работает только in-process синтаксическая проверка —
поэтому на Kraken (контейнер, cwd не git) LSP не потребляет RAM.
📌 **На Mac 64 ГБ — не проблема.** Это зафиксировано, чтобы не «оптимизировать» зря.
## Замер памяти Hermes (2026-09-29, вопрос Alex «сколько hermes жрёт памяти»)
| Что | Где | RSS |
|---|---|---|
| **hermes-whale gateway** (этот профиль) | Mac | **165 МБ** — pid 31763 = 112 МБ, pid 2934 = 53 МБ |
| **hermes-kraken** gateway | Kraken (контейнер) | **139 МБ** (замер 2026-09-27) |
| LSP-серверы | Mac | **~2.4 ГБ** (15 процессов) — это НЕ Hermes |
⚠️ Не путать: «Hermes ест 165 МБ», а «2.4 ГБ едят LSP-процессы, порождённые gateway».
Второй pid 2934 (`up 6 дней`) — второй gateway, вероятно от другого профиля/`--replace`-инстанс.
## Бэкапы (перед правкой)
`/Users/admin/.hermes/hermes-whale/backups/20260929-105131-mm-transport/`
| Файл | md5 (совпадает с рабочим) |
|---|---|
| `config.yaml` | `7b348fa585baede4d85e4bb7057694af` |
| `env` | `6f58de78b7c882bff84bf556ca8fa67b` |
⛔ **`.env` и `config.yaml` профиля ещё НЕ изменены** — транспорт не дописан.
## Скрипты этой сессии (в `/tmp`, не переживут reboot)
`whale-mm-backup.sh` · `whale-mm-probe.sh` · `whale-mm-create.sh` ·
`whale-mm-convert.sh` · `whale-mm-membership.sh` · `whale-mm-verify.sh`
⚠️ `/tmp/whale-mm-verify.sh` остался с битым heredoc (сломан харнессом при записи) —
переписать заново перед использованием, не запускать как есть.
## Ответ на вопрос «можно ли создавать каналы и пинговать бота»
| Вопрос | Ответ |
|---|---|
| Создавать каналы | ✅ да, Alex — админ. `EnableOpenServer=false` / `EnableUserCreation=false` закрывают только **самостоятельную регистрацию чужих**, админу не мешают |
| Пинговать бота | ✅ да, но бот обязан быть **в команде И в канале**, иначе посты падают 403 `api.context.permissions.app_error` |
| Команд на MM | одна — `qentra` |
## Связанные заметки
- [[personal/projects/balda/mattermost-kraken-deploy.md]] — сам сервер MM
- [[personal/tech/kraken-host-resource-limits.md]] — почему не на Kraken
- [[personal/tech/hermes-fork-vs-upstream.md]] — платформы живут в `plugins/platforms/`