Штатные конфликты и промахи ввода возвращались голым fmt.Errorf, поэтому
classifyErr отправлял их в 500 «внутренняя ошибка» вместо 409/400 (и logCmd
писал ERROR вместо DEBUG). Продолжение f8fb4fa (Tier A), по итогам ревью Fable.
Классификация ошибок:
- новый sentinel worker.ErrInvalidInput → 400 для валидации ввода команд
(refine/set type/ignore/add source/set provider/choose candidate);
- обёртки %w ErrConflict в Cancel/Retry/Defer/Undo (штатный конфликт состояния);
- classifyErr: ErrInvalidInput→400, layout.ErrCollision→409 (коллизия цели
штатно уводит в review); ветка ErrCollision в tgbot (сообщение + refreshCard);
- logCmd относит ErrInvalidInput и ErrCollision в DEBUG «command rejected».
Конвенции (docs/conventions):
- logging.md: публичные команды воркера = доменная граница (лог один раз,
logCmd); таблица уровней доменных отказов (граница команды vs асинхронная
стадия); правило про *url.Error/секреты в URL; канон категории
state transition; уровень повторяющихся сбоев фоновых циклов;
- errors.md: таблица маппинга ошибка→статус; развилка «транзиентный ответ vs
персистентная диагностика» решена как (а) — error_msg/reasons на review-экране
и tg-карточке = операторская поверхность владельца (сырой текст ок, секреты
запрещены; аудит подтвердил, что секреты туда не текут).
Унификация категории лога state transition: cancel/retry/relink/recovery
переведены с семантических msg на общий state transition (from/to) — весь
жизненный цикл собирается одним jq-фильтром.
Мелочи: reason-коды linkPlan в const-блок; httpapi лог-поля id→download_id и
msg «… failed»; комментарий «почему» у parseIgnored; preview build failure в
ReviewData DEBUG→WARN.
Беклог: задача сведена к остатку (ext.* ERROR-шторм при недоступном qBittorrent
+ эскалация устойчивого сбоя тика), понижена в приоритете.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Беклог
Единый список будущих задач по проекту: то, что уже решили сделать, и идеи,
которые ещё надо обдумать. Это источник истины по беклогу — одна задача = один
файл в этом каталоге. Не план реализации и не спецификация: принятое и
реализованное переезжает в docs/specs/docs/adr, а сам
пункт беклога удаляется.
Приоритет — грубая оценка «ценность / стоимость», не обязательство к порядку.
Спекулятивные пункты (ещё без решения «делаем») помечены префиксом [идея] в
названии — их сперва надо проработать. Пункты, помеченные (ревью 2026-07-08),
пришли из тщательного ревью ingest/worker/жизненного цикла (см. общий тег в теле).
Tududi (проект jellybit) больше не держит беклог — он служит только
инбоксом сырых идей. Прежде чем идея станет задачей, её оформляют файлом здесь.
Высокий
- Раздачи с докачиванием (merge при повторном добавлении) — Свежий сериал раздают по мере выхода: торрент с 5 из 10 эпизодов позже перезаливают…
- Ретеншн и очистка БД — Терминальные задачи (done/cancelled/failed/reverted), их попытки recognition с сырыми…
- Eval-харнес распознавания (корпус кейсов + метрика точности) — Распознавание — ядро продукта, но смена модели или правка промпта сейчас вслепую…
Средний
- Словарь единого языка (ubiquitous language) — Свести термины домена в один глоссарий, чтобы пользователь, документация, код и агент…
- Агенты-ревьюверы качества (наименования, архитектура, конвенции, стиль) — Ядро (specs+code ревьюверы) сделано и вшито в task-pipeline; остался ревьювер наименований (ждёт словарь единого языка)
- [идея] Сила совпадения кандидата и пересмотр распознавания/матчинга — ИДЕЯ (сперва проработать)
- История переходов загрузки — Сохранять полную историю переходов состояний загрузки (что/когда/почему/кто инициировал…
- Привязка уведомлений к источнику в ботах (мульти-бот) — Уведомления и запросы подтверждения должен получать тот, кто прислал загрузку: автор…
- [идея] Сложные сериальные раздачи: все сезоны разом, паки, спецраскладки — ИДЕЯ (проработать крайние случаи)
- Аниме с абсолютной нумерацией — Релизы аниме часто нумеруют серии сквозным числом (#137) без сезонов, а Jellyfin ждёт…
- Бэкап SQLite — architecture
- Глубокий healthcheck и статус зависимостей — /healthz проверяет только сам сервис
- НФТ: масштаб до 100 одновременных загрузок (потолок — 1000) — Зафиксировать в НФТ ориентир 100/1000 загрузок + аудит узких мест (SQLite, воркер, поллинг)
- Обучение на правках человека (few-shot из прошлых ревью) — Когда человек поправил матч, тип или нумерацию — сохранять это как пример и подмешивать…
- Confidence-гейт авто-раскладки: узаконить в спеке + сделать выключаемым (дефолт 0.7) — Решено (B): гейт оставляем как доп. проверку на ревью — выключаемый порог, дефолт 0.85→0.7, записать в спеку
- Внешние субтитры: пары VobSub и языковой суффикс — Привязка субтитр→серия уже работает; остались пары VobSub .idx+.sub и потеря Lang/Flags
- Defer из catched → лимбо → необратимый deleted (MAJOR-6) — Defer из ещё-не-добавленного catched уводит задачу в необратимый deleted (ревью 2026-07-08)
- processCatched: promote-without-add если торрент уже в qBittorrent (F2) — торрент уже в qBittorrent → processCatched зациклен на Add вместо promote (ревью 2026-07-08)
- Cancel во время add оставляет неуправляемый торрент в qBittorrent (F3/NIT-13) — Cancel во время add оставляет неуправляемый торрент в qBittorrent (ревью 2026-07-08)
Низкий
- Панель действий ревью вне htmx-свопа блока источника — При выборе источника одним кликом обновляется только блок источника (#source-block)…
- Мгновенные обновления через SSE — Живые обновления прогресса сейчас на htmx-поллинге (фаза 2 веб-UI) — просто и работает…
- Шум ERROR фоновых циклов при недоступной зависимости — Остаток задачи логирования: ext.* ERROR-шторм при недоступном qBittorrent + эскалация устойчивого сбоя тика (ревью Fable)
- Версии/качество одного тайтла (репаки, апгрейд 1080p → 2160p) — По калибровке болей (2026-07-02) — не боль, из приоритета выпало
- [идея] Многоступенчатая верификация привязки — ИДЕЯ (требует проработки)
- Выбор из нескольких находок метабазы в Telegram — Когда распознавание даёт несколько подходящих кандидатов в метабазе, предлагать их в…
- Улучшения UI: показывать матч с записью метабазы в Telegram — Название/год/провайдер+id в боте уже выводятся; осталась кликабельная ссылка на запись
- Добавление торрентов файлом/ссылкой — «единое окно» (остаток: URL) — magnet и .torrent-файл приняты; остался фетч .torrent по URL (нужен SSRF-гард)
- Форма приёма: длинное имя .torrent-файла ломает верстку add-row — длинное имя файла распирает лейбл файл-пикера, поле source сжимается — нужен ellipsis
- Раздачи-копии диска (DVD/BluRay: VIDEO_TS/BDMV) — Иногда для очень редких фильмов скачивается не один видеофайл, а полная копия диска…
- Проверка свободного места перед copy-fallback — Когда хардлинк невозможен (EXDEV/ENOTSUP/…), layout копирует файл, дублируя место на диске
- Кэш метабаз (и опционально LLM) — Повторные и ретраящиеся прогоны распознавания бьют TMDB/TVDB/TVMaze одним и тем же…
- [идея] guessit как сервис-спутник — ИДЕЯ
- [идея] Завершение загрузки через webhook — ИДЕЯ (решим по опыту эксплуатации)
- Авторизация веб-UI (на будущее) — Решено для v1: без авторизации в доверенной LAN, опц
- Современный Web-UI как PWA — Переделать веб-интерфейс в современное PWA-приложение (устанавливаемое, отзывчивое…
- Сделать фавиконку для jellybit — мелкая косметика: иконка вкладки/PWA для веб-UI
- Идентичность инфохэшей: split v1/v2 одного торрента + крафт-магнет отравляет владение (F4, F5) — split v1/v2 идентичность и крафт-магнет отравляют владение инфохэшами (ревью 2026-07-08)
- Приём/UI: мелкие фиксы границ и парсинга (F7, F8, F9, F10, N2) — мелочи приёма/UI: oversized→500, гонки дедупа, парсинг magnet, cap контекста, руны (ревью 2026-07-08)
- Жизненный цикл: мелкие находки (MINOR-8, MINOR-9, NIT-11, NIT-12) — claim-token распознавания, I/O под глобальным mutex, мелкие lookup/retry (ревью 2026-07-08)
- Нити приёма: NoName в контексте, устаревшие комментарии, лог без причины, bencode-аллокации (N1, N3, N4, N5) — косметика приёма: NoName в контексте, устаревшие комментарии, лог, bencode-аллокации (ревью 2026-07-08)