[2026-09-29] eagle: personal/tech/hermes-memory-architecture.md personal/tech/hermes-whale-mattermost-transport.md

This commit is contained in:
Alexey Martemyanov committed 2026-09-29 12:35:57 +06:00
1 parent 6337fa0479
commit b30684ecfb
2 files changed
+132 -2

No files matched your search

@@ -106,6 +106,45 @@ find ~/.hermes/hermes-whale/memories -type f -name "*.md"
# Редактировать prompt (через patch или write_file)
```
## 🔴 Лимиты и падение агента (наблюдение 2026-09-29)
**Симптом:** агент не отвечает в треде, в `errors.log` — серия:
```
Tool memory returned error: Memory at 2,899/3,000 chars.
Adding this entry (781 chars) would exceed the limit. Replace or remove existing entries first.
[Tool loop warning: same_tool_failure_warning; count=3; memory]
```
Итог: агент зацикливается на попытках записать факт и **не доходит до ответа**.
### Ключевой факт: USER.md — всегда глобальный
`_path_for("user")` → `memories/USER.md` **всегда**, независимо от `thread_key`.
В `threads/` уходит только `MEMORY.md`. Следствие: **забитый USER.md бьёт по всем
тредам одновременно** — `thread_scoped: true` от него не защищает.
| Файл | Лимит (конфиг) | Значение 2026-09-29 |
|---|---|---|
| `memories/USER.md` | `user_char_limit: 1375` | 2295 байт → **уже переполнен** |
| `memories/threads/<key>/MEMORY.md` | `memory_char_limit: 3000` | по треду |
| `memories/MEMORY.md` (fallback) | `memory_char_limit: 3000` | 0 байт |
⚠️ Расхождение лимитов: `user_char_limit: 1375` против `memory_char_limit: 3000`.
Сообщение об ошибке упоминает 3000 — **это лимит MEMORY.md, не USER.md**; при
диагностике смотреть оба значения в `config.yaml`.
### Диагностика
```bash
# размеры
wc -c ~/.hermes/hermes-whale/memories/USER.md ~/.hermes/hermes-whale/memories/MEMORY.md
# где именно падает
grep -n "memory returned error" ~/.hermes/hermes-whale/logs/errors.log | tail -10
```
**Лечение:** сжать USER.md (слить дубли, убрать устаревшее) до <1375, либо поднять
`user_char_limit` в `config.yaml`. Правка `config.yaml` — только скриптом с
YAML-roundtrip-валидацией (прямой `patch`/`write_file` заблокирован харнессом).
## Связанное
- [[thread-scoped-memory]] — план реализации.
@@ -4,7 +4,7 @@ created: '2026-09-29'
updated: '2026-09-29'
type: tech
namespace: personal
status: done except gateway restart — transport + telegram + pairing + toolsets committed 04fdb8b
status: транспорт+telegram+pairing+toolsets+рестарт ✅; 🔴 открыт инцидент — бот не в канале hermes-maintenance
tags:
- hermes
- mattermost
@@ -13,10 +13,13 @@ tags:
- kraken
- lsp
- telegram
- hermes-maintenance
- incident
related:
- '[[personal/projects/balda/mattermost-kraken-deploy.md]]'
- '[[personal/tech/kraken-host-resource-limits.md]]'
- '[[personal/tech/hermes-fork-vs-upstream.md]]'
- '[[personal/tech/hermes-memory-architecture.md]]'
---
# hermes-whale — Mattermost как транспорт
@@ -28,7 +31,9 @@ related:
> Telegram ✅ — токен MAIN в `.env`, платформа включена Alex'ом.
> Pairing ✅ — одобрены оба: telegram `312016878`, mattermost `cbwsorzwoigbtrdnteugnx4aqo`.
> LSP ✅ выключен. Права (toolsets) ✅ прописаны и закоммичены (`04fdb8b`).
> ⛔ **Остаток: рестарт gateway** — без него toolsets не подхватятся.
> **Рестарт gateway ✅ сделан** (2026-09-29 12:29, `✓ mattermost connected`).
> ⛔ **Остаток:** бот `whale` не добавлен в канал `hermes-maintenance` — см.
> §Инцидент 2026-09-29 ниже. Фикс: `mmctl --local channel add qentra:hermes-maintenance whale`.
## Расклад (решение)
@@ -194,6 +199,92 @@ top-level ключ), 3. вставляет новый под-блок, 4. **ва
⚠️ В коммит **не попали** `.env` (credential store — там `MATTERMOST_*` и
`TELEGRAM_BOT_TOKEN`) и посторонние правки дерева (`SOUL.md`, `memories/*`, `../skills/*`).
## 🔴 Инцидент 2026-09-29 (после рестарта): бот не отвечает в канале `hermes-maintenance`
**Симптом Alex:** «Почему в треде Hermes maintenance не отвечаешь?»
**Причина — бот НЕ член канала.** Канал создан Alex'ом, посты пишутся, но WS-события
боту не доставляются, поэтому в `gateway.log` ноль inbound из канала.
| Объект | Значение |
|---|---|
| Канал | `hermes-maintenance` / **Hermes maintenance** |
| Channel ID | `a6nyh77eyjbn5c1owh1i8eebee` |
| Team | `qentra` |
| Тип | `O` (public) |
| Члены по базе | **только `admin`** ← вот причина |
| Бот `whale` | `k4i3uihzp3gdxj5gx3en3tbeso` |
### Доказательство (база MM на Kraken, контейнер `mm-postgres`)
```bash
ssh kraken "docker exec mm-postgres psql -U mmuser -d mattermost -t -c \
\"SELECT u.username FROM channelmembers cm JOIN users u ON cm.userid=u.id \
WHERE cm.channelid='a6nyh77eyjbn5c1owh1i8eebee';\""
# → admin (бота нет)
ssh kraken "docker exec mm-postgres psql -U mmuser -d mattermost -t -c \
\"SELECT to_char(to_timestamp(p.createat/1000),'HH24:MI:SS'), u.username, LEFT(p.message,60) \
FROM posts p JOIN users u ON p.userid=u.id \
WHERE p.channelid='a6nyh77eyjbn5c1owh1i8eebee' ORDER BY p.createat;\""
# → 12:30:12 admin admin joined the channel.
# 12:30:24 admin @whale тут?
# 12:30:41 admin @whale
```
В `~/.hermes/hermes-whale/logs/gateway.log` за 12:30 — только `platform=mattermost`
DM-сообщения (`chat=ic7g837ns7fmbr896gi357c8ic`), **ни одного из канала**.
### Диагностический рецепт (когда «бот молчит в канале»)
1. Есть ли канал в базе и кто в `channelmembers` — запрос выше.
2. Есть ли inbound в `gateway.log` (`grep "inbound message" | grep mattermost`).
Нет inbound → проблема доставки, не агента.
3. Проверить `MATTERMOST_REQUIRE_MENTION` — при `true` бот в каналах слушает только `@whale`.
Обходной путь для канала без обязательного упоминания: `MATTERMOST_FREE_RESPONSE_CHANNELS`.
4. Если канал есть, bot в members, inbound есть, а тишина — смотреть `errors.log`
на `Unauthorized user` (allowlist) и на лимит `memory`.
### Фикс (выполнить)
```bash
# на Kraken: добавить бота в канал
mmctl --local channel add qentra:hermes-maintenance whale
# проверка
ssh kraken "docker exec mm-postgres psql -U mmuser -d mattermost -t -c \
\"SELECT u.username FROM channelmembers cm JOIN users u ON cm.userid=u.id \
WHERE cm.channelid='a6nyh77eyjbn5c1owh1i8eebee';\""
# ожидаем: admin + whale
```
⚠️ Без членства в канале `@whale` не работает даже при `REQUIRE_MENTION=true` —
упоминание не создаёт доставку, оно лишь фильтр поверх уже приходящих событий.
### 📌 Питфолл диагностики: `mattermost psql`
В контейнере `mattermost` **нет `psql`** (`exec: "psql": executable file not found`).
База живёт в отдельном контейнере **`mm-postgres`** (`postgres:16-alpine`):
```bash
ssh kraken "docker exec mm-postgres psql -U mmuser -d mattermost -t -c \"...\""
```
### Второй симптом той же минуты: лимит памяти
Параллельно в `errors.log` 12:00–12:28 — серия падений `memory`:
`Memory at 2,899/3,000 chars. Adding this entry … would exceed the limit`
→ `[Tool loop warning: same_tool_failure_warning; count=3; memory]`, агент зацикливался
и не доходил до ответа.
⚠️ **`USER.md` всегда глобальный** (`memories/USER.md`), в `threads/` не уходит —
поэтому забитый USER.md бьёт по ВСЕМ тредам сразу, независимо от `thread_scoped`.
Лимит проверять по `memories/USER.md`, а не по `MEMORY.md`.
| Файл | Размер на 2026-09-29 |
|---|---|
| `memories/USER.md` | 2295 байт (лимит 3000) |
| `memories/MEMORY.md` | 0 байт (глобальный fallback не используется) |
| `memories/threads/<key>/MEMORY.md` | по тред-ключу |
## 🔴 Питфоллы, найденные на месте
1. **`mmctl user convert --bot` требует ШЕСТЬ флагов, не один.**