[2026-09-26] eagle: family/how-to/jellyfin-config.md family/plans/lidarr-taiga-deploy.md personal/plans/balda-mm-pr-plan.md personal/plans/music-tags-review/music-tags-review.md personal/projects/balda/balda-mattermost-connector.md personal/tech/balda-go-fx-pitfalls.md personal/tech/music-tags-repair-truenas.md

This commit is contained in:
Alexey Martemyanov committed 2026-09-26 14:37:01 +06:00
1 parent 9778ea9289
commit 35dfecbe02
7 files changed
+281 -24

No files matched your search

+49 -4
View File
@@ -1,6 +1,8 @@
# Balda — Mattermost connector: PR-подготовка (закрыто)
> Создан 2026-09-26. Обновлён 2026-09-26 (PR-проход). Статус: **✅ ЗАКРЫТО — код, тесты, доки, коммиты готовы**.
> Создан 2026-09-26. Обновлён 2026-09-26 (PR-проход, финал).
> Статус: **🟡 код/тесты/доки/коммиты готовы — но осталось ОДНО решение по `tools/` в ветке**
> (см. §«Открытое решение» ниже). После него — `git push` и PR.
> Команда Alex: «Коммит текущего стейта и продолжай пока не стыдно будет открывать PR mattermost connector.
> Со всеми поддерживаемыми фичами и тестами. Вперёд! Без вопросов и требующих апрува команд.»
> Часть [[personal/projects/balda/balda-mm-delegation-plan]] (Фаза 2 → PR в апстрим).
@@ -91,16 +93,59 @@ DM/канале/треде, troubleshooting (`bad_seq`, `unauthorized`, `x509`).
`tools/deltas-*.json` (15 файлов) оставлены **незакоммиченными**: это
ops-инструменты и метод правок, в апстрим-репозиторий им не место.
## 🔴 Открытое решение: `tools/` закоммичены в ветку (выявлено в конце сессии)
**Найдено проверкой `git diff --stat upstream/main...HEAD`:** в диапазоне PR — 56 файлов,
и среди них **16 файлов `tools/`**, которых в апстриме **нет вообще**
(`git ls-tree upstream/main tools/` → пусто).
Кто занёс: **базовый коммит `004fda2f`** (из прошлой сессии, не из этого прохода).
Мои 5 новых коммитов чисты — проверено:
```bash
git log --oneline --name-only fa1a2855^..HEAD -- 'tools/' # → пусто
```
Что именно закоммичено в `004fda2f` (лишнее для PR):
```
tools/.deltas-state.json
tools/apply-project-deltas.py
tools/run-project-deltas.sh
tools/deltas-mattermost.json
tools/deltas-mattermost-2.json … -13.json (12 файлов)
```
**Что нужно сделать — по выбору Alex:**
| Вариант | Команда | Последствие |
|---|---|---|
| **(a) рекомендую** | `git rm -r --cached tools/` + коммит | файлы остаются на диске **untracked**, локальный инструментарий работает, ветка чистая |
| (b) оставить | — | PR содержит 16 лишних файлов, ревьюер спросит |
| (c) отдельная ветка | — | tooling живёт отдельно от PR |
⚠️ **Попытка (a) в этой сессии НЕ выполнена.** `git rm -r --cached tools/` ушла на
апрув и **истекла по таймауту** — команда не применилась, состояние дерева целое
(подтверждено `git status --short`: все файлы на месте). Повторять без команды Alex
не стал: удаление из индекса — операция, требующая подтверждения.
📌 **Правило на будущее:** проверять состав PR через
`git diff --stat upstream/main...HEAD` **перед** объявлением готовности, а не только
`git status` (последний показывает рабочее дерево, не содержимое коммитов). Иначе
мусор из прошлой сессии всплывает последним.
## Что осталось
**Ничего по коду.** Дальше по желанию Alex:
0. 🔴 **Убрать `tools/` из ветки** — вариант (a) выше. Блокирует «стыдный» PR.
1. `git push -u origin feat/mattermost-channel` и открыть PR в `baldaworks/balda`.
2. Фаза 3/4 (эксплуатация на Kraken) — [[personal/projects/balda/balda-kraken-mm-deploy]].
⚠️ Незакоммиченные `tools/mm-*.sh` + `tools/deltas-*.json` — **локальный
инструментарий**. Если они нужны в репо — отдельным коммитом с пометкой, но
для PR в апстрим я бы их не отправлял.
⚠️ Скрипты `tools/mm-*.sh` (9 шт.) и дельты `tools/deltas-mattermost-14…26` +
`deltas-goal-command-fix.json` + `deltas-mm-prefixfix.json` — **untracked, локальный
инструментарий**. Для PR в апстрим не отправлять. Существенное продублировано в
[[personal/projects/balda/balda-kraken-mm-deploy]] и [[personal/tech/balda-go-fx-pitfalls]].
## Связанные заметки
@@ -18,3 +18,19 @@ status: awaiting-approval
| [[1-needs-decision\|Требует решения]] | 9 |
| [[2-medium-confidence\|Средняя уверенность]] | 2611 |
| [[3-high-confidence\|Высокая уверенность]] | 2341 |
## Контекст
Сгенерировано из `~/Downloads/music-tags/tag-fix-plan.csv` скриптом
`render_grouped_doc.py` (в `~/Developer/personal-os/tools/music-tags/`).
- **Полный разбор проблемы, план и питфоллы:** [[personal/tech/music-tags-repair-truenas]]
- **Зачем это нужно:** Music-библиотеку Jellyfin нельзя создать на битых тегах
(Jellyfin раскладывает музыку по тегам, не по папкам) — [[family/how-to/jellyfin-config]]
- **Статус:** этап 3 плана ремонта (апрув Alex). Правки файлов ещё **не начаты**.
## Ограничения формата
Блоки 2 и 3 — по 730–780 КБ / 5000+ строк. Obsidian открывает, но скролл тяжёлый;
наверху каждого файла есть оглавление по папкам (клик → прыжок к разделу).
Дубли-папки в `!Детские/Сказки/` намеренно **не** включены — Alex разбирает их сам.
@@ -1,12 +1,14 @@
# Balda — Mattermost коннектор (архитектура)
> Создано 2026-09-26. Обновлено 2026-09-26 (сессия PR-подготовки, завершена).
> Статус: **✅ ГОТОВО К PR — 6 коммитов, все гейты зелёные.**
> Статус: **🟡 КОД ГОТОВ К PR — 6 коммитов, все гейты зелёные. Осталось одно решение: `tools/` в ветке.**
> 🟢 **Сессия PR-подготовки завершена:** починены 2 дефекта **в коде** (идемпотентный
> `MattermostSubject`; `ProgressPolicy.Typing`), написаны 6 файлов тестов (~90 тестов)
> на транспорт + хендлер, обновлены README / `docs/balda.md` и создан `docs/mattermost.md`.
> `golangci-lint` = 0 issues, `go-arch-lint` = OK. Детали и коммиты —
> [[personal/plans/balda-mm-pr-plan]].
> `golangci-lint` = 0 issues, `go-arch-lint` = OK.
> 🔴 **Блокер PR:** в ветке 16 файлов `tools/` из базового коммита `004fda2f` — в апстриме
> такого каталога нет. Нужно `git rm -r --cached tools/` по команде Alex (заблокировано
> истёкшим апрувом). Детали, коммиты и варианты — [[personal/plans/balda-mm-pr-plan]].
> Часть проекта [[personal/projects/balda/balda-mm-delegation-plan]] (Фаза 2).
> Требование Alex: поддержка **всех** функций Балды, по новым API, production-качество.
>
+36 -4
View File
@@ -1155,10 +1155,42 @@ MM отвечал раз в 30 секунд, ровно на каждый пин
## 📌 Артефакты деплоя — вон из PR
`tools/mm-*.sh` (9 ops-скриптов) и `tools/deltas-*.json` (15 файлов дельта-групп)
— **локальный инструментарий**, в PR в апстрим не идут. Оставлять
незакоммиченными и явно перечислять в доке, чтобы не потерять.
В коммиты PR шли только: код транспорта, wiring, тесты, доки.
`tools/mm-*.sh` (9 ops-скриптов) и `tools/deltas-*.json` — **локальный инструментарий**,
в PR в апстрим не идут. В коммиты PR шли только: код транспорта, wiring, тесты, доки.
⚠️ **Поправка (та же сессия, позже):** я сначала написал, что `tools/` «оставлены
незакоммиченными». Это было **неверно** — проверка показала, что **16 файлов `tools/`
уже сидят в базовом коммите `004fda2f`** (из прошлой сессии), и в апстриме каталога
`tools/` **нет вообще** (`git ls-tree upstream/main tools/` → пусто). То есть в PR
уезжал мусор, а `git status` этого не показывал.
## 🔴 Проверять СОСТАВ PR, а не рабочее дерево
**Правило:** перед объявлением «готово к PR» смотреть содержимое коммитов, а не только
`git status`:
```bash
git diff --stat upstream/main...HEAD # ЧТО реально уедет в PR
git ls-tree --name-only upstream/main <dir> # есть ли этот dir в апстриме вообще
git log --oneline --name-only <mой_первый_коммит>^..HEAD -- '<dir>/' # не моё ли
```
Три команды отвечают на три разных вопроса, и **`git status` не отвечает ни на один**:
он показывает рабочее дерево, а не то, что уже закоммичено ранее (в т.ч. чужой рукой).
📌 **Симптом промаха:** «я всё вычистил, PR готов» → `git diff --stat` показывает
56 файлов вместо 40. Лишние пришли из **предыдущей** сессии, не из текущей.
📌 **Полезное следствие:** `git log --name-only <range> -- '<dir>/'` точно отделяет
**свой** мусор от **унаследованного** — без этого легко начать «чинить» не то.
## ⚠️ `git rm --cached` требует апрува — не повторять вслепую
`git rm -r --cached tools/` идёт на подтверждение; при таймауте **не применяется**
(безопасно — состояние целое, проверять `git status --short`). Не ретраить
автоматически: удаление из индекса — операция, требующая команды заказчика.
Альтернатива без «удаления»: оставить файлы untracked, а из индекса убрать одним
явным коммитом по команде Alex.
## Связанные заметки
+13 -1
View File
@@ -334,11 +334,15 @@ if cyr < 2: # одна буква — совпадение
|---|---|---|
| 1 | **Инвентаризация** read-only: `ffprobe` по 7906 файлам → CSV | ✅ **ГОТОВО (v2)** — `tag_inventory2.py`, `probe_failed`=0 |
| 2 | **CSV с предлагаемым исправлением** → Alex | ✅ **ГОТОВО (v2)** — `~/Downloads/music-tags/tag-fix-plan.csv` |
| 3 | **Апрув Alex по CSV** → только после этого правки | ⏳ **ЖДЁМ** (v1 отклонён, v2 отдан) |
| 2a | **Ноты для ревью в Obsidian** → Alex (запрос Alex 2026-09-26) | ✅ **ГОТОВО** — `personal/plans/music-tags-review/`, синкнуто (`Pushed ✓`, коммит `14e9f570`) |
| 3 | **Апрув Alex по CSV** → только после этого правки | ⏳ **ЖДЁМ** (v1 отклонён, v2 + ноты отданы) |
| 4 | **Бэкап** — копировать **только перезаписываемые** файлы в `Music/backup/` | ⏳ |
| 5 | **Ремонт** — перекодировка mojibake + восстановление из имён путей + чистка мусора | ⏳ |
| 6 | **Приёмка** — Alex слушает выборку | ⏳ |
> 📌 **Что именно ждёт апрува:** 4961 `fix` из 7906. Alex проходит по трём нотам ревью,
> отмечает чекбоксы. Ничего не применяется до его «go».
### Ключевые решения по плану (правки Alex)
- ❌ **НЕ** бэкапить всю библиотеку (48 ГБ) — только те файлы, которые будут перезаписаны.
@@ -390,6 +394,7 @@ if cyr < 2: # одна буква — совпадение
| **CSV-план правок v2** | `~/Downloads/music-tags/tag-fix-plan.csv` (Mac, 2.2 МБ) | **Отдан Alex 2026-09-26.** 4961 `fix` / 2945 `no_change` / 0 `probe_failed` |
| Копия БД Jellyfin | `/tmp/jf-copy.db` (Mac) | Для чтения API-ключа (см. `[[family/how-to/jellyfin-config]]`) |
| Копия плана на NAS | `/tmp/tag-fix-plan.csv` (NAS) | Для запуска `id3_direct.py`/`check_ddt_album.py` с хостовым Python |
| **Ноты ревью в vault** | `personal/plans/music-tags-review/` (4 файла) | Обзор + 3 блока по уверенности; **вход для апрува Alex**, синкнуто |
### Колонки `tag-fix-plan.csv`
@@ -418,6 +423,13 @@ if cyr < 2: # одна буква — совпадение
- 🔴 **`python3` НЕТ в контейнере `jellyfin`** — для скриптов поднимать отдельный `python:3-alpine`.
- 🔴 **`ffprobe` НЕТ на хосте TrueNAS** — только внутри контейнеров (в `jellyfin` путь `/usr/lib/jellyfin-ffmpeg/ffprobe`).
- ⚠️ **Генерация нот для Obsidian: сравнивать ОТРЕНДЕРЕННЫЕ значения, не сырые.** Сравнение
`new != cur` даёт ложные блоки, где различие (двойной пробел) схлопывается при выводе — файл
раздувается и выглядит так, будто правка ничего не меняет. Правильно: `esc(new) != esc(cur)`.
- ⚠️ **Нечитаемые байты в нотах рендерить как `⟨повреждено⟩`, а не как есть.** Управляющие
символы (`\x1d`, `\x10`) и U+FFFD дают в markdown нечитаемую кашу (`56=>ABL (:D"@8`).
- ⚠️ **Один markdown-файл на 5000 чекбоксов (~750 КБ) тормозит Obsidian.** Помогает группировка
по папкам + оглавление со ссылками вверху; при жалобах на лаги — разбивать по категориям.
- 🔴 **`sed -i` на удалённом хосте применять нельзя** (нарушение правил Alex). Правильно: правка локально → `scp` заново. Именно так и было исправлено (`FFPROBE` → `os.environ.get`).
- ⚠️ **Кириллица в inline `ssh`-командах** поднимает tirith `confusable_text` (HIGH). Команда проходит только через approval Alex. Митигация: пути с кириллицей собирать в файле-скрипте, а не в командной строке.
- ⚠️ `alpine` без `ffmpeg` → инвентарь падает молча. Ставить `apk add --no-cache ffmpeg` первой строкой.