From 2ed9c9020f23fa6d0d34051ee5f65ab850adfaf1 Mon Sep 17 00:00:00 2001 From: Anton Vakhrushev Date: Fri, 3 Jul 2026 21:32:02 +0300 Subject: [PATCH] =?UTF-8?q?=D0=91=D0=B5=D0=BA=D0=BB=D0=BE=D0=B3:=203=20?= =?UTF-8?q?=D0=BF=D1=83=D0=BD=D0=BA=D1=82=D0=B0=20=D0=B8=D0=B7=20=D0=B0?= =?UTF-8?q?=D1=83=D0=B4=D0=B8=D1=82=D0=B0=20=D1=81=D0=BF=D0=B5=D0=BA?= =?UTF-8?q?=E2=86=94=D0=BA=D0=BE=D0=B4=20+=20=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BA=D0=B0=20=D1=84=D0=BE=D1=80=D0=BC=D1=83=D0=BB=D0=B8=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=BA=D0=B8=20per-download=20(docs)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit По итогам аудита соответствия спек и кода (11 сабагентов, по одному на capability): Беклог: - новый пункт: гейт авто-раскладки по confidence (спека говорит «вспомогательный сигнал», код делает жёсткий AutoThreshold=0.85) — определиться, что правда - новый пункт: привязка внешних субтитров к серии (спека требует, для сериала связь субтитр→эпизод и пары .idx/.sub в коде не выражены) - новый пункт: раздачи-копии диска DVD/BluRay (VIDEO_TS/BDMV — каталог целиком, не пофайловый разбор) - дополнен существующий баг TVDB /series/: спека metadata-match теперь тоже кодифицирует баг — фикс должен править и требование Спеки (правка на точность, поведение не меняется): - download-tracking, review: «per-download блокировка» → «единая блокировка воркера» (по факту глобальный w.mu, а не per-download) openspec validate --strict — проходит. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/backlog.md | 60 +++++++++++++++++++++++- openspec/specs/download-tracking/spec.md | 11 +++-- openspec/specs/review/spec.md | 2 +- 3 files changed, 66 insertions(+), 7 deletions(-) diff --git a/docs/backlog.md b/docs/backlog.md index 681f0c2..264591d 100644 --- a/docs/backlog.md +++ b/docs/backlog.md @@ -291,6 +291,57 @@ qBittorrent, без исходящих запросов на пользоват [«Многоступенчатая верификация»](#многоступенчатая-верификация-привязки-идея), [architecture.md](specs/architecture.md) → «Хранилище» (`hint`, `override`). +### Гейт авто-раскладки по `confidence`: спека vs код + +Аудит спек↔код (2026-07-03) нашёл расхождение в модели уверенности. +Спека `recognition` (унаследовано из `recognition.md`) утверждает, что +самооценка LLM `confidence` — **вспомогательный сигнал, НЕ единственный гейт**: +при подтверждённом матче в базе + чистой структурной валидации + согласованности +сигналов авто-раскладка допускается. Код же (`internal/recognize/validate.go`, +`confidence < AutoThreshold`, дефолт 0.85) делает `confidence` **жёстким +блокирующим условием**: план с матчем и чистой валидацией, но `confidence` 0.5 +уйдёт в review вопреки сценарию спеки. Нужно определиться, что правда: либо +признать порог `AutoThreshold` в спеке как легитимный гейт (скорее так — код его +осознанно ввёл конфигом), либо ослабить код. Заодно `AutoThreshold` как +конфигурируемый гейт спекой не описан. + +Связано: `openspec/specs/recognition` (требование «Модель уверенности и решение +auto/review»), +[ADR-2026-06-13-auto-link-requires-db-match](adr/ADR-2026-06-13-auto-link-requires-db-match.md), +пакет `recognize`. + +### Привязка внешних субтитров к серии (сериалы) + +Аудит спек↔код (2026-07-03): спека `recognition` требует «внешние субтитры SHALL +привязываться к соответствующему видео». Для **фильма** это работает — раскладка +именует субтитр по базе видеофайла. Для **сериала** связь субтитр→конкретная +серия не выражена: в `PlanFile` (`internal/recognize`) нет поля привязки, и нет +логики спаривания VobSub `.idx`+`.sub`. Нужно смоделировать привязку субтитра к +эпизоду (поле на `PlanFile` или роль с указанием `season`/`episode`) и спаривание +`.idx`+`.sub`, либо — если поддержку откладываем — сузить формулировку спеки до +реального поведения. + +Связано: `openspec/specs/recognition` (требование «Роли файлов на краях»), +[jellyfin-layout.md](specs/jellyfin-layout.md) (имена субтитров), пакеты +`recognize`, `layout`. + +### Раздачи-копии диска (DVD/BluRay: VIDEO_TS/BDMV) + +Иногда для очень редких фильмов скачивается не один видеофайл, а **полная копия +диска** — структура `VIDEO_TS/` (DVD: `VIDEO_TS.IFO`, `VTS_01_1.VOB`…) или +`BDMV/` (BluRay: `BDMV/STREAM/*.m2ts`, `index.bdmv`). Сейчас распознавание и +раскладка заточены под пофайловый разбор (один main-видеофайл фильма / серии +сериала), а тут «фильм» — это **каталог целиком**. Jellyfin такие раскладки +поддерживает (папка фильма с вложенным `VIDEO_TS`/`BDMV`), нам нужно: распознать, +что раздача — это образ диска (по наличию `VIDEO_TS`/`BDMV`), не пытаться +разбирать её по отдельным VOB/m2ts как серии, и разложить весь каталог диска +хардлинками в папку фильма Jellyfin (`Название (Год)/VIDEO_TS/…`). Крайний, но +реальный случай для редких изданий; частота низкая, поэтому в «Среднем». + +Связано: [recognition.md](specs/recognition.md) (роли файлов, что игнорируем), +[jellyfin-layout.md](specs/jellyfin-layout.md) (раскладка фильма, крайние +случаи), пакеты `recognize`, `layout`. + ## Низкий ### Баг: ссылка на запись TVDB всегда `/series/` (для фильмов ведёт не туда) @@ -307,8 +358,15 @@ URL кандидата хардкодит `.../dereferrer/series/{id}` (там виден в UI. Фикс — подставлять тип запроса в URL (одна строка); заодно свериться, что `providerURL` не расходится по типам. +> Аудит спек↔код (2026-07-03) подтвердил баг и выявил, что спека +> `metadata-match` теперь тоже «узаконивает» его: требование «Кандидат несёт +> URL» задаёт для TVDB единственный формат `/dereferrer/series/{id}` без +> различения типа. Фикс должен править и код, и это требование (movie-вариант +> по аналогии с TMDB). + Связано: [recognition.md](specs/recognition.md) (сверка с базой, кандидаты), -пакеты `metadata`, `httpapi`. +`openspec/specs/metadata-match` (требование «Кандидат несёт URL»), пакеты +`metadata`, `httpapi`. ### Мгновенные обновления через SSE diff --git a/openspec/specs/download-tracking/spec.md b/openspec/specs/download-tracking/spec.md index 6810246..4c2ea86 100644 --- a/openspec/specs/download-tracking/spec.md +++ b/openspec/specs/download-tracking/spec.md @@ -78,12 +78,13 @@ Worker SHALL периодически сверять раздачи qBittorrent - **WHEN** worker сверяет qBittorrent с БД - **THEN** для раздачи заводится загрузка в состоянии `downloading` -### Requirement: Переходы состояний под per-download блокировкой +### Requirement: Переходы состояний сериализуются воркером -Все переходы состояний загрузки SHALL проходить через worker под per-download -блокировкой, чтобы два транспорта не гонялись за одно состояние. Состояние SHALL -быть персистентным в SQLite; активность загрузки SHALL выводиться только из -`state`, без отдельного флага. +Все переходы состояний загрузки SHALL сериализоваться worker'ом под единой +блокировкой (поллинг-цикл и команды всех транспортов проходят через неё), чтобы +два источника перехода не гонялись за одно состояние. Состояние SHALL быть +персистентным в SQLite; активность загрузки SHALL выводиться только из `state`, +без отдельного флага. #### Scenario: Команды сериализуются diff --git a/openspec/specs/review/spec.md b/openspec/specs/review/spec.md index c5f1442..2f191d8 100644 --- a/openspec/specs/review/spec.md +++ b/openspec/specs/review/spec.md @@ -33,7 +33,7 @@ movie↔series), **Игнор файла**, **Позже** (`deferred`), **От (`cancelled`), **Undo** (снять созданные ссылки → `reverted`) и **Привязать заново** (из `reverted`/`cancelled`/`target_missing` → перераспознавание с ручным подтверждением). Команды из любого транспорта SHALL сериализоваться worker'ом под -per-download блокировкой; применяется последняя валидная команда. Команды, +единой блокировкой; применяется последняя валидная команда. Команды, которым нужен источник, SHALL проверять его наличие синхронно перед действием. #### Scenario: Применение создаёт раскладку