При подтверждённом матче база папки (имя+год) наследуется от живой папки-якоря того же (provider, provider_id) вместо печати заново из выхода LLM — так второй/последующий сезон ложится в ТУ ЖЕ папку, а не заводит рядом почти одинаковую. Отдельная сущность «тайтл» не вводится. - layout: Plan.FolderBase перекрывает базу в папке и именах файлов; TitleFolder разбирает dst_path в папку тайтла и базу (снятие тега). - store: LiveTitleFolders — dst_path живых ссылок того же матча. - worker: resolveFolderBase (живость якоря — по наличию папки на диске, os.Lstat, а не по статусу ссылки в БД) в linkPlan и в превью ревью (превью=применение); рассинхрон нескольких живых папок → review из linking (deferred→review в графе нет). Схема БД не менялась. Change series-folder-convergence заархивирован, требования влиты в openspec/specs/file-layout. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5.1 KiB
5.1 KiB
Why
Второй/третий сезон одного сериала должен ложиться в ТУ ЖЕ папку, а не заводить
рядом почти одинаковую. Сейчас имя папки печатается заново из выхода LLM при
каждой раскладке (layout.BuildLinks из полей плана), и совпадение
(provider, provider_id) не гарантирует совпадение строки папки: LLM может дать
«Fargo» и «Фарго», год сезона вместо года сериала — и верно заматченный второй
сезон уедет в соседнюю папку. Это ядро «проблемы второго сезона»: она не про
группировку, а про сходимость папки (см. docs/drafts/logical-title-model.md
§3, §5.2).
What Changes
- Вводим правило сходимости папки при построении плана раскладки: при
подтверждённом матче (
providerиprovider_idзаданы) база папки (Название (Год)) наследуется от живыхfile_linkдругих загрузок того же тайтла, а выход LLM для папки игнорируется. - Якорь берём из существующего
dst_pathживых ссылок (status IN linked/copied/exists) загрузок, чей current recognition имеет тот же(provider, provider_id)— живые пути — истина (переименовали папку → сверка уводит ссылки вtarget_missing, якорь исчезает, следующая загрузка печатает заново). - Унаследованная база применяется и к папке, и к именам файлов внутри
(episode/movie stem), чтобы
Fargo (2014) S02E01совпадало сFargo (2014) S01E01. Провайдер-тег[tvdbid-…]по-прежнему берётся из текущего(provider, provider_id). - Рассинхрон (несколько РАЗНЫХ живых папок с одним
(provider, provider_id), случившийся до внедрения правила) → загрузка уходит в review с явной причиной, якорь молча не выбираем. - Отдельная сущность «тайтл» не вводится: это join по существующим таблицам
(
file_link → download → recognition(is_current)), без новых сущностей/таблиц. Схема БД не меняется.
Capabilities
New Capabilities
Modified Capabilities
file-layout: добавляется правило сходимости базы папки при построении целевого пути — при подтверждённом матче база наследуется от живых ссылок того же(provider, provider_id), а не печатается из выхода распознавания; несколько расходящихся живых папок → уход в review с причиной «рассинхрон» вместо тихого выбора (по прецеденту коллизии, которая тоже уводит в review из file-layout).
Impact
- Код:
internal/layout(возможность построить план с унаследованной базой папки),internal/worker(linkPlan/построение плана раскладки: lookup якоря, ветка рассинхрон→review),internal/store(новый read-метод: живые целевые папки по(provider, provider_id), исключая текущую загрузку). - Инварианты безопасности данных: не трогаем.
downloadостаётся мостом, выход распознавания недоверенный, безопасность — на санитизации и проверке пути под библиотекой. Никаких новых прав на источник. - Схема БД: без изменений (только новый SELECT-join).
- Границы: нет якоря → папка из распознавания (как сейчас); нет матча
(
provider=none) → авто-раскладки нет, всё через review (инвариант); смена провайдера между сезонами якорь не склеит — редкий случай, штатно review (осознанная цена, черновик §6.1). - Совместимость: поведение первой загрузки тайтла не меняется; правило влияет только на последующие вклады при наличии живого якоря.