docs(mm-transport): закрыт инцидент 2026-09-30 — root-post thread_id ломал session_key
This commit is contained in:
1 parent
bfd42631e2
commit
2a6cd95355
1 file changed
+78
-2
@@ -1,10 +1,10 @@
|
|||||||
---
|
---
|
||||||
title: hermes-whale — Mattermost как транспорт
|
title: hermes-whale — Mattermost как транспорт
|
||||||
created: '2026-09-29'
|
created: '2026-09-29'
|
||||||
updated: '2026-09-29'
|
updated: '2026-09-30'
|
||||||
type: tech
|
type: tech
|
||||||
namespace: personal
|
namespace: personal
|
||||||
status: транспорт+telegram+pairing+toolsets+рестарт ✅; 🔴 открыт инцидент — бот не в канале hermes-maintenance
|
status: "транспорт+telegram+pairing+toolsets+рестарт ✅; \U0001F534 фикс root-post thread_id 2026-09-30 (916f2c7e4f) — ЖДЁТ РЕСТАРТА gateway; \U0001F534 открыт инцидент — бот не в канале hermes-maintenance"
|
||||||
tags:
|
tags:
|
||||||
- hermes
|
- hermes
|
||||||
- mattermost
|
- mattermost
|
||||||
@@ -15,6 +15,7 @@ tags:
|
|||||||
- telegram
|
- telegram
|
||||||
- hermes-maintenance
|
- hermes-maintenance
|
||||||
- incident
|
- incident
|
||||||
|
- thread-session-split
|
||||||
related:
|
related:
|
||||||
- '[[personal/projects/balda/mattermost-kraken-deploy.md]]'
|
- '[[personal/projects/balda/mattermost-kraken-deploy.md]]'
|
||||||
- '[[personal/tech/kraken-host-resource-limits.md]]'
|
- '[[personal/tech/kraken-host-resource-limits.md]]'
|
||||||
@@ -325,6 +326,81 @@ ssh kraken "docker exec mm-postgres psql -U mmuser -d mattermost -t -c \"...\""
|
|||||||
| `memories/MEMORY.md` | 0 байт (глобальный fallback не используется) |
|
| `memories/MEMORY.md` | 0 байт (глобальный fallback не используется) |
|
||||||
| `memories/threads/<key>/MEMORY.md` | по тред-ключу |
|
| `memories/threads/<key>/MEMORY.md` | по тред-ключу |
|
||||||
|
|
||||||
|
## 🔴 Инцидент 2026-09-30 (ЗАКРЫТ): один тред разъезжался на две сессии
|
||||||
|
|
||||||
|
**Симптом Alex:** «Какой нахуй другой? Один блять тред!» —
|
||||||
|
писал в тред, получал ответ, а следующим сообщением в ТОМ ЖЕ треде —
|
||||||
|
«в этом треде до тебя ничего не было». Контекст пропадал.
|
||||||
|
|
||||||
|
### Причина (найдена в коде, воспроизведена тестом)
|
||||||
|
|
||||||
|
Первое сообщение **нового** треда — это его корень, у него `root_id == ""`.
|
||||||
|
`adapter.py` делал:
|
||||||
|
|
||||||
|
```python
|
||||||
|
thread_id = post.get("root_id") or None # -> None для корневого поста
|
||||||
|
```
|
||||||
|
|
||||||
|
Дальше `build_session_key` (`gateway/session.py:659`):
|
||||||
|
|
||||||
|
```python
|
||||||
|
if source.thread_id and not thread_sessions_per_user:
|
||||||
|
isolate_user = False # тред-ветка НЕ срабатывает при thread_id=None
|
||||||
|
...
|
||||||
|
if isolate_user and participant_id:
|
||||||
|
key_parts.append(str(participant_id)) # -> приклеивается USER_ID
|
||||||
|
```
|
||||||
|
|
||||||
|
| Сообщение | `root_id` | session_key |
|
||||||
|
|---|---|---|
|
||||||
|
| Корень треда (первое) | `""` | `...:chat:{user_id}` ← неверно |
|
||||||
|
| Ответ в треде | `17zbmoan...` | `...:chat:{thread_id}` ← верно |
|
||||||
|
|
||||||
|
Один тред → **два ключа** → две сессии. Пока в треде одно сообщение, всё ок;
|
||||||
|
как только приходит второе — агент в новой сессии, истории нет.
|
||||||
|
|
||||||
|
⚠️ **`cbwsorzwoigbtrdnteugnx4aqo` в session_key — это user_id админа, а не тред.**
|
||||||
|
Именно на этом я сначала ошибся: прочитал его как «другой тред».
|
||||||
|
Проверять структуру постов — `GET /api/v4/channels/{id}/posts`, а не глазами по логу.
|
||||||
|
|
||||||
|
### Фикс (коммит `916f2c7e4f`, hermes-agent, ветка main)
|
||||||
|
|
||||||
|
`plugins/platforms/mattermost/adapter.py:~864`:
|
||||||
|
|
||||||
|
```python
|
||||||
|
thread_id = post.get("root_id") or post_id or None
|
||||||
|
```
|
||||||
|
|
||||||
|
Свой `post_id` корневого поста = канонический `root_id` треда в Mattermost,
|
||||||
|
поэтому отправка через `_resolve_root_id` не ломается (при пустом `root_id`
|
||||||
|
она и так возвращает `post_id`).
|
||||||
|
|
||||||
|
### Тесты (`tests/gateway/test_mattermost.py`)
|
||||||
|
|
||||||
|
Добавлены 2 регресс-теста. **Проверено, что падают на нефикшеном коде:**
|
||||||
|
|
||||||
|
```
|
||||||
|
- agent:main:mattermost:channel:chan_456:root_post_abc <- после фикса
|
||||||
|
+ agent:main:mattermost:channel:chan_456:user_123 <- что было
|
||||||
|
```
|
||||||
|
|
||||||
|
| Прогон | Результат |
|
||||||
|
|---|---|
|
||||||
|
| `test_mattermost.py` (48) | 48 passed |
|
||||||
|
| + `test_session.py`, `test_ws_auth_retry.py`, `test_base_topic_sessions.py` (138) | 138 passed |
|
||||||
|
| `tests/gateway/` целиком | ⚠️ 413 failed / 2294 errors — **предсуществующий мусор**, на baseline (stash фикса) 464 failed / 2144 errors. К правке отношения не имеет. Не гонять полный `tests/gateway/` как критерий. |
|
||||||
|
|
||||||
|
### 📌 Питфолл: session_key ≠ тред
|
||||||
|
|
||||||
|
`agent:main:mattermost:channel:{chat_id}:{thread_id}`. Если последний сегмент
|
||||||
|
выглядит как id пользователя — значит `thread_id` не долетел.
|
||||||
|
**Не считать это другим тредом.**
|
||||||
|
|
||||||
|
### 📌 Питфолл: полный прогон `tests/gateway/` бесполезен
|
||||||
|
|
||||||
|
456+ ошибок на чистом дереве — конфликт фикстур/состояния при параллельном
|
||||||
|
сборе. Гонять **только целевые файлы**, иначе результат нечитаем.
|
||||||
|
|
||||||
## 🔴 Питфоллы, найденные на месте
|
## 🔴 Питфоллы, найденные на месте
|
||||||
|
|
||||||
1. **`mmctl user convert --bot` требует ШЕСТЬ флагов, не один.**
|
1. **`mmctl user convert --bot` требует ШЕСТЬ флагов, не один.**
|
||||||
|
|||||||
Reference in new issue
Block a user