diff --git a/family/how-to/navidrome-truenas-android.md b/family/how-to/navidrome-truenas-android.md index 2f3d8595..65c45aed 100755 --- a/family/how-to/navidrome-truenas-android.md +++ b/family/how-to/navidrome-truenas-android.md @@ -206,6 +206,29 @@ folder="!Pop, Club, Любэ/Дискотека Авария/Москва пьё | `album` пустой | **0** | | `media_file` всего | **8043** | +### 🔴 КОРЕНЬ `(Авария)`: не граббер, а ДЕФЕКТ-КЛАСС ПЛАНА (уточнено, сессия 18) + +**Первая версия этой заметки сказала «виноват mp3-граббер». Уточнение: граббер — источник +мусора в тегах, но ЧИНИТЬ его должен был план — и не починил.** + +Полный разбор — [[personal/plans/music-artist-albumartist-repair]] §СЕССИЯ 18. Кратко: + +| | Факт | +|---|---:| +| `new_album == cur_album` (оставлено как есть) | **6202 из 7861 (79%)** | +| из них `album` в скобках | **306** | +| Источник скобочного мусора в тегах | mp3-граббер `rmp.ru` | + +**Механика дефекта:** план копировал `cur_album` в `new_album` при **непустом** значении — +без проверки смысла. Валидатор считал ПУСТЫЕ, а не мусорные. Дифф планов мусор не поймал, +потому что стоял в обеих версиях («совпало»). + +> 🔴 **Правило для будущих ревизий: дифф двух планов ≠ валидатор значений.** +> Нужен отдельный валидатор **смысла** (паттерны: `^\(.+\)$`, заглушки, спам-URL) — в пайплайне его нет. + +**Полный список оставленных значений:** `~/Downloads/music-tags/REPORT-new-album-equals-cur.csv` +(6202 строки, группировка папка → значение → count). + ### ⚠️ КОНФЛИКТ ПРАВИЛА: `album = имя папки` ломает эту категорию Правило Alex (v8 плана ремонта): «`album` для сборников и unsorted → **ИМЯ ПАПКИ**». diff --git a/personal/plans/music-artist-albumartist-repair.md b/personal/plans/music-artist-albumartist-repair.md index 947576a5..8a9ba42e 100755 --- a/personal/plans/music-artist-albumartist-repair.md +++ b/personal/plans/music-artist-albumartist-repair.md @@ -22,6 +22,94 @@ related: status: session17-gluefix-applied-image-deployed-dryrun-ok-awaiting-apply-go # Music `artist` + `albumartist` Repair — правила Alex и ход работ +## 🟣 СЕССИЯ 18 (2026-09-27) — NAVIDROME РАЗВЁРНУТ, ВСКРЫТ ДЕФЕКТ-КЛАСС «ОСТАВЛЕНО КАК ЕСТЬ» + +> **Контекст:** Navidrome поднят и просканировал библиотеку (8043 трека). Alex открыл UI и +> спросил: «**Откуда альбомы в скобках взялись?** Типа `Дискотека Авария` — для корня, +> а `(Авария)` — откуда??» → затем «**Как так получилось что что-то было оставлено?**» +> +> 🔴 **МЕТОД-УРОК:** я дважды ошибся в диагностике, прежде чем дать верный ответ: +> 1. Сказал «Navidrome сам собрал `(Авария)`» → **неверно**, `ffprobe` показал +> `TAG:album=(Авария)` — это реальный тег в файле. +> 2. Полез искать скрипт построения диффа **на NAS** → Alex: «**Ты дебил блядь?! На маке!!**» +> Скрипт лежит в `~/Automation/music-tags/diff_apply_vs_tagfixplan.py` — **все артефакты +> плана живут на МАКЕ** (`~/Downloads/music-tags/`, `~/Automation/music-tags/`), +> на NAS только боевой `apply-plan.csv` для контейнера. +> +> **Правило: артефакты планирования ищутся на маке. NAS — только то, что читает контейнер.** + +### 🔴 ДЕФЕКТ-КЛАСС: `new_album` наследует `cur_album` без валидации смысла + +**Масштаб (факт по `~/Downloads/music-tags/APPLY-PLAN.csv`):** + +| | Строк | +|---|---:| +| Всего в плане | 7861 | +| **`new_album == cur_album` (оставлено как есть)** | **6202 (79%)** | +| `new_album != cur_album` (изменено) | 1659 | + +**Механика:** план заполнял `new_album` копией `cur_album`, если значение **непустое**. +Правило было буквальное «если `album` есть — оставить», и оно копировало содержимое диска +в целевое поле **без проверки смысла**. Три шага пропустили мусор: + +| Шаг | Что проверял | Почему пропустил | +|---|---|---| +| Генератор плана | непустоту | `(Авария)` непустое → прошло | +| Валидатор | `пустых 0` | считал ПУСТЫЕ, а не мусорные | +| `diff_apply_vs_tagfixplan.py` | `new_album` плана vs `new_album` базы 38-го прогона | мусор стоял **в обоих** → «совпало», 0 расхождений | + +> 🔴 **Ключевой вывод:** **дифф двух планов НЕ является валидатором значений.** +> Если мусор унаследован из источника, он присутствует в обеих версиях и дифф его не покажет. +> Сравнение планов ловит *изменения*, а не *правильность*. Для правильности нужен +> отдельный валидатор **смысла** значения (паттерны мусора), которого в пайплайне НЕТ. + +### Явный мусор в `album` — что именно оставлено + +**`album` в скобках, 306 треков** (все `new_album == cur_album`, т.е. не чинились): + +| Папка | Оставленное значение | Треков | +|---|---|---:| +| `!Барды/Владимир Высоцкий/Филосовские` | `(Философские)` | 97 | +| `!Барды/Владимир Высоцкий/Разное` | `(Высоцкий - Разное)` | 44 | +| `!Барды/Владимир Высоцкий/Блатные` | `(Блатные)` | 42 | +| `!Барды/Владимир Высоцкий` (корень) | `(Высоцкий)` | 24 | +| `!Барды/Владимир Высоцкий/Морские` | `(Морские)` | 17 | +| `!Барды/Владимир Высоцкий/Из сказок` | `(Из Сказок)` | 16 | +| `!Барды/Владимир Высоцкий/Спортивные` | `(Спортивные)` | 14 | +| `!Pop, Club, Любэ/Дискотека Авария/Москва пьёт пиво` | `(Авария)` | 17 | +| `!Retro` | `(Авария)` | 4 | +| `!Retro/Забугр` | `(Вилли Токарев)` | 1 | + +**Прочие классы мусора, оставленного как есть:** + +| Папка | Значение | Проблема | +|---|---|---| +| `!Rock&Folk/Агата Кристи/9999 - Разное/Кавер-версии и пародии` | `исполняет М.Шац`, `исполняет ОСП`, `Slot 1`, `Раритетный` | это не названия альбомов | +| `!Retro/Забугр` | `нет альбома` | заглушка словами (ср. класс «заглушки» из v9) | +| `!Rock&Folk/Звери/Никто не круче` | 11x `Когда мы вместе никто не круче` + 2x `Никто не круче` | один альбом под двумя именами | +| `!Pop, Club, Любэ/Дискотека Авария/2006 - Четверо парней` | 16x `Четверо парней` + 1x `Четверо Парней` | регистр | +| `!Rock&Folk/Король и Шут/2004 - Бунт на корабле` | 12x `Бунт на корабле` + 3x `Бунт на Корабле` | регистр | +| `!Pop, Club, Любэ/Benassi Bros/Re Sfaction` | 13x `Re Sfaction` + 2 чужих альбома | файлы не того альбома | + +**Источник `(Авария)` — mp3-граббер** (`TAG:comment=This File from http://rmp.ru`). + +### ✅ Артефакт (создан по требованию Alex «Полный список папок и значений мне сюда готовь!») + +| Файл | Что | +|---|---| +| `~/Downloads/music-tags/REPORT-new-album-equals-cur.csv` | **6202 строки**: `folder, album_kept, count, path, title, artist, albumartist, genre` | +| `/tmp/report_kept_album.py` | генератор отчёта (группировка папка → значение → count) | + +### ⏭ Что нужно решить (ждёт Alex) + +1. **Валидатор смысла `new_album`** — паттерны: огрызок в скобках `^\(.+\)$`, заглушки + (`нет альбома`, `NULL`, `no title`, `Album`, `Non spécifié`), спам-URL. **В пайплайне его нет.** +2. Для 306 «скобочных» — какой `album` ставить: реальное название из внешнего источника, + имя подпапки, или имя папки артиста. +3. Регистровые дубли (`Четверо Парней`/`Четверо парней`, `Бунт на Корабле`) — канонизация. + +--- + ## 🔵 СЕССИЯ 17 (2026-09-27) — ПОВТОРНЫЙ РУЧНОЙ ПРОХОД ДИФФА, ЧИТАТЬ ПЕРВЫМ > ```