[2026-09-27] eagle: personal/plans/music-artist-albumartist-repair.md personal/plans/tagwriter-container.md personal/tech/id3-tag-repair.md

This commit is contained in:
Alexey Martemyanov committed 2026-09-27 15:50:21 +06:00
1 parent 392cbc22db
commit 3946ccd352
3 files changed
+250 -12

No files matched your search

+59
View File
@@ -61,6 +61,11 @@ related:
> править выхваченные строки (сессия 15: 413 из 420 «нарушений» были ложными).
> Полные формулировки — в `SKILL.md` скилла.
> ⚠️ **Обновлён до v2.1.0 (сессия 17):** **A7** (склейка `Родитель - Папка` и технический префикс
> в `album`; 🔴 разделитель бывает ТРЁХ видов — `-`/`–`/`—`, матчить все) · **A8** (в контроле
> полноты «ПОТЕРЯНО: 881» = смена ФОРМЫ записи при схлопывании D16, реальных потерь 0 —
> сверять НОВОЕ значение, а не пару `old,new`). Полные формулировки — ниже.
## 📁 Артефакты проекта
**Путь:** `~/Developer/personal-os/tools/music-tags/`
@@ -716,6 +721,60 @@ cur_album='Нечетный воин 2' → new_album='Нечётный Воин
**Общий принцип:** технические суффиксы (`(CD1)`, `(Disc 2)`) — не часть названия альбома;
перед записью значения сверять написание серии с нормой (ё, регистр).
### 🔴 A7 — СКЛЕЙКА «Родитель - Папка» / технический префикс в `album` (сессия 17)
Отдельный класс от A3 (имя подпапки) и A6 (суффиксы серии): `album` содержит **склейку**
`Категория - Подпапка`, где левая часть — не артист альбома, а корень пути. Найдено 102 строки:
```
Бард - Авангард -> Бард-авангард (18) !Рэп/Трофим/07 Бард-авангард
Radio - Старое -> Старое (77) !Radio/* — album = имя подборки
Radio - Df1 -> Df1
(2001) Infected Mushroom - B.P. Empire -> B.P. Empire (7)
```
Три формы склейки: **префикс-категория** (`Radio - `), **префикс-год+артист** (`(2001) IM - `),
**название с ошибочным разделителем** (`Бард - Авангард` → норма `Бард-авангард`, как в имени
папки). Правило: значение в `album` не должно содержать `Родитель - Ребёнок`; целевое значение
брать из **имени подпапки** или **пути**, не выдумывать (A2/D22).
🔴 **Питфолл: разделитель бывает ТРЕМЯ разными символами.** Первый прогон исправил 6 из 7
IM-строк — осталась `(2012) Infected Mushroom – U r so fucked` с **en-dash `–` (U+2013)**.
Регулярка с дефисом её не матчит, и это **не даёт ошибки** — просто строка остаётся.
```python
DASH = r"[-–—]" # hyphen U+002D, en-dash U+2013, em-dash U+2014
RE_IM = re.compile(r"^\(\d{4}\)\s+Infected Mushroom\s+" + DASH + r"\s+(.+)$")
```
**Любой поиск разделителя в значении из ID3 — матчить все три тире.** Соседний случай: NC-vs-NFD
в именах папок (§8) — тот же класс «визуально одинаковое, побайтово разное».
🔴 **Питфолл ревью: дифф проверять не только на согласованность с папкой, но и на ФОРМУ значения.**
RC-проход сверял `new_*` с именем папки-артиста и согласованностью по папке — **склейка внутри
значения не проверялась**, 102 строки прошли ревью незамеченными. Детектор по форме (`re.search`
разделителя в `album`) даёт много ложных (222 попадания на 101 реальных): отсеивать по `cur_album`
и по соседним файлам папки.
**Скрипты:** `~/Downloads/music-tags/fix_glue.py` (`--apply`), `verify_glue.py`,
`were_these_in_rc.py`, `loss_kind.py`.
### 🔴 A8 — «ПОТЕРЯНО» в контроле полноты может быть сменой ФОРМЫ записи, а не потерей
`verify_diff_completeness.py` после схлопывания диффа (D16) выдал `ПОТЕРЯНО: 881`. Реальных
потерь — **0**. Скрипт строит эталон `(path, field, old, new)` и требует точного совпадения
пары `(old, new)`; но при схлопывании у папки записывается `old = '<N разных>'`, поэтому
**`old` не совпадает**, хотя `new` тот же.
```python
# проверка: новое значение ПРИСУТСТВУЕТ в строке ПАПКА (не важно, какое там old)
if any(c[1] == nv for c in coll[(folder_of(rel), field)]):
form_change += 1 # смена формы записи, НЕ потеря
```
**Правило:** при разборе «потерь» сверять **новое значение**, а не пару `(old, new)` — иначе
отчёт пугает цифрой, за которой ничего нет. Скрипт `loss_kind.py`.
### 🔴 A5 — имя ПРОЕКТА вместо артиста + вложенные скобки в имени файла (сессия 9)
Класс: `artist` (и `albumartist`) = **название музыкального проекта**, а реальные исполнители