[2026-09-26] eagle: personal/plans/balda-mm-endtoend-plan.md personal/projects/balda/balda-kraken-mm-deploy.md personal/tech/balda-go-fx-pitfalls.md

This commit is contained in:
Alexey Martemyanov committed 2026-09-26 14:01:35 +06:00
1 parent f9b55abb8c
commit aefc2f9095
3 files changed
+318 -30

No files matched your search

@@ -1,10 +1,12 @@
# Фаза 3 — Балда на Kraken + Mattermost (деплой)
> Создан 2026-09-26. Обновлён 2026-09-26 (сессия реализации: `bad_seq`, MM-хендлер,
> привязка владельца, правки провайдера, **приёмка**).
> Статус: **✅ ФАЗА 3 ЗАКРЫТА. Сквозной путь `@balda` → ответ в UI работает и принят
> (образ `0.1.8`). Все шесть причин устранены и проверены. Push-уведомления —
> 🔴 невозможны на Team Edition, диагноз снят и задокументирован.**
> привязка владельца, правки провайдера; **🔴 статус приёмки ИСПРАВЛЕН**).
> Статус: **🔴 ФАЗА 3 НЕ ЗАКРЫТА. Бот отвечает `testuser`, но НЕ отвечает Alex.**
> Причина — аккаунт Alex не привязан как владелец (`unauthorized`); в `balda_user_bindings`
> владельцем сидит мой тестовый `testuser`. Alex: «Нихуя он мне не отвечает в ММ.
> Не готово!!» Образ `0.1.8`, все шесть технических причин устранены — осталась привязка
> аккаунта Alex (причина №7). Push-уведомления — 🔴 невозможны на Team Edition.
> Подробный план и фактические изменения — [[personal/plans/balda-mm-endtoend-plan]].
> Питфоллы и метод — [[personal/tech/balda-go-fx-pitfalls]].
> Часть проекта [[personal/projects/balda/balda-mm-delegation-plan]].
@@ -13,9 +15,56 @@
---
## ✅ ИТОГ (2026-09-26): бот работает, приёмка пройдена
## 🔴 СТАТУС: НЕ ГОТОВО — бот не отвечает аккаунту Alex
Лента канала `balda-test` (`7bjw4g7o1jdsbmjbqd649xxgaw`) — REST `GET /channels/{id}/posts`:
🔴 **Предыдущая запись «ИТОГ: бот работает, приёмка пройдена» была ЛОЖНОЙ.** Сквозной путь
проверялся от `testuser` (аккаунт, созданный для тестов), и именно `testuser` оказался
привязан владельцем. Alex пишет `@balda привет` — в логе `settlement_stage="unauthorized"`.
**Актуальная лента канала `balda-test` (`7bjw4g7o1jdsbmjbqd649xxgaw`):**
```
1790409344288 | cbwsorzwoigbtrdnteugnx4aqo | @balda привет ← Alex, БЕЗ ответа
1790409329367 | cbwsorzwoigbtrdnteugnx4aqo | Привет ← без @balda, отброшен намеренно
1790409148277 | edxrgupoxiyg5gzmr79tjypbme | работает ← ответ бота (testuser)
1790409145401 | c6udeze8dfrdxm5jbgq55bd58r | @balda reply with a single word
```
**Лог на пост Alex:**
```json
{"component":"balda.handlersfx.mattermost",
"inbound_id":"mattermost:dqagqce7pibiipt3qtqnkgfd8c",
"settlement_outcome":"terminal","settlement_stage":"unauthorized"}
```
**Корень (причина №7):** `balda_user_bindings` содержит одну строку —
`mattermost | c6udeze8dfrdxm5jbgq55bd58r` = **`testuser`**. Аккаунт Alex —
`cbwsorzwoigbtrdnteugnx4aqo` (`admin`, `system_admin`) — **в таблице отсутствует**.
`IsOwnerSubject` ищет строго по `(channel_type='mattermost', principal=<mm_user_id>)` →
для Alex пары нет → все проверки авторизации false.
📌 **Урок приёмки (durable): проверять ОТ ИМЕНИ ЗАКАЗЧИКА.** Сквозной путь,
подтверждённый чужим тестовым аккаунтом, — это НЕ приёмка. Если владелец — Alex,
тест обязан идти с его MM user_id. Подробный разбор замкнутого круга привязки —
[[personal/plans/balda-mm-endtoend-plan]] §«ПОЧЕМУ НЕ РАБОТАЕТ У ALEX».
**Остаток работы — одна строка в БД** (ожидает апрува Alex):
```sql
UPDATE balda_user_bindings
SET principal = 'cbwsorzwoigbtrdnteugnx4aqo',
display_name = 'mattermost:cbwsorzwoigbtrdnteugnx4aqo'
WHERE channel_type = 'mattermost'
AND principal = 'c6udeze8dfrdxm5jbgq55bd58r';
```
+ бэкап `state.db` с `-wal` до правки; + правка кода `handler.go:420` (двойной префикс,
см. §«Причина №7» в плане) и пересборка `0.1.9`, чтобы дефект не вернулся.
---
## 📋 ИСТОРИЯ: что реально работало (образ `0.1.8`, от `testuser`)
Лента канала `balda-test` на момент тестов от `testuser` — REST `GET /channels/{id}/posts`:
```
c6udeze8dfrdxm5jbgq55bd58r (testuser) | @balda reply with a single word
@@ -194,34 +243,42 @@ default-ветку — `/start` работает с MM без правок.
---
## ✅ Привязка владельца — ВЫПОЛНЕНА (2026-09-26)
## ✅ Привязка владельца — ВЫПОЛНЕНА, но ПРИВЯЗАН НЕ ТОТ АККАУНТ (2026-09-26)
Авторизация Balda — **subject-based**: владелец в `canonical` store привязан строкой
`<channel>:<principal>`. Для MM `channel_type='mattermost'`, `principal=<mm_user_id>`
**без** транспортного префикса.
**Итоговое состояние `balda_user_bindings`:**
**Итоговое состояние `balda_user_bindings` (актуальное):**
```
binding_id d2006cd1-3337-4159-883b-fcb90c6e9be2
user_id b6517e56-1110-4cb9-a301-302c585fbd0d ← администратор
channel_type mattermost
principal c6udeze8dfrdxm5jbgq55bd58r ← testuser, БЕЗ префикса
principal c6udeze8dfrdxm5jbgq55bd58r ← 🔴 testuser, НЕ аккаунт Alex
display_name mattermost:mattermost:c6udeze8… ← 🔴 мусор, двойной префикс остался
provenance verified-owner-onboarding
```
**Как это делалось (порядок, который сработал):**
🔴 **Это и есть причина, почему Alex не получает ответов.** Привязка сделана от
`testuser` — аккаунта, созданного мной для тестов. Аккаунт Alex
(`cbwsorzwoigbtrdnteugnx4aqo`) не привязан. Требуется `UPDATE` (см. §«СТАТУС» вверху).
⚠️ `display_name` с двойным префиксом — след того же дефекта кода (`handler.go:420`).
В прошлой сессии я поправил `principal` прямой правкой БД, но **не код**, поэтому мусор
в `display_name` и `created_by` channel-токенов остался, а дефект воспроизводится.
🔴 **Правило: чинить в коде, а не в данных.**
**Как привязка делалась (порядок, который сработал для первого аккаунта):**
1. `/start owner=<owner_auth_token>` **в DM** — команда `/start` работает только при
`Direct=true`, в канале отбивается. Скрипт `tools/mm-owner-bind.sh <user> <pass> <token>`:
логин → `POST /api/v4/channels/direct` с `[<my_id>, <bot_id>]` → `POST /api/v4/posts`
с текстом `/start owner=<token>`.
2. Получить токен:
2. Получить токен из `state.db`:
```bash
ssh kraken '/tmp/mm-owner-token.sh' # strings + sed по state.db под sudo -n
# или вручную:
ssh kraken 'sudo -n strings /srv/…-49e8f586…/docker/balda/state/state.db \
| grep -o "appowner_auth_token.\{0,45\}"' </dev/null
sqlite3 "$DB" "SELECT value_json FROM balda_app_kv WHERE key='owner_auth_token';"
# или: sudo -n strings …/state/state.db | grep -o "appowner_auth_token.\{0,45\}"
```
⚠️ Значение токена в доке **не хранится** — только способ получения.
3. 🔴 Первая попытка дала **«You are not allowed to use Balda in this channel.»** —
@@ -235,7 +292,7 @@ provenance verified-owner-onboarding
---
## Текущее состояние (2026-09-26, ФАЗА ЗАКРЫТА)
## Текущее состояние (2026-09-26, 🔴 ФАЗА НЕ ЗАКРЫТА)
| Компонент | Статус |
|---|---|
@@ -248,15 +305,17 @@ provenance verified-owner-onboarding
| Причина «bad_seq» (дельта 16) | ✅ **исправлена, проверена** |
| Причина «Processor==nil» (дельты 17-19) | ✅ **исправлена, доказана логом** |
| Причина «`/start` закрыт доступом» | ✅ **исправлена** |
| Причина «`principal` с префиксом» | ✅ **исправлена, авторизация проходит** |
| Причина «`principal` с префиксом» | ⚠️ **исправлена в БД, НО НЕ В КОДЕ** — дефект воспроизвёлся (см. причину №7) |
| Причина «провайдер `base_url` + CA» (дельта 22) | ✅ **исправлена, ПРОВЕРЕНА** |
| **Ответ бота в UI** | ✅ **ПОДТВЕРЖДЁН — бот ответил `работает` в `balda-test`** |
| **Ответ бота аккаунту Alex** | 🔴 **НЕ РАБОТАЕТ — `unauthorized`. Аккаунт Alex не привязан** |
| Ответ бота `testuser` | ✅ работает (это НЕ приёмка — чужой аккаунт) |
| Push-уведомления | 🔴 **невозможны на Team Edition** — диагноз снят, см. §Push ниже |
| MM-хендлер `handlersfx/mattermost_ingress.go` | ✅ написан, подключён в DI |
| Quality gates (build/vet/arch-lint) | ✅ все зелёные |
✅ **Приёмка пройдена: ответ бота виден в UI Mattermost** (проверено REST-чтением ленты,
`user_id` автора = бот). Фаза 3 закрыта.
🔴 **НЕ приёмка.** Требуется: привязать аккаунт Alex (`UPDATE balda_user_bindings`),
затем проверить `@balda привет` **от его аккаунта** и увидеть ответ в ленте канала.
Правку кода (`handler.go:420`) сделать в том же заходе — иначе двойной префикс вернётся.
---