- чистка стоит на каждой точке входа значения метабазы в план — сборка матча, копия кандидата для ревью, набор закреплённых значений источника и его чтение: гарантия, поставленная только на запись, обходится данными, сохранёнными прежними версиями - название, непригодное как имя каталога (пустое или без единой буквы и цифры), не подставляется — раздача уходит в review с названной причиной - гейт подтверждения матча не сдвинут: сравнение с планом идёт по значениям провайдера, чистится только копия, уходящая дальше
8.9 KiB
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 значение не изменяется