Files
jellybit/tasks/items/metadata-title-sanitize.md
T
av bb278e8744 tasks: груминг — верх очереди отдан багам и мелочам
- в «Ядре» первыми стоят metadata-title-sanitize и long-title-to-review,
  за ними живая проверка формы ответа TheTVDB и confidence-гейт
- в «Инфраструктуре» первой стала background-error-noise: единственный
  ready-дефект секции, решение по бэкоффу принято 2026-08-06
- infohash-identity-integrity понижен до research и сдвинут вниз: тело само
  не решает между change и ограничением в документе, взять его нельзя
2026-08-10 08:57:00 +03:00

73 lines
6.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 🐞 Санитизировать название из метабазы перед подстановкой в план
- **Тип:** fix
- **Категория:** Ядро продукта — дефект major: название из метабазы уезжает в имя каталога Jellyfin мимо санитизации, авто-раскладка это пропускает; оракул добыт триажом, а internal/recognize тронут tvdb-title-locale неделю назад — окно открыто
- **Зачем:** plan.Title = match.Title подставляется ПОСЛЕ sanitizePlan — название из TMDB/TVDB уезжает в имя каталога Jellyfin дословно, с невидимыми символами и гомоглифами, и авто-раскладка это пропускает
Название, пришедшее из метабазы, подставляется в план **после** того, как план
прошёл санитизацию: `plan.Title = match.Title` стоит ниже `sanitizePlan`.
Значение уезжает в имя каталога библиотеки, не сверенное ни с чем — гейт
авто-раскладки сверяет `normalize(c.Title) || normalize(c.OriginalTitle)` и
проходит по второму полю, а в путь идёт первое.
`layout.sanitizeComponent` ниже по потоку снимает `/\:*?"<>|` и байты `< 0x20`,
но категорию Cf (невидимые управляющие) не трогает и гомоглифы не сворачивает.
Итог — два визуально неотличимых каталога в медиатеке.
**Класс пре-существующий, и это важно для рамок:** тот же путь у TMDB, задача
`tvdb-title-locale` его только распространила на второго провайдера. Инвариант
«целевой путь строго под библиотекой» **держится** — проверено на `Dune/../../etc`,
`" .. "`, `"..."` и на 400 символах, выхода из песочницы нет. Поэтому `major`,
а не `critical`.
Провенанс: ревью изменения `tvdb-title-locale`, находка 2 —
[отчёт триажа](../../openspec/changes/archive/2026-08-07-tvdb-title-locale/review/report.md).
## Воспроизведение
Падающий тест на реальном `Recognizer` (оракул добыт триажом, не рассуждением).
Подать кандидата метабазы с названием и посмотреть на `plan.Title` и решение
гейта:
| Вход | Что происходит |
| --- | --- |
| три символа ZWSP (`U+200B`) | `auto=true`, в план уезжают невидимки; `sanitizeTitle` дал бы пустую строку |
| `Dune<RLO>gnp.mkv` (`U+202E`) | `auto=true`, имя каталога переворачивается при отображении |
| `Dune\nHACK` | `auto=true`, перевод строки доезжает до плана |
| `Dunа` с кириллической `а` | `auto=true`, каталог визуально неотличим от латинского `Dune` |
Во всех четырёх случаях значение в плане отличается от того, что дал бы
санитайзер, и ни одно не остановлено гейтом.
## Затрагивает
- `internal/recognize/recognize.go` — порядок подстановки `match.Title` и
`match.OriginalTitle` относительно `sanitizePlan`;
- `internal/layout` — состав `sanitizeComponent`, если решим закрывать категорию
Cf и гомоглифы здесь, а не на подстановке (выбор места — часть задачи);
- поведение **обоих** провайдеров, TMDB и TVDB: правка меняет уже работающий
TMDB, и это её главный риск;
- `openspec/specs/metadata-match/spec.md` либо `file-layout` — чьим требованием
станет «название из метабазы санитизируется перед попаданием в путь».
## Критерии приёмки
- Все четыре входа из «Воспроизведения» дают либо санитизированный `plan.Title`,
либо уход в review — но не авто-раскладку с исходным значением. **Оракул:**
тот самый падающий тест из отчёта триажа, перенесённый в дерево.
- Название, схлопывающееся санитизацией в пустую строку, не порождает каталог с
пустым именем и не роняет раскладку. **Оракул:** табличный тест на границе,
случай «три ZWSP».
- Поведение TMDB на нормальных названиях не изменилось. **Оракул:** существующие
тесты `internal/recognize` и `internal/metadata` зелёные без правок ожиданий.
- Место санитизации названо требованием спеки, а не только кодом. **Оракул:**
`openspec validate --strict` на дельте.
## Рамки
Гомоглифы сворачивать не обязательно — достаточно сделать значение в пути
предсказуемым и сверяемым; полноценная нормализация Unicode это отдельный
разговор. Инвариант «целевой путь строго под библиотекой» уже держится, ломать
его правкой нельзя. Правка задевает работающий TMDB — регресс на нём дороже
самого дефекта.