recognize: название из метабазы санитизируется перед попаданием в план
- чистка стоит на каждой точке входа значения метабазы в план — сборка матча, копия кандидата для ревью, набор закреплённых значений источника и его чтение: гарантия, поставленная только на запись, обходится данными, сохранёнными прежними версиями - название, непригодное как имя каталога (пустое или без единой буквы и цифры), не подставляется — раздача уходит в review с названной причиной - гейт подтверждения матча не сдвинут: сравнение с планом идёт по значениям провайдера, чистится только копия, уходящая дальше
This commit is contained in:
+111
@@ -0,0 +1,111 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Санитайзинг человекочитаемых полей плана
|
||||
|
||||
Перед структурной валидацией плана и сверкой с базами система SHALL санитизировать
|
||||
человекочитаемые поля плана — `title`, `original_title`, `provider_hint` — как
|
||||
недоверенный вывод LLM. Санитайзинг SHALL: (1) удалять управляющие и zero-width
|
||||
символы (C0/C1, `U+200B` и родственные, BOM `U+FEFF`); (2) сводить внутренние
|
||||
последовательности пробельных к одиночному пробелу и обрезать края; (3) сворачивать
|
||||
кирилло-латинские homoglyph-двойники (см. ниже).
|
||||
|
||||
Санитайзинг SHALL быть **общим для обоих источников названия** — вывода LLM и
|
||||
записи метабазы. Значение, пришедшее из метабазы и заменяющее поле плана при
|
||||
подтверждённом матче, SHALL проходить тот же санитайзинг перед подстановкой (см.
|
||||
`metadata-match`, требование «Подтверждение матча и каноническое имя»). Второго
|
||||
способа чистить **названия плана** система SHALL NOT заводить: одна реализация
|
||||
обслуживает оба источника. Речь только о полях плана — очистка компонента пути
|
||||
под требования файловой системы (`layout`) и очистка отображаемого ярлыка
|
||||
(`naming`) остаются своими, отдельными и законными.
|
||||
|
||||
Санитайзинг SHALL быть **идемпотентным**: повторное применение к уже
|
||||
санитизированному значению SHALL NOT изменять его. На этом свойстве стоит
|
||||
утверждение, что правка не меняет путей на диске для раздач с нормальным
|
||||
названием, и оно проверяется тестом, а не подразумевается.
|
||||
|
||||
Следствие, на которое опирается раскладка: к моменту, когда план уходит в решение
|
||||
auto/review, каждое из полей `title`, `original_title`, `provider_hint` совпадает
|
||||
с тем, что дал бы санитайзинг этого значения — независимо от того, пришло оно от
|
||||
LLM или из метабазы.
|
||||
|
||||
Свёртка двойников SHALL работать потокенно (по словам, разделённым не-буквенными
|
||||
символами): токен, все буквы которого принадлежат одному скрипту, система SHALL
|
||||
оставлять без изменений (билингвальность реальна — кириллические названия
|
||||
неприкосновенны); в токене смешанного скрипта система SHALL определять доминирующий
|
||||
скрипт по числу буквенных рун и заменять буквы-меньшинство их визуальными
|
||||
двойниками из доминирующего скрипта по курируемой таблице. При отсутствии
|
||||
доминирующего скрипта (равенство) токен SHALL оставаться без изменений.
|
||||
|
||||
Санитайзинг SHALL применяться ТОЛЬКО к перечисленным человекочитаемым полям
|
||||
**плана**. Применение того же санитайзинга к значениям, пришедшим из метабазы —
|
||||
каноническому названию и названиям кандидатов, — заказано отдельно, см.
|
||||
`metadata-match`.
|
||||
`files[].src` система SHALL NOT санитизировать — эти значения обязаны совпадать с
|
||||
реальными файлами торрента, и расхождение (в т.ч. homoglyph) SHALL оставаться
|
||||
основанием отклонить план, а не поводом «чинить» путь. `director` система SHALL
|
||||
NOT санитизировать в плане — он не участвует в пути на диске, и его очистка
|
||||
применяется при рендере отображаемого имени (см. `metadata-match`).
|
||||
|
||||
Когда санитайзинг реально изменил значение поля, система SHALL логировать это на
|
||||
уровне `Debug` (названия не относятся к секретам).
|
||||
|
||||
#### Scenario: Кириллический двойник в англоязычном названии сворачивается
|
||||
|
||||
- **GIVEN** план, где `title` = `Hаrold and the Purple Crayon` (буква `а` в первом
|
||||
слове — кириллическая `U+0430`)
|
||||
- **WHEN** план санитизируется
|
||||
- **THEN** первое слово становится `Harold` (все буквы латинские)
|
||||
- **AND** в запрос к базе и в сравнение уходит латинское название
|
||||
|
||||
#### Scenario: Честное кириллическое название не трогается
|
||||
|
||||
- **GIVEN** план российского фильма с `title` = `Тёмный рыцарь`, где все буквы
|
||||
каждого слова кириллические
|
||||
- **WHEN** план санитизируется
|
||||
- **THEN** название остаётся кириллическим без замены букв
|
||||
|
||||
#### Scenario: Токен без доминирующего скрипта не трогается
|
||||
|
||||
- **GIVEN** план, где короткий токен содержит поровну латинских и кириллических
|
||||
букв (доминирующего скрипта нет)
|
||||
- **WHEN** план санитизируется
|
||||
- **THEN** этот токен остаётся без замены букв (осознанный trade-off: двухбуквенный
|
||||
homoglyph-typo не сворачивается)
|
||||
|
||||
#### Scenario: Zero-width и лишние пробелы вычищаются
|
||||
|
||||
- **GIVEN** план, где `title` содержит zero-width символ и сдвоенные пробелы
|
||||
- **WHEN** план санитизируется
|
||||
- **THEN** zero-width удалён, внутренние пробелы сведены к одиночным, края обрезаны
|
||||
|
||||
#### Scenario: files[].src не санитизируется
|
||||
|
||||
- **GIVEN** ответ LLM, где `files[].src` содержит символ-двойник и не совпадает ни
|
||||
с одним реальным файлом торрента
|
||||
- **WHEN** план обрабатывается
|
||||
- **THEN** `files[].src` НЕ изменяется санитайзингом
|
||||
- **AND** несовпадение src приводит к отклонению плана (эскалация в review), а не к
|
||||
«починке» пути
|
||||
|
||||
#### Scenario: Название из метабазы чистится тем же санитайзингом
|
||||
|
||||
- **GIVEN** подтверждённый единичный матч, каноническое название которого содержит
|
||||
zero-width символ и кириллический двойник внутри латинского слова
|
||||
- **WHEN** каноническое название подставляется в план
|
||||
- **THEN** в плане оказывается значение, прошедшее тот же санитайзинг, что и вывод
|
||||
LLM
|
||||
|
||||
#### Scenario: После сверки с базой несанитизированных полей в плане не остаётся
|
||||
|
||||
- **GIVEN** план после подтверждённого матча с базой
|
||||
- **WHEN** оценивается решение auto/review
|
||||
- **THEN** каждое из полей `title`, `original_title`, `provider_hint` совпадает с
|
||||
тем, что дал бы санитайзинг этого значения
|
||||
- **AND** `director` под это требование не подпадает: он чистится при рендере
|
||||
отображаемого имени
|
||||
|
||||
#### Scenario: Повторный санитайзинг ничего не меняет
|
||||
|
||||
- **GIVEN** значение, уже прошедшее санитайзинг
|
||||
- **WHEN** санитайзинг применяется к нему второй раз
|
||||
- **THEN** значение не изменяется
|
||||
Reference in New Issue
Block a user