- metadata-title-sanitize: название из метабазы подставляется в план мимо санитизации и уезжает в имя каталога дословно - long-title-to-review: имя длиннее ~237 байт роняет раскладку в failed вместо отправки на ревью
5.5 KiB
🐞 Отправлять на ревью раздачу с непомещающимся именем вместо отказа
- Тип: fix
- Категория: Ядро продукта
- Зачем: название длиннее ~237 байт роняет раскладку в failed с текстом системной ошибки: пользователь видит «file name too long» вместо карточки ревью, где это чинится подсказкой
- Теги: sprint:2026-08-06
Длина компонента пути ограничена файловой системой (255 байт на имя, минус расширение и суффиксы — практический потолок около 237). Название такой длины приходит из метабазы или из распознавания штатно: длинные оригинальные заголовки и сериалы с подзаголовком в имя укладываются не всегда.
Сегодня это не проверяется нигде: раскладка доходит до link(2), получает от ядра
file name too long, и задача уходит в failed с текстом системной ошибки в
поле ошибки. Для владельца это тупик — состояние терминальное, а причина написана
языком ядра.
Правильный исход — review: там человек правит название подсказкой, ровно как при коллизии цели. Коллизия уже так и обрабатывается, то есть путь в системе есть и его надо переиспользовать, а не изобретать.
Провенанс: ревью изменения tvdb-title-locale, находка AD4 —
отчёт триажа.
Понижена там не по доказательности, а по принадлежности к диффу: путь этим
изменением не тронут.
Воспроизведение
Оракул из отчёта: подать раздачу, у которой имя целевого файла складывается в 250 байт.
n=250 → Apply err=… file name too long, results=0
Наблюдаемо: задача в состоянии failed, в поле ошибки — текст системной ошибки,
ни одной ссылки не создано, карточки ревью нет.
Ожидаемо: задача в review с названной причиной «имя не помещается», раскладка
не начата, подсказка человека чинит случай.
Затрагивает
internal/layout— проверка длины компонента доlink(2)и доменная ошибка вместо системной;internal/worker— ветка перевода задачи вreviewпо этой ошибке, рядом с существующей веткой коллизии цели;openspec/specs/file-layout/spec.md— требование о непомещающемся имени;state-reconciliation— если переход вreviewзаказывается там;- текст причины в карточке ревью: веб-UI и Telegram показывают её человеку.
Критерии приёмки
- Раздача с именем в 250 байт уходит в
reviewс доменной причиной, а не вfailedс текстом ядра. Оракул: тест на временном каталоге прогона, воспроизводящий случай из «Воспроизведения», — проверяет состояние задачи и код причины. - Ни одна ссылка не создана до отказа: частичной раскладки батча не остаётся. Оракул: тот же тест — проверяет, что каталог цели пуст.
- Причина, показанная человеку, не содержит текста системной ошибки. Оракул: утверждение теста на текст причины плюс конвенция errors.md — перевод доменной ошибки на внешней границе.
- Проверка длины стоит до первой операции с файловой системой. Оракул: чтение диффа на ревью; тест на пустоту каталога цели его подтверждает.
Рамки
Обрезать или переименовывать название самостоятельно нельзя — это решение человека, у него для этого есть подсказка на ревью. Предел длины зависит от файловой системы; зашивать 255 как универсальную константу не стоит, но и выяснять предел у ядра в рантайме ради этой задачи не требуется — достаточно консервативного значения с объяснением, откуда оно.