Files
jellybit/tasks/items/long-title-to-review.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

5.7 KiB
Raw Blame History

🐞 Отправлять на ревью раздачу с непомещающимся именем вместо отказа

  • Тип: fix
  • Категория: Ядро продукта — тот же урожай ревью и тот же стык «название → компонент пути»: вторая после первой дешевле
  • Зачем: название длиннее ~237 байт роняет раскладку в failed с текстом системной ошибки: пользователь видит «file name too long» вместо карточки ревью, где это чинится подсказкой

Длина компонента пути ограничена файловой системой (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 как универсальную константу не стоит, но и выяснять предел у ядра в рантайме ради этой задачи не требуется — достаточно консервативного значения с объяснением, откуда оно.