Files
jellybit/docs/tasks/items/long-title-to-review.md
T
av 397f8aa2c3 tasks: два дефекта из ревью tvdb-title-locale взяты в спринт
- metadata-title-sanitize: название из метабазы подставляется в план мимо
  санитизации и уезжает в имя каталога дословно
- long-title-to-review: имя длиннее ~237 байт роняет раскладку в failed
  вместо отправки на ревью
2026-08-07 17:03:59 +03:00

5.5 KiB
Raw Blame History

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

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