Кейс «Harold and the Purple Crayon»: LLM отдал title с кириллической буквой-двойником, сырое название ушло в запрос TVDB дословно (не нашлось), а гейт нормализации кир/лат двойники не сворачивал — двойной промах, пустой список кандидатов, ручной ввод id. - recognition: санитайзинг человекочитаемых полей плана (title/original_title/ provider_hint) на границе разбора, до валидации: strip control/zero-width, collapse пробелов, потокенная свёртка homoglyph-двойников по курируемой кир↔лат таблице. files[].src не трогаем (обязаны биться с торрентом). - metadata-match: тот же fold в normalize (гейт) как defense-in-depth; безгодовой второй проход сверки как fallback при известном годе и промахе первого — восстанавливает off-by-one авто-матчи и пополняет кандидатов review. В fallback требуем известный год кандидата (год-unknown → review, не авто); гейт год ±1 и инвариант авто-матча не двигаются. Спеки recognition/metadata-match обновлены, change заархивирован. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4.9 KiB
ADDED Requirements
Requirement: Санитайзинг человекочитаемых полей плана
Перед структурной валидацией плана и сверкой с базами система SHALL санитизировать
человекочитаемые поля плана — title, original_title, provider_hint — как
недоверенный вывод LLM. Санитайзинг SHALL: (1) удалять управляющие и zero-width
символы (C0/C1, U+200B и родственные, BOM U+FEFF); (2) сводить внутренние
последовательности пробельных к одиночному пробелу и обрезать края; (3) сворачивать
кирилло-латинские homoglyph-двойники (см. ниже).
Свёртка двойников SHALL работать потокенно (по словам, разделённым не-буквенными символами): токен, все буквы которого принадлежат одному скрипту, система SHALL оставлять без изменений (билингвальность реальна — кириллические названия неприкосновенны); в токене смешанного скрипта система SHALL определять доминирующий скрипт по числу буквенных рун и заменять буквы-меньшинство их визуальными двойниками из доминирующего скрипта по курируемой таблице. При отсутствии доминирующего скрипта (равенство) токен SHALL оставаться без изменений.
Санитайзинг SHALL применяться ТОЛЬКО к перечисленным человекочитаемым полям.
files[].src система SHALL NOT санитизировать — эти значения обязаны совпадать с
реальными файлами торрента, и расхождение (в т.ч. homoglyph) SHALL оставаться
основанием отклонить план, а не поводом «чинить» путь.
Когда санитайзинг реально изменил значение поля, система 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), а не к «починке» пути