diff --git a/docs/backlog/README.md b/docs/backlog/README.md index bc842a5..8e24d8a 100644 --- a/docs/backlog/README.md +++ b/docs/backlog/README.md @@ -21,7 +21,6 @@ Tududi (проект `jellybit`) больше **не** держит беклог - [Удаление средствами jellybit («единое окно», path 2)](udalenie-edinoe-okno.md) — Распознавание ручного удаления и пометка рассинхрона уже сделаны (state-reconciliation… - [Ретеншн и очистка БД](retention-ochistka-bd.md) — Терминальные задачи (done/cancelled/failed/reverted), их попытки recognition с сырыми… - [Eval-харнес распознавания (корпус кейсов + метрика точности)](eval-harness-raspoznavaniya.md) — Распознавание — ядро продукта, но смена модели или правка промпта сейчас вслепую… -- [НФТ: масштаб до 100 одновременных загрузок (потолок — 1000)](masshtab-100-zagruzok.md) — Потолок по нагрузке нигде не зафиксирован: воркер, поллинг qBittorrent, пул LLM-вызовов и… - [Гейт дозаписи хешей в dedup-ветке CreateDownloadIfNoActive (F1)](review-f1-gate-dozapisi-heshey.md) — dedup-ветка дописывает все хеши в найденную задачу без гарда — риск инварианта ≤1 активной _(ревью 2026-07-08)_ - [Readiness-preflight: запрет авто-раскладки недокачанных файлов (MAJOR-5)](review-major5-readiness-preflight.md) — САМОЕ ОПАСНОЕ: авто-раскладка недокачанных файлов рвёт целостность библиотеки _(ревью 2026-07-08)_ - [Retry/stall семантика: сброс базиса таймаута + простой от начала, а не от возраста торрента (MAJOR-1, MAJOR-2)](review-major1-2-retry-stall.md) — таймаут и простой отсчитываются от возраста торрента, а не от начала загрузки _(ревью 2026-07-08)_ @@ -33,19 +32,15 @@ Tududi (проект `jellybit`) больше **не** держит беклог - [Агенты-ревьюверы качества (наименования, архитектура, конвенции, стиль)](agenty-revyuvery-kachestva.md) — Набор узких сабагентов-ревьюверов поверх ревью-процесса из CLAUDE - [[идея] Сила совпадения кандидата и пересмотр распознавания/матчинга](sila-sovpadeniya-kandidata.md) — ИДЕЯ (сперва проработать) - [История переходов загрузки](istoriya-perehodov-zagruzki.md) — Сохранять полную историю переходов состояний загрузки (что/когда/почему/кто инициировал… -- [Машина состояний на go-библиотеке](mashina-sostoyaniy-biblioteka.md) — Сейчас FSM реализована вручную в worker - [Привязка уведомлений к источнику в ботах (мульти-бот)](uvedomleniya-multi-bot.md) — Уведомления и запросы подтверждения должен получать тот, кто прислал загрузку: автор… -- [Улучшения UI: показывать матч с записью метабазы в Telegram](telegram-match-metabazy.md) — Web-сторона реализована: страница загрузки /download/{id} и экран ревью показывают, с… - [[идея] Сложные сериальные раздачи: все сезоны разом, паки, спецраскладки](slozhnye-serialnye-razdachi.md) — ИДЕЯ (проработать крайние случаи) - [Аниме с абсолютной нумерацией](anime-absolyutnaya-numeraciya.md) — Релизы аниме часто нумеруют серии сквозным числом (#137) без сезонов, а Jellyfin ждёт… -- [Добавление торрентов файлом/ссылкой — «единое окно»](dobavlenie-edinoe-okno.md) — Поддержать источники помимо magnet: - [Бэкап SQLite](backup-sqlite.md) — architecture - [Глубокий healthcheck и статус зависимостей](healthcheck-zavisimosti.md) — /healthz проверяет только сам сервис +- [НФТ: масштаб до 100 одновременных загрузок (потолок — 1000)](masshtab-100-zagruzok.md) — Зафиксировать в НФТ ориентир 100/1000 загрузок + аудит узких мест (SQLite, воркер, поллинг) - [Обучение на правках человека (few-shot из прошлых ревью)](obuchenie-na-pravkah.md) — Когда человек поправил матч, тип или нумерацию — сохранять это как пример и подмешивать… -- [Гейт авто-раскладки по confidence: спека vs код](gate-confidence-spec-vs-code.md) — Аудит спек↔код (2026-07-03) нашёл расхождение в модели уверенности -- [Привязка внешних субтитров к серии (сериалы)](vneshnie-subtitry.md) — Аудит спек↔код (2026-07-03): спека recognition требует «внешние субтитры SHALL… -- [Раздачи-копии диска (DVD/BluRay: VIDEO_TS/BDMV)](disk-kopii-video-ts-bdmv.md) — Иногда для очень редких фильмов скачивается не один видеофайл, а полная копия диска… -- [Сделать фавиконку для jellybit](favicon.md) — мелкая косметика: иконка вкладки/PWA для веб-UI +- [Гейт авто-раскладки по confidence: спека vs код](gate-confidence-spec-vs-code.md) — Расхождение спека↔код: код делает confidence жёстким гейтом вопреки спеке — нужно решение +- [Внешние субтитры: пары VobSub и языковой суффикс](vneshnie-subtitry.md) — Привязка субтитр→серия уже работает; остались пары VobSub .idx+.sub и потеря Lang/Flags - [Sweep застрявших linking при рестарте + фикс persist-failure (MAJOR-4)](review-major4-sweep-linking.md) — задачи застревают в linking при рестарте; заодно фикс persist-failure _(ревью 2026-07-08)_ - [Defer из catched → лимбо → необратимый deleted (MAJOR-6)](review-major6-defer-catched.md) — Defer из ещё-не-добавленного catched уводит задачу в необратимый deleted _(ревью 2026-07-08)_ - [processCatched: promote-without-add если торрент уже в qBittorrent (F2)](review-f2-promote-without-add.md) — торрент уже в qBittorrent → processCatched зациклен на Add вместо promote _(ревью 2026-07-08)_ @@ -60,12 +55,16 @@ Tududi (проект `jellybit`) больше **не** держит беклог - [Версии/качество одного тайтла (репаки, апгрейд 1080p → 2160p)](versii-kachestvo-repaki.md) — По калибровке болей (2026-07-02) — не боль, из приоритета выпало - [[идея] Многоступенчатая верификация привязки](mnogostupenchataya-verifikaciya.md) — ИДЕЯ (требует проработки) - [Выбор из нескольких находок метабазы в Telegram](telegram-vybor-nahodok.md) — Когда распознавание даёт несколько подходящих кандидатов в метабазе, предлагать их в… +- [Улучшения UI: показывать матч с записью метабазы в Telegram](telegram-match-metabazy.md) — Название/год/провайдер+id в боте уже выводятся; осталась кликабельная ссылка на запись +- [Добавление торрентов файлом/ссылкой — «единое окно» (остаток: URL)](dobavlenie-edinoe-okno.md) — magnet и .torrent-файл приняты; остался фетч .torrent по URL (нужен SSRF-гард) +- [Раздачи-копии диска (DVD/BluRay: VIDEO_TS/BDMV)](disk-kopii-video-ts-bdmv.md) — Иногда для очень редких фильмов скачивается не один видеофайл, а полная копия диска… - [Проверка свободного места перед copy-fallback](svobodnoe-mesto-copy-fallback.md) — Когда хардлинк невозможен (EXDEV/ENOTSUP/…), layout копирует файл, дублируя место на диске - [Кэш метабаз (и опционально LLM)](kesh-metabaz.md) — Повторные и ретраящиеся прогоны распознавания бьют TMDB/TVDB/TVMaze одним и тем же… - [[идея] guessit как сервис-спутник](guessit-sputnik.md) — ИДЕЯ - [[идея] Завершение загрузки через webhook](webhook-zavershenie-zagruzki.md) — ИДЕЯ (решим по опыту эксплуатации) - [Авторизация веб-UI (на будущее)](avtorizaciya-web-ui.md) — Решено для v1: без авторизации в доверенной LAN, опц - [Современный Web-UI как PWA](web-ui-pwa.md) — Переделать веб-интерфейс в современное PWA-приложение (устанавливаемое, отзывчивое… +- [Сделать фавиконку для jellybit](favicon.md) — мелкая косметика: иконка вкладки/PWA для веб-UI - [Идентичность инфохэшей: split v1/v2 одного торрента + крафт-магнет отравляет владение (F4, F5)](review-f4-f5-infohash-identity.md) — split v1/v2 идентичность и крафт-магнет отравляют владение инфохэшами _(ревью 2026-07-08)_ - [Приём/UI: мелкие фиксы границ и парсинга (F7, F8, F9, F10, N2)](review-f7-f10-ingest-ui-fixes.md) — мелочи приёма/UI: oversized→500, гонки дедупа, парсинг magnet, cap контекста, руны _(ревью 2026-07-08)_ - [Жизненный цикл: мелкие находки (MINOR-8, MINOR-9, NIT-11, NIT-12)](review-lifecycle-minor.md) — claim-token распознавания, I/O под глобальным mutex, мелкие lookup/retry _(ревью 2026-07-08)_ diff --git a/docs/backlog/disk-kopii-video-ts-bdmv.md b/docs/backlog/disk-kopii-video-ts-bdmv.md index 9b1c94f..907d2c7 100644 --- a/docs/backlog/disk-kopii-video-ts-bdmv.md +++ b/docs/backlog/disk-kopii-video-ts-bdmv.md @@ -1,6 +1,6 @@ # Раздачи-копии диска (DVD/BluRay: VIDEO_TS/BDMV) -**Приоритет:** средний +**Приоритет:** низкий Иногда для очень редких фильмов скачивается не один видеофайл, а полная копия диска — структура VIDEO_TS/ (DVD) или BDMV/ (BluRay). Сейчас распознавание и раскладка заточены под пофайловый разбор, а тут «фильм» — это каталог целиком. Jellyfin такие раскладки поддерживает (папка фильма с вложенным VIDEO_TS/BDMV). Нужно: распознать, что раздача — образ диска (по наличию VIDEO_TS/BDMV), не разбирать её по отдельным VOB/m2ts как серии, разложить весь каталог хардлинками в папку фильма (Название (Год)/VIDEO_TS/…). Крайний, но реальный случай; частота низкая. diff --git a/docs/backlog/dobavlenie-edinoe-okno.md b/docs/backlog/dobavlenie-edinoe-okno.md index 4c22b44..d8324b4 100644 --- a/docs/backlog/dobavlenie-edinoe-okno.md +++ b/docs/backlog/dobavlenie-edinoe-okno.md @@ -1,7 +1,18 @@ -# Добавление торрентов файлом/ссылкой — «единое окно» +# Фетч .torrent по URL — остаток «единого окна» -**Приоритет:** средний +**Приоритет:** низкий -Поддержать источники помимо magnet: .torrent-файл и URL (отдаём их в qBittorrent, без исходящих запросов на пользовательский URL — SSRF исключён). Идеал — одно поле «единого окна»: кидаем туда текст или файл, а сервис сам разбирает, что это (magnet / ссылка / .torrent / сообщение бота), и заводит загрузку. +Приём magnet и `.torrent`-файла уже реализован: ветка `TorrentData → torrent.Parse` +(`internal/ingest/ingest.go`), файл-пикер в веб-форме (`web/templates/index.html`), +приём документа в Telegram (`internal/tgbot`). Осталась одна ветка «единого окна» — +**URL на `.torrent`**: сервис сам скачивает файл по ссылке и заводит загрузку. Была +осознанно вынесена из change `torrent-file-ingest`, потому что требует исходящего +запроса на пользовательский URL → нужен SSRF-гард (allowlist схем/хостов, запрет +приватных сетей, лимит размера/редиректов). -Связано: specs/architecture.md → «Транспорты» (source_type = magnet|torrent|url уже в схеме), пакет ingest (сейчас поддержан только magnet). +Идеал по-прежнему — одно поле, куда кидают текст или файл, а сервис разбирает, что +это (magnet / ссылка на .torrent / .torrent-файл / сообщение бота). Сейчас текстовое +поле идёт только через `magnet.Parse`. + +Связано: specs/architecture.md → «Транспорты» (source_type = magnet|torrent|url уже в +схеме), пакет ingest, архив change `torrent-file-ingest`. diff --git a/docs/backlog/favicon.md b/docs/backlog/favicon.md index 526e17b..5c1f65c 100644 --- a/docs/backlog/favicon.md +++ b/docs/backlog/favicon.md @@ -1,5 +1,5 @@ # Сделать фавиконку для jellybit -**Приоритет:** средний +**Приоритет:** низкий _Описание не заполнено._ diff --git a/docs/backlog/mashina-sostoyaniy-biblioteka.md b/docs/backlog/mashina-sostoyaniy-biblioteka.md deleted file mode 100644 index e039e2b..0000000 --- a/docs/backlog/mashina-sostoyaniy-biblioteka.md +++ /dev/null @@ -1,7 +0,0 @@ -# Машина состояний на go-библиотеке - -**Приоритет:** средний - -Сейчас FSM реализована вручную в worker. Выбрать подходящую go-библиотеку для описания воркфлоу/машины состояний и перевести переходы на неё — ради декларативности, проверяемости переходов и единого места правды. Кандидаты для оценки: looplab/fsm, qmuntal/stateless (и аналоги). Граф и переходы уже формализованы — переносим один в один. - -Связано: specs/workflow.md (текущий граф состояний). diff --git a/docs/backlog/masshtab-100-zagruzok.md b/docs/backlog/masshtab-100-zagruzok.md index 7d51b63..f4f062b 100644 --- a/docs/backlog/masshtab-100-zagruzok.md +++ b/docs/backlog/masshtab-100-zagruzok.md @@ -1,6 +1,6 @@ # НФТ: масштаб до 100 одновременных загрузок (потолок — 1000) -**Приоритет:** высокий +**Приоритет:** средний Потолок по нагрузке нигде не зафиксирован: воркер, поллинг qBittorrent, пул LLM-вызовов и запись в SQLite спроектированы «на глаз». Записать в НФТ целевой ориентир — архитектура держит до 100 одновременных загрузок в работе (приём → распознавание → раскладка), план-максимум — 1000. Сама запись требования дешева и высокоценна: задаёт рамку для решений ниже. Отдельно (дороже) — аудит узких мест: одиночное соединение SQLite и сериализация записи, конкурентность воркера и лимит параллельных распознаваний, частота/стоимость поллинга и дедуп при наплыве. diff --git a/docs/backlog/telegram-match-metabazy.md b/docs/backlog/telegram-match-metabazy.md index f7c8ecb..6067882 100644 --- a/docs/backlog/telegram-match-metabazy.md +++ b/docs/backlog/telegram-match-metabazy.md @@ -1,6 +1,6 @@ # Улучшения UI: показывать матч с записью метабазы в Telegram -**Приоритет:** средний +**Приоритет:** низкий Web-сторона реализована: страница загрузки /download/{id} и экран ревью показывают, с какой именно записью метабазы (TMDB/TVDB/IMDb) сматчилась загрузка — провайдер, id и ссылку. Осталось довести то же в Telegram: в уведомлениях/подтверждениях показывать запись матча (название, год, провайдер-id, ссылку), чтобы ошибочную привязку было видно и из бота. Полный выбор источника в вебе уже реализован. diff --git a/docs/backlog/vneshnie-subtitry.md b/docs/backlog/vneshnie-subtitry.md index 23ad76a..9a5bc9d 100644 --- a/docs/backlog/vneshnie-subtitry.md +++ b/docs/backlog/vneshnie-subtitry.md @@ -1,7 +1,21 @@ -# Привязка внешних субтитров к серии (сериалы) +# Внешние субтитры: пары VobSub и языковой суффикс **Приоритет:** средний -Аудит спек↔код (2026-07-03): спека recognition требует «внешние субтитры SHALL привязываться к соответствующему видео». Для фильма работает — раскладка именует субтитр по базе видеофайла. Для сериала связь субтитр→конкретная серия не выражена: в PlanFile нет поля привязки, и нет логики спаривания VobSub .idx+.sub. Смоделировать привязку субтитра к эпизоду (поле на PlanFile или роль с season/episode) и спаривание .idx+.sub, либо — если откладываем — сузить формулировку спеки до реального поведения. +Базовая привязка субтитр→серия для сериала уже работает: `layout.PlanFile` несёт +`Season/Episode`, а `seriesDst` именует субтитр по стему эпизода +(`internal/layout/layout.go`, код старше аудита 2026-07-03). Для фильма тоже — +субтитр именуется по базе видеофайла. + +Реальные пробелы, оставшиеся от аудита: + +- **Пары VobSub** `.idx`+`.sub` не спариваются — их надо переносить вместе как одну + дорожку. +- **Языковой суффикс теряется:** у `recognize.PlanFile` нет полей `Lang/Flags`, и + `toLayoutPlan` (`internal/httpapi/review.go`) не проставляет язык — субтитр ляжет + без `*.ru.srt`-суффикса, который ждёт Jellyfin. + +Смоделировать язык/флаги субтитра сквозь recognize→layout и спаривание `.idx`+`.sub`; +спека recognition уже требует «внешние субтитры SHALL привязываться к видео». Связано: openspec/specs/recognition, specs/jellyfin-layout.md, пакеты recognize, layout.