diff --git a/personal/plans/music-artist-albumartist-repair.md b/personal/plans/music-artist-albumartist-repair.md index 4b25ac1c..04953d43 100755 --- a/personal/plans/music-artist-albumartist-repair.md +++ b/personal/plans/music-artist-albumartist-repair.md @@ -4,7 +4,7 @@ created: '2026-09-27' updated: '2026-09-27' type: plan namespace: personal -status: БОЕВОЙ-ПРОГОН-ВЫПОЛНЕН / TCON-4359-ЗАПИСАН / BD-ПЕРЕСОЗДАНА / бага-генератора-НАЙДЕНА-20-файлов +status: БОЕВОЙ-ПРОГОН-ВЫПОЛНЕН / TCON-4359-ЗАПИСАН / BD-ПЕРЕСОЗДАНА / 2-баги-вскрыты / ПЛАН-v4-ТРЕБУЕТСЯ tags: - music - metadata @@ -54,19 +54,28 @@ related: Решение Alex: **полный набор**, дифф не пересобираем; требование «совпасть по цифрам с APPLY-PLAN-v3-changes» снято самим Alex (дифф = ГРУППЫ, прогон = ФАЙЛЫ). -⏳ **Осталось (27 сен, сессия ~32):** -1. 🔴 **БАГА ГЕНЕРАТОРА ПЛАНА НАЙДЕНА — задето 20 файлов (не 1!).** Alex: «ищи багу в скрипте - который собирал csv». Найдено: `/tmp/make_applyplan_v3.py` строки 148-154 — правила +⏳ **Осталось (27 сен, сессия ~33) — ЧЕТЫРЕ ЗАДАЧИ ОТ ALEX, план v4 НЕ СОБРАН:** +1. 🔴 **БАГА №1 генератора** — `/tmp/make_applyplan_v3.py` строки 148-154: правила `album==title` / `album==имя-файла` проверяются на **`new_*`**, а должны на **`cur_*`**. - Настоящий альбом, совпавший с названием трека, объявляется мусором и затирается **именем папки**. - Птаха — только первый симптом. **Фикс НЕ применён.** Полный разбор → § КОРЕНЬ ДЕФЕКТА ПТАХИ. -2. Приёмка в UI Navidrome (альбомы/жанры без дублей). + Задето **20 файлов** (Птаха — симптом №1). Разбор → § КОРЕНЬ ДЕФЕКТА ПТАХИ. +2. 🔴 **БАГА №2 генератора — КАТЕГОРИЯ `z Другое, Enigma, Ленинград` НЕ СРЕЗАЕТСЯ.** + В `CATEGORY_DIRS` строка набрана в СМЕШАННОЙ раскладке → `norm()` не совпадает → + `stripped=False` → правило корня выключено для **~900 файлов** (Ленинград, Сектор Газа, + Красная Плесень, Enigma, Pushnoy.ru). Именно поэтому «Тема дороги» не попала в альбом. + Разбор → § БАГА №2 — КАТЕГОРИЯ Z ДРУГОЕ. +3. **Трофим** — исполнитель `Трофим` → **`Сергей Трофимов`** (199 `new_artist` + 207 `album_artist`); + альбомы `01..04 Аристократия помойки` → без цифрового префикса (58 файлов); + **дубли альбома снести** (копии в `disk/` + `disk_v2/` Alex велел НЕ трогать — живут в сборниках). +4. **Птаха** — 1 файл `new_album` → `Красивые, богатые`. + +⚠️ **Три вопроса к Alex ОТКРЫТЫ** (без них план v4 не собрать) → § ВОПРОСЫ К ALEX. ``` Navidrome БД: /mnt/RED_2TB/docker/navidrome/data/ ← БЕЗ storage/ (дока ранее врала) compose: /mnt/RED_2TB/docker/navidrome пересоздание: docker compose stop → rm data/navidrome.db{,-shm,-wal} → docker compose up -d бэкап БД: data/navidrome.db.bak-20260927-apply-v3 (30490624 B, md5 1d9ea5de2bc217e3c954b95d21df1ca6) +БД после в3: ~/Downloads/navidrome-db/navidrome-after-v3.db (27586560 B, копия для чтения) ``` @@ -95,6 +104,11 @@ compose: /mnt/RED_2TB/docker/navidrome | 14 | 27 сен | ✅ **БД Navidrome пересоздана** — скан 4m13s, импортировано **7861** трек | `/tmp/navidrome.db.bak-20260927-apply-v3` | | 15 | 27 сен | 🔴 **Дефект Птаха найден Alex** — 1 файл в плане получил имя папки вместо альбома | `APPLY-PLAN-v3-changes.csv` | | 16 | 27 сен | 🔴 **КОРЕНЬ ДЕФЕКТА НАЙДЕН** — бага `is_junk_album` (правила на `new_*` вместо `cur_*`), задето **20 файлов**, не 1 | `/tmp/scope_bug.py` | +| 17 | 27 сен | ✅ **Жанры в БД подтверждены** — живут в `media_file.tags` (jsonb) + `tag`/`album_tags`, НЕ в `media_file.genre` (всегда пусто) | `~/Downloads/navidrome-db/navidrome-after-v3.db` | +| 18 | 27 сен | 🔴 **ДЕФЕКТ БУМЕР** — «Тема дороги»: `title='AudioTrack 17'`, `artist='Бумер'`, один в альбоме | § ДЕФЕКТ БУМЕР | +| 19 | 27 сен | 🔴 **БАГА №2 НАЙДЕНА** — категория `z Другое…` не срезается (смешанная раскладка в `CATEGORY_DIRS`) | `/tmp/diag_category.py` | +| 20 | 27 сен | 🔴 **ДЕФЕКТ ТРОФИМ** — 3 физические копии на диске → 8 альбомов, 38 имён задвоено | § ДЕФЕКТ ТРОФИМ | +| 21 | 27 сен | 📋 **Решения Alex получены, план v4 НЕ собран** — 3 вопроса открыты | § ВОПРОСЫ К ALEX | --- @@ -205,6 +219,37 @@ WHERE path NOT LIKE 'backup%' ``` Иначе бэкап всплывает как живое дерево. +### 🔴 ГДЕ В БД NAVIDROME ЛЕЖИТ ЖАНР (проверено 27 сен) +Ложная тревога «жанры не записались» возникает при запросе к НЕ ТОЙ колонке: +``` +media_file.genre = '' у всех 7861 ← УСТАРЕВШАЯ КОЛОНКА, всегда пусто +media_file.tags (jsonb) = {"genre":[{"id":"…","value":"Бардовская песня"}]} ← ЖАНР ЗДЕСЬ +tag = 438 строк (tag_name='genre', tag_value='Rock' …) +media_file_tags = 7861 строк (связь файл ↔ жанр) +album_tags = 1010 строк (связь альбом ↔ жанр, у альбома бывает НЕСКОЛЬКО) +library_tag = 438 строк (агрегат: album_count, media_file_count) +``` +🔴 **НЕ судить о жанрах по `media_file.genre`** — она пустая by design в этой версии Navidrome. +Проверка-образец (`/tmp/diag_genre_db.py`): +```sql +SELECT genre, COUNT(*) FROM media_file WHERE path NOT LIKE 'backup%' GROUP BY genre; -- ЛОЖНО +SELECT tag_value, COUNT(*) FROM tag WHERE tag_name='genre'; -- ВЕРНО +SELECT tags FROM media_file WHERE path LIKE '%Кони привередливые%'; -- ВЕРНО +``` +**Факт на 27 сен:** жанры в БД ЕСТЬ — `Rock` 3119 файлов, `Electro House` 57, +`Drum & Bass` 15, всего **438 значений**. Тревога была ложной. + +### Чтение БД Navidrome для диагностики (рабочий приём) +```bash +# копируем БД локально и читаем python3+sqlite3 на Mac (на NAS sqlite3 тоже есть) +scp -i ~/.ssh/id_rsa truenas_admin@mallexxx.duckdns.org:/mnt/RED_2TB/docker/navidrome/data/navidrome.db \ + ~/Downloads/navidrome-db/navidrome-after-v3.db +# затем: import sqlite3; con.row_factory = sqlite3.Row +``` +⚠️ **Диагностику вести ПО БАЗЕ, а не обходом диска в контейнере.** Обход 7861 файла не +укладывается в лимит форграунда (580 с) и его легко прервать; БД отдаёт те же ответы мгновенно. +Alex: «Ты из базы не можешь пути выгрузить и сравнить что-ли??» + ### Правило `.ndignore` Любой новый `backup*` в `/mnt/RED_2TB/storage/Music/` → дописать в `.ndignore` в том же прогоне. Текущее содержимое (6 записей): @@ -228,7 +273,8 @@ backup_raw ~/Downloads/music-tags/APPLY-PLAN-v3-changes.csv лог 31 правки v3, md5 2c6d2f0bb1d732d7e3e70ef1b210e7d8 ~/Downloads/music-tags/tag-fix-plan.csv 38-я волна, 7905 стр ~/Downloads/music-tags/ALBUM-FIX-306.csv скобочный прогон, 306 стр -~/Downloads/navidrome-db/navidrome-merged.db БД Navidrome (локальная копия) +~/Downloads/navidrome-db/navidrome-merged.db БД Navidrome (старая локальная копия) +~/Downloads/navidrome-db/navidrome-after-v3.db 🔴 БД ПОСЛЕ прогона v3, 27586560 B — читать отсюда ``` ### Скрипты @@ -249,6 +295,18 @@ backup_raw /tmp/find_bug.py черновик детектора (ловил album==имя-папки — НЕ та бага) /tmp/find_bug2.py папки с НЕОДНОРОДНЫМ new_album внутри одной папки /tmp/scope_bug.py 🔴 МАСШТАБ баги: 144 совпадения, 20 испорчено +/tmp/db_check_missed.py сверка БД vs план и канон (пропущенных путей 0) + Трофим по БД +/tmp/diag_genre_track.py жанры в БД + альбомы с дублями позиции (159) / все trk=0 (69) +/tmp/diag_genre_db.py 🔑 ГДЕ лежит жанр: tags jsonb / tag / album_tags, НЕ media_file.genre +/tmp/diag_bumer2.py 🔴 поиск Бумера по БД: artist='Бумер', track_number=17, саундтрек +/tmp/diag_bumer.py первый заход по Бумеру (построчно album/title/path) +/tmp/diag_temadorogi.py теги 'Тема дороги' на диске (в контейнере, /music:ro) +/tmp/diag_tasks.py трассировка категории z Другое + Трофим по канону + Птаха +/tmp/diag_category.py 🔴 БАГА №2: побайтовое сравнение CATEGORY_DIRS с norm(папки) +/tmp/diag_trofim.py дубли имён Трофима (53 имени), папки Трофима +/tmp/diag_prefix_dups.py альбомы с цифровым префиксом (15, реальных префиксов 3) +/tmp/find_bug.py черновик детектора (ловил album==имя-папки — НЕ та бага) +/tmp/find_bug2.py папки с НЕОДНОРОДНЫМ new_album внутри одной папки ~/Developer/personal-os/tools/music-tags/build_fix_plan2.py генератор плана (пофикшен) ``` @@ -262,6 +320,174 @@ DIFF-rule-vs-BASE.csv сверка правила с базой --- +## 🔴 БАГА №2 — КАТЕГОРИЯ `z Другое, Enigma, Ленинград` НЕ СРЕЗАЕТСЯ (27 сен, сессия ~33) + +**Симптом:** Alex заметил, что файл `z Другое, Enigma, Ленинград/Ленинград/Тема дороги.mp3` +не получил альбом по правилу корня («почему он туда не добавился скриптом»). + +**Трассировка** (`/tmp/diag_tasks.py`): +``` +path: z Другое, Enigma, Ленинград/Ленинград/Тема дороги.mp3 +dirs до среза: ['z Другое, Enigma, Ленинград', 'Ленинград'] +dirs после среза: ['z Другое, Enigma, Ленинград', 'Ленинград'] stripped=False +→ правило корня требует stripped AND len(dirs)==1 +→ фактически Stripped=False, len=2 => НЕ ПРИМЕНЯЕТСЯ +``` + +**Корень — смешанная раскладка в `CATEGORY_DIRS`** (`/tmp/diag_category.py`, побайтовое сравнение): +``` +norm(папки) = 'zдругоеenigm' + [а л е н и н г р а д] ← ВСЁ КИРИЛЛИЦА + z=7a д=434 р=440 у=443 г=433 о=43e е=435 + e=65 n=6e i=69 g=67 m=6d ← ЛАТИНИЦА (часть имени Enigma) + а=430 л=43b е=435 н=43d и=438 н=43d г=433 р=440 а=430 д=434 + +строкa в списке 'zдругоеenigmаleningrad': + ... e=65 n=6e i=69 g=67 m=6d а=430 ← до сюда совпадает + l=6c e=65 n=6e i=69 n=6e g=67 r=72 a=61 d=64 ← ЛАТИНИЦА вместо кириллицы + +различия по позициям [12..21] — 10 символов: + [12] список 'a'(0x61 ЛАТ) vs папка 'а'(0x430 КИР) + [13] список 'l'(0x6c) vs папка 'л'(0x43b) + [14] список 'e'(0x65) vs папка 'е'(0x435) + [15] список 'n'(0x6e) vs папка 'н'(0x43d) + [16] список 'i'(0x69) vs папка 'и'(0x438) + [17] список 'n'(0x6e) vs папка 'н'(0x43d) + [18] список 'g'(0x67) vs папка 'г'(0x433) + [19] список 'r'(0x72) vs папка 'р'(0x440) + [20] список 'a'(0x61) vs папка 'а'(0x430) + [21] список 'd'(0x64) vs папка 'д'(0x434) +``` +В списке вторая половина слова набрана **латиницей** (`leningrad`), а папка — кириллицей +(`ленинград`). Строки выглядят одинаково на экране, но не равны побайтово. + +🔴 **Масштаб: правило корня выключено для ВСЕЙ папки `z Другое, Enigma, Ленинград`** — +это Ленинград, Сектор Газа, Красная Плесень, Enigma, Pushnoy.ru, Зинчук, Vanessa Mae, +The Tiger Lillies, Тест Сабвуфера — **~900 файлов**. + +**Второй вариант в списке** (`zdrugoeenigmaleningrad`) тоже не совпадает: там `z` латиницей, +остальное кириллицей, а `norm()` даёт кириллическое `а` после `enigm`. + +**Фикс:** в `CATEGORY_DIRS` держать значения ровно те, что даёт `norm()`, и сравнивать +через `norm()` с ОБЕИХ сторон (список нормализовать на старте, а не хранить «как повезёт»). +🔑 **Общий урок: любой стоп-список сравнивать только через `norm()` с обеих сторон.** Та же +болезнь уже была в `build_fix_plan2.py` (см. § ПИТФОЛЛЫ 26). + +--- + +## 🔴 ДЕФЕКТ БУМЕР — `Тема дороги.mp3` (найден Alex в UI, 27 сен, сессия ~33) + +Alex: «Исполнитель блядь у файла track 17 — Бумер. И он показывает один на свой альбом +"саунд треки к фильму"». + +**Найдено в БД** (`/tmp/diag_bumer2.py`) — ровно этот файл: +``` +path z Другое, Enigma, Ленинград/Ленинград/Тема дороги.mp3 +album 'саунд треки к фильму' +artist 'Бумер' ← TPE1 = название ФИЛЬМА +album_artist 'Ленинград' +title 'AudioTrack 17' ← заводская заглушка +track_number 17 +``` + +**Три дефекта в одном файле:** +1. `title = 'AudioTrack 17'` — имя трека не прочиталось при рипе, Navidrome подставил `AudioTrack `. +2. `artist = 'Бумер'` — в `TPE1` залетело **название фильма**. +3. `album = 'саунд треки к фильму'` — и в этом альбоме он **ОДИН**, потому что остальные + 18 файлов папки лежат в подпапке `C.Шнуров - Бумер (2003)` с `TALB = 'Бумер (2003)'`. + +**Файл НЕ пропущен планом** — проверено: `7861 в БД = 7861 в плане`, разница **0** +(`/tmp/db_check_missed.py`). Он есть и в каноне, и в плане, но с теми же значениями +`TALB`/`TPE1` — **план счёл их верными**. Упущено не файл, а **класс дефекта**: +«мусор в `title`/`artist`, пришедший из чужого рипа». + +**Дубль:** та же песня есть с верным тегом: +``` +z Другое, Enigma, Ленинград/Ленинград/C.Шнуров - Бумер (2003)/C.Шнуров Тема дороги.mp3 + TIT2='Тема дороги' TPE1='Сергей Шнуров' TALB='Бумер (2003)' +``` + +**Решение Alex:** «Тема дороги поместить в альбом **Ленинград** по корню папки как положено». +⚠️ Исполнитель (`Ленинград` / `Сергей Шнуров` / `Various Artists`) — **вопрос открыт**. + +**Также в UI:** «AudioTrack 17. Исполнитель — Бумер. И только один в альбоме?» — да, один: +`TALB='саунд треки к фильму'` встречается в библиотеке **ровно у 1 файла**. + +--- + +## 🔴 ДЕФЕКТ ТРОФИМ — 8 альбомов вместо 4, 38 задвоенных имён + +Alex: «Аристократия помойки альбом разделился аж на 8 альбомов с разными префиксами и +суффиксами и в каждом дублированные треки». + +**Причина — ФИЗИЧЕСКИЕ ДУБЛИ ФАЙЛОВ, не теги.** Трофим лежит в ТРЁХ местах +(`/tmp/diag_tasks.py` + `/tmp/diag_trofim.py`, 208 файлов): +``` +!Pop, Club, Любэ/!Radio/z Старое/disk/3 SHANSON/Трофим 25 файлов +!Pop, Club, Любэ/!Radio/z Старое/disk_v2/3 SHANSON/Трофим 25 файлов +!Рэп/Трофим/01..11 <Альбомы> 156 файлов +``` + +Проверено: `/tmp/diag_trofim.py` — **53 имени с дублями, 38 названий задвоено/затроено**. + +**Пять альбомов в БД только на «Аристократию»:** +``` +'01 Аристократия помойки' 16 файлов trk=0 ← !Рэп/Трофим (префикс папки) +'02 Аристократия помойки 2' 15 файлов trk=0 ← !Рэп/Трофим +'03 Аристократия помойки 3' 13 файлов trk=0 ← !Рэп/Трофим +'04 Аристократия помойки 4' 14 файлов trk=0 ← !Рэп/Трофим +'Аристократия помойки 1' 6 файлов trk=13,8,6 ← disk/ + disk_v2/ (без префикса) +'Аристократия помойки 2' 11 файлов trk=есть +'Аристократия помойки 3' 6 файлов trk=есть +'Аристократия помойки 4' 6 файлов trk=есть +``` +Все `trk=0` → Navidrome склеивает в 1 позицию (тот же механизм, что у Бумера). + +**Второй корень — цифровой префикс папки уходит в `album`** (правило корня берёт имя папки +целиком). По всей БД таких **15 случаев** (`/tmp/diag_prefix_dups.py`), но **только 3 реально +задеты**: +``` +'02 Аристократия помойки 2' -> 'Аристократия помойки 2' +'03 Аристократия помойки 3' -> 'Аристократия помойки 3' +'04 Аристократия помойки 4' -> 'Аристократия помойки 4' +``` +Остальные 12 — цифра **часть названия**, резать нельзя: +`'10 лет - полёт нормальный'` (Пилот), `'1-0 в пользу девочек'` (Ногу Свело!), +`'46-й альбом'` (Красная Плесень), `'001 Амадеус N 146 2002'` (Зинчук), +`'20-ая зима без электричества'`, `'25-й кадр'`. +🔴 **Вывод: правило «срезать цифровой префикс» делать НЕЛЬЗЯ** — сломает больше, чем починит. +Правка **адресная, списком** на 3 папки Трофима. + +**Исполнители Трофима (208 файлов):** +``` +new_albumartist: 'Трофим' 207 · 'Женя Трофимов & Комната культуры' 1 +new_artist: 'Трофим' 199 · В.Маркин · С.Трофимов,группа "Тутси" · + С.Трофимов,группа "Отпетые мошенники" · Александр Маршал · + Алексей Иванов · Т. Овсиенко · С.Трофимов,Азиза · + С.Трофимов,группа "Любовные истории" · Женя Трофимов & Комната культуры +``` +⚠️ **Alex: «пофиксить исполнителя на Сергей Трофимов у всех его треков».** Под «его» — +понимать узко (только `new_artist='Трофим'`, 199) или все 208 включая `Женя Трофимов & Комната +культуры` (другой артист!) и фиты — **вопрос открыт**. + +**Решение Alex:** «не надо удалять дубли из сборников. Они корректно живут в сборниках. +Надо дубли альбомов снести (трофим в частности)». Копии в `disk/` и `disk_v2/` **остаются**. + +--- + +## 📋 ВОПРОСЫ К ALEX (открыты, блокируют сборку плана v4) + +1. **Исполнитель «Тема дороги»**: `Ленинград`, `Сергей Шнуров` или `Various Artists` (это ОСТ)? +2. **Трофим, `album_artist`**: тоже менять на `Сергей Трофимов`, или только `artist`? + И входит ли `Женя Трофимов & Комната культуры` (другой артист) в «все его треки»? +3. **Дубли Трофима**: «снести дубли альбомов» = удалить 58 файлов `!Рэп/Трофим/01..04` + с диска, или только переименовать тег `album` (сняв цифровой префикс) и оставить файлы? + +**Порядок после ответов:** фикс баги №1 (`cur_*`) + фикс баги №2 (категория) → пересборка +плана в **НОВЫЙ файл** относительно **текущей БД Navidrome** (не `cur_*` канона — они устарели) +→ список CSV + дифф → показ Alex → прогон. + +--- + ## 🔎 ВЕРИФИКАЦИЯ v3 ПЕРЕД DRY-RUN (2026-09-27) Проверено на Mac, три скрипта, все числа — из самих файлов. @@ -631,6 +857,16 @@ Navidrome: БД ПЕРЕСОЗДАНА 27 сен · скан fullScan=tr бэкап data/navidrome.db.bak-20260927-apply-v3 (md5 1d9ea5de2bc217e3c954b95d21df1ca6) 🔴 Бага генератора: new_album==new_title совпадений в каноне 144 · ИЗМЕНЕНО v3 (испорчено) 20 new_album==stem(файла) 12 · испорчено 9 · правильный альбом затёрт именем папки +БД после v3: 7861 = плану 7861, пропущенных планом путей 0 (сверка по БД) +Жанры в БД: ЕСТЬ — tag 438 значений; Rock 3119 файлов · Electro House 57 · Drum&Bass 15 + НЕ в media_file.genre (пусто by design) → tags jsonb / tag / album_tags +Позиции: альбомов со ВСЕМИ trk=0: 69 · альбомов с дублями позиции: 159 +Бумер: 'Тема дороги.mp3' — TIT2='AudioTrack 17' · TPE1='Бумер' · TALB='саунд треки к фильму' + альбом из 1 файла в БД; дубль с верным тегом в 'C.Шнуров - Бумер (2003)' +Трофим: 208 файлов в 3 местах · 53 имени с дублями · 8 альбомов 'Аристократия' +Исполнители: new_artist 'Трофим' 199 · new_albumartist 'Трофим' 207 (+1 Женя Трофимов) +Цифр.префикс: 15 альбомов, реальных префиксов 3 (Трофим 02/03/04) +БАГА №2 категория: 'z Другое, Enigma, Ленинград' не срезается → ~900 файлов без правила корня ``` --- @@ -714,6 +950,30 @@ check_album_applied*.py / verify_306*.py вспомогательные про 25. **Масштаб дефекта считать по ВСЕМУ плану, не по первому симптомy.** Птаха выглядел как 1 файл; по факту — **20** (144 совпадения `new_album==new_title`, из них 20 изменено). Диагностика `/tmp/scope_bug.py`: сравнить `new_*` канона и v3 по классу-предикату баги. +26. 🔑 **СТОП-СПИСКИ СРАВНИВАТЬ ТОЛЬКО ЧЕРЕЗ `norm()` С ОБЕИХ СТОРОН.** Бага №2: в `CATEGORY_DIRS` + строка `zдругоеenigmаleningrad` набрана в **смешанной раскладке** (`enigma` латиницей + + `leningrad` латиницей, а папка — кириллицей) → 10 символов не совпали → категория не срезалась + → правило корня выключено для **~900 файлов**. Строки выглядят одинаково на экране. + **Проверка:** печатать `[hex(ord(c)) for c in s]` обеих строк. Болезнь повторяется + (`build_fix_plan2.py` уже ловил это же) — вносить нормализацию в САМ список на старте. +27. 🔴 **Мусорный `title`/`artist` из чужого рипа — класс, а не единичный файл.** Бумер: + `TIT2='AudioTrack 17'`, `TPE1='Бумер'` (название фильма в поле исполнителя), `TALB='саунд + треки к фильму'`. План счёл эти значения верными и не тронул. **Признаки класса:** + `title` вида `AudioTrack N` / `TrackNN` / пустой; `artist` = название фильма/альбома; + `album` встречается в библиотеке ровно у 1 файла. +28. **`trk=0` у нескольких файлов = одна позиция в UI.** Navidrome склеивает треки с одинаковым + `(album, album_artist, track_number)`; при `TRCK` пустом он пишет `0` → «AudioTrack N» и + «в альбоме только один трек». По БД: **69 альбомов, где ВСЕ треки с `track_number=0`**, + **159 альбомов с дублями позиции**. Не дефект для папок-мусорок (`Разное`, `Философские`), + дефект для реальных альбомов (`Бумер (2003)` 19 файлов, `Король и Шут` 36). +29. 🔴 **Физические дубли файлов тегами не лечатся.** Трофим лежит в 3 местах (`disk/`, + `disk_v2/`, `!Рэп/Трофим/`) — 208 файлов, 53 имени с дублями. Три копии одного трека = + три альбома. **Перед правкой тегов проверять дубли путей по БД:** + `SELECT path` + группировка по `basename(path)`. +30. **Цифровой префикс папки нельзя срезать общим правилом.** Из 15 альбомов с цифровым + префиксом **только 3** — настоящие префиксы (Трофим `01..04 Аристократия`); остальные 12 — + цифра часть названия (`10 лет - полёт нормальный`, `1-0 в пользу девочек`, `46-й альбом`). + Правило сломает больше, чем починит → правка адресная, списком. ---