--- tags: - hermes - mattermost - mention - adapter - whale type: plan namespace: personal status: implemented — awaiting gateway restart created: '2026-09-29' updated: '2026-09-29' --- # План: MM mention-gating — авто-ответ в треде с ботом **Дата:** 2026-09-29 **Статус:** Реализовано, ждёт рестарта gateway (приёмка Alex в UI) ## Итог | Что | Значение | |---|---| | Файл | `~/.hermes/hermes-agent/plugins/platforms/mattermost/adapter.py` | | md5 до | `9f3def29d90d00287cdbca3db000c513` | | md5 после | `ed8c4b7735e3371f697c20cfbd11e421` | | Бэкап | `~/.hermes/hermes-whale/backups/20260929-mm-mention/adapter.py` | | Скрипт | `/tmp/mm-thread-mention.py` (идемпотентный) | | Тесты | `tests/gateway/test_mattermost.py` — 46 passed (было 43, +3) | | Коммит hermes-agent | `9b46ba791a` feat(mattermost): allow thread replies without @mention | | Push | `207a1de16c..9b46ba791a main -> main` → github.com:mallexxx/hermes-agent.git | ### Что именно изменено `_handle_ws_event`, перед mention-гейтом: ```python is_thread_reply = bool(post.get("root_id")) ... if ( require_mention and not is_free_channel and not has_mention and not is_thread_reply ): return ``` Три новых теста: - `test_thread_reply_without_mention_responds` — тред без меншна → ответ есть - `test_channel_root_without_mention_still_skipped` — корень канала без меншна → тишина - `test_thread_reply_with_mention_strips_mention` — меншн в треде всё ещё убирается из текста Остаток: рестарт gateway. Без него патч не подхватится (адаптер импортируется при старте). `gateway run --replace` из активной сессии её убьёт — рестарт делает Alex. ## Задача (Alex, дословно) > «в канале — меншен обязателен, в треде где только с ботом переписка — авто, без меншена» ## Проблема (подтверждена фактами) `plugins/platforms/mattermost/adapter.py:734` — гейт применяется к **любому** не-DM: ```python if channel_type_raw != "D": # тред = channel_type "O" → гейт срабатывает ... if require_mention and not is_free_channel and not has_mention: return # молча дроп, inbound не создаётся ``` **Доказательство (2026-09-29, канал `hermes-maintenance` = `a6nyh77eyjbn5c1owh1i8eebee`):** | Время | Пост | Меншн | inbound в gateway.log | |---|---|---|---| | 12:38:01 | `@whale` | ✅ | ✅ есть | | 12:38:40 | `тут, отлично. как нам сделать бэкап...` | ❌ | ❌ **нет** (ответа не было) | Пост 12:38:40 — в треде `pcoiddzrqty3ipqtozgcs9ttte`, начатом ботом. Меншн не нужен, но требуется. ## Решение Пропускать mention-гейт, когда пост находится **в треде** (`root_id` задан). В корне канала меншн остаётся обязательным. ### Критерий (выбран) **Тред = `root_id` непустой.** Просто, детерминированно, не требует API-запросов. Обоснование: чтобы ответить в треде, бот должен быть в канале. Треды канала — общие рабочие ветки; вовлечение в тред человеком = приглашение. Дополнительный критерий «бот уже отвечал в этом треде» требует запроса к API на каждое сообщение (латентность + зависимость от прав) и не даёт выигрыша: в канале бот и так отвечает на `@whale`. ### Правка В `_handle_ws_event` перед mention-гейтом вычислить `root_id` и добавить его в условие: ```python is_thread_reply = bool(post.get("root_id")) ... if require_mention and not is_free_channel and not has_mention and not is_thread_reply: return ``` Плюс: стрип меншна выполнять как раньше (если меншн есть — убрать из текста). ### Что НЕ меняется - Корень канала без `@whale` → по-прежнему молчит. - `MATTERMOST_FREE_RESPONSE_CHANNELS` — не трогаем. - DM — не затронуты. - `MATTERMOST_REQUIRE_MENTION=true` — остаётся. ## Шаги 1. Коммит ДО (`hermes-agent`, ветка `main`, HEAD `207a1de16c`). 2. Правка adapter.py — скрипт `python3 /tmp/.py`, не sed. 3. Тест: `pytest plugins/platforms/mattermost/ tests/ -k mattermost -o "addopts="` (если есть). 4. Коммит ПОСЛЕ. 5. Рестарт gateway — **делает Alex** (`gateway run --replace` из этой сессии её убьёт). 6. Приёмка Alex в UI: пост в треде без меншна → ответ есть; пост в корне канала без меншна → ответа нет. ## Питфоллы - 🔴 `gateway run --replace` из этой сессии убивает саму сессию (инцидент 2026-09-29 11:31). - 🔴 Логи читать из `~/.hermes/hermes-whale/logs/`, не из `~/.hermes/logs/`. - Адаптер читает `config.extra.*` ИЛИ env — при правке поведение env перебивает config (см. `_apply_yaml_config`, строки 1108-1114). - Логи уровня DEBUG не пишутся — `skipping non-DM message without @mention` в `gateway.log` не виден (`grep -c` вернул 0 при 1.6 МБ лога). Судить по наличию/отсутствию `inbound message`. ## Связанные заметки - [[personal/tech/hermes-whale-mattermost-transport.md]] — транспорт, env-ключи, инцидент с рестартом, диагностика «бот молчит в канале» - [[personal/tech/hermes-pairing-multi-profile.md]] — pairing