Files
jellybit/openspec/changes/archive/2026-08-10-long-title-to-review/specs/file-layout/spec.md
T
av b9f0929d0c layout: непомещающееся целевое имя уводит задачу в review вместо failed
- предел длины компонента (255 байт) проверяется в BuildLinks до первой
  операции с ФС: ни каталога, ни ссылки при отказе не создаётся
- причина пустого предпросмотра считается на показе (ReviewData.PreviewError)
  и печатается в панели действий и в карточке Telegram: у задачи без
  записанной причины взять её больше неоткуда
2026-08-10 12:16:44 +03:00

5.2 KiB
Raw Blame History

ADDED Requirements

Requirement: Непомещающееся целевое имя уходит в review

Система SHALL отклонять раскладку целиком, если хотя бы один компонент целевого пути (папка тайтла, папка сезона, имя файла с расширением и суффиксами) длиннее предела, и SHALL переводить задачу в review с доменной причиной, а не в failed. Проверка SHALL выполняться до первой операции с файловой системой: ни каталога, ни ссылки при отказе не создаётся. Причина SHALL нести собственный код, отличный и от кода коллизии, и от общего кода отказа построения плана, а человекочитаемый текст SHALL называть непомещающийся компонент и НЕ SHALL содержать текста системной ошибки.

Предел SHALL меряться в байтах UTF-8-представления имени, а не в символах: кириллическое название упирается вдвое раньше латинского той же длины в знаках. Величина — 255 байт (NAME_MAX у ext4/xfs/btrfs); она фиксирована и у ядра не выясняется, потому что раскладка обязана отказать до обращения к диску. На файловой системе с меньшим пределом остаётся сегодняшний исход — отказ ядра и failed; это осознанный остаток, а не пробел.

Проверка длины SHALL выполняться после проверки нахождения пути под корнем библиотеки: путь, вышедший за песочницу, SHALL отклоняться как выход за библиотеку, иначе находка безопасности спряталась бы за косметической причиной.

Самостоятельно обрезать или переименовывать название система НЕ SHALL — это решение человека.

Scenario: Слишком длинное имя файла уходит в review

  • GIVEN распознавание даёт название, из которого имя целевого файла складывается длиннее 255 байт
  • WHEN выполняется раскладка
  • THEN задача переходит в review с причиной «имя не помещается», ни один каталог и ни одна ссылка не созданы, а текст системной ошибки человеку не показан

Scenario: Предел меряется в байтах

  • GIVEN два названия одинаковой длины в знаках — латинское и кириллическое
  • WHEN строятся целевые пути
  • THEN кириллическое отклоняется вдвое раньше латинского, а граница проходит между 255 и 256 байтами

Scenario: Слишком длинное имя папки тайтла уходит в review

  • GIVEN название укладывается в имя файла, но папка тайтла с годом и provider-тегом длиннее предела
  • WHEN выполняется раскладка
  • THEN задача переходит в review с той же причиной, каталог тайтла не создан

Scenario: Выход за библиотеку важнее длины

  • GIVEN целевой путь одновременно выходит за корень библиотеки и длиннее предела
  • WHEN строятся целевые пути
  • THEN отказ называет выход за библиотеку, а не длину имени

Scenario: Подсказка человека чинит случай

  • GIVEN задача в review с причиной «имя не помещается»
  • WHEN человек задаёт название короче и применяет раскладку заново
  • THEN раскладка проходит штатно и задача переходит в done

Scenario: Унаследованная база в предел помещается всегда

  • GIVEN база имени унаследована от живой папки-якоря по правилу сходимости
  • WHEN строятся имена файлов внутри этой папки
  • THEN они помещаются в предел, потому что папка-якорь лежит на диске и уже не длиннее предела, а хвост имени файла не длиннее хвоста имени папки