Files
jellybit/openspec/changes/large-release-recognition/tasks.md
T
av 01ac0430a9 спека: заведён change large-release-recognition для больших раздач
- контракт с моделью переводится на адресацию файла номером строки списка,
  усечение промпта снимается, лимиты уходят в конфиг
- раскладка показывает все файлы раздачи, покрытие плана блокирует авто
  только при непокрытом видеофайле
2026-09-02 08:54:32 +03:00

11 KiB
Raw Blame History

1. Признак обрыва генерации из LLM

  • 1.1 Довести finish_reason до вызывающего: добавить поле в llm.Response, заполнить его в internal/llm/openai.go (сейчас разбирается и выбрасывается)
  • 1.2 Тест internal/llm: ответ с finish_reason: "length" доносит признак обрыва до вызывающего

2. Компактный формат ответа модели

  • 2.1 Добавить Index в recognize.PlanFile (i в JSON), Src оставить для запасного формата
  • 2.2 Переписать схему в schemaText (prompt.go) под адресацию номером: i вместо src, явно оговорить, что для ролей sample/ignore/extra номера сезона и серии не нужны, а notes — не более пары предложений
  • 2.3 Поправить шапку списка файлов в writeFileList: номер строки — это то, что нужно вернуть в i
  • 2.4 Резолв номера в validate.go: при i в диапазоне 1..len(in.Files) заполнять Src из своего списка
  • 2.5 Сохранить приём старого формата: пришёл src без i — проверять совпадение с реальным файлом торрента, как сегодня
  • 2.6 Элемент с обоими полями резолвить по i; несовпадение присланного src с резолвом — причина ревью, а не тихое затирание
  • 2.7 Отбраковка негодных элементов вместо отказа от плана: номер вне диапазона, повторная адресация файла (побеждает первый элемент), элемент без номера и пути — элемент отбрасывается, план живёт, каждая отбраковка названа причиной; план без единого годного файла считается неразобранным
  • 2.8 Убедиться, что отбраковка элементов не порождает correction-ретрая (это не ошибка разбора)
  • 2.9 Тесты internal/recognize: резолв номера в путь; номер вне диапазона; дубль адресации; элемент без i и src; запасной формат с src; i и src вместе — совпадающие и расходящиеся; план, где годных элементов не осталось. Отдельно: резолв не паникует ни на одном входе (i = 0, отрицательное, len+1, дробное или строковое в JSON, пустой files[], files[] длиннее списка раздачи)

3. Порядок списка файлов — свойство узла

  • 3.1 Упорядочивать список файлов по пути внутри Recognize, а не у вызывающего: сборки Input две — internal/worker/review.go:126 и cmd/jellybit/recognize.go:101
  • 3.2 Печать промпта и резолв номеров идут по одному и тому же упорядоченному срезу на всех попытках, включая correction-ретрай
  • 3.3 Тест: Recognize с перемешанным Input даёт ту же нумерацию, что и с упорядоченным (тест зовёт узел, а не воркер)

4. Лимиты в конфиг

  • 4.1 Добавить [recognition].max_files и [recognition].max_tokens в internal/config с валидацией и дефолтами 500 и 8000
  • 4.2 Пробросить их в recognize.Config на сборке зависимостей (воркер и CLI)
  • 4.3 Описать обе настройки в config.example.toml (назначение, диапазон, единицы) и в docs/database.md (настройки с числовым значением)
  • 4.4 Тест конфига: дефолты применяются, невалидные значения отвергаются

5. Цена попытки не растёт с размером раздачи

  • 5.1 Убрать повторную печать списка файлов из correctionMessage (prompt.go:180): номера названы в первом сообщении диалога
  • 5.2 Обрыв ответа по длине — review с причиной «ответ модели обрезан», без повторного запроса ни тем же промптом, ни его вариантом
  • 5.3 Усечение списка пределом max_files — отдельная причина ухода в review; знаменатель покрытия считается по полному числу файлов раздачи, а не по усечённому списку
  • 5.4 Отказ модели по размеру запроса называть отдельной причиной, а не текстом провайдера
  • 5.5 Тесты: correction-ретрай не содержит списка файлов и сопоставим по размеру с первой попыткой; обрыв не порождает ни одного повторного запроса (тест считает вызовы фейкового клиента); снятие лимита не умножает число попыток сверх [llm].max_retries

6. Свёртка причин и покрытие плана

  • 6.1 Переписать seriesWarnings (validate.go:186): одна причина на сезон с перечнем недостающих серий вместо строки на каждый разрыв
  • 6.2 Завести перечень видеорасширений в одном месте рядом с ролями файлов (в проекте такого места сегодня нет) и покрыть его тестом
  • 6.3 Покрытие плана: число «в плане N из M» показывается, когда покрыты не все файлы; блокирующей причиной становится только непокрытый видеофайл, файлы-спутники в решение auto/review не входят
  • 6.4 Тесты: сезон с тремя дырами даёт одну причину; непокрытый видеофайл уводит в review; раздача, где не покрыты только .nfo и скриншоты, авто-раскладку не теряет

7. Список файлов раздачи рядом с планом

  • 7.1 Миграция 0012: колонка со списком файлов раздачи (JSON: путь и размер) в таблице recognition
  • 7.2 Обновить ER-схему в docs/database.md — иначе краснеет шаг canon гейта
  • 7.3 Заполнять колонку при создании записи распознавания из того же Input, из которого построен план (снимок и src плана обязаны происходить из одного среза); читать при рендере страниц загрузки и ревью
  • 7.4 Записи, созданные до миграции: рендер строит строки по плану и явно называет, что список файлов недоступен и полнота не гарантирована — молчаливой деградации быть не должно

8. Раскладка показывает все файлы

  • 8.1 Развернуть buildFileRows (internal/httpapi/files.go) на файлы раздачи: план подмешивается по src, файл без записи получает пометку «не в плане»; ровно одна строка на файл раздачи
  • 8.2 Полный ключ сортировки: разложенные (сезон, серия, путь) → файлы плана без цели (extra/sample/ignore, по пути) → файлы вне плана (по пути); пустые season/episode не поднимают файл в начало списка
  • 8.3 Отобразить пометку «не в плане» и строку о недоступном списке файлов в шаблонах раскладки в единой дизайн-системе
  • 8.4 Колонка # в web/templates/partials/layout_widget.html:8 печатает порядковый номер строки — привести её к номеру адресации из списка распознавания либо убрать: расхождение сделает разбор ошибок адресации ложным
  • 8.5 Тесты internal/httpapi: файл вне плана присутствует в строках без целевого пути; порядок строк не зависит от порядка plan.Files (тест с перемешанным планом); запись без сохранённого списка файлов даёт строку о недоступности

9. Проверка на живом кейсе

  • 9.1 task gate зелёный
  • 9.2 Прогнать распознавание раздачи «Отчаянные домохозяйки» (180 файлов) на рабочем эндпоинте: план покрывает все файлы, причины ревью читаются с одного взгляда, раскладка упорядочена по сезонам
  • 9.3 Сверить фактический размер ответа модели с max_tokens: подтвердить, что запаса хватает, и при необходимости поправить дефолт
  • 9.4 Проверить, что сырой ответ модели и ключ LLM не попадают в лог (docs/conventions/logging.md), а отброшенные элементы и файлы вне плана видны числом в причинах